SSブログ

Maruduino 拡張部品 7セグメントLEDと24KEYの実装について [組み立て]

サンプルのスケッチを掲載します。
ただ、実行したArduinoのバージョンが古い(0018)ので、Arduinoの現在のバージョンとの違いが影響を及ぼすかもしれません。

仕組みとしては追加した3個のICはIO Expanderと呼ばれるもので、I2Cバスに接続されてパラレルの入出力機能を拡張するものです。

設定によって入力にしたり、出力とする事が出来ますが、7SEG LEDをドライブする場合は3つ共に出力とします。

回路図の7SEG LEDのシートの上側にトランジスタが8個並んでいる訳ですが、この8個のトランジスタがそれぞれの桁の7SEG LEDに対して電源を供給する事となります。
シート名EXTENTION IOのIO ExpanderのIC5に接続され、IO ExpanderからLOWを出力したトランジスタがONとなり、7SEG LEDに電気を供給します。
※この時注意が必要なのが、8個のトランジスタのうち、一度にONするのは必ず一つに限ります。他のトランジスタにはHIGHを出力する様にIO Expanderの出力を決めます。
トランジスタを駆動するIO ExpanderのI2Cバス上のアドレスは0x40となります。

残り2つのIO Expanderがそれぞれの行の7SEG LEDのセグメント(光る部分)をコントロールします。
7SEG LEDのそれぞれのセグメントにはアルファベットが割り付けられており、一番上をaとして時計回りにb、c、d、e、fと回り、真中のセグメントがgになります。
つまり数字で7を表示したい時はa、b、cを光らせれば7になります。
IO Expanderの出力をLOWとすれば、そのbitに接続されたセグメントが光ります。
上の行のコントロールをするIO ExpanderのI2Cバス上のアドレスは0x42、下が0x44です。

さて充分に早い時間間隔でONするトランジスタを切り替えていきます。トランジスタの位置がそのまま桁となっている点に注意してください。
通常人間は30Hz以上のフリッカーには反応できず点灯しっ放しに見えます。つまり最初の桁から最後の桁までの切り替えを30Hz以上で回さないといけないので、切り替えの周期はその8倍で240Hz以上は必要でしょう。

※IO Expanderを入力として使う時は、Writeモードで入力したいbitに1を書き込んで、Readモードで読み込んでください。

以下のスケッチはMsTimer2を使って1msでカウントアップを行っています。
---------------------------------------------
#include <MsTimer2.h>
#include <Wire.h>

//const int I2C_SEL_ADR = 0x70 >> 1;  //_ONSEMI_
//const int I2C_SEG1_ADR = 0x72 >> 1; //_ONSEMI_
//const int I2C_SEG2_ADR = 0x74 >> 1; //_ONSEMI_
const int I2C_SEL_ADR = 0x40 >> 1;    //_NXP
const int I2C_SEG1_ADR = 0x42 >> 1;   //_NXP
const int I2C_SEG2_ADR = 0x44 >> 1;   //_NXP

unsigned long systim;
unsigned long nxttim = 50UL;

#define  SEG_A  0b10000000
#define  SEG_B  0b00100000
#define  SEG_C  0b00001000
#define  SEG_D  0b00000010
#define  SEG_E  0b00000100
#define  SEG_F  0b00010000
#define  SEG_G  0b01000000
#define  SEG_DP 0b00000001

const unsigned char seg[] =
{
  ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F),  //0:abcdef
  ~(SEG_B | SEG_C),  //1:bc
  ~(SEG_A | SEG_B | SEG_D | SEG_E | SEG_G),  //2:abdeg
  ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_G),  //3:abcdg
  ~(SEG_B | SEG_C | SEG_F | SEG_G),  //4:bcfg
  ~(SEG_A | SEG_C | SEG_D | SEG_F | SEG_G),  //5:acdfg
  ~(SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G),  //6:acdefg
  ~(SEG_A | SEG_B | SEG_C),  //7:abc
  ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G),  //8:abcdefg
  ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G),  //9:abcdfg
  0b11111111,  //blank
  0b11111111,  //blank
  0b11111111,  //blank
  0b11111111,  //blank
  0b11111111,  //blank
  0b11111111,  //blank
};

void I2C_Write( unsigned char adr, unsigned char data )
{
  Wire.beginTransmission( adr );
  Wire.send( data );
  Wire.endTransmission();
}

