Arduino UNO学习笔记(5): 数码管显示温度--代码部分

0. 实验目的

数码管显示温度
书接上回Arduino UNO学习笔记(4): 数码管+温度传感器=>显示温度-CSDN博客。

1. 代码

1.1 文件构成

代码共由3个文件及两个包组成

文件列表:

  • demo.ino
  • SegmentDisplay.h
  • SegmentDisplay.cpp

安装列表:

  • OneWire
  • DallasTemperature

1.2 demo.ino

#include "SegmentDisplay.h"
#include 
#include 

#define  LED_A   12      // x define Arduino GPIO1 for led a 
#define  LED_B   8       // x define Arduino GPIO2 for led b
#define  LED_C   4       // x define Arduino GPIO3 for led c
#define  LED_D   6       // x define Arduino GPIO4 for led d
#define  LED_E   7       // x define Arduino GPIO5 for led e
#define  LED_F   11      // x define Arduino GPIO6 for led f
#define  LED_G   3       // x define Arduino GPIO7 for led g
#define  LED_H   5       // x define Arduino GPIO8 for led h

#define  LED_D1  -1      // x 如果想让数码管从第一位开始显示,可以设置为13, 由于引脚不够用,此处把线给拔掉了,设置为-1
#define  LED_D2  10      // x
#define  LED_D3  9       // x
#define  LED_D4  2       // x

#define PIN_TEMP 13      // 将原本LED_D1对应的引脚设置为温度引脚,引脚不够用,实属无奈

int count = 0;      // 计数器, count>thr退出
int n_t = 0;        // 温度, 摄氏度
SegmentDisplay dig_tube(
  LED_A, LED_B, LED_C, LED_D, LED_E, LED_F, LED_G, LED_H,
  LED_D1, LED_D2, LED_D3, LED_D4
);                                          // 定义数码管类
OneWire oneWire_8(PIN_TEMP);                // 18B20数字温度传感器接Arduino上的数字引脚
DallasTemperature sensors_8(&oneWire_8);    // 将oneWire地址传递给DallasTemperature库
DeviceAddress insideThermometer;            // 定义设备地址

void setup()
{
  Serial.begin(9600);
  dig_tube.TurnOffAllLed();                        // 关闭数码管的所有LED
  sensors_8.getAddress(insideThermometer, 0);      // 读取传感器地址
  sensors_8.setResolution(insideThermometer, 10);  // 设置分辨率
}

void loop()
{
  if (count % 50 == 0)                // 定期刷新温度, 在刷的时候会导致LED暗了一瞬
  {
    sensors_8.requestTemperatures();  // 传感器获取温度
    float temp = sensors_8.getTempC(insideThermometer); // 获取摄氏度, 此处也支持华氏温度:getTempC --> getTempF
    if (temp < 50 && temp > -50)      // 过滤异常的温度值, 传感器在初始化的时候会产生异常值, 如: -127℃, 85℃
    {
      n_t = (int)temp;
    }
  }
  dig_tube.DisplayChar(n_t);          // 显示温度值
  delay(5);
  count++;

  if (count >= 5000) {
      dig_tube.TurnOffAllLed();
      exit(0);
  }
}

1.3 SegmentDisplay.h

#ifndef _SEGMENT_DISPLY_H_
#define _SEGMENT_DISPLY_H_
#include 
#include 

//the common VCC pin dight value
#define DIGHT_0 0xC0
#define DIGHT_1 0xF9
#define DIGHT_2 0xA4
#define DIGHT_3 0xB0
#define DIGHT_4 0x99
#define DIGHT_5 0x92
#define DIGHT_6 0x82
#define DIGHT_7 0xF8
#define DIGHT_8 0x80
#define DIGHT_9 0x90
#define DIGHT_OFF 0x00

#define DIGHT_NUMBLE(n) DIGHT_##n

typedef enum  {
    SEGMENT_DISPLY_1BIT,
    SEGMENT_DISPLY_4BIT,
    SEGMENT_DISPLY_8BIT
}E_DIGHT_DISPLYA_TYPE;

class SegmentDisplay {

private :
    uint8_t dight_pin[8];
    uint8_t dight_select_pin[4];
    E_DIGHT_DISPLYA_TYPE mode;
    void numble2dis(int numble);
public :
    byte dight_display[10];
    byte display_array[4];
    SegmentDisplay(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h);
    SegmentDisplay(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4);
    void TurnOffAllLed(void);
    void DisplayChar(byte n);
    void DisplayChar(int n);
    void DisplayChar(byte sel, byte n);
};
#endif


1.4 SegmentDisplay.cpp

#include "SegmentDisplay.h"

