极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 5414|回复: 17

OCROBOT 8F328P 制作的温度测量、记录仪(用最新SPI)

[复制链接]
发表于 2017-5-22 10:17:35 | 显示全部楼层 |阅读模式
本帖最后由 D19TCI 于 2017-9-14 11:12 编辑

昨天弘老大更新了LGT的最新SPI库,解决了SD的问题,现用12位的ADC、K分度的热电偶变送器测量温度、DS1302时钟模块、2004液晶显示屏、SD卡模块做了一个温度的测量及记录仪。
实际效果图:
AAA3.jpg

存储的文件file20.txt
AAA4.PNG

存储文件的内容
AAA5.PNG 有弘老大的软硬件支持,让单片机应用简单化,我们只用集中精力解决应用问题,编程稍加学习就能用。再次感谢弘老大。


把程序贴上,比较乱,供参考

  1. /*
  2.   用K分度热电偶作为传感器;
  3.   用4~20ma的变送器处理信号;
  4.   通过143欧电阻转换成电压信号后送入MCU的A0端口;
  5.   用2004液晶显示屏显示所测量的温度值。
  6. */

  7. /* 2004液晶显示屏管脚定义
  8.   GND -> OCROBOT_LGT8F328P GND
  9.   VCC -> OCROBOT_LGT8F328P 5V
  10.   SDA -> OCROBOT_LGT8F328P A4
  11.   SCL -> OCROBOT_LGT8F328P A5
  12. */

  13. /* DS1302管脚定义
  14.   GND -> OCROBOT_LGT8F328P GND
  15.   VCC -> OCROBOT_LGT8F328P 5V
  16.   RST(DS1302 pin5) -> Arduino D5
  17.   DAT(DS1302 pin6) -> Arduino D6
  18.   CLK(DS1302 pin7) -> Arduino D7
  19. */

  20. /* SD卡管脚定义
  21.   GND     -> OCROBOT_LGT8F328P GND
  22.   VCC 5v  -> OCROBOT_LGT8F328P 5V
  23.   CS      -> OCROBOT_LGT8F328P D4
  24.   MOSI    -> OCROBOT_LGT8F328P MOSI(D11)
  25.   SCK     -> OCROBOT_LGT8F328P  SCK (D13)
  26.   MISO    ->   OCROBOT_LGT8F328P MISO(D12)
  27. */

  28. #include <EEPROM.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <DS1302.h>
  32. #include <SPI.h>  //SD
  33. #include <SD.h>   //SD
  34. #include <LiquidCrystal_I2C.h>
  35. #include <Wire.h>
  36. LiquidCrystal_I2C lcd(0x3F, 20, 4); // set the LCD address to 0x3F for a 20 chars and 4
  37. int potpin = 0 ; //定义温度信号输入的模拟接口
  38. int a;

  39. char buf[20];  //日期变量缓存
  40. char day[20];
  41. char tim[10];
  42. char AA[20];
  43. char CC[8] = "file";
  44. char BB[5] = ".txt";

  45. uint8_t CE_PIN   = 5;  ///* DS1302接口定义
  46. uint8_t IO_PIN   = 6;
  47. uint8_t SCLK_PIN = 7;
  48. /* 创建 DS1302 对象 */
  49. DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);

  50. File myFile;  //SD存储的文件名
  51. float T1 ;
  52. int n ;
  53. int n1 ;
  54. int temperature ;//定义温度值变量
  55. float voltage ;


  56. void setup()
  57. {
  58.   analogReference (INTERNAL2V048); //定义ADC的基准参考电压为内部2.048V;
  59.   // EEPROM.write(1,0);   //文件名序号复位到file1.txt
  60.   a = EEPROM.read(1);    //读取上一次文件名序号
  61.   a = a + 1;
  62.   EEPROM.write(1, a);    //当前文件名序号写入EEPROM
  63.   snprintf(AA, sizeof(AA), "%s%0d%s", CC, a, BB );  //生成文件名字符串
  64.   rtc.write_protect(false);
  65.   rtc.halt(false);
  66.   lcd.init();                      // initialize the lcd
  67.   lcd.backlight();
  68.   if (!SD.begin(4))
  69.   {
  70.     lcd.setCursor(0, 2);
  71.     lcd.print("SD card failed!");
  72.     lcd.setCursor(0, 3);
  73.     lcd.print("file not save:");
  74.     delay(2000);
  75.     return;
  76.   }
  77.   lcd.setCursor(0, 2);
  78.   lcd.print("SD card OK!");
  79.   lcd.setCursor(0, 3);
  80.   lcd.print("file save:");
  81.   lcd.print(AA);
  82. }

  83. void loop()
  84. {
  85.   //   lcd.setCursor(0, 0);
  86.   //  lcd.print(AA);
  87.   myFile = SD.open(AA, FILE_WRITE);  //SD
  88.   for (n1 = 1 ; n1 < 50 ; n1++)
  89.   {
  90.     T1 = 0;
  91.     print_time();
  92.     for (n = 1 ; n < 21 ; n++)
  93.     {
  94.       voltage = analogRead(potpin);  //读取模拟接口0 的值,并将其赋给T1
  95.       delay(50);
  96.       T1 = T1 + voltage;
  97.     }
  98.     T1 = T1 / 20 ;
  99.     voltage = 0.5 * T1 ;  //2.048内部参考时的换算公式加修正
  100.     temperature = map(voltage, 595.0, 2900.0, -50, 650) ; //4~20ma的电流信号通过143欧姆电阻取样后,送入A7计算后得出当前温度值。
  101.     lcd.setCursor(0, 1);
  102.     lcd.print("Temperature:       "); //起到清屏的作用,无明显闪烁现象。
  103.     lcd.setCursor(0, 1);
  104.     lcd.print("Temperature: ");
  105.     lcd.print(temperature);
  106.     lcd.print(" C");
  107.     lcd.setCursor(0, 0);
  108.     lcd.print(buf);
  109.     myFile.print(buf), myFile.print("  Temperature=  "), myFile.print(temperature) , myFile.println("  C");
  110.   }
  111.   myFile.close();
  112.   //lcd.clear();       //清屏,用此功能LED屏有闪烁现象
  113. }
  114. void print_time()
  115. {
  116.   /* 从 DS1302 获取当前时间 */
  117.   Time t = rtc.time();
  118.   /* 将星期从数字转换为名称 */
  119.   memset(day, 0, sizeof(day));
  120.   switch (t.day)
  121.   {
  122.     case 1: strcpy(day, "Sunday"); break;
  123.     case 2: strcpy(day, "Monday"); break;
  124.     case 3: strcpy(day, "Tuesday"); break;
  125.     case 4: strcpy(day, "Wednesday"); break;
  126.     case 5: strcpy(day, "Thursday"); break;
  127.     case 6: strcpy(day, "Friday"); break;
  128.     case 7: strcpy(day, "Saturday"); break;

  129.   }
  130.   /* 将日期代码格式化凑成buf等待输出 */
  131.   snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d ", t.yr, t.mon, t.date, t.hr, t.min, t.sec );
  132.   snprintf(CC, sizeof(CC), "%02d%02d", t.mon, t.date );
  133. }
