プログラム内容
タイマー割り込みを使用してDuty比可変の矩形波を生成する(2ch)
Duty比が可変(周波数固定)で2ch分の矩形波を生成するプログラムを作成したいです。
→micros(), millis()を使った疑似的な割り込みでは無く、タイマー割り込みを用いて実装
→矩形波の頭は2chで同期
loopの中では、ADCでアナログ入力値を0-200,000[ms]に変換(正確に言うとDuty比90%を超えないように180,000[ms]まで)するプログラムが書いてあります。
演算した時間をタイマーに設定して、割り込み処理でON/OFFを切り替えたいです。
2chの矩形波を生成したいため、それぞれのON時間を比較してタイマーを設定するプログラムを作成しました。
発生している事象
Duty比が低い状態で、1サイクルの時間を無視して高速で切り替えが起きてしまう。
ソースコード
Arduino
1#include <TimerOne.h> 2 3const unsigned long Period = 200000; 4 5unsigned long Injector1_ON = 0; 6unsigned long Injector1_OFF = 0; 7unsigned long Injector2_ON = 0; 8unsigned long Injector2_OFF = 0; 9 10void setup(){ 11 pinMode(11, OUTPUT); 12 pinMode(12, OUTPUT); 13 Timer1.initialize(10000); 14 Timer1.attachInterrupt(Inj_ON); 15} 16 17//======================================================= 18//Inj1 longer 19void Inj_g1(){ 20 PORTB &= ~_BV(4); 21 Timer1.setPeriod(Injector1_ON); 22 Timer1.attachInterrupt(Inj_g1_OFF); 23} 24void Inj_g1_OFF(){ 25 PORTB &= ~_BV(3); 26 Timer1.setPeriod(Injector1_OFF); 27 Timer1.attachInterrupt(Inj_ON); 28} 29void Inj1_OFF(){ 30 PORTB &= ~_BV(3); 31 Timer1.setPeriod(Injector1_OFF); 32 Timer1.attachInterrupt(Inj_ON); 33} 34//======================================================= 35//Inj2 longer 36void Inj_g2(){ 37 PORTB &= ~_BV(3); 38 Timer1.setPeriod(Injector2_ON); 39 Timer1.attachInterrupt(Inj_g2_OFF); 40} 41void Inj_g2_OFF(){ 42 PORTB &= ~_BV(4); 43 Timer1.setPeriod(Injector2_OFF); 44 Timer1.attachInterrupt(Inj_ON); 45} 46void Inj2_OFF(){ 47 PORTB &= ~_BV(4); 48 Timer1.setPeriod(Injector2_OFF); 49 Timer1.attachInterrupt(Inj_ON); 50} 51//======================================================= 52//same 53void Inj_same(){ 54 PORTB &= ~_BV(3); 55 PORTB &= ~_BV(4); 56 Timer1.setPeriod(Injector1_OFF); 57 Timer1.attachInterrupt(Inj_ON); 58} 59//======================================================= 60 61void Inj_ON() { 62 63 Injector1_OFF = Period - Injector1_ON; 64 Injector2_OFF = Period - Injector2_ON; 65 66 if(Injector1_ON != 0){ 67 PORTB |= _BV(3); 68 } 69 70 if(Injector2_ON != 0){ 71 PORTB |= _BV(4); 72 } 73 74 if(Injector1_ON > Injector2_ON){ //Inj1 longer 75 Injector1_ON = Injector1_ON - Injector2_ON; 76 if(Injector2_ON == 0){ 77 Timer1.setPeriod(Injector1_ON); 78 Timer1.attachInterrupt(Inj1_OFF); 79 }else{ 80 Timer1.setPeriod(Injector2_ON); 81 Timer1.attachInterrupt(Inj_g1); 82 } 83 }else if(Injector1_ON < Injector2_ON){ //Inj2 longer 84 Injector2_ON = Injector2_ON - Injector1_ON; 85 if(Injector1_ON == 0){ 86 Timer1.setPeriod(Injector2_ON); 87 Timer1.attachInterrupt(Inj2_OFF); 88 }else{ 89 Timer1.setPeriod(Injector1_ON); 90 Timer1.attachInterrupt(Inj_g2); 91 } 92 }else if(Injector1_ON == Injector2_ON){ //Inj same 93 Timer1.setPeriod(Injector1_ON); 94 Timer1.attachInterrupt(Inj_same); 95 } 96} 97 98void loop(){ 99 /* 100 Injector1_ONとInjector2_ONを決定する処理 101 */ 102}
試したこと
ADCからの計算値が200,000[ms]を超えていない→確認済み
疑問点
そもそもタイマーの使い方が間違っている(適した使い方では無い)などあれば、教えて下さい。
補足情報
機器 : Arduino Uno Rev3
IDE : Arduino IDE 2.0.3
Lib : TimerOne
回答2件
あなたの回答
tips
プレビュー