Arduinoのワイヤ数を削減-2本のワイヤでI2C LCDスクリーンとRTCクロック

私は最近Arduinoに会ったので、多くの人が私の例を簡単に見つけます。



しかし、私のような新参者にとって、この情報は有用であり、多くの時間を節約できます。



I2Cは、2本のワイヤでデバイスを通信するための標準ですが、これらのワイヤで並行してハングするデバイスの数は非常に多くなる可能性があります。 各デバイスには、デバイスがアクセスされる独自のアドレスがあります。 デバイスにハードコードされているベースアドレスを基準にして追加のオフセットを設定できるジャンパーがデバイスにある場合、アドレス指定を変更できます。



簡単に言えば。



私は、16x2文字のLCDディスプレイを伊兵衛で買ったという事実から始めました。 標準として接続することで、これは必要なものではないことに気付きました。 ワイヤーの塊-脚、カオス、無秩序の束を取ります。



画像



Googled、私は、接続を簡素化するインターフェースを備えたディスプレイがあることに気付きました。 まだグーグルで、LCD用のI2Cのアダプターを見つけました。 ちょっと待って、ちょっと待って。



画像



もっと面白そうです!







問題は、動作中のライブラリとサンプルの検索中に発生しました。 後で判明したように、最も有名なメインライブラリであるbitbucket.org/fmalpartida/new-liquidcrystal/downloadsでは、例は機能していません! 時間と労力がかかりました=)



具体的には、実際の例とライブラリへのリンクがあります。 arduino-info.wikispaces.com/LCD-Blue-I2C

また、購入できるLCD-I2Cアダプターのさまざまなバージョンの説明もあります。



これを購入しましたwww.ebay.com/itm/310565362720 PCF8574チップ上に組み立てられています



このバージョンのライブラリでは、表示パラメーターを次のように設定する必要があります



LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
      
      







最初の番号はデバイスアドレスで、残りは特定のディスプレイ用のアダプターの制御ピンに割り当てられます。 ここでは、問題は隠されていました-多くの例は、誤ったデータで画面を初期化しました-画面が点滅し、けいれんし、動作しません。



アドレスと必要なピンを含む正しい行は、特定のディスプレイによって異なります。 初心者が本質を理解し、必要なデータを獲得することは困難です!

上記はすべて有効なオプションです。 おそらく、現在使用しているライブラリよりも優れています。 しかし、それは余りにも冗長でかさばるように思えました。



2番目のライブラリはすぐに動作を開始しました。 arduino-info.wikispaces.com/file/detail/LiquidCrystal_I2C1602V1.zip/341635514

残念ながら、このライブラリのデモをどこで入手したか覚えていませんが、それは単純化されたLCDセットアップを使用しています。



 LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
      
      







この行では、デバイスアドレスが割り当てられ、表示のタイプが2行で16文字に決定されます。



最初と2番目のライブラリは相互に互換性がありません! あるライブラリの例は別のライブラリでは機能しません。 次のコードは、I2C LCDを操作するために最後に指定されたライブラリを参照します。



画面を接続した後、何かを表示したかった。 数字だけでは面白くない。 時間があるとしましょう=))たぶん私も含めて誰もがこのように行きます。 Arduinoソフトウェアクロックは時刻を表示できますが、問題はシャットダウン中のデータリセットです。 また、ボタンがないため、コンソールのCOMポートを介してケーブルを介してクロックを設定する必要があります。 一般的に、それは非常に迅速に私を悩ませました。



リアルタイムクロックRTC1307は、おそらく最も一般的な時計チップです。 多くのプラスがあります-バッテリーを備えたメインのArduino電源から独立した、メインプログラムから独立した別のマイクロ回路-確かに時間がカウントされます! 1307-I2Cに基づく時計の利点。 この場合、追加の出力を使用する必要はありません-すべてはLCDと同じ2本のワイヤを介して制御されます。



I2c時計を操作するためのライブラリはすぐに機能し、例は機能しています。 github.com/adafruit/RTClib



プログラムはシンプルで、すべてが透過的です。 番号は、番号が別々のブロックに表示される関数によって作成されます。 5x8ポ​​イントのブロックはユーザーキャラクターに設定され、最大8個まで設定できます。例はarduino.ccフォーラムから取得されます。



描画は別の機能で行われ、数字は1つずつ表示されます。 実行中の十字架-著者の気まぐれ、つまり mine))draw関数が呼び出されると、数値のオフセットが制御されます。