复制代码
回复

使用道具 举报

 楼主| 发表于 2017-5-22 10:24:24 | 显示全部楼层
上面是一个测试用的试验品,下一步在利用剩余的A6、A0、A1、A2、A3再增加几个温度测量,同时把压力的测量也做进去,找个盒子装了,放在车上坐行车数据记录仪。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 10:32:04 | 显示全部楼层
在使用LGT0.0.10最新库时,以前安装过arduino-IDE在用最新的SPI时可能会出错,解决方案见弘老大的
http://www.geek-workshop.com/thread-28834-1-1.html 帖子
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 10:38:16 | 显示全部楼层
本例还用了EEPROM,每上电一次文件自动生成一个新文件,file1.txt、file2.txt、file3.txt .........
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 15:14:08 | 显示全部楼层

用了一片2004的屏,1602屏的代码就能用,只是多了两行。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 15:47:00 | 显示全部楼层
找到一个大气压力传感器,把大气压加入

IMG_1542.JPG
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 15:47:46 | 显示全部楼层
昆明今天中午的温度及气压
回复 支持 反对

使用道具 举报

发表于 2017-6-1 20:40:58 | 显示全部楼层

不错不错!

工作时候8F328自身发热如何?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-1 23:43:34 | 显示全部楼层
Damn_intuition 发表于 2017-6-1 20:40
不错不错!

工作时候8F328自身发热如何?

基本上不发热,LGT8F328P的12位ADC在普通的工程应用上基本能满足要求,在此基础上我已完善。我是搞发动机开发的,有时要记录发动机在整车上的运行数据。比如说,不同用户的驾驶习惯、城市道路的排温特性等。以往要用专用的车载数据记录仪设备(小日本生产的),价格太高,不能大量采用。现在我用328P加上一些通用模块,做了一个简易的车载数据记录仪,可以记录2个温度(0~800度),一个车速、一个发动机转速、油门踏板信号。采样频率设为2Hz,用一块2004屏实时显示,用SD卡存储数据。工作很稳定,装在车上,车辆上电行驶后就开始自动记录,通常可以一周提取一次数据进行分析。
回复 支持 反对

