 ATtiny85具有内部温度传感器 我的工作对我的项目之一,从RTFMs录像博客(出http://rtfms.com ),需要在一个非常小的包装温度传感。 当然,我的选择是ATtiny85 - 真棒AVR小芯片,除了其他商品(如6通道PWM,串行接口等)具有内部温度传感器。 所以我决定使用一个。 这是不容易的,但挖论坛和数据表的几个小时后,我想出了一个类,它具有相当可观的可靠性和精确度的工作。
首先要运行此代码,你需要一个Arduino小( http://code.google.com/p/arduino-tiny/ )的核心和一些ISP。 我使用的ISP:阿尔杜伊诺Duemilanove。 看到我的RTFMs博客如何使它工作,这样,如何加载正确的核心等AFAIK所有流行的内核会与此代码罚款的更多细节。 我只请Arduino的,微小的,因为其丰富的功能,可以用来发动更多的ATtiny85电源。 该解决方案由两个文件,您可以复制到您的项目。 只是copypaste他们从这个网页: InternalTemperatureSensor.h #IFNDEF _INTERNAL_TEMPERATURE_SENSOR_H_ #定义_INTERNAL_TEMPERATURE_SENSOR_H_ #定义TEMPERATURE_SAMPLES 30 #定义TEMPERATURE_ADJUSTMENT -13 #定义EXTREMES_RATIO 5。 #定义MAXINT 32767 #定义MININT -32767。 / * *基于样本: * - 内部温度传感器,具有可怕的偏差。 它的输出变化很多(+ / -10度/秒),所以需要 *一些“平滑”。 我删除极端值上运行,其余的滚动平均。 这将返回OK 对20个样品和更多的结果。 可以减少样本数量,以减少响应时间,但是这 *将减少精度。 * - 线性是确定的,约1.0数据承诺 * - 需要计算每个芯片分开和在c'tor提供偏移 * *为了抵消钩的最高终端calaculate,引脚2(串行TX)9600 8N1和使用 * temperature.print()方法调用。 这将打印出温度读数。 对阵您 *校准温度计连接到芯片。 调整c'tor如果有必要的服务条款。 *多一点细节,请参阅ATtiny85表17.12章 * / 类InternalTemperatureSensor { int的抵销; 浮动系数; 读数[TEMPERATURE_SAMPLES]; INT POS; 市民: InternalTemperatureSensor(浮法K,INT O):偏移(O),系数(K),POS(0){} / /调用每次你需要准备读取传感器芯片(即在安装) / /如果你使用其它ADC除了温度之前调用每个温度读数 无效的init(); / /返回LSB目前的平均温度, 诠释in_lsb(); / /返回当前平均温度在摄氏 诠释in_c(); / /返回目前的平均温度在华氏 诠释in_f(); / /返回当前平均温度在开尔文 诠释in_k(); / /返回当前的原料温度传感器读数 原始INT(); / /在各种格式打印当前的温度读数 无效打印(); }; #ENDIF / / _INTERNAL_TEMPERATURE_SENSOR_H_ InternalTemperatureSensor.pde 包括“InternalTemperatureSensor.h” 有无效InternalTemperatureSensor :: init()方法{ / / analogReference的(INTERNAL1V1); / / P140 ATTiny85表(17.13.2),P137(17.12) / /配置ADMUX寄存器 ADMUX寄存器= B1111; / /选择温度传感器 ADMUX寄存器&=〜_BV(ADLAR)/ /右调整的结果 ADMUX寄存器| = _BV(REFS1); / /设置REF电压 ADMUX寄存器&=〜(_BV(REFS0)| _BV(REFS2)的); / / 1.1V / /配置ADCSRA寄存器 ADCSRA寄存器&=〜(_BV(ADATE)| _BV(ADIE位置)); / /禁用autotrigger的,禁用中断 ADCSRA寄存器| = _BV(亚丁); / /使能ADC ADCSRA寄存器| = _BV(ADSC的); / /启动第一次转换 / /种子样品 INT raw_temp; 而(((raw_temp =原材料())<0)); (I = 0;我<TEMPERATURE_SAMPLES; I + +){ 读数[I] = raw_temp; } } 的诠释InternalTemperatureSensor :: in_lsb(){ readings_dup [TEMPERATURE_SAMPLES]; INT raw_temp; / /记得样本 如果((raw_temp =原材料())> 0){ 读数[POS] = raw_temp; POS + +; POS%= TEMPERATURE_SAMPLES; } / /复制的样本 (I = 0;我<TEMPERATURE_SAMPLES; I + +){ readings_dup [I] =读数[I]; } / /泡沫极端阵列的两端 extremes_count = TEMPERATURE_SAMPLES / EXTREMES_RATIO; INT交换; (I = 0;我<extremes_count; + +){/ /冒泡排序的迭代%上小N工作速度比Q排序 (研究= 0; J <TEMPERATURE_SAMPLES - 1; J +){ (readings_dup [I]> readings_dup [I +1]){/ /可以与3异或没有交换,如果你喜欢花哨 交换= readings_dup [I]; readings_dup [我] = readings_dup [I +1]; readings_dup [I +1] =交换; } } } / /数组中平均 sum_temp = 0; (I = extremes_count;我<TEMPERATURE_SAMPLES - extremes_count; I + +){ sum_temp = readings_dup [I]; } 返回sum_temp /(TEMPERATURE_SAMPLES - extremes_count * 2); } INT InternalTemperatureSensor :: in_c(){ 返回in_k() - 273; } 的诠释InternalTemperatureSensor :: in_f(){ 返回in_c()* 9/5 + 32; } 的诠释InternalTemperatureSensor :: in_k(){ 返回in_lsb()+偏移; / / simplicty我用K = 1,使用下一行,如果你想ķ= 1.0 / /返回(INT)(in_lsb()*系数)+偏移; } INT InternalTemperatureSensor ::原料(){ (ADCSRA寄存器_BV(ADSC的)){ 返回-1; }否则{ RET = ADCL中(ADCH的<< 8); / /获取先前的转换结果 ADCSRA寄存器| = _BV(ADSC的); / /启动新的转换 返回RET; } } 的无效InternalTemperatureSensor ::打印(){ serial.print(“”R:“); serial.print(RAW(),12月); serial.print(“M:”); serial.print(in_lsb(),DEC)的; serial.print(“杀敌:”); serial.print(in_k(),DEC)的; serial.print(的“C:”); serial.print(in_c(),DEC)的; serial.print(“女:”); serial.print(in_f(),DEC)的; serial.println(“#”); } 用法 InternalTemperatureSensor温度(1.0 TEMPERATURE_ADJUSTMENT); / / 1.0参数默认情况下,忽略,看到c'tor评论 无效的设置(){ temperature.init(); / /调用init(在设置或每次)修改后ADCSRA寄存器或ADMUX寄存器 } 无效循环(){ / / temperature.print的(); / /去掉这个调试通过串行连接传感器的输出 INT war_sensor_data temperature.raw()/ /返回勉强可用的传感器输出 INT temperature_in_celsius temperature.in_c(); / /此回报更多的可用度的温度摄氏 } 解释 ATtinyX5使用ADC4从内部传感器中读取数据。 在init()方法与寄存器的所有必要的魔法做准备读取这个数据的系统。 你需要调用此方法每次要ADMUX寄存器的配置温度传感器的数据检索和ADCSRA寄存器。 如果你在程序中使用的唯一的ADC通道是温度传感器的ADC4,那么你应该只把它在设置(),即一次。 这将减少至少因素两温度读数手术时间。 方法InternalTemperatureSensor ::原料()返回来自传感器的原始数据。 不幸的是,这个数据是勉强可用。 为了说明问题,采取在看看从InternalTemperatureSensor输出::打印()调试方法。 第一列是什么,传感器的回报。 输出速度是每秒约5线,在2秒钟之内的传感器返回值与18度的差异。
 ATtiny85内部温度传感器读数 为了使这个数据更可用的方法InternalTemperatureSensor :: in_lsb不滚动平均,从输入中删除的极端。 结果,你可以看到上面的图片:in_lsb输出标示为L:是的方式更实用。 这是更准确了。 您可以调整滚动平均的参数,但总体来说,我不建议TEMPERATURE_SAMPLES小于20和大于50。 如果它小于20,则偏差显着增大。 使TEMPERATURE_SAMPLES超过50不会提高精度,但浪费内存和减慢计算。 也EXTREMES_RATIO定义极端值的多少将被砍伤,不使其比2(这将消除所有的值)。 使它更比TEMPERATURE_SAMPLES将有效防止从样品中去除极端。 除了这3个核心方法提供了几个实用的方法in_c(),in_k()中,in_f()。 他们返回度摄氏,华氏和开尔文温度。 一个多传感器内部的问题是,它没有校准,使每个芯片中,你需要使用print()方法输出的阅读和调整的第二个参数的构造方法,以配合您的校准温度计的值。 在源代码的价值-13只有为我ATtinies之一,也不能保证它会为别人打工。 整体内部传感器是可用的,但不要指望它。 外部传感器仍然要好得多。 这篇文章发表在硬件 , 机器人 。 |