Nokia6100液晶って130x130なんですけどの続きです。
お約束というか、ネギ振りをさせてみました。
問題なのは画像のサイズです。とりあえずATMega88からATMega168に変えました(ROMサイズ8k→16k)。130x130のデータは大きすぎるので56x48の縮小版です。絵の縮小はubuntuのGIMPを使いました。
56x48でもドットの数は2688(= 56x48)です。1ドット2バイトとして5376バイト、1.5バイトでも4032バイトです。ネギ振りの絵は6枚あるので、16kでもROMの容量が足りません。しかたがないので圧縮することにしました。難しいことはできないので、ランレングスで圧縮します。1ドット2バイト表現の上位4ビットが余っているので、ここにランレングスをいれることにしました。4ビットなので、0~Fで1~16を表すことにします。結果として5376バイトが2170バイトに縮みました。
また、アニメーション部分は変化したところだけ書き直すようにしました。結局、元画像+変化分6枚を8004バイトに圧縮できました。コードが1kくらいなので全部で9002バイトです。もっとがんばればATMega88に入れれるかもしれません。
表示部分のソースです。
圧縮するプログラムのバグがなかなか取れなくて苦労しました。
変化部分は、変化する部分を囲む四角にしていますが、複数の四角にした方が効率は良さそうです。複数の四角を組み合わせて変化部分を囲むアルゴリズムは思いつきませんでした。変化部分は、透明色ありにすればランが伸びるのでもっと圧縮できそうです。ただし、この液晶モジュールはデータの読み出しができないので、座標をスキップすることになります。
携帯のヒンジが壊れたらしく、表示される色が変です。そろそろ買い換え時なのかな。
お約束というか、ネギ振りをさせてみました。
問題なのは画像のサイズです。とりあえずATMega88からATMega168に変えました(ROMサイズ8k→16k)。130x130のデータは大きすぎるので56x48の縮小版です。絵の縮小はubuntuのGIMPを使いました。
56x48でもドットの数は2688(= 56x48)です。1ドット2バイトとして5376バイト、1.5バイトでも4032バイトです。ネギ振りの絵は6枚あるので、16kでもROMの容量が足りません。しかたがないので圧縮することにしました。難しいことはできないので、ランレングスで圧縮します。1ドット2バイト表現の上位4ビットが余っているので、ここにランレングスをいれることにしました。4ビットなので、0~Fで1~16を表すことにします。結果として5376バイトが2170バイトに縮みました。
また、アニメーション部分は変化したところだけ書き直すようにしました。結局、元画像+変化分6枚を8004バイトに圧縮できました。コードが1kくらいなので全部で9002バイトです。もっとがんばればATMega88に入れれるかもしれません。
表示部分のソースです。
// 解凍&描画 // データ形式はLLLLRRRRGGGGBBBBでLLLLが長さ void lcd_unpack(const uint8_t *p, uint16_t size) { uint8_t c0, c1, n; lcd_cmd(RAMWR); do { c0 = pgm_read_byte(p++); n = c0 >> 4; c1 = pgm_read_byte(p++); do { lcd_data(c0); lcd_data(c1); } while(n--); } while(--size); } // 外部変数 extern const uint8_t miku[2170] PROGMEM; // (0,0)-(55,47) extern const uint8_t miku01[1152] PROGMEM; // (2,1)-(42,32) extern const uint8_t miku12[1156] PROGMEM; // (2,10)-(41,39) extern const uint8_t miku23[826] PROGMEM; // (5,21)-(42,39) extern const uint8_t miku34[684] PROGMEM; // (2,20)-(40,36) extern const uint8_t miku45[926] PROGMEM; // (2,5)-(40,29) extern const uint8_t miku50[1090] PROGMEM; // (6,1)-(41,32) #define X0 36 #define Y0 40 #define DELAY 100 int main() { lcd_init(); // 最初の絵 lcd_window(X0, Y0, X0 + 55, Y0 + 47); lcd_unpack(miku, sizeof(miku) / 2); while(1){ // 0→1 _delay_ms(DELAY); lcd_window(X0 + 2, Y0 + 1, X0 + 42, Y0 + 32); lcd_unpack(miku01, sizeof(miku01) / 2); // 1→2 _delay_ms(DELAY); lcd_window(X0 + 2, Y0 + 10, X0 + 41, Y0 + 39); lcd_unpack(miku12, sizeof(miku12) / 2); // 2→3 _delay_ms(DELAY); lcd_window(X0 + 5, Y0 + 21, X0 + 42, Y0 + 39); lcd_unpack(miku23, sizeof(miku23) / 2); // 3→4 _delay_ms(DELAY); lcd_window(X0 + 2, Y0 + 20, X0 + 40, Y0 + 36); lcd_unpack(miku34, sizeof(miku34) / 2); // 4→5 _delay_ms(DELAY); lcd_window(X0 + 2, Y0 + 5, X0 + 40, Y0 + 29); lcd_unpack(miku45, sizeof(miku45) / 2); // 5→0 _delay_ms(DELAY); lcd_window(X0 + 6, Y0 + 1, X0 + 41, Y0 + 32); lcd_unpack(miku50, sizeof(miku50) / 2); } }
圧縮するプログラムのバグがなかなか取れなくて苦労しました。
変化部分は、変化する部分を囲む四角にしていますが、複数の四角にした方が効率は良さそうです。複数の四角を組み合わせて変化部分を囲むアルゴリズムは思いつきませんでした。変化部分は、透明色ありにすればランが伸びるのでもっと圧縮できそうです。ただし、この液晶モジュールはデータの読み出しができないので、座標をスキップすることになります。
携帯のヒンジが壊れたらしく、表示される色が変です。そろそろ買い換え時なのかな。
ネギ振りは見たかったので感激です。
RAMがもっとあれば透明処理もできそうですね。mega128クラスならできるかも。
でもDIPのmega168でやったことに意味があります。
拍手です。
掲示板ではお世話になりました。おかげさまでなんとかネギが振れました。思ったほど残像も出ずいい感じです。
秋月のシリアルROMを買ってきたので、もっと大きいのにも挑戦です。