使用道具 举报

发表于 2017-6-2 10:48:16 | 显示全部楼层
D19TCI 发表于 2017-6-1 23:43
基本上不发热,LGT8F328P的12位ADC在普通的工程应用上基本能满足要求,在此基础上我已完善。我是搞发动机 ...

听起来很赞,做好以后发群里看看。
回复 支持 反对

使用道具 举报

发表于 2017-6-2 10:49:25 | 显示全部楼层
工业用和diy差距很大,你的这个应该遇到过很多问题吧,期望看到这些抗干扰和增稳的内容。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-2 17:43:40 | 显示全部楼层
本帖最后由 D19TCI 于 2017-6-3 10:02 编辑
Damn_intuition 发表于 2017-6-2 10:49
工业用和diy差距很大,你的这个应该遇到过很多问题吧,期望看到这些抗干扰和增稳的内容。


是的,工业用对精度、抗干扰(电磁兼容性、温度、振动等)、稳定性有相当的要求。以前用MEGA328时仅仅用来学习一下,因为10位ADC基本上精度不够,LGT的328的ADC是12位的,基本能用,所以尝试着做一些东西。
我是做产品开发的,理解作为一个产品特别是工业产品的要求,因此在不断的完善。第一步实现功能,第二步解决抗干扰、稳定性、可靠性、成本等问题,当然有软件层面也有硬件层面,比如说在测发动机转速,其实就是测频率,参考了大家的一些成果,基本上能实现,下一步就是解决上述问题,硬件方面用一片74HC14进行整形,限幅电路也是必须的(万一输了信号电压过高,可能就把芯片烧了)软件方面必要的自诊断及监控代码是必须,同时针对特性的传感器信号必要的修正也是必须的。现在在不断的测试完善。
回复 支持 反对

使用道具 举报

发表于 2017-8-28 19:31:54 | 显示全部楼层
很惭愧啊,我这搞仪表的也都没搞出楼主的东西,能吧SD程序发出来吗,学习一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-14 11:14:05 | 显示全部楼层
太行摄狼 发表于 2017-8-28 19:31
很惭愧啊,我这搞仪表的也都没搞出楼主的东西,能吧SD程序发出来吗,学习一下

