
Arduinoには、ご存じのとおり、LCDインジケーターに情報を表示するための優れた組み込みライブラリがありますが、マトリックスサイン合成インジケーターのみをサポートしています。 そのため、私は通常のセグメントインジケータである最も単純な10ビットMT-10T8を手にしました。 タスクセットは、このインジケーターの機能と一致していました。1つのデバイスの現在の温度を表示するためです。簡単にするために、ラボの温度計と呼びます。 デバイスはArduino、具体的にはSeeduino Mega(Arduino Megaのアナログ)のバージョンによって制御されます。 MT-10T8のかなり簡潔なデータシートを簡単に知った後、少し時間をかけて、このインジケーターでArduinoを友達にすることにしました。
このインジケータはシンプルな制御プロトコルを使用し、アドレスとデータはパラレル4ビットバスを介して送信されます。 プロトコルには問題はありません。文字のアドレスはバスの4ビットに収まり、データは4ビットの2テトラッドで送信されます(1文字あたり8ビットです)。 混乱せずに注意する必要があるのは、インジケータ制御信号の推奨タイミングだけです。 インジケータへのアクセスに最小限のプロセッサ時間を費やすことが望ましいが、同時に、安定性を確保する必要があります。これは、実践が示しているように、インジケータが非常に簡単に狂うからです。
Arduinoを使用するデータシートに必要な数十ナノ秒の最小遅延は保証できませんが、arduinoのホームサイトでいくつかの検索を行った後、短い遅延に「nop」アセンブラコマンドを使用するようアドバイスしました。
__asm__("nop\n\t");
16 MHz水晶のこの設計では、62.5 nsの遅延が発生します。 データシートは50、100、200ナノ秒の最小タイミングで動作しますが、62.5、125、250ナノ秒になります。 かなり満足しています。

