アマチュア無線や電子工作,バイクの話などを徒然なるままに書き散らすメモ程度のblogです.


by jq1ocr

【ATtiny13A】温度計完成

ATtiny13A + I2C LCD + LM60 ですが,こんな感じで一応できました.
d0106518_1334382.jpg
まず,float で計算することが無理だったので,int で小数演算しないようにしました.具体的には
int data;

data/=64; //16bit → 10bit
data-=395; //0℃ 424mV の A/D 値 395 offset
data=data*50/29; //摂氏 x10 ℃への変換
という感じです.最初は気温を float にして小数で普通に計算しようとしましたが,そうするとエラーになるので,求める気温は小数点以下1位までにして,その 10 倍の値になるようにして計算し,最後に表示部で小数点を入れるようにしました.また 50/29 という数字も,何も考えずに計算すれば一時的に大きな数字になるところを途中の計算も結果が 16 ビットに収まるような近似値にしてあります.ちなみにここは *1.724 にはできません.(float を使うのと同じエラーになる)

こんな感じで書き込めるようになって問題なさそうでしたが,起動した直後の気温から変わらない,すなわち A/D 値が変化しないという現象が起きました.てっきり,ADCSRA の扱いが間違っているのかと思って,いろいろいじったのですが,結局の所別のポカミスで,ADCH から読んでいたのです.すなわち
uint16_t adv;

adv=(ADCH<<8)|ADCL;
になっていたわけです.これを
adv=ADCL|(ADCH<<8);
に直すと ADCL から読むようになったようで,動くようになりました.そういえばマニュアルに書いてあったかも.苦笑

しかし動かしてみるとずいぶん値に変動があります.1℃くらいあるでしょうか.A/D は 10 bit とれても,±2LSB の誤差があるということですから,気温にすると今回の場合はざっと ±0.7℃ 誤差があることになりそうです.そうするとまあこのくらいも仕方ないかも知れませんね.また LM60 本体も誤差は ±2℃なので,そもそも厳密にしても仕方ないという感じでしょうか.ただ,だからといって A/D を 8 bit にすると小数点以下の表示が寂しくなります.まあ 10bit のままサンプル間で平均処理とかを考える方が実用的かもしれませんね.

ところで似たようなセンサには今回使った LM60 以外にも LM35, LM61 などいろいろあります.
d0106518_219397.jpg
LM60 は 2.7V から使えること,tiny13A の内部基準1.1V で A/D するとフルスケールが 100 ℃以上なので(そこまで達しないので)気温測定には簡単に使えることなどが特徴だと思います.LM35 は温度係数が 10mV/℃と大きいため,A/D したときの誤差が小さくなりますが,氷点下は計れませんし,電源電圧も4V以上ですので,電池が3本になります.LM61 だと測定範囲は -25 ~ 85℃ と使いやすく,また温度係数も 10mV/℃ で 2.7V から動かせます.電池2本の tiny13A ならこの組み合わせがいいかも知れません.ただし,A/D の基準を内部の 1.1 V にすると,50 ℃以上が計れなくなります.が,まあ気温なら問題ないでしょう.

しかし,I2C の LCD って出来合の温度計が余裕で買えるくらいの値段ですから,そもそも作っても意味ないじゃん?というのは言わない約束ね.
[PR]
Commented by mako shark at 2014-05-23 00:16 x
AVRのADCですが、
adv=ADC;
で10bit読み込めませんか?当方開発はAtmelStudio6.1でこの方法でADCからの値を読み込んでいます。
コンパイラの出力は、下位8ビット、上位8ビットの読み込みをしているだけではありますが。
Commented by jq1ocr at 2014-05-23 01:12
コメントありがとうございます.うちは Mac の crosspack でやっていますので,AtmelStudio は使っていませんが,document を見る限り ADC というレジスタは規定されていないので,うちの環境だと読めないと思います.が,思ってるだけで,実はこっそりどこかで定義されているかも知れないので,今度試してみます!
by jq1ocr | 2014-01-25 01:00 | マイコン・電子工作 | Comments(2)