Arduino + 四位LED数码管显示当前环境温度

某宝上买的实验面包板和四位LED数码管到货了,继续折腾我的Arduino UNO R3。为了这货上周某天下班路上心血来潮还去买了一盒乐高给它搭了一个外壳。

先看下效果吧。偷懒了不用74HC595了,但这几乎耗尽了全部GPIO。

这次买到的四位数码管是共阴的3641AS,共12个引脚。其中第12、9、8、6脚分别为第一、二、三、四位的选中信号,其余的为8段(7段+小数点)显示管。发光的前提是,段引脚加高电平,Unit选择引脚是低电平。

举例而言,比如要仅仅显示第二位的小数点,则可以:

第一步,Unit 2脚,也就是第9脚设为低电平,其12脚、6脚、8脚都设为高电平(或处于断路状态,如果用自己的电源做测试的话)

第二步,DP脚,也就是第3脚设为高电平,其余脚设置为低电平。

同理,如果要显示1.8,则需要轮流显示Unit 1的1.(注意要显示小数点),以及Unit 2的8。其实每次只显示一位,但由于速度足够快,肉眼认为是在同时显示。

第一步,12脚低电平,其余片选脚高电平,使得Unit被选中。

第二步,11脚(a)、7脚(b)加高电平,3脚(dp)也加高电平,其余段码脚低电平,使得显示“1”和小数点;

第三步,9脚低电平,其余片选脚高电平,使得Unit 2被选中;

第四步,a到g脚全部高电平,dp脚低电平。

如果要显示更多位,继续片选和相应的段码电平设置。

以上只是理论上的,真要这么做可能会出现所谓的“鬼影”,也就是每个显示的数字有相互间的影响,导致显示起来有一种诡异的效果,看不清到底是在显示什么。通常需要在片选动作之前或之后先做一次全部不显示的操作。

温度继续用18B20。做这个实验如果实在没温度探头也没关系,自己指定一个需要被显示的float数就行。本实验的接线方式在上图中已有提示。漏了标注温度探头的接线,是连在A0上的。代码头部的注释也可以参考。

代码如下。有个缺点是隔段时间就暗一下用来采样,暂时还没想到什么解决办法,留着将来再改进下。


/*
  Unit1 A1
  Unit2 A2
  Unit3 A3
  Unit4 A4
 
  A-G,DP  3-10
 
  A0 18B20's data pin 

*/


#include <OneWire.h>
#include <DallasTemperature.h>

#define TempSensor A0

OneWire oneWire(TempSensor);
DallasTemperature sensors(&oneWire);

#define EyesDelay 1

void SelectUnit(int ID)
{
  switch (ID)
  {
    case 1:
      digitalWrite(A1, LOW);
      digitalWrite(A2, HIGH);
      digitalWrite(A3, HIGH);
      digitalWrite(A4, HIGH);
      break;
    case 2:
      digitalWrite(A1, HIGH);
      digitalWrite(A2, LOW);
      digitalWrite(A3, HIGH);
      digitalWrite(A4, HIGH);
      break;
    case 3:
      digitalWrite(A1, HIGH);
      digitalWrite(A2, HIGH);
      digitalWrite(A3, LOW);
      digitalWrite(A4, HIGH);
      break;
    case 4:
      digitalWrite(A1, HIGH);
      digitalWrite(A2, HIGH);
      digitalWrite(A3, HIGH);
      digitalWrite(A4, LOW);
      break;
    default:
      digitalWrite(A1, HIGH);
      digitalWrite(A2, HIGH);
      digitalWrite(A3, HIGH);
      digitalWrite(A4, HIGH);
      break;
  }
}

void ShowData(int UnitID, char * data)
{

  SelectUnit(UnitID);

  for (int i = 0; i < 8; i++)
  {
    if (data[i] == '0')
    {
      digitalWrite(i + 3, LOW);
    }
    else
    {
      digitalWrite(i + 3, HIGH);
    }
  }
}

void ShowNone()
{
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A4, HIGH);

  for (int i = 3; i <= 10 ; i++)
  {
    digitalWrite(i, LOW);
  }
}


void Show(int UnitID, char a)
{
ShowNone();
  switch (a)
  {
    case '0':
        ShowData(UnitID, "11111100");
      break;
    case '1':
      ShowData(UnitID, "01100000");
      break;
    case '2':
      ShowData(UnitID, "11011010");
      break;
    case '3':
     ShowData(UnitID, "11110010");
      break;
    case '4':
      ShowData(UnitID, "01100110");
      break;
    case '5':
      ShowData(UnitID, "10110110");
      break;
    case '6':
        ShowData(UnitID, "10111110");
      break;
    case '7':
        ShowData(UnitID, "11100000");
      break;
    case '8':
      ShowData(UnitID, "11111110");
      break;
    case '9':
        ShowData(UnitID, "11110110");
      break;
    case '.':
      ShowData(UnitID, "00000001");
      break;
    case '-':
      ShowData(UnitID, "00000010");
      break;
    default:
      ShowNone();
      break;

  }
 
    delay(EyesDelay);
}

void setup() {
  // put your setup code here, to run once:
  for (int i = 3; i <= 10; i++)
  {
    pinMode(i, OUTPUT);
  }

  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A4, OUTPUT);
 
  sensors.begin();

}

void ShowTemp(float val)
{
  char buf[8];
  for (int i = 0; i < 8; i++)
  {
    buf[i] = '\0';
  }
  dtostrf(val, 1, 3, buf);

  if (buf[1] == '.') //0.123
  {
    Show(1, buf[0]);
    Show(1, '.');
    Show(2, buf[2]);
    Show(3, buf[3]);
    Show(4, buf[4]);
  }

  if (buf[2] == '.') //11.12
  {
    Show(1, buf[0]);
    Show(2, buf[1]);
    Show(2, '.');
    Show(3, buf[3]);
    Show(4, buf[4]);
  }


  if (buf[3] == '.') //111.12
  {
    Show(1, buf[0]);
    Show(2, buf[1]);
    Show(3, buf[2]);
    Show(3, '.');
    Show(4, buf[4]);
  }

  if (buf[4] == '.') //1112.12
  {
    Show(1, buf[0]);
    Show(2, buf[1]);
    Show(3, buf[2]);
    Show(4, buf[3]);
    Show(4, '.');
  }
}

void loop() {

  // Get 18B20 Data
  sensors.requestTemperatures();
  float t = sensors.getTempCByIndex(0);
  delay(1000);
 
  for (int i = 0; i < 600; i++)
  {
    ShowTemp(t);
  }
 
  ShowNone();
}






  • 9
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ki1381

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值