Arduinoで7セグLEDを使ってみる [Arduino]
秋月電子の,「ダイナミック接続4桁高輝度赤色7セグメントLED表示器 カソードコモン カソード共通接続」OSL40562-LRを入手したので,Arduinoで動かしてみる.
今回は,ArduinoのIOピンで直接制御してみる.高輝度で点灯させるにはトランジスタを併用してLEDへの電流を確保する必要があるが,ひとまずIOピンから出力できる電流量で点灯させてみる.
Arduino Unoでは,IOピンの定格電流は40mAのようなので,これを前提に考えると...
OSL40562-LRの順方向電圧はtyp2Vだが,Minが1.8Vなのでそれで計算する.
ArduinoのIOは5Vなので,
5V - 1.8 V = 3.2V
小数点も含めると8個のLEDがあるので,Totalで30mAぐらいに収めるとすると,1LEDあたり,
30mA / 8 = 3.75mA
3.2V / 3.75mA = 0.85KΩ
ということになる.
というわけで,手元にある抵抗から近いものを探して820Ωを採用.
実際に点灯させてみれば分かるが,室内で見ている限りこれで十分な視認性が得られる.
こんな感じで接続する.
あとは,Arduino側のスケッチだが,今回は,Adafruitが公開しているLibraryを参考に改変して,出力する桁数を指定可能な7セグLED点灯用ライブラリを作ってみた.
表示テスト用のスケッチとあわせて示そう.
まず,ライブラリだが,以下の3つのファイルからなる.
Led7segment.h
Led7segment.cpp
keywords.txt
で,適当なディレクトリに,Led7segmentディレクトリを作成し,上記3つのファイルを保存してやればよい.
順にコードを示そう.
まず,Led7segment.h
次に,Led7segment.cpp
最後に,keywords.txt
ダウンロードするなら,こちらから.
Led7segment.zip.jpg
ただし,So-netのブログでは,zip圧縮ファイルのアップロードができないため,zip圧縮してから拡張子に.jpgをつけて無理矢理アップロードしている.
なので.ダウンロードしたら.jpgを消してzipファイルとして展開してやってください.
また,ライブラリの追加方法は,「arduino ライブラリ 追加」等で検索してみてください.
で,表示テスト用のスケッチは,Led_7seg.ino.
Led7segmentライブラリの使い方は,Led7segment.hと,これを見れば分かると思う.
なお,このスケッチではMsTimer2ライブラリを使用しているので,別途追加してやってください.
この表示テスト用スケッチでは,
それでは,お試しあれ.
今回は,ArduinoのIOピンで直接制御してみる.高輝度で点灯させるにはトランジスタを併用してLEDへの電流を確保する必要があるが,ひとまずIOピンから出力できる電流量で点灯させてみる.
Arduino Unoでは,IOピンの定格電流は40mAのようなので,これを前提に考えると...
OSL40562-LRの順方向電圧はtyp2Vだが,Minが1.8Vなのでそれで計算する.
ArduinoのIOは5Vなので,
5V - 1.8 V = 3.2V
小数点も含めると8個のLEDがあるので,Totalで30mAぐらいに収めるとすると,1LEDあたり,
30mA / 8 = 3.75mA
3.2V / 3.75mA = 0.85KΩ
ということになる.
というわけで,手元にある抵抗から近いものを探して820Ωを採用.
実際に点灯させてみれば分かるが,室内で見ている限りこれで十分な視認性が得られる.
こんな感じで接続する.
あとは,Arduino側のスケッチだが,今回は,Adafruitが公開しているLibraryを参考に改変して,出力する桁数を指定可能な7セグLED点灯用ライブラリを作ってみた.
表示テスト用のスケッチとあわせて示そう.
まず,ライブラリだが,以下の3つのファイルからなる.
Led7segment.h
Led7segment.cpp
keywords.txt
で,適当なディレクトリに,Led7segmentディレクトリを作成し,上記3つのファイルを保存してやればよい.
順にコードを示そう.
まず,Led7segment.h
/* * 数値を7セグLED用向けビットマップ値に変換する */ #ifndef LED_7SEGMENT_H #define LED_7SEGMENT_H class Led7segment { public: void print(unsigned char *buff, double value, unsigned int numeric_digits, unsigned int frac_digits = 1); /* * buff : 格納先バッファ(呼び出し元で必要なサイズ分を用意すること) * value : 変換する値 * numeric_digits : 出力する桁数(-符号含む桁数."."は含まない).例えば出力が"12.34"なら4. * frac_digits : 出力する小数点以下桁数(桁数不足で表示できない場合は丸められる) */ private: void write(unsigned char *buff, unsigned int x, unsigned int num, bool is_dot = false); void write_minus(unsigned char *buff, int display_index); void write_space(unsigned char *buff, int display_index); void write_error(unsigned char *buff, int display_index); }; #endif // LED_7SEGMENT_H
次に,Led7segment.cpp
/* * This is a library for 7segment LED OSL40562-LR. * * function Led7segment::print were copied and modified from * Adafruit-LED-Backpack-Library(original function: Adafruit_7segment::printFloat). * https://github.com/adafruit/Adafruit-LED-Backpack-Library */ /*************************************************** This is a library for our I2C LED Backpacks Designed specifically to work with the Adafruit LED Matrix backpacks ----> http://www.adafruit.com/products/ ----> http://www.adafruit.com/products/ These displays use I2C to communicate, 2 pins are required to interface. There are multiple selectable I2C addresses. For backpacks with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks with 3 Address Select pins: 0x70 thru 0x77 Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. MIT license, all text above must be included in any redistribution https://github.com/adafruit/Adafruit-LED-Backpack-Library/blob/master/license.txt ****************************************************/ #include <math.h> #include "Led7segment.h" namespace { const unsigned char digits_table[] = { /* _____ * | A | * F| |B * |_____| * | G | * E| |C * |_____| o DP * D */ /* DP G F E D C B A */ 0x3F, /* 0 : 0 0 1 1 1 1 1 1 */ 0x06, /* 1 : 0 0 0 0 0 1 1 0 */ 0x5B, /* 2 : 0 1 0 1 1 0 1 1 */ 0x4F, /* 3 : 0 1 0 0 1 1 1 1 */ 0x66, /* 4 : 0 1 1 0 0 1 1 0 */ 0x6D, /* 5 : 0 1 1 0 1 1 0 1 */ 0x7D, /* 6 : 0 1 1 1 1 1 0 1 */ 0x07, /* 7 : 0 0 1 0 0 1 1 1 */ 0x7F, /* 8 : 0 1 1 1 1 1 1 1 */ 0x6F, /* 9 : 0 1 1 0 1 1 1 1 */ 0x00, /* : 0 0 0 0 0 0 0 0 */ 0x40, /* - : 0 1 0 0 0 0 0 0 */ 0x80, /* . : 1 0 0 0 0 0 0 0 */ }; const int SPACE_INDEX = 10; const int MINUS_INDEX = 11; const int DOT_INDEX = 12; } // namespace void Led7segment::print(unsigned char *buff, double value, unsigned int numeric_digits, unsigned int frac_digits) { const unsigned int base = 10; bool is_minus = false; int display_index = numeric_digits - 1; if (value < 0) { is_minus = true; numeric_digits--; value *= -1; } if (numeric_digits <= frac_digits) { frac_digits = numeric_digits - 1; } unsigned long to_int_factor = pow(base, frac_digits) + 0.5; unsigned long display_value = value * to_int_factor + 0.5; unsigned long max_limit = pow(base, numeric_digits) + 0.5; while (display_value >= max_limit) { to_int_factor /= base; display_value = value * to_int_factor + 0.5; frac_digits--; } if (to_int_factor != 0) { if (display_value != 0) { for (int i = 0; (display_value != 0) || (i <= frac_digits); i++) { const bool is_dot = (frac_digits != 0) && (i == frac_digits); write(buff, display_index--, display_value % base, is_dot); display_value /= base; } } else { for (int i = 0; i <= frac_digits; i++) { const bool is_dot = (frac_digits != 0) && (i == frac_digits); write(buff, display_index--, 0, is_dot); } } if (is_minus == true) { write_minus(buff, display_index--); } while (display_index >= 0) { write_space(buff, display_index--); } } else { while (display_index >= 0) { write_error(buff, display_index--); } } } void Led7segment::write(unsigned char *buff, unsigned int i, unsigned int num, bool is_dot) { if (is_dot == true) { buff[i] = digits_table[num] | digits_table[DOT_INDEX]; } else { buff[i] = digits_table[num]; } } void Led7segment::write_minus(unsigned char *buff, int display_index) { write(buff, display_index, MINUS_INDEX); } void Led7segment::write_space(unsigned char *buff, int display_index) { write(buff, display_index, SPACE_INDEX); } void Led7segment::write_error(unsigned char *buff, int display_index) { write(buff, display_index, MINUS_INDEX); }
最後に,keywords.txt
Led7segment KEYWORD1 print KEYWORD2
ダウンロードするなら,こちらから.
Led7segment.zip.jpg
ただし,So-netのブログでは,zip圧縮ファイルのアップロードができないため,zip圧縮してから拡張子に.jpgをつけて無理矢理アップロードしている.
なので.ダウンロードしたら.jpgを消してzipファイルとして展開してやってください.
また,ライブラリの追加方法は,「arduino ライブラリ 追加」等で検索してみてください.
で,表示テスト用のスケッチは,Led_7seg.ino.
Led7segmentライブラリの使い方は,Led7segment.hと,これを見れば分かると思う.
なお,このスケッチではMsTimer2ライブラリを使用しているので,別途追加してやってください.
#include <MsTimer2.h> #include <Led7segment.h> const int anode_pins[] = { 12, // A 8, // B 5, // C 3, // D 2, // E 11, // F 6, // G 4, // DP }; const int cathode_pins[] = { 13, // DIG.1 10, // DIG.2 9, // DIG.3 7, // DIG.4 }; const int ANODE_PINS_NUM = sizeof(anode_pins) / sizeof(anode_pins[0]); const int CATHODE_PINS_NUM = sizeof(cathode_pins) / sizeof(cathode_pins[0]); unsigned int display_buffer[CATHODE_PINS_NUM] = {0}; void write_1digit(const unsigned char bitmap) { for (int i = 0; i < ANODE_PINS_NUM; i++) { digitalWrite(anode_pins[i], bitmap & (1 << i) ? HIGH : LOW); } } void clear() { for (int i = 0; i < ANODE_PINS_NUM; i++) { digitalWrite(anode_pins[i], LOW); } } void write() { for (int i = 0; i < CATHODE_PINS_NUM; i++) { digitalWrite(cathode_pins[i], LOW); write_1digit(display_buffer[i]); delayMicroseconds(100); clear(); digitalWrite(cathode_pins[i], HIGH); } } void print_7seg(unsigned char *buff) { noInterrupts(); for (int i = 0; i < CATHODE_PINS_NUM; i++) { display_buffer[i] = buff[i]; } interrupts(); } void setup() { for (int i = 0; i < ANODE_PINS_NUM; i++) { pinMode(anode_pins[i], OUTPUT); } for (int i = 0; i < CATHODE_PINS_NUM; i++) { pinMode(cathode_pins[i], OUTPUT); digitalWrite(cathode_pins[i], HIGH); } MsTimer2::set(1, write); MsTimer2::start(); } void loop() { unsigned char buff[CATHODE_PINS_NUM] = {0}; const unsigned int numeric_digits = CATHODE_PINS_NUM; const unsigned int frac_digits = 3; Led7segment led; for (long i = -1000; i <= 10000; i++) { double d = i; led.print(buff, d, numeric_digits, frac_digits); print_7seg(buff); delay(100); } for (long i = -1000; i <= 10000; i++) { double d = i / 10.0; led.print(buff, d, numeric_digits, frac_digits); print_7seg(buff); delay(100); } for (long i = -1000; i <= 10000; i++) { double d = i / 100.0; led.print(buff, d, numeric_digits, frac_digits); print_7seg(buff); delay(100); } for (long i = -1000; i <= 10000; i++) { double d = i / 1000.0; led.print(buff, d, numeric_digits, frac_digits); print_7seg(buff); delay(100); } }
この表示テスト用スケッチでは,
・-1000 〜 10000 まで,1 ずつ
・-100.0 〜 1000.0 まで,0.1 ずつ
・-10.00 〜 100.00 まで,0.01 ずつ
・-1.000 〜 10.000 まで,0.001ずつ
順に表示する動作になっていて,桁数が足りなくて表示できない値は「----」と表示されます.それでは,お試しあれ.
タグ:7セグLED