项目介绍:
本项目的主要功能是通过红外线看见环境中温度的情况,快速获得环境中平均温度、最低温度和最高温度。用来发向环境中的过热点,排查隐患。
硬件介绍:
1、主控芯片:MAX32660
厂家:美信
用途:主控模块,用于驱动各个模块,读取温度数据以及展示结果数据。
介绍:MAX32660:属于美信DARWIN产品系列,是一款超低功耗、性价比突出、集成度非常高的32位控制器。芯片封装非常小,适合电池供电。MAX32660采用了带浮点运算功能的Cortex-M4内核,最大主频96MHz, 带256KB Flash和96KB SRAM,性能很强劲。
2、8x8的红外热传感器:AMG8833
厂家:松下
用途:用来读取环境温度。
介绍:测温点数:64(8x8的矩阵).帧率:10帧每秒或1帧每秒.红外测温分辨率:0.25℃.热敏电阻测量温度范围:-20℃~80℃.热敏电阻分辨率:0.0625℃.红外测温的准确度:High gain误差在2.5℃以内;Low gain误差在3℃以内。
介绍:主控SSD1307Z;能显示96*16个点0.65寸的OLED显示屏,做好了驱动板,引出IIC接口。
4、LDO芯片:ADP151AUJZ-3.3-R7 厂家:ADI 用途:将输入电压转换为3.3V。
AMG8833模块 | MAX32660定义 |
3V3 | VDDIO |
GND | GND |
SCL | P0_8 |
SDA | P0_9 |
OLED模块接线
OLED 模块 | MAX32660定义 |
GND | GND |
VCC | VDDIO |
SCL | P0_2 |
SDA | P0_3 |
1、Power Control寄存器:设置AMG8833的工作模式。工作模式有4中:0X00:正常模式;0X10:休眠模式;0X20:60秒待机模式;0X21:10秒待机模式。这里使用正常模式。
2、Reset寄存器:进行软复位。两种复位模式:Flag Reset会清除Status寄存器(0x04)、中断标志、中断表(0x10~0x17);Initial Reset会复位标志,并使AMG8833的参数恢复初始。这里使用后者(Initial Reset)。 3、Frame Rate寄存器:设定帧率。有两个选择:1:每秒1帧;0:每秒10帧。我用每秒1帧。
0X03和0X0D是中断寄存器,本项目没有使用中断部分,所以不做设置。
4、Thermistor寄存器:热敏电阻测量的温度值。这是个12位数据。最高位为符号位,值为0表示正,值为1表示负。步进值为0.0625℃。用来作为基准温度,这个温度是由AMG8833中的热敏电阻获得的,既为模块自身的温度值。在此项目中作为环境的基准温度。5、Temperature寄存器:从0X80到0XFF为红外点阵测量的温度值。每个暑假有12位数据。最高位为符号位,值为0表示正,值为1表示负。步进值为0.25℃。一共是64个数据,模块保障了数据是一次读出的,所以不用担心新的温度值和旧的温度值会混在一起。
MAX32660提供了丰富的例程,这里使用IIC的例程来作为基础工程进行修改。AMG8833模块在Arduino中有已经写好了的例子,找到对应的文件,直接参考Arduino的例子来改写AMG8833的读取部分。
//IIC连续写
//addr:器件地址
//reg:寄存器地址
//len:写入长度
//buf:数据区
void write(uint8_t reg,uint8_t *buf,uint8_t len){
uint8_t i,data[100],error;
data[0]=reg;
for(i=1;i<len+1;i++){
data[i]=buf[i-1];
}
error=I2C_MasterWrite(MXC_I2C0, (AMG88xx_ADDRESS<<1)|0, data, len+1, 0);
//printf("%X %X %d\n",data[0],data[1],error);
}
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
void read(uint8_t reg,uint8_t *buf,uint8_t len){
//uint8_t res;
I2C_MasterWrite(MXC_I2C0, (AMG88xx_ADDRESS<<1)|0, ®, 1, 0);
I2C_MasterRead(MXC_I2C0, (AMG88xx_ADDRESS<<1)|1, buf, len, 0);
//res=I2C_MasterRead(MXC_I2C0, (AMG88xx_ADDRESS<<1)|1, buf, len, 0);
//printf("read len=%d\n",res);
}
void write8(uint8_t reg,uint8_t data) {
write(reg, &data, 1);
}
uint8_t read8(uint8_t reg) {
uint8_t ret;
read(reg, &ret, 1);
return ret;
}
/**************************************************************************/
/*!
@brief convert a 12-bit signed magnitude value to a floating point number
@param val the 12-bit signed magnitude value to be converted
@returns the converted floating point value
*/
/**************************************************************************/
float signedMag12ToFloat(uint16_t val){
//take first 11 bits as absolute val
uint16_t absVal = (val & 0x7FF);
return (val & 0x8000) ? 0 - (float)absVal : (float)absVal ;
}
/**************************************************************************/
/*!
@brief disable the interrupt pin on the device
*/
/**************************************************************************/
void disableInterrupt(){
_intc.INTEN = 0;
write8(AMG88xx_INTC, getINTC());
}
/**************************************************************************/
/*!
@brief Setups the I2C interface and hardware
@param addr Optional I2C address the sensor can be found on. Default is 0x69
@returns True if device is set up, false on any failure
*/
/**************************************************************************/
int amg88xxInit(void){
//enter normal mode
_pctl.PCTL = AMG88xx_NORMAL_MODE;
write8(AMG88xx_PCTL, getPCTL());
//software reset
_rst.RST = AMG88xx_INITIAL_RESET;
write8(AMG88xx_RST, getRST());
//disable interrupts by default
disableInterrupt();
//set to 10 FPS
_fpsc.FPS = AMG88xx_FPS_10;
write8(AMG88xx_FPSC, getFPSC());
delay_ms(10);
return 0;
}
//读取8*8=64个点的温度值
void readPixels(float* pixbuf){
uint8_t bufraw[128],i,pos;
uint16_t recast;
read(AMG88xx_PIXEL_OFFSET, (uint8_t*)bufraw, 128);
//将128个点转换为具体的温度(摄氏度)
for(i=0;i<64;i++){
pos = i << 1;
recast = ((uint16_t)bufraw[pos + 1] << 8) | ((uint16_t)bufraw[pos]);
pixbuf[i] = signedMag12ToFloat(recast) * AMG88xx_PIXEL_TEMP_CONVERSION;
}
}
//读取参考值温度
/**************************************************************************/
/*!
@brief read the onboard thermistor
@returns a the floating point temperature in degrees Celsius
*/
/**************************************************************************/
float readThermistor(){
uint8_t raw[2];
read(AMG88xx_TTHL, raw, 2);
uint16_t recast = ((uint16_t)raw[1] << 8) | ((uint16_t)raw[0]);
return signedMag12ToFloat(recast) * AMG88xx_THERMISTOR_CONVERSION;
}
将64个点的温度读取后,计算最大值、最小值和平均值。通过OLED进行显示。左侧使用较大数字显示当前基准温度或平均温度,使用按键进行切换(屏幕上有A或B 的标记进行区分,显示基准温度是开发板的LED灯会对应亮起。显示到小数点后一位。)。右侧用小字体,在上边显示最大温度值。下边显示最小温度值。每秒刷新一次。有了最大、最小温度,就可以很直观地知道面前空间的温度分布情况了,如果有异常,必然会在最大或最小温度上体现出来。
心得体会:
感谢电子森林举办的fastbond活动。参加这次活动体验了一次项目从构思、设计到完成全过程的经历,很艰辛,也很有趣。完成项目过程中总结了几点经验:
1、能用面包板就避免用杜邦线。手头的杜邦线给自己带来了太多麻烦,接错线、松动……浪费了太多时间。如果可以,打板验证应该是好的选择。
2、多阅读器件文档,从文档中了解清楚器件的寄存器的用法,再去参考一些程序,就很容易上手模块了。