アナログピンをpinModeしない
アナログピンはsetupでpinModeしないこと.
pinModeするとデジタルピン扱いになり,不都合が発生しやすい.
2015/06/06 追記:
スケッチを公開.
目的
analogRead値(今回は半固定抵抗)を変換してLEDの明るさを調節したい.
環境
- Windows 8.1
- Arduino UNO
- Arduino 1.0.5
スケッチ
半固定抵抗の抵抗値でデューティー比を変化させて,LEDの明るさを調節させる.
const int LED = 9; // LEDはpinNO.D9 const int RES = A0; // 半固定抵抗はpinNO.A0 /* アナログ入力値(0~1023)をデジタルPWMで扱える値(0~255)に変換 */ int convert(int analog_in); /* 各ピンの入出力,シリアル通信のbpsを設定 */ void setup(void) { pinMode(LED, OUTPUT); // LEDは出力 Serial.begin(9600); // シリアル通信は9600bps // pinMode(RES, INPUT); // 半固定抵抗は入力 // デジタルピンとして扱ってしまう } /* 繰り返す */ void loop(void) { Serial.println(analogRead(RES)); analogWrite(LED, convert(analogRead(RES))); } /* アナログ入力値(0~1023)をデジタルPWMで扱える値(0~255)に変換 */ /* 引数 int analog_in: アナログ入力値 */ /* 返却値 int: デジタルPWMで扱える値 */ int convert(int analog_in) { double x = (double)analog_in / 1023.0 * 255.0; return (int)floor(x + 0.5); }
結論
アナログピンとして扱いたいのにpinModeしてしまうとデジタルピン扱いになり,当然値は0/1になるので動くと思ったプログラムも動かない.
プログラムのバグか,回路のバグか,知識がないと判断が困難になる.
おまけ
上記のスケッチを検討した後に,以下のスケッチも検討していた.
#define WAVE random(0, 3) // 0->step 1->saw 2->triangle const int LED = 9; // LEDはpinNO.D9 int getDutyCycle(int val); // デューティー比からanalogWriteで与える引数を求める void stepwave(void); // ステップ波 void sawwave(void); // のこぎり波 void trianglewave(void); // 三角波 /* 各ピンの入出力,シリアル通信のbpsを設定 */ void setup() { Serial.begin(9600); // シリアル通信は9600bps randomSeed(analogRead(A0)); // 未接続のアナログピンからランダム値を取得して乱数のシードとする pinMode(LED, OUTPUT); // LEDは出力 } /* 繰り返す */ void loop() { switch( WAVE ){ case 0: stepwave(); break; // ステップ波 case 1: sawwave(); break; // のこぎり波 case 2: trianglewave(); break; // 三角波 default: Serial.println("制御外です"); analogWrite(LED, 0); break; } } /* デューティー比からanalogWriteで与える引数を求める */ /* int val : 平均電圧として電源電圧のval%(デューティー比)を要求*/ /* val%を0-255に変換した値を返却(四捨五入) */ int getDutyCycle(int val) { double x = (double)val * 255.0 / 100.0; return (int)floor(x + 0.5); } /* ステップ波 */ void stepwave(void) { Serial.println("StepWave"); for( int val = 0, cnt = 0; ; ++cnt, val = (val + 25) % 125 ){ /* デューティー比val%でPWM派をLEDのピンから出力 */ analogWrite(LED, getDutyCycle(val)); /* 一定時間その平均電圧を保つ */ delay(1000); } } /* のこぎり波 */ void sawwave(void) { Serial.println("sawWave"); for( int val = 0, cnt = 0; ; ++cnt, val = (val + 1) % 101 ){ /* デューティー比val%でPWM派をLEDのピンから出力 */ analogWrite(LED, getDutyCycle(val)); /* 一定時間その平均電圧を保つ */ delay(1000 / 255); } } /* 三角波 */ void trianglewave(void) { Serial.println("triangWave"); for( int cnt = 0; ; ++cnt ){ int val = 0; /* 上昇 */ for( ; val < 81 ; ++val ){ /* 平均電圧4Vは80% */ /* デューティー比val%でPWM派をLEDのピンから出力 */ analogWrite(LED, getDutyCycle(val)); /* 一定時間その平均電圧を保つ */ delay(1000 / 204); } /* 下降 */ for( ; -1 < val ; --val ){ /* 平均電圧0Vは0% */ /* デューティー比val%でPWM派をLEDのピンから出力 */ analogWrite(LED, getDutyCycle(val)); /* 一定時間その平均電圧を保つ */ delay(1000 / 204); } } }
randomSeedの引数として 未接続の アナログピンを使用する.
しかし,「未接続の」というのをすっかり読み落としており,前の回路で使用しているA0をそのまま引数に(回路を組み直すのを面倒がって半固定抵抗を接続したままLEDの回路だけ使用していた).
ステップ波しか出力されないと思いきや,という感じ.
もちろん,半固定抵抗をぐるぐる触ってからリセットすると別の波形になる.