読者です 読者をやめる 読者になる 読者になる

M.C.P.C. (Mamesibori Creation Plus Communication)

印刷屋から五反田のWeb屋に転職したCLのブログです。

秋月電子7セグメントLED DIP化キット10桁をArduino/Raspberry Pi/mbedで点灯

秋月電子 汎用ロジックIC Arduino Raspberry Pi mbed スイッチサイエンス

2016/03/04に、秋月電子通商で発売になった、「秋月電子7セグメントLED DIP化キット」を12個入手したので、そのうちの10個を使って点灯させてみます。

7セグメントLED DIP化キットとは?

akizukidenshi-ogp-injector.dtpwiki.jp

この製品は、通常だと点灯するのに手間がかかる7セグメントLEDを容易に駆動できるよう、シフトレジスタIC74HC595と、LED用の抵抗を実装した基板です。

(2016-03-15追記)

7セグLEDセット販売の製品も用意されました。

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

74HC595を使うと、

  • 数珠つなぎにすることで、複数の7セグメントLEDをまとめて操作できる
  • 一度点灯の指示をすると次の指示を出すまで点灯したままにできる
    • ループや割り込みで桁駆動する必要がなくプログラムで楽できる

抵抗が実装されていることで、

  • 1桁ごとに8個の抵抗を用意する必要がなくなる
  • 7セグメントLEDに電流を流し過ぎて故障させる事故が減る

というとてもありがたい基板です。

欠点もあって、

  • 常時点灯なので(=ダイナミック点灯ではない)、LEDの寿命が比較的短くなり、消費電力が大きい
  • マイコンなどで表示パターンをシリアル転送してやらないと点灯しない

となります。

点灯させる前に……消費電流の確認

製品の仕様としては、全セグメント点灯で45mAとのこと。

7セグLEDユニットとしてC-551SRDを載せ、全セグ点灯で5Vで流した場合、7セグLEDユニット5個で0.08A、10個で0.17A(簡易電流計による測定)流れていました。

Adruino Pro Miniには最大12Vの電源から降圧して5Vを作り出すレギュレータがついているのですが、保証されている最大電流値は150mAとなっています。実際のテストでは、オンボードレギュレータの使用では、4個までしか駆動できませんでした(Arduinoにリセットがかかる)。10桁(10個)駆動させるには、5V/450mA程度の電源(USBの電源など)を使う必要があります。

Raspberry Piで3.3Vで点灯させた場合は、簡易電流計によると7セグ10個で0.21Aとなっていましたが、点灯の瞬間は倍以上の電流が流れていました。そもそもGPIOの3.3Vピンからは50mAしか流せないはずなのでやってはいけないです。Raspberry Piの5Vを電源に使い、GPIOは後述しますが3.3V出力を74HC4050で5Vに上げ74HC595に入力しする形で、7セグLED側は5Vとして取り扱います。

Arduinoで点灯させる

早速Arduinoで点灯させます。うちで使うのは、ブレッドボードに乗せやすい、Arduino Pro Mini 5V/16MHzです。

部品名 価格
Arduino Pro Mini 328 5V 16MHz 1243

www.switch-science.com

部品表

部品名 個数 価格
赤色7セグメントLED カソードコモン ボディ黒 C-551SRD 10個 400
7セグメントLED DIP化キット 10個 1600
ブレッドボード BB-102 1枚 300

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

配線

74HC595とのインタフェースとして、3線式シリアル通信用のSPIインタフェースと、ラッチに任意のピンを1ピン分をGPIOの出力モードで利用します。3線式シリアル通信というのは、クロック信号SCK、データ入力信号SDI・データ出力信号SDOの3本の配線でシリアルデータを送受信する方式です。送信だけなら、クロック信号SCK・データ線SDOの2線です。

Arduino 7セグ基板 意味
5V VDD +5V
GND GND Ground(0V)
SCK(pin13) SCK SPI SCK クロック入力
MOSI(pin11)SDO SDI SPI SDI Masterから見たらOut/SlaveからはIn
pin10 LATCH 74HC595 ラッチ(表示を固定)

