Arduinoでラリコン作る話(3)~ 激闘編
前回、Arduino UNOじゃなくてATtiny44でラリコン作り始めたところまででした。
↓
kikyujin.hatenablog.com
早くもメゲそうです・・・というかメゲました^^;
とりあえずそこに至る経緯を。
周波数測ってみよう
本題に入る前に、先日のラリーで試作1号使ってみたらちょっと誤差大きくて・・・と言っていた件について。 kikyujin.hatenablog.com
問題の切り分けをしたいので、とりあえず秋月で周波数も測れるテスターを買ってきました。
試作1号は0.1秒間隔(10Hz)でタイマー割り込みを入れて距離の積算をしているので、その間隔がなんらかの影響で長くなっているようならば実走行距離より積算が小さくなるはずなのです。
そこで、割り込みハンドラー内部でLEDのON/OFFを交互に入れてチカチカさせて、その周波数を測ることに。要は5Hzですな。
早速測定開始
んー
これは割り込みタイミングの狂いとかでは無いな・・・
じゃあ演算の誤差とかなんだろうか・・・
ちょっと長丁場になりそうなので、とりあえず試作2号機で対処することにしようっと(俺にぶん投げ)
ATtiny44でソフトウェアシリアル通信
んじゃま、作業を続けましょう。
とりあえず、ATtiny44でソフトウェアシリアルを動かしてみるところからです。
今回確認用にAmazonでUSB-シリアル変換器を買っておきました。
2個で799円、安い。
これをATtiny44に繋いで、PCからの送信をエコーバックできればまあOKという寸法ですな。
配線図はこのように。
ソースはこのように。
#include <LiquidCrystal_I2C.h> #include <SoftwareSerial.h> // RX D2 // TX D3 SoftwareSerial ss(2, 3); // I2C address 0x27 16x2 LiquidCrystal_I2C lcd(0x27, 16, 2); void setup() { // debug serial ss.begin(9600); ss.print(F("Good morning!\r\n")); // LCD init lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("Hello world?")); lcd.setCursor(0, 1); // キョウハイイテンキ lcd.print(F("\xb7\xae\xb3\xca\xb2\xb2\xc3\xdd\xb7")); } void loop() { while (ss.available() > 0) { // echo back char c = ss.read(); ss.write(c); } }
まあ普通に動きますわな。
ところが、コンパイル時に不穏なメッセージが出るようになってしまいました。
おっと、これは・・・
メモリが足らん!
おじさん、マイコンのメモリの少なさナメてましたわ。
ATtiny44は4いうだけあって、プログラム用のフラッシュが4KBしか無いのでした。
なんとかなるかな?と思ってたけど、なんともなりませんでした。
ごめんね でも本当です・・・
ちなみに試作1号って、どれくらいの容量で動いていたのかな? うーん、10KBちょっとぐらいか・・・ それにしてもATmega328Pのフラッシュメモリは広大だ。
しかしどうしたもんか・・・せや、この前ついでに買ったATtiny85使ったろ!
これならフラッシュ8KBあるし!
勝ったも同然だ!(だれに)
ATtiny85でなんとかならんか?
というわけで書き込みシールドを改造して、とりあえずATtiny85にもプログラム書けるようにしてみました。
ATtiny85と仲間たちを繋ぐ
とりあえず繋いで動かしてみます。
基本的にはATtiny44と同じですが、ピン配置がだいぶ違います(あと少な・・・はっ、誰か来たようだ)。
ATtiny85にLCD1602つけてるのも割とレアかもしれん。
ソフトウェアシリアルも動くには動く・・・ 送信は良いけど、受信はバケバケのバケ蔵じゃんよ! 9600bpsでこれか・・・4800bpsだとどうだろう
うまくやってるように見えてバケとる・・・
いろいろ試してボーレートを2400bpsまで落とせば送受信とも大丈夫という結果でした。
うーん、控え目に言って使い物になりませんな!
なおソースはこちら
↓
#include <LiquidCrystal_I2C.h> #include <SoftwareSerial.h> typedef unsigned char u8; u8 g_count = 0; // RX D3 // TX D4 SoftwareSerial ss(3, 4); // I2C address 0x27 16x2 LiquidCrystal_I2C lcd(0x27, 16, 2); void setup() { // debug serial ss.begin(4800); ss.print(F("Good morning!\r\n")); // LCD init lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("Hello world?")); lcd.setCursor(0, 1); // キョウハイイテンキ lcd.print(F("\xb7\xae\xb3\xca\xb2\xb2\xc3\xdd\xb7")); } void loop() { #if 1 while (ss.available() > 0) { // echo back char c = ss.read(); ss.write(c); } #else char buff[4]; u8 n = g_count; buff[3] = 0; buff[2] = '0' + n % 10; n /= 10; buff[1] = '0' + n % 10; n /= 10; buff[0] = '0' + n; ss.print(buff); g_count++; delay(100); #endif
さて、どうする?
とりあえずATtiny44/85での制作継続は難しそうです。
UNOと同じATmega328が無難かな
しかし28ピンのICソケットはハンダ付けしたくない。
ここでPICの出番ですよ・・・?
まあちょっと考えます^^;(キモい顔文字)