質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

Q&A

解決済

2回答

1420閲覧

ArduinoMegaでanalogReadが0しか返しません

VVVF_IR

総合スコア1

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

0グッド

0クリップ

投稿2021/07/17 11:49

編集2021/07/17 12:35

前提・実現したいこと

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のレジスタを編集しています。
波形テーブルの宣言と、モーター音指定プログラムは省略しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/07/17 12:15

setup()/loop()もなくてmain()がある、これ本当にArduinoのプログラムですか? AVRのCプログラムとしてもコンパイル通らないし...(変数の未定義等ぽろぽろと) これを見せてどうしろとおっしゃるのでしょう。
thkana

2021/07/17 12:30

おっと、Arduino IDEもmain()を通すのか。まぁ、いずれにしろコンパイルは通らない。
VVVF_IR

2021/07/17 12:38 編集

波形生成テーブルがあまりにも長すぎるため定義を省略しています。つまり宣言されていません。 波形テーブルの宣言の部分のみを追加しました。テーブルの中身は省略しているためコンパイルは通らないと思います。(テーブルの中身も書くと、文字数制限に引っかかるのです…)
thkana

2021/07/17 12:59 編集

動くはずのない、つまりプログラムたり得ないものからデバッグをしろ、と回答者にリクエストしているということですか?
thkana

2021/07/17 12:59

質問するときのヒント( https://teratail.com/help/question-tips#questionTips3-5-1 )に 「最も良いのは、現象を再現するためのミニマムなプログラムを改めて作ることです。」とあります。現象が再現するのですから当然動くプログラムということですが。 これを実行するつもりはありませんか?
guest

回答2

0

ベストアンサー

こちらの手元で「現象を再現するためのミニマムなプログラム」にまで絞り込んでみたところ、こうなりました。

C++

1int main() { 2 analogReference(DEFAULT); 3 Serial.begin(9600); 4 while (true) {//LOOP 5 Serial.println(analogRead(A0), DEC);//デバッグ 6 } 7 return 0; 8}

まぁどう見ても「analogRead()を読み取るだけのプログラム」ですが、なぜあなたの手元では動いたのにこちらでは動かないのでしょう。もしかして、setup()-loop()のArduino式プログラムで「動いた」と言っていたのでしょうか。そうだとすると、ArduinoIDE内でC++に展開する時に付け加えられる
init();
が効いているのでは...という予想がたちます。では、

C++

1int main() { 2 init(); //追加 3 analogReference(DEFAULT); 4 Serial.begin(9600); 5 while (true) {//LOOP 6 Serial.println(analogRead(A0), DEC);//デバッグ 7 } 8 return 0; 9}

としてみましょう。はい動きました。他にも初期化が行われていないペリフェラルがあるのかも知れませんが、私の知るところではありません。
逆に、init()を使いたくないというのなら、init()の中を覗いてADCの初期化っぽいところを取り込んでみるとこんなところでしょうか。

C++

1 2//マクロ追加 3#ifndef sbi 4#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 5#endif 6 7int main() { 8 //追加 9 sbi(ADCSRA, ADPS2); 10 sbi(ADCSRA, ADPS1); 11 sbi(ADCSRA, ADPS0); 12 sbi(ADCSRA, ADEN); 13 //ここまで 14 analogReference(DEFAULT); 15 Serial.begin(9600); 16 while (true) {//LOOP 17 Serial.println(analogRead(A0), DEC);//デバッグ 18 } 19 return 0; 20}

投稿2021/07/17 13:35

thkana

総合スコア7629

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

VVVF_IR

2021/07/17 13:44

おお!直りました!! なるほど、初期化が抜けていたんですね。軽量化のためにmain()を使ったのですが、そんな落とし穴があったんですね。 ありがとうございました!!助かりました!!
thkana

2021/07/17 21:59

> 軽量化のためにmain()を使った フルのプログラムをコンパイルしたときのメモリの使用量とかみてませんでしたけど、逼迫してましたか? mainにしたときにどれだけの「軽量化」が期待できるかというとかなり限定的だと思うのですが。
VVVF_IR

2021/07/20 13:21

loop()はわざわざmain()からコールされているのでその分処理速度が遅いのです。僕はなるべく高速な処理を実現したかったため、main()を使いました。(まあ確かにかなり限定的かもしれませんが…)
thkana

2021/07/20 13:34

> その分処理速度が遅い 定量的に「どれだけ遅い」のでしょうか。それがプログラムの動作に影響するのですか。 (もちろん影響する場合もあるでしょうが...) loop()の関数コールを気にするのに、digitalWriteのオーバーヘッドは許容できるのですか?
VVVF_IR

2021/07/20 13:53

プログラム書いてる途中からわざわざデータシート見るのが面倒になってきて、digitalWriteを使いました。(圧倒的ダメ人間) 使ってみたところ、特に動作には影響はありませんでした。そのため、そのまま残しています。 そのときmain()をloopに戻しても良かったのでしょうが、その必要性は感じなかったため、戻しませんでした。
guest

0

9 東洋IGBT (東京メトロ16000系)

10日立IGBT (JRE231系1000番台)
opereator_type sin_operator, SinBuffer;
opereator_type sin_operator_adder;
volatile char soundwave;

ここんところ、コメントの閉じ記号がないため、以降のコードがコメントアウトされてしまってますが、
実際はどーなってるでしょうか

投稿2021/07/17 11:55

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

VVVF_IR

2021/07/17 11:57

すみません、省略するときに消してしましました。いま修正します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問