f:id:C_L:20160308231222p:plain

Arduino Mini Pro

プログラム(Arduino IDE 1.65)

ダイナミック点灯ではないので、ラッチを上げたまま1文字分のビットパターン8bitを10回合計80bitを転送した後、一瞬だけラッチを下してすぐにラッチを上げることで描画が完了します。

ラッチのためのpinにSPIインタフェースでいうところのSSのピンを使っているのは、本当は良くないけれども動くことは動く。

#include <SPI.h>

// SPI: 10(SS)、11(MOSI)、12(MISO)、13(SCK) 
const unsigned char digits[] = {
  0x3f, 0x06, 0x5b, 0x4f,
  0x66, 0x6d, 0x7d, 0x27,
  0x7f, 0x6f,
};

const char str[] = "3.14159265358";
char buf[12];

void setup() {
  //Serial.begin(9600);
  
  SPI.begin() ;                          // SPIを行う為の初期化
  SPI.setBitOrder(MSBFIRST);             // ビットオーダー
  SPI.setClockDivider(SPI_CLOCK_DIV4);   // クロックをシステムクロックの1/4で使用(16MHz機の時は4MHz)
  SPI.setDataMode(SPI_MODE0) ;           // クロック極性0(HIGH) クロック位相1(HIGH)

  char j = -1;
  for ( char i = 0; i < strlen( str ); i++ ) {
    char s = str[i];
    if ( s == '.') {
      buf[j] |= 128;
    }
    else {
      j++;
      buf[j] = s;
    }
    
  }
  show();

}
void show() {
  digitalWrite(SS, HIGH);  // 74HC595 ラッチ On(表示固定)
  for ( char i = 0; i < 10 ; i++ ) {
    char d = buf[i];
    char s = ( d & 128); // 128以上のときは128、127以下のときは0
    d &= 127;            // 下位7bitのみマスク
    s += digits[d-48];   // 文字コードに合わせたパターンを合成
    SPI.transfer(s);        // 74CH595 SPIで8ビット分転送
  }
  digitalWrite(SS, LOW);   // 74HC595 ラッチ Off(表示更新)
  digitalWrite(SS, HIGH);  // 74HC595 ラッチ On(表示固定)
}

void loop() {
}

動作例

あとで写真載せる とりあえずTwitterに上げた写真でも置いておく

Raspberry Piで点灯させる

Raspberry Piでも、SPIを使って点灯します。あと、プログラミング言語node.jsで行きます。

せっかくだからRaspberry Pi Zeroなんか使ってみるといいですね。

部品名 価格
Raspberry Pi Zero $5

www.raspberrypi.org

部品表

部品名 個数 価格
赤色7セグメントLED カソードコモン ボディ黒 C-551SRD 10個 400
7セグメントLED DIP化キット 10個 1600
ブレッドボード BB-102 1枚 300
6回路バッファ CD74HC4050E 1個 40

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

配線

74HC595とのインタフェースには、3線式シリアル通信に適用できるSPIインタフェースと、ラッチ用に任意の1ピンをGPIOの出力モードで利用します。

あと、3.3Vでも光りますが、3.3Vピンの限界超えているので、5Vを使います。

電源として5Vを使うとなると、このままだと信号線が3.3Vなのですが、74HC595のデータシートを見るとVCC=4.5[V]でVIH=3.15[V]となっていて、きわどいです。計算するとVCC=5[V]でVIH=3.5[V]となりますので。

f:id:C_L:20160317003850p:plain

実際にVCC=5[V]を供給して、SPI出力を3.3Vのままで接続してみると、やはりSCLKが5Vまで登り切らないとちゃんとDSIデータpinから状態を正常に取得できないようで、表示が乱れてしまいます。そこで、信号線を5Vにするためにレベルシフタとして使える6chバッファIC74HC4050を使うといいです。

6chバッファIC74HC4050は、マイコンからの出力の場合に限って、レベルシフタとして使えます。安価なので用意しておくと多い日も安心です。