Arduinsのコード
 // Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> #include "RTClib.h" #include <LiquidCrystal_I2C.h> RTC_DS1307 rtc; LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display byte LT[8] = { B00111, B01111, B11111, B11111, B11111, B11111, B11111, B11111 }; byte UB[8] = { B11111, B11111, B11111, B00000, B00000, B00000, B00000, B00000 }; byte RT[8] = { B11100, B11110, B11111, B11111, B11111, B11111, B11111, B11111 }; byte LL[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B01111, B00111 }; byte LB[8] = { B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111 }; byte LR[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11110, B11100 }; byte MB[8] = { B11111, B11111, B11111, B00000, B00000, B00000, B11111, B11111 }; byte block[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 }; // loop counter int count = 0; void setup () { Serial.begin(57600); Wire.begin(); rtc.begin(); lcd.init(); // initialize the lcd lcd.backlight(); lcd.home(); lcd.createChar(0,LT); lcd.createChar(1,UB); lcd.createChar(2,RT); lcd.createChar(3,LL); lcd.createChar(4,LB); lcd.createChar(5,LR); lcd.createChar(6,MB); lcd.createChar(7,block); // sets the LCD's rows and colums: lcd.clear(); if (! rtc.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled // rtc.adjust(DateTime(__DATE__, __TIME__)); } } void custom0(int x) { // uses segments to build the number 0 lcd.setCursor(x,0); // set cursor to column 0, line 0 (first row) lcd.write(0); // call each segment to create lcd.write(1); // top half of the number lcd.write(2); lcd.setCursor(x, 1); // set cursor to colum 0, line 1 (second row) lcd.write(3); // call each segment to create lcd.write(4); // bottom half of the number lcd.write(5); } void custom1(int x) { lcd.setCursor(x,0); lcd.write(1); lcd.write(2); lcd.print(" "); lcd.setCursor(x,1); lcd.write(4); lcd.write(7); lcd.write(4); } void custom2(int x) { lcd.setCursor(x,0); lcd.write(6); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(3); lcd.write(4); lcd.write(4); } void custom3(int x) { lcd.setCursor(x,0); lcd.write(6); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(4); lcd.write(4); lcd.write(5); } void custom4(int x) { lcd.setCursor(x,0); lcd.write(3); lcd.write(4); lcd.write(7); lcd.setCursor(x, 1); lcd.print(" "); lcd.print(" "); lcd.write(7); } void custom5(int x) { lcd.setCursor(x,0); lcd.write(3); lcd.write(6); lcd.write(6); lcd.setCursor(x, 1); lcd.write(4); lcd.write(4); lcd.write(5); } void custom6(int x) { lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(6); lcd.setCursor(x, 1); lcd.write(3); lcd.write(4); lcd.write(5); } void custom7(int x) { lcd.setCursor(x,0); lcd.write(1); lcd.write(1); lcd.write(2); lcd.setCursor(x, 1); lcd.print(" "); lcd.print(" "); lcd.write(7); } void custom8(int x) { lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(3); lcd.write(4); lcd.write(5); } void custom9(int x) { lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.print(" "); lcd.print(" "); lcd.write(7); } //void clearnumber(int x) //{ // clears the area the custom number is displayed in // lcd.setCursor(x,0); // lcd.print(" "); // lcd.setCursor(x,1); // lcd.print(" "); //} void loop () { digitalClockDisplay(); delay(1000); } void digitalClockDisplay(){ // digital clock display of the time DateTime now = rtc.now(); printDigits(now.hour()/10,0); printDigits(now.hour()%10,4); printDigits(now.minute()/10,9); printDigits(now.minute()%10,13); // lcd.setCursor(7, 1); // lcd.print(now.second()/10); // lcd.print(now.second()%10); if (now.second()%10%2==0){ lcd.setCursor(7, 0); lcd.print("+ "); lcd.setCursor(7, 1); lcd.print(" +"); lcd.setCursor(3, 1); lcd.print("+"); lcd.setCursor(12, 0); lcd.print("+"); lcd.setCursor(3, 0); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(" "); } else { lcd.setCursor(7, 0); lcd.print(" +"); lcd.setCursor(7, 1); lcd.print("+ "); lcd.setCursor(3, 0); lcd.print("+"); lcd.setCursor(12, 1); lcd.print("+"); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); } //  } void printDigits(int digits, int x){ // utility function for digital clock display: prints preceding colon and leading 0 switch (digits) { case 0: custom0(x); break; case 1: custom1(x); break; case 2: custom2(x); break; case 3: custom3(x); break; case 4: custom4(x); break; case 5: custom5(x); break; case 6: custom6(x); break; case 7: custom7(x); break; case 8: custom8(x); break; case 9: custom9(x); break; } }
      
      











コードをよりコンパクトにする方法を教えてくれた経験豊富なプログラマに感謝します。 同じタイプのデータを最適化する多くの機会があるように見えますが、私はそれを実装する方法を知りません。 同じフォーラムarduino.ccで例を見ましたが、何が起こっているのか本質を理解していませんでした-コードのコメントアウトが不十分で、どこから足が伸びているのかわかりません。 そこにLCDコントローラのメモリに関連するものがありました/コードについてコメントしてくれてありがとう。



UPD:メモがサンドボックスにある間、私はさらにいくつかの監視オプションを作成しました。 誰もこれに興味がありますか? 3x2疑似3dフォントを作成し、毎秒チェックするビープ音を追加しました



画像



1つの1602画面に時間、分、秒を表示し、曜日と日付を表示するために、2x2文字の細いフォントを作成しました。 コードの形で細いフォントを見つけられませんでした-ランダムな絵で自分で描きました。 また、ブザー+ RGB LEDが追加され、1秒ごとに色が変わります。 一般的に、それはすべてでした-私はすべてを台無しにしました))



画像







All Articles