学习笔记:温度计《DS18B20与SPI串行LCD12864》
本帖最后由 waxman 于 2014-2-19 15:34 编辑了解到arduino,是来自于树莓派的了解过程。惭愧,作为IT人士多年,居然这么迟才知道这两个好东西。呵呵。速度从DFRobot采购了一批设备,开工。
好吧,废话不说,直入主题。基于最学习目的,选了最简单的温度计来练手。
硬件:
主控 arduino duo r3,多功能接口扩展板 Interface shield V1.1 IICSPI,温度传感器 DS18B20,LCD显示器 SPI串行并行LCD12864。
软件:
C语言荒废多年了,重新捡起来,参考论坛各位前辈的代码,教程和软件,颇有收益,多谢多谢。
代码简单说明一下:
1、首先显示“欢迎”,其次显示“温度xx”。(基于该温度传感器的参数,只对百位以内数字显示进行处理)
2、读取温度传感器数据,直接使用了传感器范例代码。
3、显示温度数值的代码,主要精力花在这里了。主要实现的处理:零下温度显示“-”,0-10度在百位和十位显示空白,10-100度在百位显示空白,小数点四舍五入到1位。
一点心得:
LCDA.DisplayString 用汉字内码显示字符。
LCDA.DisplaySig用ASCII码显示字符。
备注:当hds=-16,显示的时候运算后hds=32,即空格。
当然,还可以更完美一些,目前代码里零下温度的负号显示在固定位置,可以更完美一些,依据十位,个位数字,显示在不同位置。呵呵
/***********************************************
1. SPI Interface Inatruction
clockPin --> SCK(EN)
latchPin --> CS(RS)
dataPin --> SID(RW)
2. Connection:
1)Turn the BL_ON Switch to the "ON" side;
2)Turn the PBS_ON Switch to the "SPI" side
Method1:
LCD Arduino
EN Digital Pin 2
RS Digital Pin 7
RW Digital Pin 10
VCC 5V
GND GND;
Method2:
LCD Arduino
SCK clockPin(defined in the "initDriverPin" function)
CS latchPin(defined in the "initDriverPin" function)
SID dataPin (defined in the "initDriverPin" function)
VCC 5V
GND GND
***********************************************/
#include <OneWire.h>
#include "LCD12864RSPI.h"
#define AR_SIZE( a ) sizeof( a ) / sizeof( a )
unsigned char show1[]={
0xBB,0xB6,0xD3,0xAD
};
unsigned char show2[]={
0xCE,0xC2,0xB6,0xC8,0xA3,0xBA
};
unsigned char show3[]={
0xA1, 0xE6
}; //℃
unsigned char show4[]={
0x2E, 0x00
}; //.
unsigned char show5[]={
0xA3, 0xAD
}; //-
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
//Temperature chip i/o
OneWire ds(DS18S20_Pin);// on digital pin 2
void setup()
{
//Serial.begin(9600);
LCDA.initDriverPin(3,8,9);
LCDA.Initialise(); // INIT SCREEN
delay(100);
LCDA.DisplayString(0,0,show1,4);
delay(3000);
LCDA.DisplayString(0,0,show2,6);
LCDA.DisplayString(1,5,show4,2);
LCDA.DisplayString(1,7,show3,2);
}
void loop()
{
float temp1 = getTemp();
//Serial.println(temperature);
//temp1 = -188.4;
if (temp1<0.0) {
LCDA.DisplayString(1,1,show5,2);
temp1 = -temp1;
}
temp1 = (float)((int)(temp1 * 100+5)) / 100;
int hd = (int)(temp1/100.0);
int td = (int)((temp1-hd*100)/10.0);
int hds,tds;
if (hd==0) {
hds=-16;
if (td==0){
tds=-16;
}
else {
tds=td;
}
}
else {
hds=hd;
tds=td;
}
int sd = (int)((temp1-hd*100-td*10));
int dt = (int)((temp1-hd*100-td*10-sd)*10);
LCDA.DisplaySig(1,2,hds+48);
LCDA.DisplaySig(1,3,tds+48);
LCDA.DisplaySig(1,4,sd+48);
LCDA.DisplaySig(1,6,dt+48);
delay(60000);
}
float getTemp(){
//returns the temperature from one DS18S20 in DEG Celsius
byte data;
byte addr;
if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}
if ( OneWire::crc8( addr, 7) != addr) {
Serial.println("CRC is not valid!");
return -1000;
}
if ( addr != 0x10 && addr != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (int i = 0; i < 9; i++) { // we need 9 bytes
data = ds.read();
}
ds.reset_search();
byte MSB = data;
byte LSB = data;
float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
记学习笔记真心是个好习惯,楼主下一步打算做什么啊?记得要分享到论坛啊:lol 楼主的学习笔记为人类的Arduino事业做出了贡献啊 Phoebe 发表于 2014-2-20 10:05
记学习笔记真心是个好习惯,楼主下一步打算做什么啊?记得要分享到论坛啊 ...
目前计划的研究方向:汽车盲区检测告警,并线检测告警,追尾预警。另外有打算四驱小车或者飞行控制器。 waxman 发表于 2014-2-20 11:07
目前计划的研究方向:汽车盲区检测告警,并线检测告警,追尾预警。另外有打算四驱小车或者飞行控制器。 ...
期待。。。。 waxman 发表于 2014-2-20 11:07
目前计划的研究方向:汽车盲区检测告警,并线检测告警,追尾预警。另外有打算四驱小车或者飞行控制器。 ...
这个感觉需要用摄像头才能完成啊。另外也许用激光雷达也能部分实现一些功能。希望能说说你的实现思路,很有意思的项目。 很好,期待下一部作品。。
页:
[1]