質問:
明るさを上げるとLEDが点滅することがあるのはなぜですか?
Adrian
2015-11-20 09:09:37 UTC
view on stackexchange narkive permalink

これは確かに LEDフェードの誤動作(ランダムフラッシュ)からのクロスポストですが、Arduinoフォーラムで回答を得ることができません。

私はいじくり回していましたいくつかの非常に基本的なコードで、LEDを0の明るさで1秒間繰り返し保持してから完全な明るさにフェードインすると、各フェードの開始時に小さなフラッシュが発生することがあります(一見ランダムに見えます)。

  int led = 11; int bright = 0; void setup(){pinMode(led、OUTPUT);} void loop(){if(brightness > = 256)//明るさをチェックします255を通過し、0にリセットされます{analogWrite(led、255);明るさ= 0; } analogWrite(led、brightness); if(brightness == 0){delay(1000); // LEDが1秒間オフ} brightness + = 1; //輝度遅延をインクリメント(20);}  

つまり、私が完全に困惑しているのは、別のコード(以下)を使用でき、フラッシュが消えることです!

  int i = 0; int led = 11; void setup(){pinMode(led、OUTPUT);} void loop(){analogWrite(led、i); delay(6); if (i%256 == 0){i = 0; delay(1000);} i ++;}  

これが発生する理由について誰かが手がかりを得ましたか?どちらのプログラムも基本的に同じコードですが、最初のプログラムではiが0にリセットされ、2番目のプログラムでは、analogWrite 'がオーバーフローするように255を超えてインクリメントし続けます。ファームウェア(またはソフトウェア?)の問題だと思います。

YouTubeに Arduino-LEDのフェージングの問題というビデオがあります。 p>

`analogWrite(led、255);`を削除してみてください。その下の2行を考えると、まったく役に立たないので、0に戻されます。コードに実際に問題があることはわかりません(少し奇妙な順序を除いて)。 。
2番目のコードで、 `delay(6)`を `delay(20)`に変更します-フラッシュは表示されますか? 2番目のコードは最初のコードの3倍の速さでローリングしているので(もちろん1秒の遅延は無視します)、ランダムフラッシュはおそらく検出できません。 *なぜフラッシュがあるのか​​ ...わかりません。
@Gerbenそれは本当です... :)します
@CharlieHanson遅延を増やしてみましたが、効果がありません。 6秒の遅延でフラッシュを検出できます。 Arduinoフォーラムでなぜそれが起こるのかについて、私は今、良い答え/説明を得ました。
おっと、私は6ミリ秒の遅延を意味しました。
1 回答:
brtiberio
2015-11-21 01:38:22 UTC
view on stackexchange narkive permalink

arduino.ccフォーラムから提供したリンクによると、質問は多かれ少なかれ答えられています。それほど重要ではない場合は、 analogWrite(led、0)を避け、それでも analogWrite(led、1)

にします。 > analogWrite(led、0)、アドバイスを使ってコードをテストしましたが、レジスタを手動で変更しても問題なく動作するようです:

  #include "wiring_private.h" int led = 11; int bright = 0; void setup(){pinMode(led、OUTPUT);} void loop(){if(brightness > = 256)//明るさをチェック255を過ぎ、0にリセットされます{明るさ= 0; sbi(TCCR2A、COM2A1); OCR2A = 0; // pwmデューティを設定します} analogWrite(led、brightness); if(brightness == 0){delay(1000); // LEDが1秒間オフ}明るさ+ = 1; //輝度遅延をインクリメント(20);}  

編集:これらの「奇妙なコード」が何であるかを説明する