程序未整理,比较乱,供参考,见谅好久未上论坛了

  1. /*
  2.   用K分度热电偶作为传感器;
  3.   用4~20ma的变送器处理信号;
  4.   通过143欧电阻转换成电压信号后送入MCU的A0端口;
  5.   用2004液晶显示屏显示所测量的温度值。
  6. */

  7. /* 2004液晶显示屏管脚定义
  8.   GND -> OCROBOT_LGT8F328P GND
  9.   VCC -> OCROBOT_LGT8F328P 5V
  10.   SDA -> OCROBOT_LGT8F328P A4
  11.   SCL -> OCROBOT_LGT8F328P A5
  12. */

  13. /* DS1302管脚定义
  14.   GND -> OCROBOT_LGT8F328P GND
  15.   VCC -> OCROBOT_LGT8F328P 5V
  16.   RST(DS1302 pin5) -> Arduino D5
  17.   DAT(DS1302 pin6) -> Arduino D6
  18.   CLK(DS1302 pin7) -> Arduino D7
  19. */

  20. /* SD卡管脚定义
  21.   GND     -> OCROBOT_LGT8F328P GND
  22.   VCC 5v  -> OCROBOT_LGT8F328P 5V
  23.   CS      -> OCROBOT_LGT8F328P D4
  24.   MOSI    -> OCROBOT_LGT8F328P MOSI(D11)
  25.   SCK     -> OCROBOT_LGT8F328P  SCK (D13)
  26.   MISO    ->   OCROBOT_LGT8F328P MISO(D12)
  27. */

  28. #include <EEPROM.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <DS1302.h>
  32. #include <SPI.h>  //SD
  33. #include <SD.h>   //SD
  34. #include <LiquidCrystal_I2C.h>
  35. #include <Wire.h>
  36. LiquidCrystal_I2C lcd(0x3F, 20, 4); // set the LCD address to 0x3F for a 20 chars and 4
  37. int potpin = 0 ; //定义温度信号输入的模拟接口
  38. int a;

  39. char buf[20];  //日期变量缓存
  40. char day[20];
  41. char tim[10];
  42. char AA[20];
  43. char CC[8] = "file";
  44. char BB[5] = ".txt";

  45. uint8_t CE_PIN   = 5;  ///* DS1302接口定义
  46. uint8_t IO_PIN   = 6;
  47. uint8_t SCLK_PIN = 7;
  48. /* 创建 DS1302 对象 */
  49. DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);

  50. File myFile;  //SD存储的文件名
  51. float T1 ;
  52. int n ;
  53. int n1 ;
  54. int temperature ;//定义温度值变量
  55. float voltage ;


  56. void setup()
  57. {
  58.   analogReference (INTERNAL2V048); //定义ADC的基准参考电压为内部2.048V;
  59.   // EEPROM.write(1,0);   //文件名序号复位到file1.txt
  60.   a = EEPROM.read(1);    //读取上一次文件名序号
  61.   a = a + 1;
  62.   EEPROM.write(1, a);    //当前文件名序号写入EEPROM
  63.   snprintf(AA, sizeof(AA), "%s%0d%s", CC, a, BB );  //生成文件名字符串
  64.   rtc.write_protect(false);
  65.   rtc.halt(false);
  66.   lcd.init();                      // initialize the lcd
  67.   lcd.backlight();
  68.   if (!SD.begin(4))
  69.   {
  70.     lcd.setCursor(0, 2);
  71.     lcd.print("SD card failed!");
  72.     lcd.setCursor(0, 3);
  73.     lcd.print("file not save:");
  74.     delay(2000);
  75.     return;
  76.   }
  77.   lcd.setCursor(0, 2);
  78.   lcd.print("SD card OK!");
  79.   lcd.setCursor(0, 3);
  80.   lcd.print("file save:");
  81.   lcd.print(AA);
  82. }

  83. void loop()
  84. {
  85.   //   lcd.setCursor(0, 0);
  86.   //  lcd.print(AA);
  87.   myFile = SD.open(AA, FILE_WRITE);  //SD
  88.   for (n1 = 1 ; n1 < 50 ; n1++)
  89.   {
  90.     T1 = 0;
  91.     print_time();
  92.     for (n = 1 ; n < 21 ; n++)
  93.     {
  94.       voltage = analogRead(potpin);  //读取模拟接口0 的值,并将其赋给T1
  95.       delay(50);
  96.       T1 = T1 + voltage;
  97.     }
  98.     T1 = T1 / 20 ;
  99.     voltage = 0.5 * T1 ;  //2.048内部参考时的换算公式加修正
  100.     temperature = map(voltage, 595.0, 2900.0, -50, 650) ; //4~20ma的电流信号通过143欧姆电阻取样后,送入A7计算后得出当前温度值。
  101.     lcd.setCursor(0, 1);
  102.     lcd.print("Temperature:       "); //起到清屏的作用,无明显闪烁现象。
  103.     lcd.setCursor(0, 1);
  104.     lcd.print("Temperature: ");
  105.     lcd.print(temperature);
  106.     lcd.print(" C");
  107.     lcd.setCursor(0, 0);
  108.     lcd.print(buf);
  109.     myFile.print(buf), myFile.print("  Temperature=  "), myFile.print(temperature) , myFile.println("  C");
  110.   }
  111.   myFile.close();
  112.   //lcd.clear();       //清屏,用此功能LED屏有闪烁现象
  113. }
  114. void print_time()
  115. {
  116.   /* 从 DS1302 获取当前时间 */
  117.   Time t = rtc.time();
  118.   /* 将星期从数字转换为名称 */
  119.   memset(day, 0, sizeof(day));
  120.   switch (t.day)
  121.   {
  122.     case 1: strcpy(day, "Sunday"); break;
  123.     case 2: strcpy(day, "Monday"); break;
  124.     case 3: strcpy(day, "Tuesday"); break;
  125.     case 4: strcpy(day, "Wednesday"); break;
  126.     case 5: strcpy(day, "Thursday"); break;
  127.     case 6: strcpy(day, "Friday"); break;
  128.     case 7: strcpy(day, "Saturday"); break;

  129.   }
  130.   /* 将日期代码格式化凑成buf等待输出 */
  131.   snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d ", t.yr, t.mon, t.date, t.hr, t.min, t.sec );
  132.   snprintf(CC, sizeof(CC), "%02d%02d", t.mon, t.date );
  133. }
复制代码
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2019-7-16 23:07 , Processed in 0.065539 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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