お世話になります。
Arduinoのプログラムで質問が有ります。
下記のプログラムは2番ピンに信号が入ると割り込みで13番ピンのLEDが設定時間点灯します。
ただ、設定時間になると信号が入っていてもLEDは消灯してしまいます。
そこで、信号が入っている間(ボタンが押されている時)はLEDに点灯してもらいたいのです。
2番ピンに入る信号が不安定なのですが、LEDはずーっと点灯してもらいたいのです。
ちなみにDelayは使いたくありません。(わがままスミマセン)
皆様、よろしくお願い致します。
int PinFlag ;
long TimeCount ;
void InterPin()
{
PinFlag = 1 ; // 割込み有ればON
}
void setup()
{
pinMode(13,OUTPUT) ; // 13番ピン付属LED出力
attachInterrupt(0,InterPin, RISING) ; // 2番ピンの割込みを指定(立上がりで割込み)
PinFlag = 0 ;
TimeCount = 0 ;
}
void loop()
{
// 割込み有ればその時点の時刻を保存してLEDを点灯する
while(PinFlag) {
PinFlag = 0 ;
TimeCount = millis() ; // 現在の時刻を保存
digitalWrite(13,HIGH) ; // LEDを点灯
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount != 0) {
if ((millis() - TimeCount) >= 1010) {
TimeCount = 0 ;
digitalWrite(13,LOW) ; // LEDを消灯
}
}
}
No.7ベストアンサー
- 回答日時:
>このプログラムをLEONARDOで4系統で制御したいのですが上手くいきません。
すべて4つ必要。
volatile int PinFlag1 ; //1系統目INPUT2/OUTOUT13用
volatile int PinFlag2 ; //2系統目INPUT3/OUTOUT12用
volatile int PinFlag3 ; //3系統目INPUT0/OUTOUT11用
volatile int PinFlag4 ; //4系統目INPUT1/OUTOUT10用
long TimeCount1 ; //1系統目INPUT2/OUTOUT13用
long TimeCount2 ; //2系統目INPUT3/OUTOUT12用
long TimeCount3 ; //3系統目INPUT0/OUTOUT11用
long TimeCount4 ; //4系統目INPUT1/OUTOUT10用
//1系統目INPUT2割り込み
void InterPin1()
{
PinFlag1 = 1 ; // 割込み有ればON
}
//2系統目INPUT3割り込み
void InterPin2()
{
PinFlag2 = 1 ; // 割込み有ればON
}
//3系統目INPUT0割り込み
void InterPin3()
{
PinFlag3 = 1 ; // 割込み有ればON
}
//4系統目INPUT1割り込み
void InterPin4()
{
PinFlag4 = 1 ; // 割込み有ればON
}
void setup()
{
pinMode(2,INPUT) ; // 1系統目2番ピン付属ボタン入力
pinMode(3,INPUT) ; // 2系統目3番ピン付属ボタン入力
pinMode(0,INPUT) ; // 3系統目0番ピン付属ボタン入力
pinMode(1,INPUT) ; // 4系統目1番ピン付属ボタン入力
pinMode(13,OUTPUT) ; // 1系統目13番ピン付属LED出力
pinMode(12,OUTPUT) ; // 2系統目12番ピン付属LED出力
pinMode(11,OUTPUT) ; // 3系統目11番ピン付属LED出力
pinMode(10,OUTPUT) ; // 4系統目10番ピン付属LED出力
attachInterrupt(2,InterPin1, CHANGE) ; // 1系統目2番ピンの割込みを指定(変化したら割り込み)
attachInterrupt(3,InterPin2, CHANGE) ; // 2系統目3番ピンの割込みを指定(変化したら割り込み)
attachInterrupt(0,InterPin3, CHANGE) ; // 3系統目0番ピンの割込みを指定(変化したら割り込み)
attachInterrupt(1,InterPin4, CHANGE) ; // 4系統目1番ピンの割込みを指定(変化したら割り込み)
PinFlag1 = 0 ; // 1系統目
PinFlag2 = 0 ; // 2系統目
PinFlag3 = 0 ; // 3系統目
PinFlag4 = 0 ; // 4系統目
TimeCount1 = 0 ; // 1系統目
TimeCount2 = 0 ; // 2系統目
TimeCount3 = 0 ; // 3系統目
TimeCount4 = 0 ; // 4系統目
}
void loop(){
{
// 1系統目
// 割込み有ればその時点の時刻を保存する
while(PinFlag1) {
PinFlag1 = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(2)==HIGH) {
// 立ち上がりなのであれば
TimeCount1 = 0 ; // タイマー停止
digitalWrite(13,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount1 = millis() ; // 現在の時刻を保存
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount1 != 0) {
if ((millis() - TimeCount1) >= 1010) {
TimeCount1 = 0 ;
digitalWrite(13,LOW) ; // LEDを消灯
}
}
}
// 2系統目
// 割込み有ればその時点の時刻を保存する
while(PinFlag2) {
PinFlag2 = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(3)==HIGH) {
// 立ち上がりなのであれば
TimeCount2 = 0 ; // タイマー停止
digitalWrite(12,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount2 = millis() ; // 現在の時刻を保存
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount2 != 0) {
if ((millis() - TimeCount2) >= 1010) {
TimeCount2 = 0 ;
digitalWrite(12,LOW) ; // LEDを消灯
}
}
}
// 3系統目
// 割込み有ればその時点の時刻を保存する
while(PinFlag3) {
PinFlag3 = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(0)==HIGH) {
// 立ち上がりなのであれば
TimeCount3 = 0 ; // タイマー停止
digitalWrite(11,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount3 = millis() ; // 現在の時刻を保存
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount3 != 0) {
if ((millis() - TimeCount3) >= 1010) {
TimeCount3 = 0 ;
digitalWrite(11,LOW) ; // LEDを消灯
}
}
}
// 4系統目
// 割込み有ればその時点の時刻を保存する
while(PinFlag4) {
PinFlag4 = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(1)==HIGH) {
// 立ち上がりなのであれば
TimeCount4 = 0 ; // タイマー停止
digitalWrite(10,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount4 = millis() ; // 現在の時刻を保存
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount4 != 0) {
if ((millis() - TimeCount4) >= 1010) {
TimeCount4 = 0 ;
digitalWrite(10,LOW) ; // LEDを消灯
}
}
}
}
系統番号とINPUTピン番号、OUTPUTピン番号が順番通りになってない場合は、以下のような対応一覧表を作って、ミスを防ぎましょう。
系統番号 INPUT OUTPUT InterPin TimeCount PinFlag
1 2 13 1 1 1
2 3 12 2 2 2
3 0 11 3 3 3
4 1 10 4 4 4
この回答への補足
chie65535様
早速のご回答ありがとうございます。
スケッチをコピーしてIDE(ライティングソフト)に張り付けましたがエラーに
void loop(){の{ を削除したら書き込めたのですがLEDは点灯せず。
スケッチとにらめっこしていますが、修正するところが見つかりません。
全て、4系統必要なのですね・・・・勉強になります。
一覧表は必要ですね。作成します。
本当に、ありがとうございます。差し上げるお礼ポイントが足りないです。
chie65535様
ありがとうございます。
{と}を追加したら動作しました。
ありがとうございました。
本当に勉強になりました。
これから、もっと勉強しますので、よろしくお願い致します。
No.6
- 回答日時:
重要な追記。
割り込みルーチンの中で変化する変数には「volatile」を付けないといけません。
int PinFlag ;
は
volatile int PinFlag ;
と書かないといけません。
「volatile」は「割り込みの中で値が変化するから、毎回、ちゃんと値を調べないといけない」と言う修飾です。
例えば
int Flag ;
void loop()
{
Flag=0 ;
while(Flag) {
// Flagを一切使わない処理
}
}
と書いたら、最適化されて
int Flag ;
void loop()
{
Flag=0 ;
while(0) {
// Flagを一切使わない処理
}
}
になり、「while(0)の部分は絶対に実行されないから」と更に最適化されて
int Flag ;
void loop()
{
Flag=0 ;
}
になり、Flagに値を代入したあと使ってないので更に最適化され
int Flag ;
void loop()
{
}
になってしまう可能性があります。
もし、こうなってしまったら「ボタンもLEDも何も動かない。実行しても何もしない」と悩む事になります。
なので、割り込み内で値が変化する変数は「最適化するな」と指示しないといけません。
そのため、割り込みの中で値が変化する変数は
volatile int Flag ;
のように書かないといけません。
これを忘れると、思わぬ落とし穴にハマります。
この回答への補足
chie65535
すみません、その後ハマってしまっています。
このプログラムをLEONARDOで4系統で制御したいのですが上手くいきません。
入力は分割できたのですが出力が1個光っていると他のLEDが消えません。
で4個同時に消えるプログラムになってしまいました。
その後、LEDを消灯するプログラムも4分割したのですが全く動作しません。
TimeCountが4個有ると指定して各チャンネルに設定しないといけないのでしょうか?
大変申し訳ありません。
よろしければ、教えて下さい。
volatile int PinFlag ;
long TimeCount ;
void InterPin()
{
PinFlag = 1 ; // 割込み有ればON
}
void setup()
{
pinMode(2,INPUT) ; // 2番ピン付属ボタン入力
pinMode(3,INPUT) ; // 3番ピン付属ボタン入力
pinMode(0,INPUT) ; // 0番ピン付属ボタン入力
pinMode(1,INPUT) ; // 1番ピン付属ボタン入力
pinMode(13,OUTPUT) ; // 13番ピン付属LED出力
pinMode(12,OUTPUT) ; // 12番ピン付属LED出力
pinMode(11,OUTPUT) ; // 11番ピン付属LED出力
pinMode(10,OUTPUT) ; // 10番ピン付属LED出力
attachInterrupt(0,InterPin, CHANGE) ; // 2番ピンの割込みを指定(変化したら割り込み)
attachInterrupt(1,InterPin, CHANGE) ; // 3番ピンの割込みを指定(変化したら割り込み)
attachInterrupt(2,InterPin, CHANGE) ; // 0番ピンの割込みを指定(変化したら割り込み)
attachInterrupt(3,InterPin, CHANGE) ; // 1番ピンの割込みを指定(変化したら割り込み)
PinFlag = 0 ;
TimeCount = 0 ;
}
void loop(){
{
// 割込み有ればその時点の時刻を保存する
while(PinFlag) {
PinFlag = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(2)==HIGH) {
// 立ち上がりなのであれば
TimeCount = 0 ; // タイマー停止
digitalWrite(13,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount = millis() ; // 現在の時刻を保存
}
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount != 0) {
if ((millis() - TimeCount) >= 1010) {
TimeCount = 0 ;
digitalWrite(13,LOW) ; // LEDを消灯
}
}
}
{
// 割込み有ればその時点の時刻を保存する
while(PinFlag) {
PinFlag = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(3)==HIGH) {
// 立ち上がりなのであれば
TimeCount = 0 ; // タイマー停止
digitalWrite(12,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount = millis() ; // 現在の時刻を保存
}
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount != 0) {
if ((millis() - TimeCount) >= 1010) {
TimeCount = 0 ;
digitalWrite(12,LOW) ; // LEDを消灯
}
}
}
{
// 割込み有ればその時点の時刻を保存する
while(PinFlag) {
PinFlag = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(0)==HIGH) {
// 立ち上がりなのであれば
TimeCount = 0 ; // タイマー停止
digitalWrite(11,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount = millis() ; // 現在の時刻を保存
}
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount != 0) {
if ((millis() - TimeCount) >= 1010) {
TimeCount = 0 ;
digitalWrite(11,LOW) ; // LEDを消灯
}
}
}
{
// 割込み有ればその時点の時刻を保存する
while(PinFlag) {
PinFlag = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(1)==HIGH) {
// 立ち上がりなのであれば
TimeCount = 0 ; // タイマー停止
digitalWrite(10,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount = millis() ; // 現在の時刻を保存
}
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount != 0) {
if ((millis() - TimeCount) >= 1010) {
TimeCount = 0 ;
digitalWrite(10,LOW) ; // LEDを消灯
}
}
}
}
重ね重ね、ありがとうございます。
volatile int Flag ; の事を丁寧にありがとうございます。
本当に勉強になります。もう少し調べてみます。
今回のスケッチにもvolatile int PinFlag ;に変えました。
今の所、変える前でも変えても希望通りに動作しています。
変えておいた方が、忘れないのと勉強になるのでvolatile int PinFlag ;で行きます。
感謝します。
ありがとうございました。
No.5
- 回答日時:
>すみません、問題が発覚しました。
>割り込みで設定した時間(1010ms)以上、ボタンを押しているとLEDが消えずに点灯したままになってしまいました。
>時間設定を長くする以外に方法有りますか
int PinFlag ;
long TimeCount ;
void InterPin()
{
PinFlag = 1 ; // 割込み有ればON
}
void setup()
{
pinMode(2,INPUT) ; // 2番ピン付属ボタン入力
pinMode(13,OUTPUT) ; // 13番ピン付属LED出力
attachInterrupt(0,InterPin, CHANGE) ; // 2番ピンの割込みを指定(変化したら割り込み)
PinFlag = 0 ;
TimeCount = 0 ;
}
void loop()
{
// 割込み有ればその時点の時刻を保存する
while(PinFlag) {
PinFlag = 0 ;
// 立ち上がりか立ち下がりか調べて
if (digitalRead(2)==HIGH) {
// 立ち上がりなのであれば
TimeCount = 0 ; // タイマー停止
digitalWrite(13,HIGH) ; // LEDを点灯
} else {
// 立ち下がりなのであれば
TimeCount = millis() ; // 現在の時刻を保存
}
}
// 設定秒間カウントしたらLEDを消灯する
if (TimeCount != 0) {
if ((millis() - TimeCount) >= 1010) {
TimeCount = 0 ;
digitalWrite(13,LOW) ; // LEDを消灯
}
}
}
ありがとうござます。
スケッチしていただき申し訳ありません。
勉強させていただきました。
実際に書き込んで長時間ボタンを押して話しても1010ms後に消えました。
本当にありがとうございました。
さらに勉強します。
No.4
- 回答日時:
追記。
立ち上がりと立ち下りの両方を割り込みさせる(attachInterruptの3番目にCHANGEを指定すると)、割り込みは、同じルーチンに飛んで来るので、PinFlagで割り込みの有無を調べるだけでは足りません。
「割り込みの有無を表すPinFlag変数」の他に「立ち上がり、立ち下り、どっちの割り込みかを表す変数」が必要になるでしょう。
変数を使わない場合は、setupにpinMode(2,INPUT)を追加して、割り込みあったと判定した後で、digitalRead(2)の戻り値がLOWかHIGHか判定して、立ち上がり、立ち下りを区別して下さい。
No.3
- 回答日時:
割込みを使う必要はないです。
ループの中で2番ピンがHIGHならPinFlagを1にするプログラムを追加するだけ。
この回答への補足
すみません、問題が発覚しました。
割り込みで設定した時間(1010ms)以上、ボタンを押しているとLEDが消えずに点灯したままになってしまいました。
時間設定を長くする以外に方法有りますか
ありがとうございます。
難しく考えすぎました。
{
if (digitalRead(2) == HIGH) { //スイッチの状態を調べる
digitalWrite(13,HIGH) ; //スイッチが押されているならLEDを点灯
Loopの下に、これを入れたら思い通りの動作しました。
本当にありがとうございました。
No.1
- 回答日時:
プログラムを
・2番ピンの立ち上がり割り込み時
LEDの点灯と、TimeCountを0にする処理を行う
・2番ピンの立ち下がり割り込み時
現在時刻の保存だけを行う(TimeCountを0以外の値にする)
・メインループ
TimeCountが0でないなら、現在時刻とTimeCountを比較し、指定秒間に達したら、LEDを消灯してTimeCountを0にする処理を行う
と言う形にすれば良いです。
LEDが消灯されるのは「立下りのあと、指定した時間、何も割り込みが起きない時だけ」なので、2番ピンが不安定でチャタリングを起こしても、つまり、立ち上がりと立下りの割り込みが短時間に連続で入ってきても、点灯しっ放しになります。
ご丁寧に、ありがとうございます。
ただ、私は初心者でして「なんとなく」分かるのですがどうしたらいいのか・・・・
さらに、勉強してchie65535様のプログラムもスケッチしてみたいです。
本当に、ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(法律) 自動車の点灯義務について 6 2023/02/24 15:01
- 工学 LED、CdS(受光素子)、ディジタル IC(組み合わせ回路,順序回路)、タイマーICの技術を組み合 1 2022/12/23 10:45
- バイク車検・修理・メンテナンス 125スクーターのLEDヘッドライトが夜間、エンジンスタート同時に点灯せず、そのまま約3分後、突然点 3 2022/07/23 20:42
- その他(趣味・アウトドア・車) Arudino nanoが正常に動作しない原因 1 2022/10/30 18:29
- 照明・ライト 懐中電灯は、スイッチを一回押すとランタン用のLEDが点いて、もう一回押すと懐中電灯用の別のLED電球 1 2023/04/05 20:18
- カスタマイズ(バイク) ウインカーをLEDに交換したら一箇所だけ点かない 4 2022/04/16 11:16
- バッテリー・充電器・電池 いつまで経っても充電が100%にならないモバイルバッテリー 2 2022/04/10 17:18
- その他(パソコン・周辺機器) USB端子間に挟んで使う、スイッチのような物は売られていますか。 3 2022/08/25 22:26
- 防犯カメラ・監視カメラ・小型カメラ 夜間の防犯カメラの撮影は、暗視モードというのがあって、赤いLEDが点灯すると思うんですが、隣人が最近 2 2023/03/25 13:59
- CPU・メモリ・マザーボード HP製パソコンのBIOSの立上げ方を教えて下さい。 2 2022/10/28 18:28
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スーパーのレジで並んでいたら...
-
マイコン C言語 割り込み処理...
-
C-Builder OnChangeをマスク
-
USJでの割り込み
-
(H8マイコン)タイマ割込で変更...
-
AKI-H8/3048Fでのタイマ割り込み
-
PIC(MOVFで何故、STATUS Zフラ...
-
【組込み】割り込み中のstatic...
-
picのタイマ1発振開始時間に関...
-
PCの割り込み処理とはなんでし...
-
【H8-3052F】タイマ割り込み
-
Macターミナルで実行中のプログ...
-
緯度、経度の 10進法と 60進法...
-
家電製品の電力周波数を変える機械
-
大容量のメモリ確保をスワップ...
-
Mac 乗数の入力方法
-
【C言語 数独】 C言語で9×9の数...
-
符号付きにすべきか、符号なし...
-
Excel-VBAのmsgBox()の不思議
-
VBA
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CPUの処理量を減らすコーデ...
-
pic 複数の割り込み関数 切り分...
-
【組込み】割り込み中のstatic...
-
USJでの割り込み
-
CPU負荷率の安全な上限と計...
-
ウォッチドッグタイマ(WDT)の...
-
電車乗車時、並んでいるのに割...
-
USB機器からのデータ受信による...
-
一定時間操作がなかったら、と...
-
Amazonfireタブレットにわから...
-
マイコン C言語 割り込み処理...
-
PICマイコンでエンコーダパルス...
-
電車で待機列の割り込みについ...
-
駅のトイレでナイチンに邪魔さ...
-
実行した後、どうしてもフリー...
-
電車のドアの前での並び方
-
V.B.6 多重Call用スプール作成...
-
H8マイコンでの割り込み(シリ...
-
VB.net 割り込みの禁止
-
割り込みについて
おすすめ情報