前提・実現したいこと
ArduinoMegaでVVVFインバーターを作って、電車のモーター音を再現しています。
発生している問題・エラーメッセージ
analogRead()がずっと0を返しています。
該当のソースコード
Arduino
1/* 2 ピン配置 3 U 46 4 V 45 5 W 44 6 B.B 22 7*/ 8#include <avr/pgmspace.h> 9#include <avr/io.h> 10#include <avr/interrupt.h> 11#define plus +(1-Vout)*0.5 12#define threePhaseMODE 1 13#define tableLegth 256 14#define Shift 4194304 15#define opereator_type uint64_t 16const byte MaxFrequency = 250; 17volatile bool nutral_mode = false; 18volatile bool phaseMode, Hitachi; 19volatile byte macroMODE = 0; 20volatile byte Type = 1; 21/* 22 0 オリジナルGTO「オクターブ」 23 1 東洋IGBT (京急2100形) 24 2 日立IGBT (JRE531系) 25 3 SiemensIGBT (京急1000形) 26 4 SiemensGTO (京急1000形) 27 5 三菱GTO (JR209系) 28 6 SiemensIGBT (Desiro) 29 7 日立GTO (東急9000系) 30 8 日立GTO (西武6000系) 31 9 東洋IGBT (東京メトロ16000系) 32 10日立IGBT (JRE231系1000番台) 33 11東洋GTO (京急600形) 34 12オリジナルIGBT「オクターブ」 35 13オリジナルIGBT「ランダム変調」 36 14オリジナルGTO 「多変調」 37 15オリジナルGTO「大きな木」 38*/ 39boolean pulseMode, ModeBuffer; 40volatile double Kfrq, KfrqT, Vout, Vout_To, Hz, HzS, hzss, Discom, HzTo; 41volatile int pulse, PulseBuffer; 42float stepper, StepBuffer; 43int analog; 44double Vout_U, Vout_V, Vout_W; 45volatile uint16_t U, V, W, Top, Top2; 46volatile int32_t SynU, SynV, SynW; 47int RANDOMT; 48bool H, SendTrigger; 49const volatile uint8_t U_table[] PROGMEM = {/*sinU相*/}; 50const volatile uint8_t V_table[] PROGMEM = {/*sinV相*/}; 51const volatile uint8_t W_table[] PROGMEM = {/*sinW相*/}; 52 53const volatile bool sqU_table[] PROGMEM = {/*矩形U相*/}; 54const volatile bool sqV_table[] PROGMEM = {/*矩形V相*/}; 55const volatile bool sqW_table[] PROGMEM = {/*矩形W相*/} 56 57const volatile uint8_t Mu_table[] PROGMEM = {/*広域3パルス比較波U相*/}; 58const volatile uint8_t Mv_table[] PROGMEM = {/*広域3パルス比較波V相*/}; 59const volatile uint8_t Mw_table[] PROGMEM = {/*広域3パルス比較波W相*/}; 60opereator_type sin_operator, SinBuffer; 61opereator_type sin_operator_adder; 62volatile char soundwave; 63 64const byte XPulse_table_U[2][28][114] PROGMEM = {/*同期モードテーブルU相*/}; 65const byte XPulse_table_W[2][28][114] PROGMEM = {/*同期モードテーブルV相*/}; 66const byte XPulse_table_V[2][28][114] PROGMEM = {/*同期モードテーブルW相*/}; 67 68#define Ut pgm_read_byte_near(&sqU_table[(sin_operator/Shift)]) 69#define Vt pgm_read_byte_near(&sqV_table[(sin_operator/Shift)]) 70#define Wt pgm_read_byte_near(&sqW_table[(sin_operator/Shift)]) 71#define Mut pgm_read_byte_near(&Mu_table[(sin_operator/Shift)]) 72#define Mvt pgm_read_byte_near(&Mv_table[(sin_operator/Shift)]) 73#define Mwt pgm_read_byte_near(&Mw_table[(sin_operator/Shift)]) 74 75void setVout(uint8_t SoundType) { 76 //省略 77} 78void setKfrq(uint8_t SoundType) { 79 //省略 80} 81void setType() { 82 Type += 1; 83 Type = Type % 17; 84} 85void Sp_Up(void) {//周波数あげる 86 macroMODE = 0; 87 if (Vout < Vout_To) { 88 Vout += 0.001; 89 90 91 nutral_mode = true; 92 } else { 93 94 HzS = hzss; 95 96 nutral_mode = false; 97 } 98} 99void Sp_Dn(void) {//周波数下げ下げマン 100 macroMODE = 1; 101 if (Vout < Vout_To) { 102 Vout += 0.001; 103 104 nutral_mode = true; 105 } else { 106 if (Hz > 0) { 107 HzS = hzss * -1; 108 } else { 109 HzS = 0; 110 } 111 nutral_mode = false; 112 } 113} 114void SerialSendToMain(uint8_t SenderNum, uint8_t SendContent) {//デバッグ用 115 if (!SendTrigger) { 116 Serial.flush(); 117 Serial.write(SenderNum); 118 SendTrigger = true; 119 } else { 120 if (Serial.available() >= 1) { 121 if (Serial.read() == SenderNum) { 122 Serial.write(SendContent); 123 SendTrigger = false; 124 } 125 } 126 } 127} 128//タイマ割り込み 129ISR(TIMER2_COMPA_vect) {//SINオペレーター更新 130 sin_operator += (opereator_type)(sin_operator_adder); 131 sin_operator &= (tableLegth * Shift) - 1; 132} 133ISR(TIMER4_COMPA_vect) {//速度制御 134 Hz += HzS * 10; 135} 136ISR(TIMER3_COMPA_vect) {//1パルス 137 PORTL = (Ut * 8) | (Vt * 16) | (Wt * 32); 138} 139ISR(TIMER5_CAPT_vect) {//マルチパルス 140 sin_operator += (opereator_type)(sin_operator_adder); 141 sin_operator &= (tableLegth * Shift) - 1; 142 stepper = sin_operator / sin_operator_adder; 143 if ((int)stepper % 2 == 0)sin_operator += (opereator_type)(sin_operator_adder); 144 SynU = (Top * (((pgm_read_byte_near(&XPulse_table_U[Hitachi][(int)((pulse - 3) * 0.5)][(int)stepper]) * Vout) / 256)plus)); 145 SynV = (Top * (((pgm_read_byte_near(&XPulse_table_V[Hitachi][(int)((pulse - 3) * 0.5)][(int)stepper]) * Vout) / 256)plus)); 146 SynW = (Top * (((pgm_read_byte_near(&XPulse_table_W[Hitachi][(int)((pulse - 3) * 0.5)][(int)stepper]) * Vout) / 256)plus)); 147 148 OCR5A = (SynU < Top && SynU > 0) * SynU + (SynU > Top) * Top; 149 OCR5B = (SynV < Top && SynV > 0) * SynV + (SynV > Top) * Top; 150 OCR5C = (SynW < Top && SynW > 0) * SynW + (SynW > Top) * Top; 151 TCCR5A = 0b10101000; 152} 153ISR(TIMER5_OVF_vect) {//マルチパルス 154 sin_operator += (opereator_type)(sin_operator_adder); 155 sin_operator &= (tableLegth * Shift) - 1; 156 stepper = sin_operator / sin_operator_adder; 157 if ((int)stepper % 2 == 1)sin_operator += (opereator_type)(sin_operator_adder); 158 SynU = (Top * (((pgm_read_byte_near(&XPulse_table_U[Hitachi][(int)((pulse - 3) * 0.5)][(int)stepper]) * Vout) / 256)plus)); 159 SynV = (Top * (((pgm_read_byte_near(&XPulse_table_V[Hitachi][(int)((pulse - 3) * 0.5)][(int)stepper]) * Vout) / 256)plus)); 160 SynW = (Top * (((pgm_read_byte_near(&XPulse_table_W[Hitachi][(int)((pulse - 3) * 0.5)][(int)stepper]) * Vout) / 256)plus)); 161 162 OCR5A = (SynU < Top && SynU > 0) * SynU + (SynU > Top) * Top; 163 OCR5B = (SynV < Top && SynV > 0) * SynV + (SynV > Top) * Top; 164 OCR5C = (SynW < Top && SynW > 0) * SynW + (SynW > Top) * Top; 165 TCCR5A = 0b10101010; 166} 167ISR(TIMER5_COMPA_vect) { //TOP値更新 168 Top = (uint16_t)(1000000 / Kfrq); 169 ICR5 = Top; 170 if (soundwave < 1) { 171 soundwave++; 172 } else { 173 soundwave = -1; 174 } 175} 176int main() { 177 cli(); 178 Hz = 0; 179 HzS = 0; 180 pinMode (12, INPUT); 181 pinMode (13, INPUT); 182 pinMode (22, OUTPUT); 183 pinMode (44, OUTPUT); 184 pinMode (45, OUTPUT); 185 pinMode (46, OUTPUT); 186 attachInterrupt(4, setType, FALLING); 187 analogReference(DEFAULT); 188 TCCR4A = 0b00000011; 189 TCCR4B = 0b00011001; 190 TIMSK4 = 0b00000010; 191 sei(); 192 bool SETUP = true; 193 Serial.begin(9600); 194 while (true) {//LOOP 195 196 197 if (Vout > 0 && Hz > 0 && Kfrq > 0) { //波形出力あり 198 if (pulseMode) { 199 if (pulse == 1) {//1パルスモード 200 TIMSK5 = 0; 201 TCCR5A = 0; 202 TCCR5B = 0; 203 if (Vout >= 0.01) { 204 TCCR3A = 0b00000011; 205 TCCR3B = 0b00011001; 206 OCR3A = 350; 207 TIMSK3 = 0b00000010; 208 digitalWrite(22, HIGH); 209 } else { 210 TIMSK3 = 0; 211 digitalWrite(22, LOW); 212 } 213 TCCR2A = 0b10000010; 214 TCCR2B = 0b00000010; 215 OCR2A = (1000000 / 10000) - 1; 216 TIMSK2 = 0b00010010; 217 sin_operator_adder = (opereator_type)((tableLegth * Shift) * Hz / 20000); 218 Top = (uint16_t)(1000000 / Kfrq); 219 } else {//マルチパルスモード 220 digitalWrite(22, HIGH); 221 TIMSK5 = 0b00100011;//同期モード用割り込み 222 TCCR5B = 0b00010010;//メインタイマ指定 223 TIMSK3 = 0;//1パルスモードなし 224 TIMSK2 = 0;//SINオペーレーター通常更新なし 225 Kfrq = Hz * pulse; 226 Top = (uint16_t)(1000000 / Kfrq); 227 sin_operator_adder = (tableLegth * Shift) / (pulse * 2); 228 } 229 } else {//非同期モード 230 TIMSK3 = 0; 231 TCCR2A = 0b10000010; 232 TCCR2B = 0b00000010; 233 OCR2A = (1000000 / 10000) - 1; 234 TIMSK2 = 0b00010010; 235 sin_operator_adder = (opereator_type)((tableLegth * Shift) * Hz / 20000); 236 TCCR5A = 0b10101010; 237 TCCR5B = 0b00010010; 238 TIMSK5 = 0b00000010; 239 OCR5A = (uint16_t)(Top * (((pgm_read_byte_near(&U_table[(sin_operator / Shift)]) * Vout) / 255)plus)); 240 OCR5B = (uint16_t)(Top * (((pgm_read_byte_near(&V_table[(sin_operator / Shift)]) * Vout) / 255)plus)); 241 OCR5C = (uint16_t)(Top * (((pgm_read_byte_near(&W_table[(sin_operator / Shift)]) * Vout) / 255)plus)); 242 digitalWrite(22, HIGH); 243 } 244 } else { //波形出力なし 245 digitalWrite(22, LOW); 246 TIMSK3 = 0; 247 TCCR5A = 0; 248 TCCR5B = 0; 249 } 250 TCCR4A = 0b00000011; 251 TCCR4B = 0b00011001; 252 TIMSK4 = 0b00000010; 253 OCR4A = (8000000 / 1000) - 1;//速度制御 254 analog = analogRead(A0); 255 //analog = 1023; 256 HzTo = analog / 4; 257 Serial.println(analogRead(A0), DEC);//デバッグ 258 if (round(Hz) == round(HzTo)) { 259 260 } else { 261 if (HzTo > Hz) { 262 Sp_Up(); 263 } else { 264 Sp_Dn(); 265 } 266 } 267 if (SETUP) { 268 if (Hz > -1) { 269 Hz -= 0.1; 270 } else { 271 SETUP = false; 272 } 273 } 274 275 /*if (digitalRead(13))Sp_Up(); 276 if (digitalRead(12))Sp_Dn(); 277 if (digitalRead(13) && digitalRead(12)) { 278 HzS = 0; 279 macroMODE = 0; 280 }*/ 281 282 283 SerialSendToMain(1,round(Hz)); 284 RANDOMT = (int)random(-50, 50); 285 setKfrq(Type); 286 setVout(Type); 287 } 288 return 0; 289} 290 291 292
試したこと
新たにanalogRead()を読み取るだけのプログラムを作り、試したら正常に動作したため、ピンが壊れているということはなさそうです。また、ピンを変えても結果は同じで、ずっと0を返します。
補足
特殊なPWMを出すため、TIMER2,TIMER3,TIMER4,TIMER5のレジスタを編集しています。
波形テーブルの宣言と、モーター音指定プログラムは省略しています。
回答2件
あなたの回答
tips
プレビュー