/************************************************/ /* ナダ電子 AS-289R */ /* プリンタシールドを使ったチャートレコーダ */ /* prnsld03 */ /************************************************/ // 2014-04-21 下間憲行 // P_ZERがチャートのゼロ点位置 要調整 // ※トランジスタ技術2014年6月号に掲載 // 2015-10-06 PROGMEMの書式を変更 // 2016-08-14 送り速度設定をDSWをやめて // Fast/Slowのプッシュスイッチに // 2024-07-02 イベントマーカ機能を追加 // チャートの上端に2入力のイベントを記録 // スイッチ操作 // SW1 Start/Stop (offでstart状態) // SW2 CH1 on/off (offでon状態) // SW3 CH2 on/off (offでon状態) // SW4 紙送り Fast // SW5 紙送り Slow // ポート // PB0 IO8 in SW4 紙送り速度 Fast (onでL) // PB1 IO9 in SW3 紙送り速度 Slow (〃) // PB2 IO10 in SW2 CH1 on/off (offで動作) // PB3 IO11 in SW3 CH2 on/off (〃) // PB4 IO12 out - // PB5 IO13 out LED (!!!) テストパルス loop実行時間 // PC0 AD0 in A/D0 CH1アナログ入力 // PC1 AD1 in A/D1 CH2アナログ入力 // PC2 AD2 in EVENT1 CH1 イベントマーカー入力(onでL) // PC3 AD3 in EVENT2 CH2 イベントマーカー入力(onでL) // PC4 AD4 in A/D値テスト印字 // PC5 AD5 out - // PD0 IO0 in RXD // PD1 IO1 out TXD → プリンタシールドへのシリアルデータ // PD2 IO2 out (!!!) テストパルス 0.5ms割り込み // PD3 IO3 out (!!!) テストパルス A/D割り込み // PD4 IO4 out - // PD5 IO5 out - // PD6 IO6 in SW1 Start/Stop (offで動作) // PD7 IO7 out - // タイマー2 0.5msタイマー割り込み /***** ライブラリ *****/ // ※includeしなくてもOK // #include "wiring_private.h" // sbi,cbi命令用 // #include // 0.5msに対応していないので使わない // #include // #include // PROGMEME用 // #include // 割り込み用 // #include /***** マクロ *****/ #define DIMSIZ(a) (sizeof(a) / sizeof(*a)) // 配列の大きさ /***** ピン制御マクロ *****/ // SW入力 on,offチェック #define INP_START ( PIND & (1 << PD6)) // PD6 SW1 Start/Stop #define INP_CH1 ( PINB & (1 << PB2)) // PB2 SW2 CH1 on/off #define INP_CH2 ( PINB & (1 << PB3)) // PB3 SW3 CH2 on/off #define INP_FAST ((~PINB) & (1 << PB0)) // PB0 SW4 Fast (Lでon) #define INP_SLOW ((~PINB) & (1 << PB1)) // PB1 SW5 Slow #define INP_EVENT1 ((~PINC) & (1 << PC2)) // PC2 イベントマーカーch1入力 #define INP_EVENT2 ((~PINC) & (1 << PC3)) // PC3 イベントマーカーch1入力 #define INP_ADTEST ((~PINC) & (1 << PC4)) // PC4 A/D test // タイミングチェックパルス出力 #define PD2_H (PORTD |= (1 << PD2)) // PD2 (D2) 0.5ms割り込み #define PD2_L (PORTD &= ~(1 << PD2)) #define PD3_H (PORTD |= (1 << PD3)) // PD3 (D3) A/D割り込み #define PD3_L (PORTD &= ~(1 << PD3)) #define PB5_H (PORTB |= (1 << PB5)) // PB5 (D13) #define PB5_L (PORTB &= ~(1 << PB5)) #define PB5_X (PINB |= (1 << PB5)) // トグル /***** EEPROMデータ *****/ byte EEMEM ep2_chk; // 先頭にダミーデータ (0x5A) byte EEMEM ep2_speed; // 紙送り速度 0~DIMSIZ(feedpls) /******************************/ /* イメージプリント処理 */ /******************************/ /***** プリントデータバッファ *****/ #define P_BYTE 48 // 1行バイト数 384ドットのバイト数 byte p_bff[P_BYTE]; // 1行分のバッファ // これをプリンタに送出 /***** イメージプリントコマンド *****/ const byte pcmd_bitimg[] PROGMEM ={ 0x1c, 0x2a, 0x63, // イメージ登録+プリント 0x00, 0x01, // 1line }; /***** 1ラインバッファ出力 *****/ void prnpbff(void) { byte i; for(i = 0; i < sizeof(pcmd_bitimg); i++){ // コマンド出力 Serial.write(pgm_read_byte(&pcmd_bitimg[i])); } for(i = 0; i < P_BYTE; i++){ // バッファ出力 Serial.write(p_bff[i]); // 1行 } } /***** ビットイメージデータ *****/ const byte bit_on[] PROGMEM ={ 0b10000000, // 0 0b01000000, // 1 0b00100000, // 2 0b00010000, // 3 0b00001000, // 4 0b00000100, // 5 0b00000010, // 6 0b00000001, // 7 }; /***** ビットイメージデータ(左側) *****/ const byte bit_on1[] PROGMEM ={ 0b11111111, // 0 0b01111111, // 1 0b00111111, // 2 0b00011111, // 3 0b00001111, // 4 0b00000111, // 5 0b00000011, // 6 0b00000001, // 7 }; /***** ビットイメージデータ(右側) *****/ const byte bit_on2[] PROGMEM ={ 0b10000000, // 0 0b11000000, // 1 0b11100000, // 2 0b11110000, // 3 0b11111000, // 4 0b11111100, // 5 0b11111110, // 6 0b11111111, // 7 }; /***** ドットセット *****/ // 左上 0,0  383,0 右上 // 左下 0,1  383,1 右下 void pset(int x) { p_bff[x / 8] |= pgm_read_byte(&bit_on[x % 8]); // 1ビットオン } /***** プリントバッファクリア *****/ void clrpbff(void) { memset(p_bff, 0, sizeof(p_bff)); } /**********************************/ /* プリント、紙送り処理 */ /**********************************/ /***** 紙送りデータ *****/ #define CM_MS 125 // 5秒/1cmの基準パルス // 5秒/80パルス = 0.0625秒 // 0.5ms割り込みで125回 volatile byte tm_feed; // 紙送り基準タイマー // 1msでアップカウント volatile word feed_cnt; // feedplsと比較して1ピッチ紙送り volatile byte f_feed; // 紙送りフラグ // タイマー割り込み内でオン byte feed_8; // 紙送り1mmチェック // 1mmで8パルス word feed_mm; // 紙送りmm単位の長さ // 00~999mmを繰り返す byte f_swstart; // SW_STARTの状態 byte f_swston; // START オンのエッジ byte f_swstoff; // START オフのエッジ byte feed_speed; // 紙送り速度 0が最速 // sw_fast,sw_slowで設定 byte f_speedx; // DSWデータが変化したときにオン volatile byte tm_swstck; // SW_STARTチェック用タイマー // fast,slow SW チェック byte f_fast; // FAST on byte f_slow; // SLOW on volatile byte tm_swfsck; // fast,slow チェック用タイマー // イベントマーカー byte f_event1; // INP_EVENT1をチェック byte f_event2; // INP_EVENT2をチェック // 1lineプリントで上端にマーク /***** 紙送り速度 *****/ // 5秒/cmの紙送りパルス(62.5ms)を単位として指定 // feed_speedなら0~9が範囲 // sw_fast,slowで設定 const word feedpls[] PROGMEM ={ 1, // 0 5秒/cm 2, // 1 10秒/cm 6, // 2 30秒/cm 12, // 3 1分/cm 24, // 4 2分/cm 60, // 5 5分/cm 120, // 6 10分/cm 360, // 7 30分/cm 720, // 8 1時/cm 1440, // 9 2時/cm 4320, // 10 6時/cm 8640, // 11 12時/cm fast,slow SWでの拡張↓ 17280, // 12 1日/cm }; /***** 紙送り速度表示データ *****/ const char spd0[] PROGMEM = "5sec/cm"; const char spd1[] PROGMEM = "10sec/cm"; const char spd2[] PROGMEM = "30sec/cm"; const char spd3[] PROGMEM = "1min/cm"; const char spd4[] PROGMEM = "2min/cm"; const char spd5[] PROGMEM = "5min/cm"; const char spd6[] PROGMEM = "10min/cm"; const char spd7[] PROGMEM = "30min/cm"; const char spd8[] PROGMEM = "1hour/cm"; const char spd9[] PROGMEM = "2hour/cm"; const char spd10[] PROGMEM = "6hour/cm"; const char spd11[] PROGMEM = "12hour/cm"; const char spd12[] PROGMEM = "1day/cm"; const char * const spdmsg[] PROGMEM = { spd0, spd1, spd2, spd3, spd4, spd5, spd6, spd7, spd8, spd9, spd10, spd11, spd12, }; // 用紙スケール 0~383の384ドット // | . | 0.5mm // | . . . . . . . . . | 1mm // | . . . . . . . . . . . . . . . . . . . | 10mm #define P_SCL 382 // スケール上限 #define P_ZER 7 // スケール ゼロ位置(左端) #define P_PIT 36 // 1mmごと 1/10スケール #define P_CEN (P_ZER + (5 * P_PIT)) // 中央 #define P_FUL (P_ZER + (10 * P_PIT)) // 右端 /***** スケールを描画 *****/ void pscale(void) { int i; pset(P_ZER); // 左端:ゼロ点 pset(P_FUL); // 右端 if((feed_8 == 0) && ((feed_mm % 10) == 0)){ // 10mmピッチ for(i = 0; i < P_BYTE; i++){ // 1cmのライン p_bff[i] = 0b11001100; } } else if(feed_8 == 0){ // 1mmピッチ for(i = P_ZER + P_PIT; i < P_FUL; i+=P_PIT){ pset(i); } } else if((feed_8 % 4) == 0){ // 0.5mmピッチ pset(P_CEN); // 中央の点 } } /***** イベントマーカー描画 *****/ // 0011100 7ドットの範囲で3ドットをon void pevent(void) { if(f_event1){ // イベントマーカー ch1 f_event1 = 0; p_bff[P_BYTE-3] &= 0b00001111; // 360~ p_bff[P_BYTE-3] |= 0b11000000; // マーク p_bff[P_BYTE-4] &= 0b11111000; // 352~ p_bff[P_BYTE-4] |= 0b00000001; // マーク } if(f_event2){ // イベントマーカー ch2 f_event2 = 0; p_bff[P_BYTE-4] &= 0b00000001; // 352~ p_bff[P_BYTE-4] |= 0b00111000; // マーク } } /******************************/ /* A/D処理 */ /******************************/ /**** A/D データ *****/ // AD0 ch1データ入力 // AD1 ch2データ入力 volatile byte ad_ch; // A/D変換チャンネル // 0,1 : min,max処理 // AD0,AD1 データ (ch1,ch2,データ) volatile int ad_data[2]; // A/D変換データ 0~1023 volatile int ad_max[2]; // A/D max volatile int ad_min[2]; // A/D min // A/D min,max更新フラグ volatile byte f_adnext; // A/Dmin,maxを次データに // メイン側でオンして割り込みでクリア /***** A/D 変換チャンネル指定 *****/ const byte ad_mux[] PROGMEM ={ 0b11000000, // ch0 入力1 0b11000001, // ch1 入力2 // ||| ++++---- MUX ch // ||+--------- ADLAR // ++---------- REFS 内部基準電圧1.1V }; /***** A/D割り込み処理 *****/ // タイマー割り込みでA/D変換開始 // 1msで2chの変換を終わる // 0,1は入力データ // min,max判定のためこの処理の中で ISR(ADC_vect) { int d; PD3_H; // (!!!)test d = (word)ADCL; // d |= (ADCH & 0x03) << 8; // 符号なしで 0~3FF // 測定値 ad_data[ad_ch] = d; // データを保存 if(d > ad_max[ad_ch]) ad_max[ad_ch] = d; // max if(d < ad_min[ad_ch]) ad_min[ad_ch] = d; // min // 2ch変換完了 ad_ch++; // 次ch if(ad_ch >= sizeof(ad_mux)){ // 2ch終了 ad_ch = 0; // ch0に戻す // AD0,1 : フラグがあれば次データに更新 if(f_adnext){ // 次変換データの処理 ad_max[0] = ad_min[0] = ad_data[0]; // ch1入力 ad_max[1] = ad_min[1] = ad_data[1]; // ch2入力 f_adnext = 0; } } PD3_L; } /******************************/ /* タイマー割り込み */ /******************************/ /***** タイマー値 *****/ volatile byte tm_1ms; // 1msダウンカウントタイマー max 255ms /***** タイマー2 0.5mS割り込み *****/ // A/Dに対して変換指令 ISR(TIMER2_COMPA_vect) { static byte tc = 0; // 1msカウント PD2_H; // (!!!)test // 0.5ms 紙送りタイマー if(f_swstart){ // start/stop SW, 記録on状態 tm_feed++; // 1msアップカウント if(tm_feed >= CM_MS){ // 63.5msが基準 tm_feed = 0; feed_cnt++; // 送りカウンタ if(feed_cnt >= pgm_read_word(&feedpls[feed_speed])){ // DSW設定値 feed_cnt = 0; f_feed = 1; // 紙送りフラグをオン } } } // 0.5msを2回カウントして1msに tc++; // 0,1 if(tc >= 2){ // 1ms tc = 0; // 1ms計時処理(ダウンカウント) if(tm_1ms) tm_1ms--; if(tm_swstck) tm_swstck--; // start/stop SW if(tm_swfsck) tm_swfsck--; // fast/slow SW } // A/D変換 データの読み出しは変換完了割り込みで ADMUX = pgm_read_byte(&ad_mux[ad_ch]); // ch指定 ADCSRA |= (1 << ADSC); // A/D変換開始 PD2_L; // (!!!)test } /****************************************/ /* スイッチ入力チェック */ /****************************************/ /***** START/STOPスイッチチェック *****/ // on,offのエッジを見つける void ckswstart(void) { static byte ck = 0; byte d; if(INP_START) d = 1; // START SW (Hでstart) else d = 0; switch(ck){ case 0: if(d != f_swstart){ // 変化あり tm_swstck = 10; // 10ms ck++; } break; case 1: if(d == f_swstart){ // 元に戻った ck = 0; } else{ // 変化継続 if(tm_swstck == 0){ // 10ms経過 f_swstart = d; // 新状態 if(d) f_swston = 1; // onのエッジ else f_swstoff = 1; // offのエッジ ck = 0; // 変化チェックへ } } break; } } /***** 紙送りFAST/SLOW スイッチチェック *****/ // onのエッジを見つける // feed_speedを更新 void ckswfs(void) { static byte ck = 0; // 実行区分 static byte od = 0; // チェックデータ byte d; // bit 0:FAST,1:SLOW d = 0; if(INP_FAST) d |= 1; // FAST SW on if(INP_SLOW) d |= 2; // SLOW SW on switch(ck){ case 0: // 最初のon待ち if(d != 0){ // どちらかon? tm_swfsck = 10; // 10ms od = d; // チェックデータ保存 ck++; } break; case 1: // 安定待ち if(d != od){ // 変化した ck = 0; // 最初から } else{ // 継続 if(tm_swfsck == 0){ // 10ms経過 if(d & 1) f_fast = 1; // fast on 確定 if(d & 2) f_slow = 1; // slow on 確定 tm_swfsck = 20; // 20ms ck++; // オフを待つ } } break; case 2: // オフするまで待つ if(d == 0){ // オフ継続 if(tm_swfsck == 0){ // タイムアップ ck = 0; // on待ちに } } else{ // まだオンしている tm_swfsck = 20; // 20ms } break; } // fast,slowのonエッジでfeed_speedの値を変える if(f_fast){ // FAST on f_fast = 0; if(feed_speed > 0){ // 紙送りを早く (0が最速) feed_speed--; f_speedx = 1; // 変化ありを知らせる } } if(f_slow){ // SLOW on f_slow = 0; if(feed_speed < (DIMSIZ(feedpls) - 1)){ // 紙送りを遅く feed_speed++; f_speedx = 1; // 変化ありを知らせる } } } /******************************/ /* A/D 値スケーリング */ /******************************/ /***** A/D値からX位置を計算 *****/ // in a:A/D 0~1023 // ret X位置 0~380 int xpos(int a) { long x; x = (long)a * (long)P_SCL; // 用紙幅とスケーリング x /= 1024L; // 10bit if(x > P_SCL) x = P_SCL; if(x < 0) x = 0; return (int)x; } /***** グラフ描画 *****/ // x1,x2 座標 void pgrph(int x1, int x2) { #if 0 // psetでの描画 int a; if(x1 > x2){ a = x1; x1 = x2; x2 = a; } a = x1; for(a = x1; a <= x2; a++){ pset(a); } #else // 左・中・右に分けて描画 int i, a1,b1, a2,b2; if(x1 > x2){ // x2を大きく a1 = x1; x1 = x2; x2 = a1; } if(x1 == x2) x2+=1; // 同じ点なら左へ拡張 // アドレスとビット位置 a1 = x1 / 8; b1 = x1 % 8; a2 = x2 / 8; b2 = x2 % 8; // 同じアドレスか if(a1 == a2){ // 同じアドレス p_bff[a1] |= pgm_read_byte(&bit_on1[b1]) & pgm_read_byte(&bit_on2[b2]); // 左右ビットをANDしてOR } else{ // 違うアドレス p_bff[a1] |= pgm_read_byte(&bit_on1[b1]); // 左 p_bff[a2] |= pgm_read_byte(&bit_on2[b2]); // 右ビット if((a2 - a1) > 1){ // 中間がある for(i = (a1 + 1); i < a2; i++){ // 間はFFで埋める p_bff[i] |= 0xff; } } } #endif } /***** 紙送り速度を出力 *****/ void prnspeed(void) { char s[16]; strcpy_P(s,(PGM_P)pgm_read_word(&spdmsg[feed_speed])); // 設定値 Serial.print(s); // 送り速度 Serial.write('\r'); // 印字と改行 } /**********************************/ /* キャラジェネ */ /**********************************/ /***** 数字 0~9 *****/ // 横16ドット 高8ドット 横向きで const word PROGMEM cg09[]={ // 0 0b0011111111111100, 0b0111111111111110, 0b1100000000000011, 0b1100000000000011, 0b1100000000000011, 0b1100000000000011, 0b0111111111111110, 0b0011111111111100, // 1 0b0000000000000000, 0b0000000000010000, 0b1100000000011100, 0b1111111111111111, 0b1111111111111111, 0b1100000000000000, 0b0000000000000000, 0b0000000000000000, // 2 0b1111000000011100, 0b1111100000011110, 0b1100110000000011, 0b1100011000000011, 0b1100001100000011, 0b1100000110000011, 0b1100000011111110, 0b1100000001111100, // 3 0b0011000000001100, 0b0111000000001110, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b1100001111000011, 0b0111111001111110, 0b0011111000111100, // 4 0b0000011110000000, 0b0000011111100000, 0b0000011001111000, 0b0000011000011100, 0b0000011000000110, 0b1111111111111111, 0b1111111111111111, 0b0000011000000000, // 5 0b0011000001111111, 0b0111000011111111, 0b1100000011000011, 0b1100000011000011, 0b1100000011000011, 0b1100000011000011, 0b0111111111000011, 0b0011111110000011, // 6 0b0011111111111100, 0b0111111111111110, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b0111111100000110, 0b0011111000000100, // 7 0b0000000000000011, 0b0000000000000011, 0b0000000000000011, 0b1111110000000011, 0b1111111110000011, 0b0000001111100011, 0b0000000001111111, 0b0000000000011111, // 8 0b0011111001111100, 0b0111111111111110, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b0111111111111110, 0b0011111001111100, // 9 0b0110000001111100, 0b0110000011111110, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b1100000110000011, 0b0111111111111110, 0b0011111111111100, }; /********************************/ /* 1cm単位プリント */ /********************************/ /***** 1cmピッチプリント用データ *****/ word p1cm_cg[2+8+2]; // 1cmピッチプリント用バッファ // 2:空白 8:データ 2:空白 // 10桁と1桁は別タイミングでプリント byte p1cm_ptr; // lineバッファへのコピー位置 byte p1cm_cnt; // コピーデータ数 // 0以外なら紙送りのタイミングで // グラフの右端にプリント /***** 紙送り1cmピッチプリント開始 *****/ // 1cmごとにプリント m:0~9 void prn1cmset(word m) { memcpy_P(p1cm_cg+2, &cg09[m * 8], 16); // 1桁 p1cm_cnt = 12; // 空白4ドット,データ8ドット p1cm_ptr = 0; // 先頭ライン } /***** 紙送り1cmピッチプリント実行 *****/ // lineバッファの右端(+45,+46,+47)にコピー void prn1cmexc(void) { p_bff[P_BYTE-1] = lowByte(p1cm_cg[p1cm_ptr]); // LSB CG 左端 p_bff[P_BYTE-2] = highByte(p1cm_cg[p1cm_ptr]); // MSB CG 1/2右 p_bff[P_BYTE-3] &= 0b11110000; // 364~367 p1cm_ptr++; // 次行へ p1cm_cnt--; // カウンタ -1 } /********************************/ /* ch番号プリント */ /********************************/ /***** ch番号プリント用データ *****/ word pch_cg[8]; // ch番号キャラジェネ byte pch_ptr; // lineバッファへのコピー位置 byte pch_cnt; // コピーデータ数 // 0以外なら紙送りのタイミングでプリント byte pch_pos; // 印字位置(0~47) /***** ch番号プリント開始 *****/ // x1:グラフ描画左端位置(min) x2:右端(max) void prnchset(int x1,int x2, byte ch) { memcpy_P(pch_cg, &cg09[ch * 8], 16); // 1桁 pch_cnt = 8; // データ8ドット pch_ptr = 0; // 先頭ライン if(x2 < 336){ // max位置 42コラム pch_pos = ((x2 | 0x0007) + 1) / 8; } else if(x1 >= 16){ // min位置 pch_pos = ((x1 & 0xfff8) - 16) / 8; } else{ pch_pos = 0; } } /***** ch番号プリント実行 *****/ // pch_posの位置にコピー void prnchexc(void) { p_bff[pch_pos+1] = lowByte(pch_cg[pch_ptr]); // LSB CG 左端 p_bff[pch_pos] = highByte(pch_cg[pch_ptr]); // MSB CG 1/2右 pch_ptr++; // 次行へ pch_cnt--; // カウンタ -1 } /************************************/ /* グラフ出力 */ /************************************/ /***** グラフデータプリント *****/ // 紙送り指令でプリント void prndata(void) { int i, x1, x2; int d_now[2]; // ad_data ch1,ch2 int d_max[2]; // max int d_min[2]; // min // A/D 測定データ ch1,ch2 clrpbff(); // プリントバッファをクリア pscale(); // スケールを描画 // ch1,ch2データ読み出しとプリント cli(); // 割り込み禁止にして for(i = 0; i < 2; i++){ // 2ch分のA/Dデータを取得 d_max[i] = ad_max[i]; // maxとmin d_min[i] = ad_min[i]; d_now[i] = ad_max[i] = ad_min[i] = ad_data[i]; // 新データに } sei(); // 割り込み再開 if(INP_CH1){ // ch1 on x1 = xpos(d_min[0]); // A/D min~max x2 = xpos(d_max[0]); pgrph(x1, x2); // グラフ if((feed_8 == 0) && ((feed_mm % 100) == 5)){ // 5mm位置 prnchset(x1, x2, 1); // ch番号 } } if(INP_CH2){ // ch2 on x1 = xpos(d_min[1]); // A/D min~max x2 = xpos(d_max[1]); pgrph(x1, x2); // グラフ if((feed_8 == 0) && ((feed_mm % 100) == 15)){ // 15mm位置 prnchset(x1, x2, 2); // ch番号 } } // 紙送りcmをプリント if((feed_8 == 4) && ((feed_mm % 10) == 8)){ // 8mmで10桁 prn1cmset((((feed_mm / 10) +1) % 100) / 10); } if((feed_8 == 1) && ((feed_mm % 10) == 0)){ // 0mmで1桁 prn1cmset((feed_mm / 10) % 10); // CGデータをセット } if(p1cm_cnt) prn1cmexc(); // cmプリント実行 // ch番号をプリント if(pch_cnt) prnchexc(); // ch番号プリント // イベントマーカー描画 pevent(); // ch1 ch2 上端に // バッファを出力 PB5_L; // (!!!)test PB5_H; if(INP_ADTEST){ // テスト印字 Serial.print(d_now[0]); // ch1データ Serial.print(" "); Serial.println(d_now[1]); // ch2データ } else{ // test sw オフなら prnpbff(); // バッファをプリント } // 紙送りピッチ feed_8++; // 紙送りピッチ if(feed_8 >= 8){ // 1mm feed_8 = 0; feed_mm++; if(feed_mm >= 1000){ feed_mm = 0; // 0~999mm } } } /******************************/ /* セットアップとループ */ /******************************/ /***** セットアップ *****/ void setup() { byte d; byte err = 0; // EEPROMエラーフラグ cli(); // 割り込み禁止 // I/Oイニシャル PORTB = 0b00101111; // data/pull up DDRB = 0b00110000; // port in/out指定 // |||||+---- PB0 IO8 in SW4 紙送り速度 Fast (onでL) // ||||+----- PB1 IO9 in SW3 紙送り速度 Slow (〃) // |||+------ PB2 IO10 in SW2 CH1 on/off (offで動作) // ||+------- PB3 IO11 in SW3 CH2 on/off (〃) // |+-------- PB4 IO12 out - // +--------- PB5 IO13 out LED (!!!) テストパルス loop実行時間 PORTC = 0b00011100; // data/pull up DDRC = 0b00100000; // portin/out指定 // |||||+---- PC0 AD0 in A/D0 CH1アナログ入力 // ||||+----- PC1 AD1 in A/D1 CH2アナログ入力 // |||+------ PC2 AD2 in EVENT1 CH1 イベントマーカー入力(onでL) // ||+------- PC3 AD3 in EVENT2 CH2 イベントマーカー入力(onでL) // |+-------- PC4 AD4 in A/D値テスト印字 (Lでテスト) // +--------- PC5 AD5 out - PORTD = 0b01000011; // data/pull up DDRD = 0b10111110; // portin/out指定 // |||||||+---- PD0 IO0 in (RXD シリアルデータ入力) // ||||||+----- PD1 IO1 out TXD シリアルデータ出力 // |||||+------ PD2 IO2 out (!!!) テストパルス 0.5ms割り込み // ||||+------- PD3 IO3 out (!!!) テストパルス A/D割り込み // |||+-------- PD4 IO4 out - // ||+--------- PD5 IO5 out - // |+---------- PD6 IO6 in SW1 Start/Stop (offで動作) // +----------- PD7 IO7 out - // A/D入力 ch0,ch1 DIDR0 = 0b00000011; // AD0,AD1 デジタル入力禁止 ADMUX = 0b00000000; // 内蔵A/D // ||| ++++---- ADC0 // ||+--------- ADLAR // ++---------- 外部 AREF接続 ADCSRA = 0b10001111; // |||||+++---- プリスケーラ 1/128 125kHz // ||||+------- ADIE 割込あり // |||+-------- ADIF // ||+--------- ADATE // |+---------- ADSC // +----------- ADEN 有効に // タイマー2 0.5ms割り込み TCCR2A = 0b00000010; // ++---- WGM21,20 CTCモード TCCR2B = 0b00000100; // |+++---- プリスケーラ1/64 // +------- WGM22 OCR2A = 125-1; // 16MHz / 64 / 125 = 2kHz TIMSK2 = 0b00000010; // +----- OCIE2A sei(); // 割込許可 // シリアル Serial.begin(9600); // 9600BPSで // 最初の測定 tm_1ms = 100; // 0.1sec待ち while(tm_1ms); f_adnext = 1; // A/D min,max更新指令 while(f_adnext){ // 2ms経過して更新完了までwait PB5_X; // (!!!)test } f_feed = 0; // 最初の紙送りを無視 // EEPROMチェック d = eeprom_read_byte(&ep2_chk); // チェックデータ(0x5A) if(d != 0x5A) err = 1; // 違えばエラー d = eeprom_read_byte(&ep2_speed); // 送り速度 0~12 if(d >= DIMSIZ(feedpls)) err = 1; // 最遅速度? エラー // エラーあれば初期値書込み if(err){ eeprom_write_byte(&ep2_chk, 0x5A); // チェックデータ eeprom_write_byte(&ep2_speed, 0); // 速度は0に } // EEPROM保存データ読み出し feed_speed = eeprom_read_byte(&ep2_speed); // 送り速度 0~ // START/STOP スイッチ if(INP_START) f_swstart = 1; // START SW on状態 else f_swstart = 0; if(f_swstart){ // start状態 prnspeed(); // 紙送り速度をプリント } } /***** ルー プ *****/ void loop() { // イベントマーカー入力チェック // 入力があればf_event1,f_event2に残す // 一瞬でもonがあればフラグをon if(INP_EVENT1) f_event1 = 1; if(INP_EVENT2) f_event2 = 1; // スイッチチェック ckswstart(); // STARTスイッチ状態 if(f_swston){ // onした f_swston = 0; prnspeed(); // 紙送り速度をプリント eeprom_update_byte(&ep2_speed, feed_speed); // 速度値EEPROMに f_adnext = 1; // A/D min,max更新指令 while(f_adnext); // 2ms経過して更新完了までwait feed_8 = 0; // 0mmから feed_mm = 0; f_feed = 0; // 紙送りをキャンセル p1cm_cnt = 0; // 1cmスケール印字をキャンセル pch_cnt = 0; // ch番号印字をキャンセル } if(f_swstoff){ // offした f_swstoff = 0; eeprom_update_byte(&ep2_speed, feed_speed); // 速度値をEEPROMに記録 } // 紙送り速度 ckswfs(); // fast/slow swチェック if(f_speedx){ // 変化があれば f_speedx = 0; prnspeed(); // 紙送り速度をプリント } // 紙送り,プリント if(f_feed){ // 紙送り指令 PB5_H; // (!!!)test f_feed = 0; prndata(); // グラフデータをプリント PB5_L; } } /*===== end of prnsld03 =====*/