日本語対応の電光掲示板ができました [Arduino]
いままでの成果
・I2C EEPROM
・日本語処理
・16x8 マトリックスLED
これらをまとめたものが完成しました。
再生できない場合、ダウンロードは🎥こちら
シリアルで入力した文字列を、スクロール表示するスケッチです。
ふと思ったのは、LinuxやMac OSだとシフトJISでないかもしれないことです。
しかし確認のしようがないのでごめんなさい。
あと、アナログピンソケットの接触不良は、ピンをすこし曲げることで応急処置が可能でした。
スケッチはビギナーらしく、きれいとは言えませんが、
i2c_eeprom_read_buffer()
sjisToElisa()
asciiToElisa()
matrixClear()
matrixRefresh()
これらの以前使ったものを再利用して、
さらに、シリアルからのテキストを受信/テキストをドットイメージに変換/スクロール表示部分を追加しました。
お恥ずかしながら、スケッチを載せます。
・I2C EEPROM
・日本語処理
・16x8 マトリックスLED
これらをまとめたものが完成しました。
再生できない場合、ダウンロードは🎥こちら
シリアルで入力した文字列を、スクロール表示するスケッチです。
ふと思ったのは、LinuxやMac OSだとシフトJISでないかもしれないことです。
しかし確認のしようがないのでごめんなさい。
あと、アナログピンソケットの接触不良は、ピンをすこし曲げることで応急処置が可能でした。
スケッチはビギナーらしく、きれいとは言えませんが、
i2c_eeprom_read_buffer()
sjisToElisa()
asciiToElisa()
matrixClear()
matrixRefresh()
これらの以前使ったものを再利用して、
さらに、シリアルからのテキストを受信/テキストをドットイメージに変換/スクロール表示部分を追加しました。
お恥ずかしながら、スケッチを載せます。
#include <Wire.h> //I2C library byte buf[8]; byte scrollText[64], scrollImage[256]; int scrollSpeed = 10; // 1行スクロールあたりのリフレッシュ回数(多いとゆっくり) boolean scrollHorizontal = true; // true 横、false 縦 void setup() { Wire.begin(); // initialise the connection Serial.begin(9600); } void loop() { unsigned int sjisH, sjisL; signed int elisa; int i, col, row, p = 0, len = 16; // テキストが届くまで待機 while( !getTextFromSerial( scrollText ) ); // テキストをイメージに展開 for( i = 0; i < 256; i++ ) scrollImage[ i ] = 0; // イメージ初期化 for( i = 0; i < 64; ) { sjisH = scrollText[ i++ ]; // 1byte 読み込む if( sjisH == 0 ) break; elisa = asciiToElisa ( sjisH ); // ASCII文字 → ELISAでの位置 if( elisa == -1 ) { // シフトJIS上位1バイトなら漢字を表示 sjisL = scrollText[ i++ ]; elisa = sjisToElisa( (sjisH << 8) + sjisL ); if( elisa == -1 ) continue; // 対応文字コードがなければ終了 } else if( elisa < -1 ) continue; // 制御コード、半角カナなどなら終了 i2c_eeprom_read_buffer( 0x50, elisa * 8, buf, 8 ); if( scrollHorizontal ) { // 横スクロールの場合 for( row = 0; row < 8; row++ ) { for( col = 0; col < 8; col++ ) { bitWrite( scrollImage[ len + col ], row , bitRead( buf[ row ], 7 - col ) ); } } } else { // 縦スクロールの場合 for( row = 0; row < 8; row++ ) scrollImage[ len + row ] = buf[ row ]; } len += 8; scrollImage[ len++ ] = 0; // 1文字毎に1行あける if( len >= 256 - 16 ) break; } // テキストをLED表示 while( !Serial.available() ) { for( i = 0; i < scrollSpeed; i++ ) matrixRefresh( &scrollImage[0] + p ); if( p > len ) p = 0; else p++; } } int getTextFromSerial( byte textdata[] ) { int i; if( !Serial.available() ) return 0; for( i = 0; i < 64; i++ ) { textdata[i] = Serial.read(); if( Serial.available() ) continue; delay(10); // 10msec待ってもデータがこなければ終了 if( Serial.available() ) continue; textdata[i + 1] = 0; break; } return i + 1; // 読み込んだ文字数を返す } // maybe let's not read more than 30 or 32 bytes at a time! void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) { Wire.beginTransmission(deviceaddress); Wire.send((int)(eeaddress >> 8)); // MSB Wire.send((int)(eeaddress & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(deviceaddress,length); int c = 0; for ( c = 0; c < length; c++ ) if (Wire.available()) buffer[c] = Wire.receive(); } signed int sjisToElisa(unsigned int sjiscode) { // シフトJISからELISAフォント上の位置に byte jisH, jisL; int sp, jiscode; // まず、シフトJISをJISに変換 jisH = sjiscode / 256; // 上位バイト jisL = sjiscode % 256; // 下位バイト jisH = (jisH - ((jisH <= 0x9F) ? 0x71:0xB1)) * 2 + 1; if( jisL > 0x7F ) jisL--; if( jisL >= 0x9E ) jisH++; jisL -= ((jisL >= 0x9E) ? 0x7D:0x1F); jiscode = (jisH << 8) + jisL; // JISから ELISAフォントでの文字位置を計算 if (jiscode>=0x2121 && jiscode<=0x222e) sp = 0; // 一般記号 else if(jiscode>=0x223a && jiscode<=0x2241) sp = 11; // 集合記号 else if(jiscode>=0x224a && jiscode<=0x2250) sp = 19; // 論理記号 else if(jiscode>=0x225c && jiscode<=0x226a) sp = 30; // 幾何記号 else if(jiscode>=0x2272 && jiscode<=0x2279) sp = 37; // 音楽記号 else if(jiscode==0x227e) sp = 41; // 丸記号 else if(jiscode>=0x2330 && jiscode<=0x2339) sp = 56; // 数字 else if(jiscode>=0x2341 && jiscode<=0x235a) sp = 63; // 英大文字 else if(jiscode>=0x2361 && jiscode<=0x237a) sp = 69; // 英小文字 else if(jiscode>=0x2421 && jiscode<=0x2473) sp = 73; // ひらがな else if(jiscode>=0x2521 && jiscode<=0x2576) sp = 84; // カタカナ else if(jiscode>=0x2621 && jiscode<=0x2638) sp = 92; // ギリシャ大文字 else if(jiscode>=0x2641 && jiscode<=0x2658) sp = 100; // ギリシャ小文字 else if(jiscode>=0x2721 && jiscode<=0x2741) sp = 138; // キリル大文字 else if(jiscode>=0x2751 && jiscode<=0x2771) sp = 153; // キリル小文字 else if(jiscode>=0x2821 && jiscode<=0x2840) sp = 166; // 罫線 else if(jiscode>=0x3021 && jiscode<=0x4f53) sp = 886; // 第一水準漢字 else if(jiscode>=0x5021 && jiscode<=0x7426) sp = 929; // 第二水準漢字 else return -1; // 対応文字コードがなければ -1 return (jiscode / 256 - 0x21) * 94 + (jiscode % 256) - 0x21 - sp; } signed int asciiToElisa(unsigned int code) { // 半角を全角ELISAに変換 (半角カナはごめんなさい) static byte ElisaMark[] = { 0, 9, 40, 83, 79, 82, 84, 38, 41, 42, 85, 59, 3, 60, 4, 30, 6, 7, 66, 64, 67, 8, 86, 45, 78, 46, 15, 17, 13, 47, 34, 48, 16}; if((code>=0x81 && code<=0x9f) || (code>=0xe0 && code<=0xef)) return -1; // ★ シフトJIS上位1バイトは -1 ★ if(code < 32) return -2; // 制御文字 if(code <= 47) return ElisaMark[code-32]; // 記号 SP ! " # $ % & ' ( ) * + , - . / if(code <= 57) return code + 99; // 数字 if(code <= 64) return ElisaMark[code-42]; // 記号 : ; < = > ? if(code <= 90) return code + 92; // 英大文字 if(code <= 96) return ElisaMark[code-68]; // 記号 [ \ ] ^ _ if(code <= 122) return code + 86; // 英小文字 if(code <= 126) return ElisaMark[code-94]; // 記号 { | } ~ if(code == 127) return -2; // 制御文字 DEL if(code >= 0xa1 && code <= 0x9f) return -4; // 半角カタカナで return -3; // 未使用またはシフトJIS下位1バイト } void matrixClear() { for(int i = 0; i < 16; i++ ) pinMode( i + 2, INPUT ); } void matrixRefresh( byte bitmap[] ) { for(int x = 0; x < 16; x++ ){ matrixClear(); pinMode( x + 2, OUTPUT ); // 点灯する列を指定 digitalWrite( x + 2, LOW ); for(int y = 0; y < 8; y++ ) { // 指定列のデータを表示 if( bitRead( bitmap[x], y ) ) { pinMode( y + ( ( x < 8) ? 10 : 2 ) , OUTPUT ); digitalWrite( y + ( ( x < 8) ? 10 : 2 ) , HIGH ); } } delay(1); } }
2011-06-08 23:55
nice!(0)
コメント(0)
トラックバック(0)
コメント 0