/************************************/ /* 出窓用センサー回路3 */ /* "DEMADO_SENS3.C" */ /************************************/ // 2023-08-18 // ATtiny13Aを使用 // fuse -fh11111001 (F9) -fl01111010 (7A) // 9.6MHzクロック // 2015-01-28 開始 // I/Oポート // PB0 out - 割り込みタイミングチェック用出力 // PB1 in 焦電センサー入力 Hでオン // PB2 out リレー出力 Hでオン // PB3 in A/D3 VR1入力 検出時間設定 // PB4 in A/D2 VR2入力 駆動時間設定 // PB5 - /RESET /***** インクルード *****/ #include #include #include #include /***** ヒューズ *****/ FUSES = { .high = 0b11111001, // F9 // ||||+---- RSTDIS off // ||++----- BOD 4.3V // |+------- DWEN off // +-------- SELFPG off .low = 0b01111010, // 7A // ||||||++---- CKSEL 9.6MHz // ||||++------ SUT start up // |||+-------- CKDIV 1/1 // ||+--------- WDTON off // |+---------- EESAVE off // +----------- SPIEN on }; /***** 配列のデータ数を返すマクロ *****/ #define DIMSIZ(a) (sizeof(a)/sizeof(*a)) /***** マクロ *****/ #define nop() asm volatile("nop;") // NOPコード /***** I/Oポート定義 *****/ #define PO_TMICK (1 << PB0) // タイマー割り込みチェック #define PI_SENS (1 << PB1) // 焦電センサー入力 Hでオン #define PO_RELAY (1 << PB2) // リレー出力 // 出力実行 #define RELAY_ON (PORTB |= PO_RELAY) // リレー出力 #define RELAY_OFF (PORTB &= ~PO_RELAY) #define TMICK_ON (PORTB |= PO_TMICK) // タイミングチェック #define TMICK_OFF (PORTB &= ~PO_TMICK) // 入力実行 #define SENS_CK (PINB & PI_SENS) // センサー入力 // Hでオン /********************************/ /* グローバルデータ */ /********************************/ /***** タイマーデータ *****/ volatile uint8_t tm_10ms; // 10mSタイマー volatile uint8_t f_10ms; // 10mS経過フラグ volatile uint16_t tm_sens; // センサーチェックタイマー // 10mSごとにカウント /***** A/Dデータ *****/ // 2ch分のデータ VR1,VR2 // 10bit 0~1023 // 注意:割り込みで書き込むのでメインで読む時は //  割込禁止にしてから処理すること volatile uint16_t ad_data[2]; // A/D 平均結果 volatile uint16_t ad_add[2]; // A/D 平均加算値 volatile uint8_t ad_ch; // A/D変換チャンネル // 0:A/D ch3 VR1 // 1:A/D ch2 VR2 volatile uint8_t ad_cnt; // A/D 平均回数 // 64回 (max 16bit) /********************************/ /* A/D変換割り込み */ /********************************/ /***** A/D変換 MUX テーブル *****/ uint8_t const ad_muxtbl[] PROGMEM = { 0b00000011, // 0 ch3 : VR1 0b00000010, // 1 ch2 : VR2 // || ++--- MUX // |+-------- ADLAR // +--------- REFS : VCC }; /***** A/D変換割り込み処理 *****/ // 変換開始は1msタイマー割り込み内で // 1ms×64回平均×2ch ISR(ADC_vect) { uint16_t d; TMICK_ON; // (!!!) PB0 5pin d = (uint16_t)ADCL; // A/D変換結果 d |= ((uint16_t)(ADCH & 0x03) << 8); ad_add[ad_ch] += d; // 平均値加算 ad_ch++; // 次ch if(ad_ch >= DIMSIZ(ad_muxtbl)){ // ch3,ch2 ad_ch = 0; ad_cnt++; // 加算回数+1 if(ad_cnt >= 64){ // 64回? ad_cnt = 0; ad_data[0] = ad_add[0] / 64; // VR1 ad_data[1] = ad_add[1] / 64; // VR2 ad_add[0] = 0; ad_add[1] = 0; } } ADMUX = pgm_read_byte(&ad_muxtbl[ad_ch]); // 次変換MUXセット TMICK_OFF; // (!!!) } /********************************/ /* タイマー0割り込み */ /********************************/ /***** タイマー0割り込み処理 *****/ // 1mSサイクル ISR(TIM0_COMPA_vect) { static uint8_t cnt10 = 0; // 10mSカウント TMICK_ON; // (!!!) PB0 5pin // 内蔵A/D ADCSRA |= (1 << ADSC); // A/D変換開始 // 10mSカウント cnt10++; if(cnt10 >= 10){ // 10ms cnt10 = 0; if(tm_10ms) tm_10ms--; // 10mSタイマー f_10ms = 1; // 10mS経過フラグ } // A/D読み出しデータのテスト #if 0 if(tm_sens >= ad_data[0]) RELAY_ON; tm_sens++; if(tm_sens > 1024){ tm_sens = 0; RELAY_OFF; // リレー駆動のdutyをチェック } #endif // 割込リターン TMICK_OFF; // (!!!) } /****************************/ /* 初期化 */ /****************************/ /***** 初期化 *****/ void initio(void) { PORTB = 0b00000000; // pull up DDRB = 0b00000101; // |||||+---- PB0 out - // ||||+----- PB1 in 焦電センサー入力 Hでオン // |||+------ PB2 out リレー出力 // ||+------- PB3 in A/D3 VR1入力 // |+-------- PB4 in A/D2 VR2入力 // +--------- PB5 - /RESET // タイマー0 クロック:9.6MHz TCCR0A = 0b00000010; // ++--- WGM CTC TCCR0B = 0b00000011; // |+++--- CS 1/64 150kHz // +------ WGM02 CTC OCR0A = 150-1; // 1mS TIMSK0 = 0b00000100; // ||+---- TOIE0 // |+----- OCIE0A コンペアマッチA // +------ OCIE0B // A/D DIDR0 = 0b00011000; // デジタル禁止 // |||+----- A/D1 // ||+------ A/D3 VR1 // |+------- A/D2 VR2 // +-------- A/D0 ADCSRA = 0b10001110; // | |+++--- CLK 1/64 125kHz // | +------ ADIE // +---------- ADEN ADCSRB = 0b00000000; // +++--- free run ADMUX = 0b00000011; // || ++--- MUX : ch3 // |+-------- ADLAR // +--------- REFS : VCC } /************************************/ /* VR1、VR2読み出し */ /************************************/ /***** VR1読み出し *****/ // 検出on確定用 // ad_data[0] / 4 + 1 // 0.01~2.56sec uint16_t readvr1(void) { uint16_t d; cli(); // いったん割り込み禁止 d = ad_data[0]; // 0~1023 sei(); // 割り込み再開 d = 1 + (d / 4); // 1~256 return d; } /***** VR2読み出し *****/ // on保持時間 // ad_data[1] * 3 + 31 // 0.31~31.00sec uint16_t readvr2(void) { uint16_t d; cli(); // いったん割り込み禁止 d = ad_data[1]; // 0~1023 sei(); // 割り込み再開 d = 31 + (d * 3); // 31~3100 return d; } /************************************/ /* センサー検出処理実行 */ /************************************/ /***** 実行区分 *****/ uint8_t sens_exc; // センサー検出処理区分 #define SENS_ON 2 // オン安定チェック /***** 開始 *****/ // A/D安定時間待ちタイマーをセット void sensinit(void) { tm_10ms = 50; // 0.5秒待ち sens_exc++; // next } /***** A/D安定時間待ち *****/ void senswait(void) { if(tm_10ms == 0) sens_exc++; // タイムアップで次へ } /***** センサー入力オンチェック *****/ // オンを待ってリレー出力をオン // 0.1~2.56sec void senson(void) { if(f_10ms){ // 10msサイクル f_10ms = 0; if(SENS_CK){ // センサー入力オン tm_sens++; if(tm_sens >= readvr1()){ // VR1 比較 RELAY_ON; // 出力オン tm_sens = readvr2(); // VR2 セット sens_exc++; // next } } else{ // センサー入力オフ if(tm_sens) tm_sens--; // 0までダウンカウントする } } } /***** センサー入力オフチェック *****/ // オフ継続をチェックしてリレーをオフ // 0.31~31.0sec void sensoff(void) { if(f_10ms){ // 10msサイクル f_10ms = 0; if(SENS_CK){ // センサー入力オン tm_sens = readvr2(); // VR2 セット } else{ // センサー入力オフ if(tm_sens == 0){ // タイムアップ RELAY_OFF; // 出力オフ sens_exc = SENS_ON; // オン待ちに } else{ tm_sens--; // ゼロまでカウントダウン } } } } /***** センサー検出実行 *****/ typedef void (*JOB)(void); // 実行関数テーブル JOB const jobtbl[] PROGMEM = { sensinit, // 0 開始 senswait, // 1 A/D安定時間待ち senson, // 2 * オン安定チェック sensoff, // 3 オフチェック }; // 実行する実体関数 void sensexc(void) { JOB jj; jj = (JOB)pgm_read_word(&jobtbl[sens_exc]); // 実行テーブル jj(); // 実行 } /************************************/ /* Main実行 */ /************************************/ /***** Main *****/ int main(void) { initio(); // I/O初期化 sei(); // 割込許可 // loop while(1){ sensexc(); // センサー検出処理実行 } } /*===== end of "DEMADO_SENS3.C" =====*/