ArduinoベースのシャワーキャビンFMラジオ
コンポーネントと消耗品
> ![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 6 | |||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
![]() |
| × | 1 | |||
| × | 1 |
このプロジェクトについて
数年前、私はラジオ付きのTR028制御システムを設置した中国のシャワーキャビンを購入しました。残念ながら、ある天気の良い日、私はこのシステムが完全に死んでいることに気づきました。誰も修理できなかったので、もっと安いシャワーラジオを買いました。約1年後に亡くなりました。
私の家族は以前シャワー室にラジオを持っていたので、私はこれらのラジオがどのように作られているかを研究し始めました。 TR028システムの中に、奇妙なTEA5767モジュールが見つかりました。いくつかの検索は、それが小さな安価なFMラジオモジュールであることを私に知らせました。検索結果で、別の興味深いFMラジオモジュールであるRDA5807を見つけました。 TEA5767と非常によく似ていますが、RDS、ボリュームコントロール、低音ブースト機能があります。そのため、新しいプロジェクトでRDA5807を使用することにしました。
インターネットを検索したところ、RDA5807モジュールが使用されているプロジェクトがいくつか見つかりました:
- 私のビジョンに影響を与えたメインプロジェクト。
- 優れた信号強度の兆候とより有用な情報を見つけたバリエーション。
- 別のバリエーション。
- 優れた無線モジュールライブラリ
- 役立つ情報(ロシア語)。
- もう1つ
これらのプロジェクトの1つを繰り返すことは可能でしたが、私のビジョンを正確に満たした人は誰もいませんでした。
私のビジョンは次のとおりです。
- 防水構造を確保するためのタッチスクリーン付きデバイス。 (私は死んだTR0289からのタッチパネル付きエンクロージャーを使用しました。)
- ラジオ
- いくつかのお気に入りのラジオ局のプリセット
- 音量調節
- 自動ラジオ局シーク機能
- 探しているラジオ局を暗記する可能性
- 現在の時刻を確認するための時計。
- オン/オフ機能
- ライトコントロール
- キャビン内の温度、RDSなどのマイナーな情報が表示されます。
私はAliexpressでRDA5807、32kbのEEPROMを備えたTiny RTC、PAM8403、NOKIA 5110 LCD、LM2596モジュールを10€未満で購入し、実験を開始しました。
最終的に得たもの:
- 2列(!)RDSのFMラジオ
- お気に入りのラジオ局用の6つのプリセット
- 自動または手動の調整
- お気に入りのラジオ局を6つのプリセットのいずれかに保存する可能性
- 音量と低音のブースト制御
- シャワーキャビンライトコントロール
- 時計の蟻のカレンダー
- RSSI(無線信号強度インジケーター)
- ステレオモードインジケーター
- オン/オフ機能
プロジェクトの写真 <図>

NOKIA 5110ディスプレイの場合、素敵なライブラリを見つけました
<図>
TR028タッチパネルがどのように機能するかを理解しました。実際には、2列X7行のキーパッドです。それを操作するために、私はこのライブラリを使用しました。
<図>
<図>

<図>

組み立てたボードを箱に入れます。 USBソケットをはんだ除去し、ケーブルを直接はんだ付けしたことがわかります。 PCを接続する可能性と将来のソフトウェアの改善のためです。
<図>
<図>

<図>

<図>

仕組み:
- 電源を接続した後、ラジオはオンになりません。これにより、電力線が安定していない場合や電力が失われた場合にラジオが再生されなくなります。初めてラジオをオンにするには、電源を接続し、数秒後に電源キーを押す必要があります。ラジオは、最後に再生されたラジオ局をレベル03の音量で再生します。動作モードはVOLUMEコントロールになります。ラジオをオフにするには、電源キーを押すだけです。デバイスは、LCD、LCDバックライト、アンプ、LED /ハロゲンランプをオフにします。
- ラジオ局を探すには、「Mod」ボタンを押して自動または手動のチューニングモードを選択できます。 「<」または「>」ボタンを押すと、ラジオは周波数を増減するラジオ局を検索します。見つかったラジオ局を保存するには、[Mem]ボタンを押してください。保存したい6つのプリセットの1つを4秒で選択できます。
- 現在の日付を表示するには、I(情報)キーを押します。日付は4秒で表示されます。コードのこの部分は、delay()関数を使用するため、最適化できます。
- 時計を調整するには、時報(時報)が聞こえたらDキーを2秒以上押し続けるか、正確な時計で1時間の最後の秒を確認します。 Dキーを離してhh.00.00を設定します。時計が15分から1分遅れた場合、分と秒は00に設定され、時間は1増加します。時計が1分から15分に急いでいた場合、調整手順の後、分と秒のみが00に設定されます。 。
何を変更しますか:
- RTCモジュールの共振器は精度が高くなりますが、クロック調整機能によりこの問題を解決できます。
- 5110LCDをより大きく明るいものに。プロジェクトで使用されているNOKIA5110 LCDの情報が読みにくい場合があるため、1、8 "、または2.0"のカラーLCDの場合があります。
- 2x15Wの出力電力または同じ特性のTDA7297を備えたPAM8610へのPAM8403アンプ。
結論:
私の新しいプロジェクトがどのように機能するかを嬉しく思います。時計の精度を除いて、1か月の作業後に問題は観察されませんでした。
私はプログラマーではないので、コードをより適切に最適化できます。私のC / C ++プログラミングの経験は約1年で、自己学習しています。これは、Arduinoプラットフォームを使用した最初の便利なプロジェクトであり、ハブで共有している最初のプロジェクトです。起こりうる間違いと私の悪い英語を理解し、許してください。
ご不明な点がございましたら、コメントやPMでお気軽にお問い合わせください。
アップデート1:ハードウェアとソフトウェアのマイナーアップデート。
ハードウェア-12Vラインに2Aヒューズを取り付けました。安全上の理由から。
ソフトウェア-586行の menu
を追加しました =
1;
これにより、電源キーを押した後、モードがVOLUMEに戻ります。
アップデート2:
残念ながら、私のラジオのLCDは死にそうです。
<図>

だから私は安いNOKIA5110LCDの代替品を探しています。小さくて読みにくいので、新しい5110LCDはインストールしません。 1.8インチTFTLCDを試してみようと思います。良い点は、大きく、明るく、解像度が高いことです。悪い点は、1.8インチTFTが重要なリソースをより多く消費すると確信しています。
LCDの交換に関するアドバイスは大歓迎です。
コード
- プロジェクトスケッチ
- 信号強度記号
プロジェクトスケッチ Arduino
/////////////////////////////////////////////// //////////////////// ArduinoベースのシャワーFMラジオプロジェクト//// Arduino NANO、RDA5807M、RTC、EEPROM、LCD5110、サーミスター//////// ////////////////////////////////////////////////// /////////#include//http://www.rinkydinkelectronics.com/library.php?id=48#include // https:// github。 com / cyberp / AT24Cx#include // Arduino IDE include#include //http://www.mathertel.de/Arduino/RadioLibrary.aspx#include // http://www.mathertel.de/Arduino/RadioLibrary.aspx#include //https://github.com/adafruit/RTClib#include // http:// www。 mathertel.de/Arduino/RadioLibrary.aspx#include //http://playground.arduino.cc/Code/Keypad#define MAXmenu 4#define ledPin 13#define blPin 7 //キーパッドのボタン[7] [2] ={{'L'、 'P'}、// LED、POWER {'I'、 'D'}、// INFO、DISPLAY {'1'、 '2 '}、//プリセット{' 3 '、' 4 '}、// from 1 {' 5 '、' 6 '}、// to 6 {' M '、' m '}、// MODE、MEM {' <'、'> '} // down、up}; byte rowPins [7] ={11 、12、10、17、9、16、8}; //キーパッドバイトの行ピン配置に接続しますcolPins [2] ={15、14}; //キーパッドの列ピン配置に接続します//キーパッドkpd =Keypad(makeKeymap(keys)、rowPins、colPins、ROWS、COLS); Keypad keypad =Keypad(makeKeymap(keys)、rowPins、colPins、7、2); boolean bass =0、dspl =0、memdisplay =0、mempress =0、adj =0; boolean ledPin_state、power_state; int menu; int volume、volumeOld =5; intfrequency、frequencyOld; int txtl =0、temparray =0; int samples [5]; unsigned int status [6]; unsigned long timeprevious =0、timeprev =0; // EEPROM objectAT24CX mem; RTC_DS1307 rtc; //(clk、din、dc、ce、rst)LCD5110 lcd(6、 5、4、2、3); // RDA5807チップradioRDA5807Mラジオのインスタンスを作成します; /// RDSパーサーを取得しますRDSParserrds; extern unsigned char SmallFont []; extern uint8_t signal5 []; extern uint8_t signal4 []; extern uint8_t signal3 []; extern uint8_t signal2 []; extern uint8_t signal1 []; // -------------------------- SETUP ---- ------------------------------ // void setup(){analogReference(EXTERNAL); Serial.begin(9600); Wire.begin(); // Radio radio.init();を初期化します。 radio.debugEnable(); //画面を初期化しますlcd.InitLCD(); lcd.clrScr(); //lcd.setContrast(45); //デフォルトが適切でない場合は調整しますlcd.setFont(SmallFont); lcd.enableSleep(); //スタンバイモードpower_state =0; //電源が接続されているときにユニットの「電源オン」(スタンバイモード)を行わないでください//キーボードを初期化しますkeypad.addStatedEventListener(keypadEvent); //このキーパッドのイベントリスナーを追加しますkeypad.setHoldTime(1500); pinMode(ledPin、OUTPUT); //デジタルピンを出力として設定します。 pinMode(blPin、OUTPUT); //デジタルピンを出力として設定します。 digitalWrite(ledPin、LOW); // LEDをオフにします。 digitalWrite(blPin、LOW); // BLをオフにします(スタンバイモード)ledPin_state =digitalRead(ledPin); //初期LED状態を保存します。 LEDが点灯しているときはHIGH。 // rtcを調整する必要がある場合はコメントを解除します/ * if(!rtc.isrunning()){Serial.println( "RTC is not running!"); //次の行は、RTCをこのスケッチがコンパイルされた日時に設定しますrtc.adjust(DateTime(F(__ DATE __)、F(__ TIME__))); //この行は、RTCに明示的な日付と時刻を設定します。たとえば、// 2014年1月21日午前3時に、次のように設定します。//rtc.adjust(DateTime(2018,3、13、22、33、0) ); } * ///最後の周波数周波数の値を読み取る=mem.readInt(201);ボリューム=2; //スタートメニューの音量レベル=1; //開始時にVOLUMMEモードを表示if(volume <0)volume =0; if(volume> 15)volume =15; if(頻度<0)頻度=0; if(頻度> 210)頻度=210; WriteReg(0x02、0xC00d); // 0xC00dをReg.2に書き込みます(ソフトリセット、有効化、RDS、)// bbz canal(frequency); // RDSデータの情報チェーンを設定します。 radio.attachReceiveRDS(RDS_process); rds.attachServicenNameCallback(DisplayServiceName); //rds.attachTimeCallback(DisplayTime); //将来の使用のため。 RDS信号が弱い場合は非常に不正確です。 rds.attachTextCallback(DisplayText);} // -----------------------セットアップの終了-------------- ---------------------- //// ------------------------ --LOOP ---------------------------------------- // void loop(){ if(周波数!=周波数Old){周波数Old =周波数; mem.writeInt(201、頻度);運河(頻度); } if(volume!=volumeOld){volumeOld =volume; WriteReg(5、0x84D0 |ボリューム); } //キーボードを読み取るcharkey =keypad.getKey(); // RDSデータをチェックしますradio.checkRDS(); //温度プローブを0.6秒ごとに5回読み取り、平均フロート平均を計算します。 unsigned long timenow =millis(); if((unsigned long)(timenow --timeprevious)> 600){timeprevious =timenow; samples [temparray] =analogRead(A7); temparray ++; } if(temparray ==5){//読み取り値の平均を計算するaverage =0; for(int i =0; i <5; i ++){平均+ =サンプル[i]; } printTemp(average); temparray =0; } // MEM表示の4秒のタイムアウトで、unsigned long dabar =millis();と入力します。 if(mempress ==1){timeprev =dabar; memdisplay =1; mempress =0; } if(memdisplay ==1){if((unsigned long)(dabar --timeprev)<4000){memdisplay =1; } else {memdisplay =0; }} / *時間調整手順:1。シリアルモニターを実行します。2。9600ボードを設定します。3。Enterキーを押してシリアル読み取りをアクティブにします。シリアルモニターは「HoursXX」と書き込む必要があります。5。mXXと書き込みます。ここで、XXは、あるタイムサーバーで読み取っている現在の分であり、Enterキーを押してRTC分を調整します。シリアルモニターは「MinutesXX」と書き込む必要があります。6。sXXを書き込みます。ここで、XXは、あるタイムサーバーでの現在の読み取り秒数であり、Enterキーを押してRTC秒数を調整します。シリアルモニターは「SecondsXX」と書く必要があります。7。調整できるのは時間のみです。つまり夏時間が変更されたとき。 8.時刻のみを修正する必要がある場合は、秒のみを調整できます。 9. RTCをゼロ(年、月、日など)から調整する必要がある場合は、RTC調整ステートメントの行のコメントを外し、スケッチをアップロードします。 * / DateTime now =rtc.now(); if(Serial.available()> 0){char t =Serial.read(); switch(t){case( 'h'):{unsigned int hours =Serial.parseInt(); rtc.adjust(DateTime(now.year()、now.month()、now.day()、hours、now.minute()、now.second())); Serial.println(F( "Hours")); Serial.println(時間);壊す; } case( 'm'):{unsigned int mins =Serial.parseInt(); rtc.adjust(DateTime(now.year()、now.month()、now.day()、now.hour()、mins、now.second())); Serial.println(F( "Minutes")); Serial.println(mins);壊す; } case( 's'):{unsigned int sec =Serial.parseInt(); rtc.adjust(DateTime(now.year()、now.month()、now.day()、now.hour()、now.minute()、sec)); Serial.println(F( "Seconds")); Serial.println(sec);壊す; }}} // LCDにさまざまな情報を表示するprintSignalStrength(); printLines(); printTime(); printFreq(); printStereo(); printMode(); printMenu(); printDate(); lcd.update();} // ------------------------ループの終わり-------------- ---------------------- // void printSignalStrength()// 0000から1111(0-63){unsigned int sig; Readstatus(); sig =status [1] / 1000; if((sig> =0)&&(sig <=12)){lcd.drawBitmap(1、1、signal1、17、6); } if((sig> =13)&&(sig <=24)){lcd.drawBitmap(1、1、signal2、17、6); } if((sig> =25)&&(sig <=36)){lcd.drawBitmap(1、1、signal3、17、6); } if((sig> =37)&&(sig <=48)){lcd.drawBitmap(1、1、signal4、17、6); } if(sig> =49){lcd.drawBitmap(1、1、signal5、17、6); }} void printLines(){lcd.drawLine(0、9、84、9); lcd.drawLine(0、39、84、39);} void printTemp(float average)//最適化できます:){average / =5;平均=1023 /平均-1;平均=51700 /平均;フロートスタインハート; steinhart =平均/ 50000; //(R / Ro)steinhart =log(steinhart); // ln(R / Ro)steinhart / =3950; // 1 / B * ln(R / Ro)steinhart + =1.0 /(25 + 273.15); // +(1 / To)steinhart =1.0 / steinhart; // steinhartを反転-=273.15; //摂氏変換inttmp =round(steinhart); lcd.printNumI(tmp、60、1、2); lcd.print(F( "〜C")、72、1);} /// RDSモードのときにLCDディスプレイのServiceNameテキストを更新します。voidDisplayServiceName(char * name){lcd.print(name、18、 22);} void DisplayText(char * text){// 2番目のRDS行をスクロールlcd.print(text、txtl、30); txtl =txtl-66; if(txtl ==-396)txtl =0;} void printTime(){DateTime now =rtc.now(); lcd.printNumI(now.hour()、24、1、2、 '0'); lcd.print( ":"、36、1); lcd.printNumI(now.minute()、42、1、2、 '0');} void printDate(){if(dspl ==1){//ディスプレイキーが押されたかどうかを確認ClearRDS(); DateTime now =rtc.now(); lcd.printNumI(now.year()、12、22、4); lcd.print( "。"、36、22); lcd.printNumI(now.month()、42、22、2、 '0'); lcd.print( "。"、54、22); lcd.printNumI(now.day()、60、22、2、 '0'); int dw =now.dayOfTheWeek();スイッチ(dw){ケース0:lcd.print(F( "Sekmadienis")、CENTER、30); // sdram breakを保存する日曜日のF()マクロ;ケース1:lcd.print(F( "Pirmadienis")、CENTER、30); //月曜日など... break;ケース2:lcd.print(F( "Antradienis")、CENTER、30);壊す;ケース3:lcd.print(F( "Treciadienis")、CENTER、30);壊す;ケース4:lcd.print(F( "Ketvirtadienis")、CENTER、30);壊す;ケース5:lcd.print(F( "Penktadienis")、CENTER、30);壊す;ケース6:lcd.print(F( "Sestadienis")、CENTER、30);壊す; } lcd.update(); delay(4000); //最適ではないClearRDS(); dspl =0; }} void printMode(){lcd.print(F( "MODE")、0、41);} void printMenu(){if(menu ==1){lcd.print(F( "VOLUME")、30 41); if(volume <0){lcd.print(F( "XX")、72、41); } else lcd.printNumI(volume + 1、72、41、2、 '0'); } if(menu ==2){lcd.print(F( "AUTO-TUNE")、30、41); } if(menu ==3){lcd.print(F( "MAN.-TUNE")、30、41); } if(menu ==4){lcd.print(F( "BASS")、30、41); if(bass ==0){lcd.print(F( "OFF")、66、41); } else lcd.print(F( "ON")、66、41); }} void printFreq()//現在の頻度を表示します{int frHundr、frDec; unsigned int fr; fr =870+周波数; frHundr =fr / 10; frDec =fr%10; lcd.printNumI(frHundr、30、12、3); lcd.print(F( "。")、48、12); lcd.printNumI(frDec、54、12、1); lcd.print(F( "MHz")、66、12);} void printStereo(){if(memdisplay ==1){// MEMキーが押された場合lcd.print(F( "MEM>")、0 、12); } //ステレオ検出elseif((status [0]&0x0400)==0)lcd.print(F( "()")、0、12); // MONOを意味しますelselcd.print(F( "(ST)")、0、12); // STEREOを意味します} void search(byte direc)//自動シーク{byte i; //上または下を探すif(!direc)WriteReg(0x02、0xC30d); else WriteReg(0x02、0xC10d); for(i =0; i <10; i ++){delay(200); Readstatus(); if(status [0]&0x4000){頻度=status [0]&0x03ff;壊す; }}} void canal(int canal)//直接頻度{byte numberH、numberL; numberH =運河>> 2; numberL =((canal&3)<<6 | 0x10); Wire.beginTransmission(0x11); Wire.write(0x03); Wire.write(numberH); //周波数をビット15:6に書き込み、調整ビットWire.write(numberL);を設定します。 Wire.endTransmission();} // RDA5807_adrs =0x10; // I2C-シーケンシャルAccessintReadstatus(){Wire.requestFrom(0x10、12);のRDAチップをアドレス指定します。 for(int i =0; i <6; i ++){status [i] =256 * Wire.read()+ Wire.read(); } Wire.endTransmission();} // RDA5807_adrr =0x11; // I2C-ランダムAccessvoidWriteReg(byte reg、unsigned int valor){Wire.beginTransmission(0x11);のRDAチップをアドレス指定します。 Wire.write(reg); Wire.write(valor>> 8); Wire.write(valor&0xFF); Wire.endTransmission(); // delay(50);} void RDS_process(uint16_t block1、uint16_t block2、uint16_t block3、uint16_t block4){rds.processData(block1、block2、block3、block4);} void ClearRDS(){lcd.print( ""、 0、22); lcd.print( ""、0、30);} //いくつかの特別なイベントの処理.voidkeypadEvent(KeypadEvent key、KeyState kpadState){switch(kpadState){/ *時間を調整する別の方法:1。長押しします時報が聞こえたとき、または正確な時計で最後の1時間秒が表示されたときに、キーDを少なくとも2秒間押します。 2.キーDを放して、hh.00.00を調整します。 3.調整後、時計が15分から1分遅れた場合、分と秒は00になり、時間は1増加します。4。時計が1分から15分に急いでいた場合、分と秒だけが00になります。 。* / case HOLD:if(key =='D' &&power_state ==1){adj =1; } 壊す; case RELEASED:if(key =='D' &&adj ==1){DateTime now =rtc.now(); if(now.minute()> =45 &&now.minute()<=59){rtc.adjust(DateTime(now.year()、now.month()、now.day()、now.hour() + 1、0、0)); } if(now.minute()> =1 &&now.minute()<=15){rtc.adjust(DateTime(now.year()、now.month()、now.day()、now.hour( )、0、0)); } adj =0; } 壊す;押されたケース:if(key =='M' &&power_state ==1){memdisplay =0; menu ++; if(menu> MAXmenu)menu =1; } if(key =='>' &&power_state ==1){memdisplay =0;スイッチ(メニュー){ケース1:if(volume <0){if(bass ==0){WriteReg(0x02、0xD00D);ボリューム=0; } if(bass ==1){WriteReg(0x02、0xC00D);ボリューム=0; }} else volume ++; if(volume> 15)volume =15;壊す;ケース2:search(0); ClearRDS();壊す;ケース3:周波数++; if(周波数> 210)周波数=210; //周波数の上限ClearRDS();壊す;ケース4:if(bass ==0){bass =1; WriteReg(0x02、0xD00D); } 壊す; }} if(key =='<' &&power_state ==1){memdisplay =0;スイッチ(メニュー){ケース1:音量-; if(volume <0){WriteReg(0x02、0x800D); //ボリューム=0; } 壊す;ケース2:search(1); ClearRDS();壊す;ケース3:頻度-; (頻度<0)頻度=0の場合; ClearRDS();壊す;ケース4:if(bass ==1){bass =0; WriteReg(0x02、0xC00D); } 壊す; }} // LEDライトのオン/オフif(key =='L' &&power_state ==1){digitalWrite(ledPin、!digitalRead(ledPin)); ledPin_state =digitalRead(ledPin); //点灯または消灯のLEDの状態を覚えておいてください。 } //「電源」をオンまたはオフにします(スタンバイモード)if(key =='P'){digitalWrite(blPin、!digitalRead(blPin)); power_state =digitalRead(blPin); if(power_state ==0){lcd.enableSleep(); digitalWrite(ledPin、LOW); } else lcd.disableSleep();ボリューム=2;メニュー=1; } if(key =='1' &&power_state ==1){switch(memdisplay){case 0:frequency =mem.readInt(110); ClearRDS();壊す;ケース1:mem.writeInt(110、頻度); memdisplay =0;壊す; }} if(key =='2' &&power_state ==1){switch(memdisplay){case 0:frequency =mem.readInt(120); ClearRDS();壊す;ケース1:mem.writeInt(120、頻度); memdisplay =0;壊す; }} if(key =='3' &&power_state ==1){switch(memdisplay){case 0:frequency =mem.readInt(130); ClearRDS();壊す;ケース1:mem.writeInt(130、頻度); memdisplay =0;壊す; }} if(key =='4' &&power_state ==1){switch(memdisplay){case 0:frequency =mem.readInt(140); ClearRDS();壊す;ケース1:mem.writeInt(140、頻度); memdisplay =0;壊す; }} if(key =='5' &&power_state ==1){switch(memdisplay){case 0:frequency =mem.readInt(150); ClearRDS();壊す;ケース1:mem.writeInt(150、頻度); memdisplay =0;壊す; }} if(key =='6' &&power_state ==1){switch(memdisplay){case 0:frequency =mem.readInt(160); ClearRDS();壊す;ケース1:mem.writeInt(160、頻度); memdisplay =0;壊す; }} if(key =='m' &&power_state ==1){mempress =1; } else {mempress =0; } if(key =='I' &&power_state ==1){dspl =1; } 壊す; }}
信号強度記号 C / C ++
#if defined(__ AVR __)#include#define imagedatatype const uint8_t#elif defined(__ PIC32MX __)#define PROGMEM #define imagedatatype const unsigned char#elif defined(__ arm __)#define PROGMEM #define imagedatatype const unsigned char#endifimagedatatype signal5 [] PROGMEM ={0xC1、0xC2、0xC4、0xFF、0xC4、0xC2、0xC1、0xC0、0xE0、0xC0、0xF0、0xC0、0xF8、0xC0、0xFC、0xC0、// 、}; imagedatatype signal4 [] PROGMEM ={0xC1、0xC2、0xC4、0xFF、0xC4、0xC2、0xC1、0xC0、0xE0、0xC0、0xF0、0xC0、0xF8、0xC0、0xFC、0xC0、// 0x0010( }; imagedatatype signal3 [] PROGMEM ={0xC1、0xC2、0xC4、0xFF、0xC4、0xC2、0xC1、0xC0、0xE0、0xC0、0xF0、0xC0、0xF8、0xC0、0xC0、0xC0、// 0x0010(16); imagedatatype signal2 [] PROGMEM ={0xC1、0xC2、0xC4、0xFF、0xC4、0xC2、0xC1、0xC0、0xE0、0xC0、0xF0、0xC0、0xC0、0xC0、0xC0、0xC0、// 0x0010(16) imagedatatype signal1 [] PROGMEM ={0xC1、0xC2、0xC4、0xFF、0xC4、0xC2、0xC1、0xC0、0xE0 、0xC0、0xC0、0xC0、0xC0、0xC0、0xC0、0xC0、// 0x0010(16)ピクセル0xC0、};
回路図

製造プロセス