初心者のArduino電子工作
気温、湿度、照度、は取れてSDカードに記録してる中、ボードの配線整理しようとしてたら、「パキッ!」液晶表示器AE-AQM1602A 割ってしまいまして、とりあえず予備で買っていたAE-AQM1602Y付けたもののコントラストの調整が難しく、微妙な電源電圧の変動で見えたり見えなくなったり。
で、Amazonで3個セットのOLED I2C接続のもの安かったのでポチリ
こんな感じの小さな箱に入ったものがアマゾンのプチプチ袋に3個入って送ってきました。説明書もなくただ本体だけ。なかなかArduino初心者には厳しい。
で、ネットで調べてまずは単体で接続してテスト。
#include <Adafruit_SSD1306.h>
使ったら、簡単に表示できましたってところまではよかったけど。
さあ、今度はAE-AQM1602YをのSSD1306に入れ替えてさあプログラムも併せて書き換えてコンパイルしたら、コンパイルはできているもののメモリーが少ないですのアラート。
ボードに書き込んでみるとSetupのところでハングしていたり、勝手に再起動何回もしてみたりで トホホ。
AE-AQM1602YだとうまくSDカードに記録できていたのに。
プログラムの途中にSirial.print入れても、SSD1360でdisplay.printのところで暴走の様子。
ネット調べたら先人がいたものの、設定が悪いんじゃないのとか、配線違っている?とか、なかなか厳しいご意見があるサイトしか見つからずに。トホホ
検索ワードいろいろ変えてやってたら、英語のサイトでこんなの発見
I'm using the ssd1306_128x64_i2c example file from the 1306's library.
It works perfectly until I add the #include SD.h line, after which it gives the allocation failed error.
Please advise.
今まで日本語のサイトしか見てなかったけど、 「あれっ!!」これは
ここでGoogle翻訳の出番です。
ドンピシャですね。
SDライブラリとSSD1306ライブラリはどちらも大きなバッファを必要とします。それはたくさんのメモリを意味します。あなたはたくさんの記憶を持っていません。
- SDは、セクターバッファー(コンパイル時に割り当てられる)に少なくとも512バイトを必要とします。
- SSD1306は、(実行時に割り当てられる)ディスプレイバッファー用に少なくとも1kiBを必要とします。
- シリアルは、TXおよびRXバッファー(コンパイル時に割り当てられる)に少なくとも128バイトを必要とします。
- ワイヤーライブラリは、TXバッファに32バイトを必要とします。
これは合計2048の1696バイトであり、プログラム、さまざまなライブラリ、およびArduinoコア自体に必要な他の変数やもの、およびスタック(および指定された最小サイズの安全ゾーン)は考慮されていません。
Arduinoをより多くのメモリを備えたものにアップグレードするか、デザインを複数のArduinoに分割する以外に、それについてできることは何もありません。
っで、この回答はありがたいですね
I was able to make it all fit by using the text-only library for the OLED.
SSD1306Ascii Library
要はAdafruit_SSD1306.hはいろいろグラフィックできるけど、重いので文字表示だけの軽いライブラリーがあるようで。早速ダウンロードして入れ替えてみます。
おおおお!!!軽い。 SDカードシールドと共存できてパキッと動きました。
ただ、文字サイズが年寄りには小さすぎ。
もう少し真面目にDOC読めば何とかなるでしょう。
さあてサミスタ残りくっつけるか、気圧計はどうしよう。
ArduinoはPCとは違うね。ESP32だと楽勝みたいだ
まあ昔もMZ80Bのころは64KBのメモリーにHu-BASIC入れてパックパン入れて遊んでたんだからなあ。あの頃のメモリーのサイズ感かな。
今回のスケッチ
-----------------------------------------------
/*
* SSD1306 & TF Card Write Test
* URK Labo
*/
//OLED Display SSD1306用軽いキャラクタライブラリー
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiAvrI2c oled;
//SD TF Card
#include <SPI.h>
#include <SD.h>
#define SD_SS 4
char *filename="DataLog.csv";
//時計
#include <DS3232RTC.h>
String Hiduke;
String Jikoku;
#include <Wire.h> //I2C接続用
void setup() {
Serial.begin(9600);
Serial.println("Set Up");
//表示初期化
oled.begin(&Adafruit128x32, I2C_ADDRESS); //こっちにすると文字高さ2倍
// oled.begin(&Adafruit128x64, I2C_ADDRESS); //これは小さくぎっちりサイズ
oled.setFont(System5x7); //文字フォント調べるか
oled.clear();
oled.println("URK");
init_SD; //SD接続初期化
// ここでRTCの時刻をもとにArduinoの時刻を合わせる
setSyncProvider(RTC.get);
if(timeStatus() != timeSet) {
Serial.println("Unable to sync with the RTC");
}
else{
Serial.println("RTC has set the system time");
oled.println("RTC set system time");
}
pinMode(7,OUTPUT); //動作チェック用LED
}
void loop() {
oled.clear();
//日付 時刻の取得
Hiduke=String(year())+"/"+strPad2(month(),2)+"/"+strPad2(day(),2);
Jikoku=strPad2(hour(),2)+":"+strPad2(minute(),2)+":"+strPad2(second(),2);
oled.println(Hiduke+" "+Jikoku);
//書込み
File dataFile=SD.open(filename,FILE_WRITE);
if(dataFile){
dataFile.print(Hiduke +" "+Jikoku+",");
dataFile.println(analogRead(A3));
Serial.println("Written "+Hiduke +" "+Jikoku +" " + String(analogRead(A3)));
oled.println(" A3val=" + String(analogRead(A3)));
Pikari(100,3);
}
else{
Serial.println("Error:can't Oprn File");
oled.println("Error:can't Oprn File");
init_SD();
Pikari(30,20);
}
dataFile.close();
delay(5000);
}
void init_SD(){
Serial.println("--SD init--");
pinMode(SS,OUTPUT);
SD.begin(SD_SS);
delay(500);
}
void Pikari(int Dtime,int Dcnt){
for (int i=0;i<Dcnt;i++){
digitalWrite(7,HIGH);
delay(Dtime);
digitalWrite(7,LOW);
delay(Dtime);
}
}
// 数値の左側ゼロ埋め桁合わせ表示 時計表示用に
String strPad2(int num,int zeroCount){
char tmp[256];
char param[5] = {'%','0',(char)(zeroCount+48),'d','\0'};
sprintf(tmp,param,num);
return tmp;
}