インジケーターは即興の手段を使用して接続され、結果のフランケンシュタインが写真に示されています。 制御プログラムでは、インジケータのハードウェア機能を使用して、シンボルを「連続して」表示します。 特定のアドレスに文字を表示した後、バスにアドレスを設定せずに次のデータ転送コマンドを呼び出すと、現在のアドレスに続くアドレスに文字が表示されます。
今、おそらく質問に答える価値があります-なぜですか? 実際、10桁のマトリックスインジケーターのコストが250ルーブルである場合、なぜ70ルーブルである最小限のセグメントインジケーターを使用するのでしょうか。 安い? まあ、第一に、ペニーはルーブルを節約します。第二に、LiquidCrystalライブラリは、控えめに言っても、ボリュームが小さくありません。 そして、ここでミニマリズムのルール。
実際、コードは特別な説明を必要としません。 まず、インジケーター自体に情報を表示する機能:
// writeSymbol -
// address - (0..9)
// symbol -
// dot -
void writeSymbol(byte address, byte symbol, boolean dot)
{
//
//
digitalWrite(A0_PIN, LOW);
//
digitalWrite(DB0_PIN, bitRead(address,0));
digitalWrite(DB1_PIN, bitRead(address,1));
digitalWrite(DB2_PIN, bitRead(address,2));
digitalWrite(DB3_PIN, bitRead(address,3));
__asm__("nop\n\t"); //62.5ns
//
digitalWrite(WR1_PIN, HIGH);
__asm__("nop\n\t""nop\n\t"); //125.5ns
digitalWrite(WR1_PIN, LOW);
__asm__("nop\n\t"); //62.5ns
//
writeNextSymbol(symbol, dot);
}
// writeNextSymbol - ,
// symbol -
// dot -
void writeNextSymbol(byte symbol, boolean dot)
{
if (dot)
symbol+=16;
//
digitalWrite(DB0_PIN, bitRead(symbol,0));
digitalWrite(DB1_PIN, bitRead(symbol,1));
digitalWrite(DB2_PIN, bitRead(symbol,2));
digitalWrite(DB3_PIN, bitRead(symbol,3));
//
digitalWrite(A0_PIN, HIGH);
// WR
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); //250ns
//
digitalWrite(WR1_PIN, HIGH);
__asm__("nop\n\t""nop\n\t"); //125.5ns
digitalWrite(WR1_PIN, LOW);
//
//
digitalWrite(DB0_PIN, bitRead(symbol,4));
digitalWrite(DB1_PIN, bitRead(symbol,5));
digitalWrite(DB2_PIN, bitRead(symbol,6));
digitalWrite(DB3_PIN, bitRead(symbol,7));
// WR
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); //250ns
//
digitalWrite(WR1_PIN, HIGH);
__asm__("nop\n\t""nop\n\t"); //125.5ns
digitalWrite(WR1_PIN, LOW);
}
// clearAll -
void clearAll()
{
for (int i=0;i<10;i++)
{
writeSymbol(i, 0, false);
}
}
// unblockBus- /.
// ,
//
void unblockBus()
{
//
digitalWrite(A0_PIN, LOW);
// 0F -
digitalWrite(DB0_PIN, HIGH);
digitalWrite(DB1_PIN, HIGH);
digitalWrite(DB2_PIN, HIGH);
digitalWrite(DB3_PIN, HIGH);
__asm__("nop\n\t"); //62.5ns
//
digitalWrite(WR1_PIN, HIGH);
__asm__("nop\n\t""nop\n\t"); //125.5ns
digitalWrite(WR1_PIN, LOW);
__asm__("nop\n\t"); //62.5ns
// : DB0=1
digitalWrite(DB0_PIN, HIGH);
digitalWrite(DB1_PIN, LOW);
digitalWrite(DB2_PIN, LOW);
digitalWrite(DB3_PIN, LOW);
//
digitalWrite(A0_PIN, HIGH);
// WR
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); //250ns
//
digitalWrite(WR1_PIN, HIGH);
__asm__("nop\n\t""nop\n\t"); //125.5ns
digitalWrite(WR1_PIN, LOW);
}
そして戦闘の使用例:
// , Arduino
const byte A0_PIN=10;
const byte WR1_PIN=8;
const byte WR2_PIN=9;
const byte DB0_PIN=2;
const byte DB1_PIN=3;
const byte DB2_PIN=4;
const byte DB3_PIN=5;
//
//
const byte SEG_A=8;
const byte SEG_B=32;
const byte SEG_C=64;
const byte SEG_D=4;
const byte SEG_E=2;
const byte SEG_F=128;
const byte SEG_G=1;
const byte SEG_H=16;
// " ".
const byte WHITESPACE = 0; //
//
const byte DIGIT_ZERO = SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F;
const byte DIGIT_ONE = SEG_B + SEG_C;
const byte DIGIT_TWO = SEG_A + SEG_B + SEG_G + SEG_E + SEG_D;
const byte DIGIT_THREE = SEG_A + SEG_B + SEG_G + SEG_C+ SEG_D;
const byte DIGIT_FOUR = SEG_F + SEG_G + SEG_B + SEG_C;
const byte DIGIT_FIVE = SEG_A + SEG_F + SEG_G + SEG_C + SEG_D;
const byte DIGIT_SIX = SEG_A + SEG_F + SEG_G + SEG_C + SEG_D + SEG_E;
const byte DIGIT_SEVEN = SEG_A + SEG_B + SEG_C;
const byte DIGIT_EIGHT = SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G;
const byte DIGIT_NINE = SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G;
// .
const byte SYMBOL_MINUS = SEG_G;
const byte SYMBOL_C = SEG_A + SEG_F + SEG_E + SEG_D;
const byte SYMBOL_DEGREE= SEG_A + SEG_B + SEG_G + SEG_F;
const byte SYMBOL_UPDASH = SEG_A;
const byte SYMBOL_LOWDASH = SEG_D;
void setup() {
// , -
pinMode(A0_PIN, OUTPUT);
pinMode(WR1_PIN, OUTPUT);
pinMode(WR2_PIN, OUTPUT);
pinMode(DB0_PIN, OUTPUT);
pinMode(DB1_PIN, OUTPUT);
pinMode(DB2_PIN, OUTPUT);
pinMode(DB3_PIN, OUTPUT);
unblockBus();
}
void loop() {
//
clearAll();
delay(1000);
//
writeSymbol(0, DIGIT_ZERO, false);
delay(100);
writeNextSymbol( DIGIT_ONE, false);
delay(100);
writeNextSymbol( DIGIT_TWO, false);
delay(100);
writeNextSymbol( DIGIT_THREE, false);
delay(100);
writeNextSymbol( DIGIT_FOUR, false);
delay(100);
writeNextSymbol( DIGIT_FIVE, false);
delay(100);
writeNextSymbol( DIGIT_SIX, false);
delay(100);
writeNextSymbol( DIGIT_SEVEN, false);
delay(100);
writeNextSymbol( DIGIT_EIGHT, false);
delay(100);
writeNextSymbol( DIGIT_NINE, true);
delay(500);
clearAll();
writeSymbol(0, SYMBOL_MINUS, false);
delay(100);
writeNextSymbol( SYMBOL_C, false);
delay(100);
writeNextSymbol( SYMBOL_DEGREE, false);
delay(100);
writeNextSymbol( SYMBOL_UPDASH, false);
delay(100);
writeNextSymbol( SYMBOL_LOWDASH, false);
delay(1000);
clearAll();
// 156.4
writeSymbol(3, SYMBOL_MINUS, false);
writeNextSymbol( DIGIT_ONE, false);
writeNextSymbol( DIGIT_FIVE, false);
writeNextSymbol( DIGIT_SIX, true);
writeNextSymbol( DIGIT_FOUR, false);
writeNextSymbol( SYMBOL_DEGREE, false);
writeNextSymbol( SYMBOL_C, false);
delay(1000);
clearAll();
//
for (int i=0;i<10;i++)
{
writeSymbol(i, SYMBOL_UPDASH, false);
if (i>0) writeSymbol(i-1, WHITESPACE, false);
delay(200);
}
for (int i=0;i<10;i++)
{
writeSymbol(9-i, SYMBOL_LOWDASH, false);
delay(200);
}
delay(1000);
}