static void drive_seg( void )
{
  static int keta;
  unsigned char sel,seg1,seg2;

  switch( keta )
  {
    case 0 :  /*LSB*/
      sel = 0x7f;
      seg1 = seg[systim % 10];
//      seg2 = seg[systim % 10];
      break;
    case 1 :
      sel = 0xbf;
      seg1 = seg[(systim / 10) % 10];
//      seg2 = seg[(sec / 10) % 10];
      break;
    case 2 :
      sel = 0xdf;
      seg1 = seg[(systim / 100UL) % 10];
//      seg2 = seg[(sec / 100UL) % 10];
      break;
    case 3 :
      sel = 0xef;
      seg1 = seg[(systim / 1000UL) % 10];
//      seg2 = seg[(sec / 1000UL) % 10];
      break;
    case 4 :
      sel = 0xf7;
      seg1 = seg[(systim / 10000UL) % 10];
//      seg2 = seg[(sec / 10000UL) % 10];
      break;
    case 5 :
      sel = 0xfb;
      seg1 = seg[(systim / 100000UL) % 10];
//      seg2 = seg[(sec / 100000UL) % 10];
      break;
    case 6 :
      sel = 0xfd;
      seg1 = seg[(systim / 1000000UL) % 10];
//      seg2 = seg[(sec / 1000000UL) % 10];
      break;
    case 7 :  /*MSB*/
      sel = 0xfe;
      seg1 = seg[(systim / 10000000UL) % 10];
//      seg2 = seg[(sec / 10000000UL) % 10];
      break;
  }
  I2C_Write( I2C_SEL_ADR, 0xff );
  I2C_Write( I2C_SEG1_ADR, seg1 );
  I2C_Write( I2C_SEG2_ADR, seg1 );
  I2C_Write( I2C_SEL_ADR, sel );

  if( ++keta > 7 ) keta = 0;
}

static void systim_hdr( void )
{
  systim++;
}

void setup()
{
  Wire.begin();
  I2C_Write( I2C_SEL_ADR, 0xff );
  I2C_Write( I2C_SEG1_ADR, 0xff );
  I2C_Write( I2C_SEG2_ADR, 0xff );

  MsTimer2::set( 1, systim_hdr );
  MsTimer2::start();
}

void loop()
{
    drive_seg();
}




以下、昔の書き込み
---------------------------------------------
まだマルツさんからは部品セットとして販売していませんが、7セグメントLEDと24KEYは同時に実装する事ができません。

機能的にはI2C エキスパンドIOが入力モードか出力モードの何れかしか選択できないので、7セグメントLEDでは出力、24KEYでは入力と同時設定はできないものです。

ただ物理的に実装は可能なので、7セグメントLEDと24KEYの両方を実装してしまうこともあり得るのですが、いまの回路ではこれに対応できません。最悪ではLEDかトランジスタの故障と言う事になります。
実装はかならずどちらかを選んでください。

どうしても一つの基板で7セグメントLEDと24KEYを実装したい場合は、トランジスタを3pinのソケットヘッダーを使って実装(差し込む)事をお勧めします。24KEYを使う場合はトランジスタを外してしまいます。
私も手持ちのMaruduinoではそうしています。

nice!(0)  コメント(5)  トラックバック(0) 

nice! 0

コメント 5

yommme

はじめまして。
7セグ、24スイッチを全て実装したのですが、肝心のスケッチが全くかけず困っております・・・
おそらくWireライブラリを使うのだろうと思っているのですが、7セグの回路図が読解できず、ぜひサンプルを拝見させていただきたいです。
by yommme (2012-07-03 04:03) 

yommme

大変参考になりました。
ありがとうございます!
by yommme (2012-07-04 10:49) 

大吠二千一

こんにちは。
MABTB-BASEにMaruduiono化キット、I/OエクスパンダICとタクトスイッチ、それに抵抗器を実装しました。これを使ってメロディを演奏してみたいのですが、何かサンプルコードはありますでしょうか?
by 大吠二千一 (2020-05-06 16:13) 

hamayan

連絡が遅くなり申し訳ありません。

> これを使ってメロディを演奏してみたい

これはtoneライブラリを使うのがもっとも簡単だと思います。
それ以外の方法でしょうか。
http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2484

by hamayan (2020-05-13 14:53) 

大吠二千一

ありがとうございます。参考にします。
by 大吠二千一 (2020-05-17 06:33) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。