SegmentDisplay::SegmentDisplay(
  uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h
  )
{
    mode = SEGMENT_DISPLY_1BIT;
    dight_pin[0] = a;
    dight_pin[1] = b;
    dight_pin[2] = c;
    dight_pin[3] = d;
    dight_pin[4] = e;
    dight_pin[5] = f;
    dight_pin[6] = g;
    dight_pin[7] = h;
    dight_display[0] = DIGHT_NUMBLE(0);
    dight_display[1] = DIGHT_NUMBLE(1);
    dight_display[2] = DIGHT_NUMBLE(2);
    dight_display[3] = DIGHT_NUMBLE(3);
    dight_display[4] = DIGHT_NUMBLE(4);
    dight_display[5] = DIGHT_NUMBLE(5);
    dight_display[6] = DIGHT_NUMBLE(6);
    dight_display[7] = DIGHT_NUMBLE(7);
    dight_display[8] = DIGHT_NUMBLE(8);
    dight_display[9] = DIGHT_NUMBLE(9);

    for (int i = 0; i < 8; i++) {
        pinMode(dight_pin[i], OUTPUT);  //set all led diplay array pin output mode
        digitalWrite(dight_pin[i], LOW);
    }
}

SegmentDisplay::SegmentDisplay(
  uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h,
  uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4
)
{
    mode = SEGMENT_DISPLY_4BIT;
    dight_pin[0] = a;
    dight_pin[1] = b;
    dight_pin[2] = c;
    dight_pin[3] = d;
    dight_pin[4] = e;
    dight_pin[5] = f;
    dight_pin[6] = g;
    dight_pin[7] = h;
    dight_display[0] = DIGHT_NUMBLE(0);
    dight_display[1] = DIGHT_NUMBLE(1);
    dight_display[2] = DIGHT_NUMBLE(2);
    dight_display[3] = DIGHT_NUMBLE(3);
    dight_display[4] = DIGHT_NUMBLE(4);
    dight_display[5] = DIGHT_NUMBLE(5);
    dight_display[6] = DIGHT_NUMBLE(6);
    dight_display[7] = DIGHT_NUMBLE(7);
    dight_display[8] = DIGHT_NUMBLE(8);
    dight_display[9] = DIGHT_NUMBLE(9);

    dight_select_pin[0] = d1;
    dight_select_pin[1] = d2;
    dight_select_pin[2] = d3;
    dight_select_pin[3] = d4;

    for (int i = 0; i < 8; i++) {
        pinMode(dight_pin[i], OUTPUT);  //set all led diplay array pin output mode
        digitalWrite(dight_pin[i], LOW);
    }
    for (int i = 0; i < 4; i++) {
        pinMode(dight_select_pin[i], OUTPUT);  //set all led diplay array pin output mode
        digitalWrite(dight_select_pin[i], LOW);
    }
}

void SegmentDisplay::TurnOffAllLed(void)
{
    for (int i = 0; i < 8; i++)
    digitalWrite(dight_pin[i], HIGH);
    if (mode == SEGMENT_DISPLY_4BIT) {
        for (int i = 0; i < 4; i++)
        digitalWrite(dight_select_pin[i], LOW);
    }
}
void SegmentDisplay::numble2dis(int numble)
{
    int numble_bit = 0;
    int bit_base = 1000;
    for (numble_bit = 0; numble_bit < 4; numble_bit++ )
    {
        if (numble/bit_base != 0)
        {
            display_array[numble_bit] = numble/bit_base;    // integer date convert to ASCII
            numble = numble%bit_base;
        }else
        {
            display_array[numble_bit] = 0;                 // led display none
        }
        bit_base = bit_base / 10;
    }
}

void SegmentDisplay::DisplayChar(byte n)
{
    byte ch = dight_display[n];
    if (n < 10) {
        for (byte i = 0; i < 8; i++) {
            if (ch & (1 << i)) {
                digitalWrite(dight_pin[i], HIGH);
            } else {
                digitalWrite(dight_pin[i], LOW);
            }
        }
    }
}

void SegmentDisplay::DisplayChar(int n)
{
    if (mode == SEGMENT_DISPLY_4BIT) {
        numble2dis(n);
        for(int i = 0; i < 4; i++) {
            DisplayChar((byte)display_array[i]);
            digitalWrite(dight_select_pin[i], HIGH);
            delay(5);
            digitalWrite(dight_select_pin[i], LOW); // you must turn off
        }
    }
}

void SegmentDisplay::DisplayChar(byte sel, byte n)
{
    byte ch = dight_display[n];
    for (byte i = 0; i < 8; i++) {
        if (ch & (1 << i)) {
            digitalWrite(dight_pin[i], HIGH);
        } else {
            digitalWrite(dight_pin[i], LOW);
        }
    }
    digitalWrite(dight_select_pin[sel] ,HIGH );
}

2. 效果演示

数码管温度

如果您觉得本文有用/有意思,请点赞收藏鼓励一下

后续仍会继续发布一些其他实验结果和改进,欢迎各位玩家来交流~~

你可能感兴趣的:(硬件,学习,笔记)