搜索

作者简历和生物 情侣我的爱好有关的文章 - 机器人
我关于移民澳洲的印象。在俄罗斯只。 为解决日常问题的食谱
Linux相关的职位 Windows相关的职位
与软件相关的职位 很多有关硬件信息
不同的工具,你可能会发现有用 关于各种Web技术的文章
一切不符合其余的菜单 RSS订阅本博客

标签云

档案

链接

安德烈Mikhalchuk的博客

English flagItalian flagKorean flagChinese (Simplified) flagPortuguese flagGerman flagFrench flagSpanish flagJapanese flagRussian flagDanish flagFinnish flagHebrew flag

Technoblog对生活

2011年06月20日,阅读ATtiny85/45/25内部温度传感器

ATtiny85 has internal temperature sensor

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 Internal Temperature Sensor Readouts

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之一,也不能保证它会为别人打工。
整体内部传感器是可用的,但不要指望它。 外部传感器仍然要好得多。

这篇文章发表在硬件机器人

没有评论

到目前为止没有评论

发表评论

网站地图 (三)安德烈·Mikhalchuk,2005-2008