afkfkl
@afkfkl (a m)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

arduino,温度センサICを使って7セグに表示ができない

解決したいこと

arduino,温度センサーを使ってled7セグメントに温度を表示させるプログラムを書いています。プログラミング初心者なので下のコードのNumPrint関数の仕組みがよくわかりません。二次元配列などもわからないのでご教授ください。
また,ソースコードで間違っているところがあれば教えていただきたいです。
動作確認をしたところ,led7セグメントに予期せぬ数字が表示されたり,そもそも数字にならず光ってしまったりしました。
7セグメントはアノードコモンのものです。

該当するソースコード


/*アノードコモン7セグ・LM35dz 1秒おきに温度を更新*/
int _cnt = 0; //時間調整用カウンタ
int _number = 0; //表示(温度)
int temperaturePin = A0; //温度センサーピン
char _flg = 0;//表示桁切り替え

void setup() {
//2~8番ピン デジタル出力へセット
for (int i=2; i<=8; i++) {//7セグ2~8ピン。カソードにつなぐ。抵抗1kΩ。
pinMode(i,OUTPUT);
}

pinMode(11,OUTPUT);//1桁目 アノードコモン 直接つなぐ
pinMode(13,OUTPUT);//2桁目 アノードコモン 直接つなぐ
}
//LEDレイアウトを定義 
boolean Num_Array[10][7]= {
  {0,0,0,0,0,0,1}, //0
  {1,0,0,1,1,1,1}, //1
  {0,0,1,0,0,1,0}, //2
  {0,0,0,0,1,1,0}, //3
  {1,0,0,1,1,0,0}, //4
  {0,1,0,0,1,0,0}, //5
  {0,1,0,0,0,0,0}, //6
  {0,0,0,1,1,0,1}, //7
  {0,0,0,0,0,0,0}, //8
  {0,0,0,0,1,0,0} //9
};
//7セグに数字0~9を表示させる関数を定義 Numberに表示したい数字
void NumPrint(int Number) {
for (int j=0; j<7; j++) {
digitalWrite(j+2,Num_Array[Number][j]);
}
}

void loop() {
//温度を取得
if(++_cnt==200) { //5*200=1秒毎に更新&&カウントリセット
_cnt=0;
_number = map(analogRead(temperaturePin),0,1023,0,100);//LM35DZ用map関数 map(value, fromLow, fromHigh, toLow, toHigh)
                                                       //戻り値は変換後の数値

// _number = map(analogRead(temperaturePin),0,1023,-30,100);//例えばLM61CIZならこう
}

//7セグ表示 100Hz
if(_flg==0) {//1桁目表示
digitalWrite(13,HIGH);//2桁目消す
NumPrint(_number%10);//1桁目の数字を合わせる 
digitalWrite(11,LOW);//1桁目表示
_flg = 1;

} else {//2桁目表示
digitalWrite(11,HIGH);//1桁目消す
NumPrint(_number/10);//2桁目の数字に合わせる
digitalWrite(13,LOW);//2桁目表示
_flg = 0;
}

delay(5);
}

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

0

1Answer

PC上でLED表示パターンと数字の関連付けを確認しましたが、
こちらそのものは正常動作しているように見えました。
(※下記はえいやでくんだサンプルコード。気にしないでください)。

問題があるならば、ハードウェア/電気回路から見たほうが良いかもしれません。

例えば、数字から表示するLEDの点灯パターンは、
ソースコードからは以下のような紐づけに見えました。
こちらの認識はハードウェア/電気回路上の実装と一致しておりますか?

     {a,b,c,d,e,f,g}={pin2,3,4,...}

     baaac
     b   c
     bdddc
     e   f
     egggf

デバッグをするのであれば、以下のようにデバッグすると、どの部分で問題が起きているのかを特定しやすいかもしれません。

#if 0
        _number = map(analogRead(temperaturePin), 0, 1023, 0, 100);
        //LM35DZ用map関数 map(value, fromLow, fromHigh, toLow, toHigh)
        //戻り値は変換後の数値
        //例えばLM61CIZならこう
        // _number = map(analogRead(temperaturePin),0,1023,-30,100);
#else
        _number = ( _number + 1 ) % 100;
        // デバッグならば、_number = 0; など決め打ちにしたほうがよい
