ニックネーム: 居酒屋ガレージ店主
★ZAQのBlogari停止のため、あれこれ「データ吸い出し」対策しています。 新規記事はとりあえず停止。 コメント書き込みはまだ有効です。 (JH3DBO 下間憲行)
2015年10月06日(火)
チャートレコーダーのスケッチを修正
プリンタシールドでチャートレコーダ
Arduino IDEをバージョンアップしたら、「PROGMEM」の
使い方が変わっていたようでプリンタ・シールドの
プログラムにエラーが出るようになってしまいました。

旧来はこんな書式で、固定データをフラッシュ
ROM内に置いていました。

  PROGMEM prog_uint16_t feedpls[]={
  PROGMEM prog_uchar bit_on[]={
  PROGMEM prog_char spd0[] = "5sec/cm";
  PROGMEM prog_char *spdmsg[] = {

PROGMEMと「prog_なんたら」で、固定データ
を表してました。
新IDEでコンパイルすると、これらがエラーに。

新しいIDEで通るようにするには、こんな
書式で記述します。

  const word feedpls[] PROGMEM ={
  const byte bit_on[] PROGMEM ={
  const char spd0[] PROGMEM = "5sec/cm";
  const char * const spdmsg[] PROGMEM = { …(1)
  
このうち、(1)は文字列を示すポインタの
固定配列。
大きな修正ではありませんが、ちょいと面倒
です。

※これらの固定データを使っているプログラム
本体のほうは、無修正で動いています。

★修正したプログラム、アップロードしておきました。
http://act-ele.c.ooco.jp/toukou/prnsld/prnsld01a.zip
http://act-ele.c.ooco.jp/toukou/prnsld/prnsld02a.zip

★旧スケッチ
http://act-ele.c.ooco.jp/toukou/prnsld/prnsld_ino_02.zip


※補足
それともう一つ。 「虫」もどきがありました。
チャートの紙送り速度を設定するロータリー型
デジタルスイッチを読むルーチンです。

0〜9の設定値を読み、チャタリングを除去した
安定したデータとしてdsw_rotを書き換えます。
これに微妙なミスがありました。

※修正前の生スケッチ↓
 /***** ROT-DSW入力   *****/
 //  dsw_rotにデータを残す
 void ckrotdsw(void)
 {
 static byte ck = 0;
 static byte d;
   switch(ck){
    case 0:
     if(dsw_rot != rddsw()){  // 変化あり ★1
      d = rddsw();       // 変化した状態 ★2
      tm_dswck = 100;     // 100ms
      ck++;
     }
     break;
    case 1:
     if(d != rddsw()){     // また変わった ★3
      ck = 0;         // 最初から
     }
     else{           // 同じ状態継続
      if(tm_dswck == 0){    // 100ms経過
       dsw_rot = d;      // 新状態
       f_dswrotx = 1;     // 変化ありを知らせる
       ck = 0;
      }
     }
     break;
   }
 }

この処理のまずいところを説明しておきます。

関数rddsw()はデジタルスイッチの値を返します。
★1でその値の変化を見つけて、★2で変化した値を
一時保存しています。
★3では100ms間、値が安定することを見ています。

ここでの★1と★2のタイミングが問題。
普通は、両方とも同じ値です。
しかし、★1のタイミングでパルス的なノイズの飛び
込みがあると、★1と★2の値が異なってしまいます。
★2と★3はノイズが無い前回値です。

つまり、値に変化が無いのに処理が進んでしまい、
変化が無かったのに「変化ありフラグがオン」して
しまうのです。

スイッチを人が操作したときは、結果的に同じ値
で「変化あり」になっても、操作した結果ですので
違和感はありません。
ところがノイズだと、何もしていないのに、紙送り
速度が変わったようだけど、前と同じ設定やんと
なってしまいます。

ということで、この処理でのスイッチ読み出し値は、
途中で変化しないようにしなければなりません。
そこで、次のように、ルーチンの先頭で1回だけ読み
込むだけにします。
処理内でスイッチの値が変化しないようにしておけば
解決します。


※修正後
 void ckrotdsw(void)
 {
 static byte ck = 0;
 static byte d;
 byte r;
   r = rddsw();          // DSW 設定値 ★1
   switch(ck){
    case 0:
     if(dsw_rot != r){     // 変化あり
      d = r;          // 変化した状態
      tm_dswck = 100;     // 100ms
      ck++;
     }
     break;
    case 1:
     if(d != r){        // また変わった
      ck = 0;         // 最初から
     }
     else{           // 同じ状態継続
      if(tm_dswck == 0){    // 100ms経過
       dsw_rot = d;      // 新状態
       f_dswrotx = 1;     // 変化ありを知らせる
       ck = 0;
      }
     }
     break;
   }
 }

これで、ノイズが入って「変化が無いのに変化あり」
となってしまうことが避けられます。


※補足
・ckrotdswはメインループで毎回実行
・tm_dswckはタイマー割り込みでダウンカウント
・メイン処理としてf_dswrotxをチェックし、スイッチの
 値に変化があったことを検出している
   (変化があると、紙送り速度をプリント)

Arduino IDE 「PROGMEM」について




2015年10月6日 12時01分 | 記事へ | コメント(1) | トラックバック(0) |
| ・電子回路工作 |
トラックバックURL:http://blog.zaq.ne.jp/igarage/trackback/4249/
※ブログ管理者が承認するまで表示されません
何かむずかしそう。昔すこし勉強しました。
コメントを記入  
お名前(必須)
 
パスワード:
 
メール:
 
URL:
 
非公開:  クッキーに保存: 
※非公開にチェックを入れると、管理者のみにコメントが届きます。
ブログの画面には表示されません。
captcha


※画像に表示されている文字を入力してください(半角・大文字/小文字の区別なし)。
文字が読みづらい場合はこちらをクリックしてください。
小文字 太字 斜体 下線 取り消し線 左寄せ 中央揃え 右寄せ テキストカラー リンク