极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12173|回复: 2

用8位串口数码管由红外控制显示时间、温湿度

[复制链接]
发表于 2014-11-2 15:41:47 | 显示全部楼层 |阅读模式
本帖最后由 glmyc 于 2014-11-2 16:43 编辑

本程序参考了论坛上部分程序与设计思想,本程序能实现在有人在附近时,显示年月日然后显示时分秒再显示温度与湿度,无人时自动关闭显示。
难的是在淘宝购买的8位串口LED数码管,没有ARDUINO程序参考,只有51程序,参考了网上应用后写了以下程序,对使用别人程序成果表示感谢!

#include <stdio.h>
#include <string.h>                //字符串处理头文件
#include <DS1302.h>                //数字时钟模块头文件
#include <dht11.h>        //温湿度传感器头文件
dht11 DHT11;       
uint8_t CE_PIN   = 3;       //时钟模块的RST接ARDUINO的3脚、DAT接4脚、CLK接5脚
uint8_t IO_PIN   = 4;
uint8_t SCLK_PIN = 5;
int DHT11pin = 2;        //DHT11 接在2脚
int red = 6;     //红外线探测接6脚
int dio = 8;     //8位串口LED数码管DIO接8脚、RCLK接9脚、SCLK接10脚
int rclk = 9;
int sclk = 10;
/* 日期变量缓存 */
char buf1[50];                //显示年月日缓冲区
char buf2[50];                //显示时分秒缓冲区
char buf3[50];                //显示温度与湿度缓冲区
char day[10];
/* 串口数据缓存 */
String comdata = "";
int numdata[7] = {0}, j = 0, mark = 0;
/* 创建 DS1302 对象 */
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);

char char_map[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x8C, 0xBF, 0xC6, 0xA1, 0x86, 0xFF, 0xBF};
char index_map[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '-'};

void ledout(unsigned char chr)
{
  unsigned char i;
  for (i = 8; i >= 1; i--)
  {
    if (chr & 0x80) {
      digitalWrite(dio, 1);
    } else {
      digitalWrite(dio, 0);
    }
    chr <<= 1;
    digitalWrite(sclk, 0);
    digitalWrite(sclk, 1);
  }
}

void ledshow(const char* str)
{
  int len = strlen(str);
  int hasDot = 0;
  for (int i = len - 1, m = 0; i >= 0; i--) {
    char chr = str;
    if (chr == '.') {       
      hasDot = 1;
      continue;
    }
    int n = 0;
    for (; n < 17; n++) {
      if (chr == index_map[n])
        break;
    }
    if (n != 17) {
      unsigned char chr1 = char_map[n];
      if (hasDot)
        chr1 &= 0x7f;        //小数点处理
      ledout(chr1);
      ledout((int)ceil(pow(2, m)));
      digitalWrite(rclk, 0);
      digitalWrite(rclk, 1);
    }
    m++;
    hasDot = 0;
  }
}


void print_time()
{
  for (int l = 0; l < 100; l++) {                //有人后一直显示较长时间L=100,就可以显示9分多钟
    Time t = rtc.time();  /* 从 DS1302 获取当前时间 */
    memset(day, 0, sizeof(day));    /* 将星期从数字转换为名称 */
    int chk = DHT11.read(DHT11pin);
    int humi = DHT11.humidity;
    int temper = DHT11.temperature;
    snprintf(buf1, sizeof(buf1), "%04d.%02d.%02d", t.yr, t.mon, t.date);        //格式化日期字符串
    snprintf(buf2, sizeof(buf2), "%02d %02d %02d", t.hr, t.min, t.sec);                //格式化时间字符串
    snprintf(buf3, sizeof(buf3), "% 4d% 4d", temper, humi);                //格式化温湿度
    Serial.println(buf1);                //串口监视一下需要显示的数据
    Serial.println(buf2);
    Serial.println(buf3);
        //下面是显示相应数据,需要维持一定时间才能显示
    for (int i = 0; i < 500; i++) {
      ledshow(buf1);
    }
    for (int i = 0; i < 500; i++) {
      ledshow(buf2);
    }
    for (int i = 0; i < 500; i++) {
      ledshow(buf3);
    }
  }
  //下面处理没有人时显示
  int redl = digitalRead(red);
  if (!redl) {
    for (int i = 0; i < 500; i++) {
      ledshow("");
    }
  }
  //snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day, t.yr, t.mon, t.date, t.hr, t.min, t.sec);
  //Serial.println(buf);  /* 输出日期到串口 */
}


void setup()
{
  pinMode(dio, OUTPUT);
  pinMode(rclk, OUTPUT);
  pinMode(sclk, OUTPUT);
  Serial.begin(9600);
  //Serial.println("Reset");
  rtc.write_protect(false);
  rtc.halt(false);
}

void loop()
{
  while (Serial.available() > 0)  /* 当串口有数据的时候,将数据拼接到变量comdata */
  {
    comdata += char(Serial.read());
    delay(2);
    mark = 1;
  }

  if (mark == 1)  /* 以逗号分隔分解comdata的字符串,分解结果变成转换成数字到numdata[]数组 */
  {
    Serial.print("You inputed : ");
    Serial.println(comdata);
    for (int i = 0; i < comdata.length() ; i++)
    {
      if (comdata == ',' || comdata == 0x10 || comdata == 0x13)
      {
        j++;
      }
      else
      {
        numdata[j] = numdata[j] * 10 + (comdata - '0');
      }
    }
    Time t(numdata[0], numdata[1], numdata[2], numdata[3], numdata[4], numdata[5], numdata[6]);      /* 将转换好的numdata凑成时间格式,写入DS1302 */
    rtc.time(t);
    mark = 0; j = 0;
    comdata = String("");    /* 清空 comdata 变量,以便等待下一次输入 */
    for (int i = 0; i < 7 ; i++) numdata = 0;    /* 清空 numdata */
  }
  //有人后调用LED显示
  int redl = digitalRead(red);
  if (redl) {
    print_time();  /* 打印当前时间 */
  }
  delay(1000);
}
回复

使用道具 举报

 楼主| 发表于 2014-11-2 16:05:51 | 显示全部楼层

上传照片

本帖最后由 glmyc 于 2014-11-2 16:31 编辑

显示温度湿度


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-2 16:16:10 | 显示全部楼层
本帖最后由 glmyc 于 2014-11-2 16:42 编辑

显示结束后,8位串口数码管会在第6位(左侧第2位)显示一个数字2等,不知如何解决,请大侠指导!谢谢!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-18 04:28 , Processed in 0.034352 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表