« 修理:文化シャッターのリモコンSTX8901 | トップページ | 「ZILOG SUPER 8 DESIGN MODULE REV1」という基板 »

2021年10月 8日 (金)

可変抵抗器の「陽極酸化」実験回路 #3

2021年10月 4日:可変抵抗器の「陽極酸化」実験回路 #2の続き。
Arduino-UNOベースでプログラム(スケッチだぁ)をごそごそ。
  ※20文字x4行の液晶、バックライト無しのしか
   手持ちが無かった。
これにどうやって8つのA/D値(0~1023の4桁)を表示するかが
悩みどころ。

似たような表示に、
  2015年02月07日:またまた長期間実験を始めます
LEDの劣化実験。
これも10bit A/D値を表示してます。
この時は、液晶画面右側に「4行x2」で表示しています。

表示数字、0~1024と4桁ですが、隣との区切りにスペースが
一つ必要ですんで、実質は5文字。
横2行に並べると5文字x4x2行と20文字に入ります。
でも、左端のスペースにch番号を示す文字を入れるとややこしく
なります。
その数字、表示データの数字と区別できるよう、液晶のCGデータ
設定を用いてみました。
A11_20211008140901
キャラジェネデータ、「1:」と「5:」を作って、左端に配置。
A12_20211008140901
これで、どの順でデータが並んでいるのかがわかるかと。
ついでに温度表示用に「℃」も。
A13_20211008140901
「 ゚C 」だと2文字必要なのが1文字幅で表記できます。

※数字の「0」、プログラムリストで使う時は「斜線の入ったゼロ」は
歓迎なんですが、こういった数字だけの表示の時は斜線無しのほうが好き。
1文字ずつ時前で処理する時(出来合いのライブラリを使わず)は、
「ゼロ」を「オー」に変換していました。


外付けEEPROMの書き込みについて追記

Arduinoでごそごそしていると、ライブラリとして使わせて
もらっているプログラムをどこから「もらってきた」のかが
わからなくなってしまいます。
 ※忘れても、いつでも見つかる(はず)
  という安心感が原因か。

今回の「陽極酸化検証スケッチ」の中でも、
  「これの原典、どこだっけ」
というのが外付けEEPROMの読み書き処理
Wire」を使ってこんな関数を使っているんですが、
「これ、どこからもらってきたの?」になっちゃい
ました。
   ※「Wire」のどこかのサンプルだろうけど

/***** EEPROM 1バイト書き込み *****/
void eepwrite( int deviceaddress,
       unsigned int eeaddress,
       byte data ){
int rdata = data;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));  // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(rdata);
  Wire.endTransmission();
  delay(10);     // wait 10ms
}
/***** EEPROM ページ書き込み  *****/
// 24LC256 では1ページ64バイト
void eepwritep( int deviceaddress,
       unsigned int eeaddresspage,
       byte* data, byte length ) {
byte c;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddresspage >> 8));  // MSB
  Wire.write((int)(eeaddresspage & 0xFF)); // LSB
  for ( c = 0; c < length; c++){
    Wire.write(data[c]);
  }
  Wire.endTransmission();
  delay(10);      // wait 10ms
}

この関数の書き込み後の待ち時間「delay(10)」。
たいていのEEPROM、書き込み待ち時間のmaxが「5ms」。
余裕を見て10ms待ちにしていると想像できます。
私の場合、この「無駄待ちdelay」がキライ

ですんで、今回もこんなふうに手直ししてます。
   ※ちょっと端折って記します。
void eepwritep( int・・・){
byte c;
  while(tm_eep);   // 書き込み時間待ち
  Wire.beginTransmission(deviceaddress);
   :
  Wire.endTransmission();
  tm_eep = 6;     // 6ms (EEPROMのスペックは5ms)
}

1バイト書き込みの手順ですが、
  ・書き込み完了の時間待ちは処理前に。
  ・EEPROMの読み出しにも、書き込み完了時間待ちを
   頭に入れる。
  ・時間待ちタイマー「tm_eep」は1msタイマー割込で
   デクリメント。 タイムアップでゼロに。

こうすると、EEPROMに書き込んだ直後、別の処理をすぐに
実行できます。
もちろん、連続して書き込みが続く場合の待ち時間は同じ
です。
でも、時間をおいた単発の書き込みだと、無駄待ちを
しなくてすみます。
  ※10msというのは結構長い。
   スイッチのスキャンだとミスすることも。
   ブザー報知だとタイミングがおかしくなったりと。

そして、時間待ちを実行の前でという処理、
EEPROMのページ書き込みで役立ちます。

使ったEEPROMは32kバイトの24LC256。
1ページが64バイトで、同一ページを書く限りは、1バイトでも
64バイトでも待ち時間は5ms(max)

今回のデータは「18バイト」と中途半端ですんで、ページを
またいでの書き込みが発生します。
  ※9ch分の2バイトデータを保存するんで
4回に1回は、「ページまたぎ」が起こって、2回の書き込み
完了待ちが発生するわけです。

時間待ちを書き込み実行の前でという処理にしておくと、
1回目の書き込み完了後に実行する別の処理は待ち時間
なしでok。
ページをまたがなければ、次の記録指令が来るまで
無駄待ちなし(delayなし)で処理を進めれます。

「ページまたぎ」が起こった時は、次の処理を2回目の
書き込み前、つまり時間待ちの前に行っておけば、
「何もしないで待っている」から逃れることができます。
  ※応答を良くしたいときなど、これがありがたい。

オシロ波形で見てみましょう。
上からI2CのSCLとSDA。 (EEPROMの信号)
そして、1msタイマー割込と直後のA/D変換割込で
タイミングチェックのために作っているパルス。
H期間が割り込み処理の長さです。
   (この波形では細くて測れませんが)
一番下がシリアル出力。
9600BPSのシリアルデータです。
Bb000_20211008163501
↑のは同一ページの書き込みで、1回のアクセスで
18バイトを書いています。
そして、書き込み直後に、シリアルデータを出力。
待ち時間なく、シリアル出力処理が行われています。

次のは「ページまたぎ」の処理が発生して18バイトの
書き込みが2分割された様子です。
Bb001_20211008163801

1回目の書き込み直後にシリアル出力処理を行い、
それが終わってから2回目の書き込み(待ち時間発生)です。
シリアル出力は、1回目の直後から始まっているので、
「ページまたぎによる時間待ち」が見えません。

シリアル出力は割込で処理されるので、じっさいに
かかっている時間はわずかです。
しかし、液晶表示だといがいと時間がかかりますんで、
2回目の待ちの間に表示処理を進められるでしょう。

タイマー割込によるタイマー管理が必須になります、
「無駄待ちはキライだ」を実現するには「これしき」です。

|

« 修理:文化シャッターのリモコンSTX8901 | トップページ | 「ZILOG SUPER 8 DESIGN MODULE REV1」という基板 »

Arduino」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« 修理:文化シャッターのリモコンSTX8901 | トップページ | 「ZILOG SUPER 8 DESIGN MODULE REV1」という基板 »