Raspberry Pi 7セグ基板 意味
5V(2pin) VDD +5V
GND(20pin) GND Ground(0V)
SCLK(23pin) SCK SPI SCK クロック入力
MOSI(19pin) SDI SPI SDI Masterから見るとOut/SlaveからはIn
GPIO25(22pin) LATCH 74HC595 ラッチ(表示を固定)

Raspberry-pi-gpio

Pi Zero

f:id:C_L:20160315022416p:plain

プログラム(Raspbian Jessie/node.js)

ダイナミック点灯ではないので、ラッチを上げたまま10文字分のビットパターン80bitを転送した後、一瞬だけラッチを下してすぐにラッチを上げることで描画が完了します。

肝腎のnode.js環境の準備はプログラム冒頭のコメント参照。Raspbian Jessieで最初から入るnode.js環境を取り除くなど破壊的な操作が入りますので、再インストールしても問題がないRaspberry Piで試しましょう。

どうでもいいがpi-spiのコールバックの中ではonoffのGPIO操作とかうまく動かないのを知った。promise使う場面なのかね

'use strict';

// akizuki-7seg-10col.js:
// Usage:
// (Raspberry PiにRaspbian Jessieをインストールして、
// sudo raspi-config で SPI使用を有効にしてリブート後、
// piユーザでログイン)
// sudo apt-get update
// sudo apt-get -y remove nodered nodejs nodejs-legacy
// curl -LO http://node-arm.herokuapp.com/node_latest_armhf.deb
// sudo dpkg -i node_latest_armhf.deb
// mkdir 7seg
// cd $_
// npm install onoff pi-spi
// curl -LO https://gist.githubusercontent.com/CLCL/ab5be8ddc4caa0d72aa5/raw/80600eec8e20584d945c7b249ebb001cd2661b59/akizuki-7seg-10col.js
// sudo node akizuki-7seg-10col.js


//
// #Use libs/Global Objects
//

var SPI  = require('pi-spi');
var Gpio = require('onoff').Gpio;

// SPI初期化
var spi = SPI.initialize('/dev/spidev0.0');
spi.clockSpeed(31250000); // 250MHzの8分周=31.25MHz(実用できる限界速度)

//
// #define
//

// 信号値定義
var HIGH = 1;
var LOW  = 0;
// 信号ピン定義
var LATCH =  25; // GPIO25(22pin):74HC595 LATCH           -> LAT
                 // MOSI(19pin)[変更不可]:SPI DATA OUTPUT -> DAT
                 // SCLK(23pin)[変更不可]:SPI CLOCK       -> CLK

//
// Class
//

var SEG7 = function(f) {
  this.gpio = {
    lat : new Gpio(f.LAT, 'out')
  };
  this.digits = [
    0x3f, 0x06, 0x5b, 0x4f,
    0x66, 0x6d, 0x7d, 0x27,
    0x7f, 0x6f
  ];
  this.gpio.lat.writeSync(LOW);  // ラッチ(LED表示固定)
};

SEG7.prototype = {
  write: function(buf) {
    return new Promise(function(resolve, reject) {
      spi.write( buf, function(e) {
        if (e) console.error(e);
      });
    });
  },
  latch: function() {
    var self = this;
    return new Promise(function(resolve, reject) {
      self.gpio.lat.writeSync(HIGH); // ラッチ解除(シフトレジスタ内容表示)
      self.gpio.lat.writeSync(LOW);  // ラッチ(LED表示固定)
    });
  },
  show: function(f) {
    var self = this;

    var buf = Buffer(f);
    var buf2 = new Buffer(10);
    var j = 0;
    for (var i = 0; i < buf.length; i++) {
      if (buf[i].toString() == '.'.charCodeAt(0)) {
        buf2[j-1] |= 128;
      }
      else {
        buf2[j] = self.digits[buf[i]-48];
        j++;
      }
    }

    self.write(buf2).then(self.latch());
  }

};

//
// Main Routine
//

var seg7 = new SEG7({LAT: LATCH});

