すっかりハマっております^^;
目に止まったのが、このサイト
OLEDは、RAMを大量消費するので無理かと思ってました。
「Tiny Graphics Library」ってのがあるようですね~
最後の方に
「Tiny Graphic Library Program」部にスケッチへのリンクがあります。
このリンクはちと分かり難かった~
そのリンクのスケッチを開いて、全てコピーして
Arduino IDE Ver.1.8.3に貼り付けます。
取り敢えず、そのまま[検証・コンパイル]してみます。
設定は、これです。
お~っ!何事もなく無事コンパイルできました!
懸念してたグローバル変数の使用量は、10%です!
この8pinのIC、ひょっとしたらと思ったら
何と!
ATtiny85でOLED(SH1106 128x64 I2C)を使えてるのです。何と!
OLEDは、RAMを大量消費するので無理かと思ってました。
「Tiny Graphics Library」ってのがあるようですね~
特別にライブラリをインストールするわけではなさそうです。
詳しい英文の解説が続いて、最後の方に
「Tiny Graphic Library Program」部にスケッチへのリンクがあります。
このリンクはちと分かり難かった~
そのリンクのスケッチを開いて、全てコピーして
Arduino IDE Ver.1.8.3に貼り付けます。
取り敢えず、そのまま[検証・コンパイル]してみます。
設定は、これです。
お~っ!何事もなく無事コンパイルできました!
懸念してたグローバル変数の使用量は、10%です!
さて、作者David Johnson-Daviesさん使用の温度センサーは、
TMP37 20mV/℃、0mV at 0°C
マーティー手持ちの温度センサーも同じ様な TO-92 3pin
NSのLM35DZ、10mV/℃、0mV @0℃
温度センサーの計算式だけ変更すればいいハズです。
LM35DZは、0℃で0mV、100℃で1000mV
analogReference(INTERNAL1V1);
なので、基準電圧:1.1V
入力:1.1V の時にADC:1023になるので
100℃、1000mVの時、
・温度[℃]=(ADC値 ÷ 1023 x 1100mV)÷ 10mV/℃
= ADC値 x 110 ÷ 1023
更に1目盛 0.5℃刻みなので
・温度[0.5℃刻み]= ADC値 x 110 ÷ 1023 x 2
= ADC値 x 220 ÷ 1023
ということで、スケッチを
*********
int Temperature = (analogRead(A2)*25)/233;
⇒
int Temperature = (analogRead(A2)*220)/1023;
*********
に変更します。
ATtiny85は、すっかりお気に入りになり
int Temperature = (analogRead(A2)*25)/233;
⇒
int Temperature = (analogRead(A2)*220)/1023;
*********
に変更します。
ATtiny85は、すっかりお気に入りになり
新品の生チップを10個、ここで調達しております。
US$ 12.31/10個(送料無料)
この設定にして、Arduino UNOの書込機でやるので
[書込装置:”Arduino as ISP”]です
新品の生チップは、
Clock:8MHz、Prescale Resister:1/8になってるのでUS$ 12.31/10個(送料無料)
この設定にして、Arduino UNOの書込機でやるので
[書込装置:”Arduino as ISP”]です
新品の生チップは、
最初に[ブートローダを書き込む]して
Fuse bitをセットする必要があります。
スケッチを書き込みます。
書き込みも無事終わりました。
この時作ったArduino UNOの書込装置です。
ちなみに、14pinのソケットを新調しております^^;
US$ 1.01/2個(30% OFF)
表示には数秒かかるという遅さで、
半世紀前のPC8001のBASICインタプリタを思いだしました^^;
ちゃんと表示されたと思いきや
ん?温度が表示されません(T_T)
あれっ? 15分経つと画面が真っ暗になってしまいました(-_-;)
電源入れ直すと、目盛りは、また表示されます。
スケッチを見直すと~
「int Temperature = (analogRead(A2)*220)/1023;」
の「analogRead(A2)*220」の最大時
intの最大 32767 < 1023 x 220 でオーバーフローしてました~(-_-;)
ちゃんと表示されたと思いきや
ん?温度が表示されません(T_T)
あれっ? 15分経つと画面が真っ暗になってしまいました(-_-;)
電源入れ直すと、目盛りは、また表示されます。
スケッチを見直すと~
「int Temperature = (analogRead(A2)*220)/1023;」
の「analogRead(A2)*220」の最大時
intの最大 32767 < 1023 x 220 でオーバーフローしてました~(-_-;)
Y軸のTemperature値がオーバーフローすると止まるようです。
ということで、
オリジナルのセンサー 20mV/℃ から 10mV/℃への変更だけなので
元の式を単純に2倍することにして
int ⇒ unsigned int にして
65535 > 1023 x 25 x 2
なので、今度はオーバーフローしないハズです^^;
*********
int Temperature = (analogRead(A2)*25)/233;
⇒
unsigned int Temperature = (analogRead(A2)*25*2)/233;
*********
それと、15分間隔で24時間は、確認が大変なので
ひとまず、1.5秒間隔にします。
*********
while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo);
⇒
while ((unsigned long) ((StartMins + millis()/100)/15)%96 == SampleNo);
*********
横軸 2.4分になりました。
途中、センサーを手で温めて山を作ってみました^^;
無事動作したので
横軸を24時間に戻して~
*********
while ((unsigned long) ((StartMins + millis()/100)/15)%96 == SampleNo);
⇒
while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo);
*********
夜中の0時に始めるので
*********
const int Now = 1547; // To set the time; eg 15:47
⇒
const int Now = 0000;
*********
にして、書き込んで開始です。
一晩様子を見たいと思います。
・・・朝8時、夜中の室温は、もう初夏なのであまり下がってないですね~
小型のリチウムイオン電池のモバイルバッテリーで放置してます。
ということで、
オリジナルのセンサー 20mV/℃ から 10mV/℃への変更だけなので
元の式を単純に2倍することにして
int ⇒ unsigned int にして
65535 > 1023 x 25 x 2
なので、今度はオーバーフローしないハズです^^;
*********
int Temperature = (analogRead(A2)*25)/233;
⇒
unsigned int Temperature = (analogRead(A2)*25*2)/233;
*********
それと、15分間隔で24時間は、確認が大変なので
ひとまず、1.5秒間隔にします。
*********
while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo);
⇒
while ((unsigned long) ((StartMins + millis()/100)/15)%96 == SampleNo);
*********
横軸 2.4分になりました。
途中、センサーを手で温めて山を作ってみました^^;
無事動作したので
横軸を24時間に戻して~
*********
while ((unsigned long) ((StartMins + millis()/100)/15)%96 == SampleNo);
⇒
while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo);
*********
夜中の0時に始めるので
*********
const int Now = 1547; // To set the time; eg 15:47
⇒
const int Now = 0000;
*********
にして、書き込んで開始です。
一晩様子を見たいと思います。
・・・朝8時、夜中の室温は、もう初夏なのであまり下がってないですね~
小型のリチウムイオン電池のモバイルバッテリーで放置してます。
こういうスタンドアローンのデータロガーもなかなか面白いですね~
ちょっとPlotの描画速度を測りたいと思います。
PB1(6pin)が空いてるので
setupに1行追加して
*********
void setup() {
// initialize
pinMode(1, OUTPUT); // PB1(pin6) for PlotDot時間確認用
PINB |= 0b10; // PB1反転
*********
CPU Clock 8MHz(internal)
PB1の波形を見ます。
1周期の1/2(HIGH or LOW期間)が1dotプロットする時間なので
2.1msec/dotってとこですね~
かなり遅いな~
1msecを軽く切ると思ってました。
では、CPU Clock 16MHz(PLL)
ちなみに、ATtiny85のCPU Clockを変更するには、
[16MHz(PLL)]にして
で、忘れるのはマーティーだけだと思うのですが
この[ブートローダを書き込む]を忘れないように実行してから
スケッチを書き込みます。
CPU Clock 16MHz(PLL)
1.9msec
ちょっとしか速くなりませんね~
ADC Clock 50KHzでも高々0.26msecのはずなので、
analogReadの時間が支配的だとも考え難いし~?
ATtiny85のDatasheetには、
*********
void setup() {
// initialize
pinMode(1, OUTPUT); // PB1(pin6) for PlotDot時間確認用
*********
最高速にするため、while行をコメントアウトします。
*********
// Now start plotting the temperature every 15 mins
// while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo);
*********
*********
// Now start plotting the temperature every 15 mins
// while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo);
*********
PlotPointコードの後に「PINB |= 0b10;」を追加して
は、ADC完了毎にPB1をトグルしてます。
つまり、1dotプロットする毎にPB1を反転させます。
PB1のパルスの1/2が、ADCしてPlotPointする処理時間になります。
*********
PlotPoint(SampleNo+x1, Temperature-10+y1);つまり、1dotプロットする毎にPB1を反転させます。
PB1のパルスの1/2が、ADCしてPlotPointする処理時間になります。
*********
PINB |= 0b10; // PB1反転
*********
CPU Clock 8MHz(internal)
PB1の波形を見ます。
1周期の1/2(HIGH or LOW期間)が1dotプロットする時間なので
2.1msec/dotってとこですね~
かなり遅いな~
1msecを軽く切ると思ってました。
では、CPU Clock 16MHz(PLL)
ちなみに、ATtiny85のCPU Clockを変更するには、
[16MHz(PLL)]にして
で、忘れるのはマーティーだけだと思うのですが
この[ブートローダを書き込む]を忘れないように実行してから
スケッチを書き込みます。
CPU Clock 16MHz(PLL)
1.9msec
ちょっとしか速くなりませんね~
ADC Clock 50KHzでも高々0.26msecのはずなので、
analogReadの時間が支配的だとも考え難いし~?
ATtiny85のDatasheetには、
ADC Clockは、CPU Clockに応じて決まると書いてあるだけですが
たぶん、
Clock 8MHzではPrescale 1/64でADC Clock 125KHz
Clock 16MHzではPrescale 1/128でADC Clock 125KHz
では、CPU Clock 16MHzのまま
更に、ADCもコメントアウトして殺します。
たぶん、
Clock 8MHzではPrescale 1/64でADC Clock 125KHz
Clock 16MHzではPrescale 1/128でADC Clock 125KHz
で13cycleだと0.104msecだと思われます。
更に、ADCもコメントアウトして殺します。
forルーチン内はこれだけです。
*********
for (;;) {
SampleNo = (SampleNo+1)%96;
*********
for (;;) {
SampleNo = (SampleNo+1)%96;
// unsigned int Temperature = (analogRead(A2)*25*2)/223;
unsigned int Temperature = 20;
PlotPoint(SampleNo+x1, Temperature-10+y1);
PINB |= 0b10; // PB1反転
}
*********
1.75msec(Clock 16MHz)
unsigned int Temperature = 20;
PlotPoint(SampleNo+x1, Temperature-10+y1);
PINB |= 0b10; // PB1反転
}
*********
1.75msec(Clock 16MHz)
ADC有り1.9msecから0.15msec減ってるので
やはりADC処理部は、0.1~0.15msecということになります。
整理すると
この差、つまりADCの有無の処理時間を波形で見ます。
*********
unsigned int Temperature = (analogRead(A2)*25*2)/223;
⇒
unsigned int Temperature = 20;
整理すると
この差、つまりADCの有無の処理時間を波形で見ます。
*********
unsigned int Temperature = (analogRead(A2)*25*2)/223;
⇒
unsigned int Temperature = 20;
*********
PB1のパルスの1/2が、ADCとPlotPointする処理時間になります。
CPU Clock 8MHzのADC処理部の有り
CPU Clock 8MHzのADC処理部の無し
CPU Clock 16MHzのADC処理部の有り
CPU Clock 16MHzのADC処理部の無し
CPU Clock 8MHzのADC処理部の有り
CPU Clock 8MHzのADC処理部の無し
CPU Clock 16MHzのADC処理部の有り
CPU Clock 16MHzのADC処理部の無し
8MHz、16MHzともADC Clockは、自動的に125KHzだと考えられます。
I2C Clock Default 100KHzらしいので、400KHzにしてみます。
Wire.begin();
の後に追加
Wire.setClock(400000);
I2C Clock Default 100KHzらしいので、400KHzにしてみます。
Wire.begin();
の後に追加
Wire.setClock(400000);
を追加して変更できるのですが、このATtiny85では変化なし(T_T)
Wire.setClock(100000L);
Wire.setClock(100000L);
でも変化なし
#define I2C_FASTMODE 1
#define I2C_FASTMODE 1
も変化なし
これは、CPU Clock 16MHzのADC処理部の無し
I2C 400KHzにしたつもりですが、一つ上のショットと全く変わりありません。
どうやらATtiny85では、固定されてるようです。
で、どこだったか、こんな文章が!
ということで、
1dot 2msecとして、横100dotだと、200msecになるので
5Hzの1周期がReal Timeでサンプリングして表示できる速度です。
ATmega328Pでは、TWI ModuleのBit Rate Generatorをいじってますね~
ATtiny85には、TWI Moduleがないので変化しないんですね。で、どこだったか、こんな文章が!
「the default Arduino Wire() library does not support changes in bus speed or feature proper clock stretching support.」
・・・I2C speedは、変更できないのか~(T_T)
このSoftI2CMasterライブラリを使えばできるようですが、
またの機会にします^^;
1dot 2msecとして、横100dotだと、200msecになるので
5Hzの1周期がReal Timeでサンプリングして表示できる速度です。
何に応用しようかな~?
最後に、Y軸の温度範囲を変更しようと思いましたが
画面ドットの座標は、この図の仕様で
これを8x8pixelに分割してProgram Memoryに格納して
Graphic Fontとして表示しています。
だからバッファ領域が不要なのですが、
データ作るのは、とても大変ですね~
汎用のツールがないので、自力でソフト組まないといけないのです。
Pythonで作れそうですが、マーティーにはちと重たいな~(-_-;)
もう一つ、同じ作者David Johnson-Davies氏の
これ、面白そうなんですが
ATtiny85のRAMでは、OLED 64x48が限界だそうで、
I/Fは、IICではなく、描画データ転送速度が速いSPIが必要らしいので
今回はできませんね~
さて、OLEDシリーズ第4弾に取り掛かるとします^^;
最後に、Y軸の温度範囲を変更しようと思いましたが
画面ドットの座標は、この図の仕様で
これを8x8pixelに分割してProgram Memoryに格納して
Graphic Fontとして表示しています。
だからバッファ領域が不要なのですが、
データ作るのは、とても大変ですね~
汎用のツールがないので、自力でソフト組まないといけないのです。
Pythonで作れそうですが、マーティーにはちと重たいな~(-_-;)
これ、面白そうなんですが
ATtiny85のRAMでは、OLED 64x48が限界だそうで、
I/Fは、IICではなく、描画データ転送速度が速いSPIが必要らしいので
今回はできませんね~
さて、OLEDシリーズ第4弾に取り掛かるとします^^;
2 件のコメント:
IOTばやりの時代です。第4弾はぜひそちら方向に発展させてください。
当方注文中のOLEDいまだ到着せず。��
昔青年さん、全弾でコメントいただきありがとうございますm(_ _)m
IOTですか~
通信系はあまり得意じゃなくて...(-_-;)
ESP32なんちゃら辺りでServer化して面白そうなことできそうな気もするんですけどね~
ちなみに第4段は、大昔に宿題いただいてたタコメーターの予定で~す^^;
コメントを投稿