#endif
  1. _number = 8; -> 1桁目の全LEDが付くか?(a,b,c,d,e,f,g)
  2. _number = 0; -> 1桁目の中央部LEDが消えるか?(d)
  3. _number = 3; -> 1桁目の左側LED2個が消えるか?(b,e)
  4. _number = 5; -> 1桁目の右上、左下LEDが消えるか?(c,e)
  5. _number = 2; -> 1桁目の左上、右下LEDが消えるか?(b,f)
  6. _number = 7; -> 1桁目の下LEDが消えるか?(g他)
  7. _number = 1; -> 1桁目の上LEDが消えるか?(a他)
  8. _number = 80; -> 2桁目の... 以下同

以下のサンプルコードは、linux上でコンパイルして試すための者です。このままarduinoなどに持って行ってもコンパイルできません。

test.c

/**
 * ロジック検証用にPC上でシミュレーションするプログラム
 */

// コンパイルを通すためにArduinoのお作法をごまかす
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>

typedef bool boolean;
const int HIGH   = 1;
const int LOW    = 0;
const int OUTPUT = 0xFF;
#define A0 (0);

int _lcdid = 0;
int _lcd[8*2] = {0};

void pinMode(int _pin, int _mode){
        printf("[DEBUG] pin (%d) -> %s \n",
                        _pin,
                        (_mode == OUTPUT)?"OUTPUT":"INPUT");
}

void delay(int _msec)
{
        // usleepはnano sec
        // arduinoのdelayはmili sec
        // 1000倍して都合を合わせる
        usleep( _msec * 1000 );
}

void lcd_show();

void digitalWrite( int _pin, boolean _level )
{
        switch(_pin){
                case 11:
                case 13:
                if ( _level == HIGH) {
                        /* 7seg切り替え */
                        _lcdid = (_pin == 11)?0:1;
                }else{
                        /* 表示 */
                        lcd_show();
                }
                break;
                case 2: case 3: case 4: case 5:
                case 6: case 7: case 8:
                        _lcd[ _lcdid * 7 + (_pin - 2) ] = _level;
                break;
        }
#if 0
        printf("[DEBUG] pin (%d) -> %s \n",
                        _pin,
                        (_level = HIGH)?"HIGH":"LOW");
#endif
}
/*
 * boolean Num_Array[10][7] = {
    { 0, 0, 0, 0, 0, 0, 1 },    //0
    { 1, 0, 0, 1, 1, 1, 1 },    //1
    { 0, 0, 1, 0, 0, 1, 0 },    //2
    { 0, 0, 0, 0, 1, 1, 0 },    //3
    { 1, 0, 0, 1, 1, 0, 0 },    //4
    { 0, 1, 0, 0, 1, 0, 0 },    //5
    { 0, 1, 0, 0, 0, 0, 0 },    //6
    { 0, 0, 0, 1, 1, 0, 1 },    //7
    { 0, 0, 0, 0, 0, 0, 0 },    //8
    { 0, 0, 0, 0, 1, 0, 0 }     //9
};
      a  c  f  g  e  b  d

     baaac
     b   c
     bdddc
     e   f
     egggf
*/