var timer = Date.now();
(function loop() {
  var now = Date.now();
  if (now - timer > 16) {
    seg7.show('3.141592653');
    timer = now;
  }
  process.nextTick(loop);
})();

動作例

あとで写真載せる とりあえずツイッターのでお茶を濁す

mbedで点灯する

せっかくなので(このくだりいるのか?)mbedでも光らせます。

今回は、ArduinoマイコンATmega328Pよりも安価なマイコンLPC1114FN28を使ってるmbed LPC1114FN28を使います。これ、プログラム出来上がったらマイコンを外して直接ブレッドボードやら基板やらに設置して動かせるんですよね。

部品名 価格
mbed LPC1114FN28 2160

www.switch-science.com

部品表

部品名 個数 価格
赤色7セグメントLED カソードコモン ボディ黒 C-551SRD 10個 400
7セグメントLED DIP化キット 10個 1600
ブレッドボード BB-102 1枚 300

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

akizukidenshi-ogp-injector.dtpwiki.jp

配線

74HC595と通信するLPC1114FN28側のインタフェースには、3線式シリアル通信に適用できるSPIインタフェースと、ラッチ用に任意の1ピンをGPIOの出力モードで利用します。 あと、3.3Vでも光ります。

LPC1114FN28 7セグ基板 意味
VIN 3.3V VDD IC単体で使う時は外部から+3.3V供給
GND GND Ground(0V)
SCLK(dp6) SCK SPI SCK クロック入力
MOSI(dp2) SDI SPI SDI Masterから見るとOut/SlaveからはIn
dp9 LATCH 74HC595 ラッチ(表示を固定)

f:id:C_L:20160312225119p:plain

プログラム(mbed)

ダイナミック点灯ではないので、ラッチを上げたまま1文字分のビットパターン8bitを10回合計80bitを転送した後、一瞬だけラッチを下してすぐにラッチを上げることで描画が完了します。mbedはspi.write()での1回の転送幅を変更できるが、8bitが使いやすいのではないでしょうか。

#include "mbed.h"

const unsigned char digits[] = {
  0x3f, 0x06, 0x5b, 0x4f,
  0x66, 0x6d, 0x7d, 0x27,
  0x7f, 0x6f,
};

const char str[] = "3.14159265358";
char buf[12];

// mbed LPC1114FN28
// SPI: dp2(MOSI)、dp1(MISO)、dp6(SCK) 
SPI spi(dp2, dp1, dp6); // mosi, miso, sck
// LATCH: 9
DigitalOut latch(dp9);

void show() {
    latch = 1; // 74HC595 ラッチ On(表示固定)
    for ( char i = 0; i < 10 ; i++ ) {
        char d = buf[i];
        char s = ( d & 128); // 128以上のときは128、127以下のときは0
        d &= 127;            // 下位7bitのみマスク
        s += digits[d-48];   // 文字コードに合わせたパターンを合成
        spi.write(s);        // 74CH595 SPIで8ビット分転送
    }
    latch = 0;  // 74HC595 ラッチ Off(表示更新)
    latch = 1;  // 74CH595 ラッチ On(表示固定)
}

void main() {
    spi.format(8,0);
    spi.frequency(12000000); // 12MHz
    
    char j = 0;
    for ( char i = 0; i < strlen( str ); i++ ) {
        char s = str[i];
        if ( s == '.') {
            buf[j-1] |= 128;
        }
        else {
            buf[j] = s;
            j++;
        }
    }
    show();
}

動作例

あとで写真載せる

とりまTwitterに貼った写真でお茶濁す

本当にこの製品は有用なの?

8桁ならコンポーネント製品はある。これも常時点灯(74HC595が8個載っている)

akizukidenshi-ogp-injector.dtpwiki.jp

多桁7セグ表示器をダイナミック点灯・ディスクリート部品で作るとこんなにもじゃっとするんやでー

ダイナミック点灯のためループか割り込みでガシガシ桁駆動させる必要があるので、プログラムも割ともじゃっとする。