この分野の説明はあまり専門的ではありませんこれはどのように正確に機能しますが、基本的に sbi はAtmel(?)によってマクロで定義された関数であり、「 s et b it i n "であり、ATmegaチップのレジスタを変更するために使用されます。つまり、基本的に私が行ったのは、マクロ TCCR2A によって定義されたレジスタを変更し(なぜですか?ピン11のPWMを制御するレジスタであるため)、ビットマスク COM2A1 を渡します(これはデータシートで定義されている比較モード)および OCR2A は、デューティサイクルを定義する比較値を格納するために使用されるレジスタです。シグナルクロックからティックを受信するたびに、カウンターの値を OCR2A に格納されている値と比較し、その値が渡されたかどうかにかかわらず、ピンをハイまたはローに設定するカウンターを想像してみてください。 ( TCCR2A に保存されているモードに応じて、多かれ少なかれこのようになります。)

しかし、実際、私はいくつかのブラックマジックを行っていません。 analogWrite()のコードを調べたところ、ピン11でPWMの値を設定する方法です。

  void AnalogWrite(uint8_t pin、int val){//回転するときに、PWM出力をサポートするピンに対して// PWM出力が有効になっていることを確認する必要があります。それらを使用してデジタルで読み取りまたは//書き込む場合はオフになります。また、配線との一貫性を保つために、ピンが//出力モードになっていることを確認してください。これは、アナログ出力ピンの// pinMode呼び出しを必要としません。 pinMode(pin、OUTPUT); if(val == 0){digitalWrite(pin、LOW); } else if(val == 255){digitalWrite(pin、HIGH); } else {switch(digitalPinToTimer(pin)){... #if defined(TCCR2A)&& defined(COM2A1)case TIMER2A:// pwmをタイマー2のピンに接続し、チャネルA sbi(TCCR2A、COM2A1); OCR2A = val; // pwmデューティブレークを設定します; #endif ...}  

つまり、基本的には、arduino.ccフォーラムのリンクから提案されているように、その情報を使用してレジスタをゼロに設定しました。

ArduinoのPWMについて詳しく知りたい場合は、このサイトに多くの情報があり、レジスタのモードについても説明しています。

ありがとう@Personagem,テストしますが、** sbi **、** TCCR2A **、** COM2A1 **、および** OCR2A **の使用について説明してください。また、wiring_private.hがArduinoディレクトリにインクルードされたヘッダーファイルであることを考えると、それをインクルードする必要がありますか?
また、そもそもこれらのライブラリの使い方をどのように学びますか?
@Adrianこれらのコードの一部を説明するために編集しましたが、それを含めないとarduinoIDEが文句を言います。私は本当に専門家ではありませんが、掘り下げたいのであれば、atmegaのデータシートはあなたの友達です。これは、ちょっと高度な方法で使用する必要があります。 arduino.ccチームが行ったこと(そしてそれはみんなの世界を少し変える本当の美しさです)は、一般的なユーザーがデータシートやいくつかのレジスタ設定を掘り下げる必要のない単純な関数を作成することでした。彼らは、経験の浅い人々にとっては難しいかもしれないことをちょっと単純にしました。ただし、本当に必要な場合は、arduinoのgithubにあるすべてのコードを確認できます。
ヘルプ、説明、リンクをありがとうございました。私は基本的に今それを行う方法を見ることができます。すべてのコードは\ hardware \ arduino \ avr \ cores \ arduinoにもあると思います。
`analogWrite(led、1)`は `sbi(TCCR2A、COM2A1); OCR2A = 0;`と同様の効果を伴いませんか?つまり、出力をLOWに設定する直前に、デューティサイクルを非常に低い値に設定します。それはそれをはるかに読みやすくするでしょう。
はい、そうです、私は最初の文でそれを提案しました。しかし、彼が何らかの理由で、または単に好奇心を持って本当に欲しかった場合には、これが道であるはずです。実際、問題は、analogWrite関数がレジスタを変更せずに0と255の値を処理する方法に依存しています


このQ&Aは英語から自動的に翻訳されました。オリジナルのコンテンツはstackexchangeで入手できます。これは、配布されているcc by-sa 3.0ライセンスに感謝します。
Loading...