void lcd_show()
{
        #define POS(idx,y,x) ( 17 *y + x + idx * 6 )
        uint8_t _fb [17 * 5];
        memset(_fb,0,sizeof(_fb));

        for ( int i = 0; i < 2 ; i ++ ){
                /* a */
                if ( _lcd[i * 7 + 0] == 0 ) {
                        _fb[POS(i,0,1)] = _fb[POS(i,0,2)] = _fb[POS(i,0,3)] = 1;
                }
                /* c */
                if ( _lcd[i * 7 + 1] == 0 ) {
                        _fb[POS(i,0,4)] = _fb[POS(i,1,4)] = _fb[POS(i,2,4)] = 1;
                }
                /* f */
                if ( _lcd[i * 7 + 2] == 0 ) {
                        _fb[POS(i,3,4)] = _fb[POS(i,4,4)] = 1 ;
                }
                /* g */
                if ( _lcd[i * 7 + 3] == 0 ) {
                        _fb[POS(i,4,1)] = _fb[POS(i,4,2)] = _fb[POS(i,4,3)] = 1;
                }
                /* g */
                if ( _lcd[i * 7 + 4] == 0 ) {
                        _fb[POS(i,4,0)] = _fb[POS(i,3,0)] = 1;
                }
                /* g */
                if ( _lcd[i * 7 + 5] == 0 ) {
                        _fb[POS(i,2,0)] = _fb[POS(i,1,0)] = _fb[POS(i,0,0)] = 1;
                }
                /* g */
                if ( _lcd[i * 7 + 6] == 0 ) {
                        _fb[POS(i,2,1)] = _fb[POS(i,2,2)] = _fb[POS(i,2,3)] = 1;
                }
        }

        for ( int iv = 0; iv < 14; iv++)
        {
                printf("%d ", _lcd[iv] );
        }
        printf("\n");

        for ( int iy = 0; iy < 5; iy++){
                for ( int ix = 0 ; ix < 17; ix ++ ){
                        if ( _fb[iy * 17 + ix] == 1 )
                        {
                                printf ("*");
                        }else{
                                printf (" ");
                        }
                }
                printf("\n");
        }
}

void setup();
void loop();

int main()
{
    setup();
    while(1) loop();
}

/**
 * ここまでがシミュレーションプログラム
 **/

/*アノードコモン7セグ・LM35dz 1秒おきに温度を更新*/
int _cnt = 0;                   //時間調整用カウンタ
int _number = 0;                //表示(温度)
int temperaturePin = A0;        //温度センサーピン
char _flg = 0;                  //表示桁切り替え

void setup()
{
    // 2~8番ピン デジタル出力へセット
    // 7セグ2~8ピン。カソードにつなぐ。抵抗1kΩ。
    for (int i = 2; i <= 8; i++) {
        pinMode(i, OUTPUT);
    }

    pinMode(11, OUTPUT);        //1桁目 アノードコモン 直接つなぐ
    pinMode(13, OUTPUT);        //2桁目 アノードコモン 直接つなぐ
}

//LEDレイアウトを定義 
boolean Num_Array[10][7] = {
    { 0, 0, 0, 0, 0, 0, 1 },    //0
    { 1, 0, 0, 1, 1, 1, 1 },    //1
    { 0, 0, 1, 0, 0, 1, 0 },    //2
    { 0, 0, 0, 0, 1, 1, 0 },    //3
    { 1, 0, 0, 1, 1, 0, 0 },    //4
    { 0, 1, 0, 0, 1, 0, 0 },    //5
    { 0, 1, 0, 0, 0, 0, 0 },    //6
    { 0, 0, 0, 1, 1, 0, 1 },    //7
    { 0, 0, 0, 0, 0, 0, 0 },    //8
    { 0, 0, 0, 0, 1, 0, 0 }     //9
};

//7セグに数字0~9を表示させる関数を定義 Numberに表示したい数字
void NumPrint(int Number)
{
    for (int j = 0; j < 7; j++) {
        digitalWrite(j + 2, Num_Array[Number][j]);
    }
}

void loop()
{
    //温度を取得
    if (++_cnt == 200) {        //5*200=1秒毎に更新&&カウントリセット
        _cnt = 0;
#if 0
        _number = map(analogRead(temperaturePin), 0, 1023, 0, 100);
        //LM35DZ用map関数 map(value, fromLow, fromHigh, toLow, toHigh)
        //戻り値は変換後の数値
        //例えばLM61CIZならこう
        // _number = map(analogRead(temperaturePin),0,1023,-30,100);
#else
        _number = ( _number + 1 ) % 100;
        // デバッグならば、_number = 0; など決め打ちにしたほうがよい
#endif
    }
    //7セグ表示 100Hz
    if (_flg == 0) {            //1桁目表示
        digitalWrite(13, HIGH); //2桁目消す
        NumPrint(_number % 10); //1桁目の数字を合わせる 
        digitalWrite(11, LOW);  //1桁目表示
        _flg = 1;

    } else {                    //2桁目表示
        digitalWrite(11, HIGH); //1桁目消す
        NumPrint(_number / 10); //2桁目の数字に合わせる
        digitalWrite(13, LOW);  //2桁目表示
        _flg = 0;
    }

    delay(5);
}

0Like

Your answer might help someone💌