mega8
TQFPのATmega8を購入したのは10年以上前になりましょうか。tiny2313などで当時のプログラムはすべて賄えていたようであまり使っていません。その後、mega88、168、328p が出ましたのでそちらに関心が行ったようです。部品箱や実験ボードにmega8が残っていますのでその遊びをここに置くことにします。
1 LCD表示の実験
2 I2CドライブLCDモジュール
3 もう一つのatmega8ボード
4 mega8の気圧計(BMP280)
1 LCD表示の実験 2017.05.16
長い間眠っていたmega8を思い出してみようとmega48で確認できたLCDの表示実験をしました。とりあえずm48のプログラムをそのままにm8デバイスでコンパイルすると問題なくLCD表示ができました。
PB0にLEDを入れています。どうにもならないときのLチカから始められるように、という意味もあります。実はうまく動かなかったのでMCUチップを入れ替えて配線をし直しました。が、やはり動かないのです。Lチカが動かない−−−経験のないことです。文法に間違いはありません。ベリファイは問題がありません。−−−−−−− ようやく気づきました。同じと思って変更なしにmakefileを使ったのでした。MCUはm48でなくm8に変更が必要です。 当然Lチカは動作し、LCDの表示も正常になりました。(オソマツ)
プログラム 作者メモ\prA\_2017\m8\m8_LCDtest01
2 I2CドライブLCDモジュール 2017.05.20
mega8でLCD表示ができましたので、これを利用してI2Cスレーブの表示器を計画しました。マスター側はIO端子が少なく、かつ、Arduino-IDEで書けるESP8266などを考えています。
I2Cスレーブのテストは随分前にmega88でいただいたプログラムを自分流に修正して i2c_slv_x8.h i2c_slv_x8.c として作ってあったのですが内容についてはほとんど忘れています。今回、mega48とmega8で使ってみたところ使えることがわかったところです。なお、私のこのルーチンはスレーブの内部アドレスについては十分確認されておらず場合によって適当に処理しなければなりません。
ハードウエアは手持ちのmega8TQFPを使っています。今まで配線は0.2mmUEWだったのですが、今回は0.26mmを使ってみました。線にこしがあってこの方が楽な点もあるのですがTQFPにはやや難しいこともありました。
負電源はportB0の矩形波から取っています。直結で適当なコントラストとなりましたので可変抵抗は入れていません。
実験に使ったマスターはESP8266で、Arduino-IDEプログラムは次のとおりです。
#include <Wire.h>
uint8_t j;
void setup() {
Wire.begin();//master
j = 0;
}
void loop() {
Wire.beginTransmission(0x22);
Wire.write(0); // スレーブプログラムに合わせて挿入
Wire.write("2 kuman2600 "); // 2は2行目に表示
j = j + 1; if (j > 9) {
j = 0;
}
Wire.write(j+'0');
Wire.write(" ");
Wire.endTransmission();
delay(500); // スレーブの反応を待つ
Wire.beginTransmission(0x22);
Wire.write(0);
Wire.write("1Hello, World! ");
Wire.write('x' );
Wire.write('\0');
Wire.endTransmission();
delay(500);
}
スレーブプログラムが内部アドレスを取り込むようなので余分な0を送っています。
どこに問題があるのかよくわかりませんがややもたつく感じながら表示されています。時計程度であれば表示器として使えるようです。
プログラム 作者メモ\prA\_2017\m8\m8_i2c_LCDtest01
Arduino-IDEを使ったプログラム
Arduino-IDEにはI2Cのスレーブを作る機能があります。これを使えば簡単なプログラムで実現できそうだと感じました。ただ、今回はmega8を使っているので、mega8のボードがbords.txtに必要です。調べると Arduino NG or older がmega8を使っています。これは16MHzですから発振を8MHzに変更して使うことにしました。
試行錯誤の後になんとか動く状態になりました。avrのプログラムに合わせてI2C通信時にスレーブのhighアドレスを入れているので、そして、Arduino-IDEではこのアドレス(値は0)を第1データとして取り込むので、受信時の第1バイトは無視し第2バイトの1,2はLCDの行位置制御に使い第3バイトから16バイトを表示データとして使うことにしました。
さて、一連の関係から電源電圧は3.3Vで考えているのでLCD用に負電源が必要です。Arduino-IDEではAVRの割り込み処理はできないようです。色々探すとtoneという機能があって、特定のポートに指定周波数の方形波が出せるそうです。必要な30kHzまで出せるかどうかはわかりませんがポートB0にこれを出してみました。試行の結果、負電源の出力コンデンサに10μFを抱かせると出力が上がり、結果として5000Hzで適当なコントラストとなっています。周波数を上げると濃くなりすぎます。抵抗は入れていません。
Arduinoのpin番号は次の図によりました。
プログラムです。 筆者メモ \_0MicroComp\Arduino181\sketchbook\201705\m8\m8lcd_2
#include<LiquidCrystal.h>
#include <Wire.h>
LiquidCrystal lcd(2, 3, A0, A1, A2, A3);
uint8_t i;
char s[20],s1[20],s2[20];
void setup() {
DDRB = 0b00000001; PORTB = 0xff; // LEDモニタ
pinMode(8, OUTPUT);
Wire.onReceive(myReadLine); //割り込み関数の指定
lcd.begin(16, 2);
lcd.setCursor(1, 0);
lcd.print("hello world! ");
i = 0;
tone(8,5000) ;
}
void loop() {
Wire.begin(0x22) ; //アドレスを0x22に設定 //この位置OK 割り込み前に設定
lcd.setCursor(0, 0); lcd.print(s1);
delay(50);
lcd.setCursor(0, 1); lcd.print(s2);
delay(50);
}
void myReadLine(int a) {
int cnt = 0;
uint8_t j;
if (Wire.available() > 0) {//受信したら
delay(100);
cnt = 17; //最大文字数
for (int i = 0; i < cnt; i++) {
s[i] = Wire.read();
}
s[cnt] = '\0'; //終端文字
s[0] = '0';
}
if (s[1] == '1') {for (j = 2; j < 19; j++) {s1[j - 2] = s[j];}}
if (s[1] == '2') {for (j = 2; j < 19; j++) {s2[j - 2] = s[j];}}
}
AVRだけをさわっているときは思いませんでしたが他のデバイスを使うに当たってArduinoシステムは本当に便利だ、と感心しています。
(2017.05.22) mega8をArduino-IDEで使うときは
1 内部RC発振 8MHz として
2 書込みは(hexファイルを書き出して)avrdude-CUIで
します。したがって bords.txt を一部修正しています。
## Arduino NG or older w/ ATmega8 で追加及び修正した場所
atmegang.build.f_cpu=8000000L
atmegang.menu.cpu.atmega8=ATmega8(3.3V, 8 MHz)
atmegang.menu.cpu.atmega8.bootloader.low_fuses=0xe4
atmegang.menu.cpu.atmega8.bootloader.high_fuses=0xd9
もっとも、ヒューズは別に書き込むので変更の意味は無いのですが。
2 I2CドライブLCDモジュール おわり Top
3 もう一つのatmega8ボード 2019.11.14
もう一枚のmega8ボードが出てきました。何のために作ったのか、いつ頃作ったのか記憶がありません。少し変更してここに記録を残します。
元は E:\MC\_0MicroComp\AVR\prA\m8 で動いていたものです。
今回の変更点は
Xtalを取り替えました。
シリアル端子を付け替えました。
リセットスイッチをつけました。
の3件です。
(2019.11.17) I2C回路設定のため、一部変更しました。
・LCDの 3RSをPD2 に、4EnをPD3に変更。関係して lcd.hのポート指定を変更。
・I2Cコネクタを増設。 SDAはPC4に、SCLはPC5に接続。
3 もう一つのatmega8ボード おわり Top
4 mega8の気圧計(BMP280) 2019.11.23
上の実験回路はmega8による気圧計の準備段階でした。
AVRを使ってもarduinoで書けばライブラリを使って簡単にbmp280の気圧計が出来上がります。しかし、余分なものが多く含まれるためかプログラムメモリが多く必要になります。mega8の8kBメモリでは到底足りません。
gccで書けば必要な部分だけを書くことができますから少ないメモリでできるのではないかと考えて実験を進めました。
LCD表示とI2C接続のRTC ds3231 の読み書きはすでに経験しています。したがって、bmp280 の読み取りができればできるはずです。
webを随分探しましたがarduinoによるものは豊富にあるのですが、gccのものはなかなか見つかりません。これのライブラリもあるようですが、私の知識の届かないところにありました。
しかし、探しているうちに PIC によるものですがライブラリを使わずにbme280を読み書きしているプログラムに出会いました。(http://www7b.biglobe.ne.jp/~nobosan_flute/lab_theme88.htm)。
別の場所でbme280(bmp280)は一部のデータをレジスタから読み取り加工した後にレジスタに書き込む。続けて多くのデータを読み出し、複雑な計算をして気圧・温度・(湿度)を求めることを知りました。
このプログラムではその読み取り、書き込み、データの計算、の過程がわかりやすく書かれており、私の方法で読みだしたデータを当てはめれば使えると考えました。
途中、知識の不足から試行錯誤を繰り返すことになりましたが、なんとか初期の目的に達することができました。
未熟なため間違いも多くありますが、関係のファイルをここに置きます。
プログラム量は 約5.5kB でmega8に余裕で入りました。
手持ちがbmp280のため気圧と温度の2つで湿度はありません。
気圧はhPaまでで少数以下はありません。温度も設置条件で大きく変わりますから小数点以下はありません。
自分の都合で気圧・温度とも補正をしています。
メニューボタンを押し続けたままリセットするとシリアル通信による時刻設定ができます(teratermを使っています)。
四捨五入スイッチを押すと、ややタイムラグがありますが、0秒に設定できます。微調整に便利です。
余談ですが、Arduino-IDEにコピーすると「自動整形」でインデントが正しくなります(便利です)。
やがてはケース入りの単体にするつもりです。(いつのことやら・・・)
(2021.08.03追記)
RTC DS3231S のリードを変更しました。I2C通信に必要な SDA SCL Vcc GND の4本だけを引き出しました。同時にこのボードのソケットに合うように取り出しています。
作者メモ:\AVR\prA\m8\m8_i2c02_bme02
4 mega8の気圧計(BMP280) おわり Top
工事中
1 めんにゅー 1 2017.05.20