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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Arduino

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

Q&A

解決済

3回答

541閲覧

Aduinoのプログラミングについて

shincra

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Arduino

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

0グッド

0クリップ

投稿2019/03/21 09:04

編集2019/03/21 22:29

以下のプログラミングをしたのですが(見づらくて申し訳ないです)、問題点がいくつかありました。

1、if文にボタンを押したら(status = HIGHの状態)割り込み?のようにすぐ飛んでほしい。
2、サーボモーターは止まっているはずが、常に微動している。
3、LEDテープの色が(255,255,255)で白になるはずが、オレンジになってしまう。

Arduino UNO R3 の互換品を使っています。
いい解決策があれば、できれば具体的に修正点を教えていただきたいです。

C

1 2 3 4 5 6#include <Adafruit_NeoPixel.h> 7 8//ライブラリインクルード 9#include <Adafruit_NeoPixel.h> 10 11#define LED_COUNT ( 40 ) 12#define DIGITAL_PIN ( 6 ) 13 14 15#define input_pin 2 16#define input_pin2 3 17#define input_pin3 10 18#define input_pin4 11 19#define input_pin5 12 20 21 22 23//www.elegoo.com 24//2016.12.08 25#include <Servo.h> 26 27Servo myservo; // create servo object to control a servo 28// twelve servo objects can be created on most boards 29 30int pos = 0; // variable to store the servo position 31 32 33Adafruit_NeoPixel led = Adafruit_NeoPixel( LED_COUNT,DIGITAL_PIN , NEO_GRB + NEO_KHZ800); 34void setup() { 35 //初期化処理 36 led.begin(); 37 led.show(); 38 39 pinMode(input_pin,INPUT) ; 40 pinMode(input_pin2,INPUT) ; 41 pinMode(input_pin3,INPUT) ; 42 pinMode(input_pin4,INPUT) ; 43 pinMode(input_pin5,INPUT) ; 44 45 pinMode(13, OUTPUT); 46 47 Serial.begin(9600); 48 myservo.attach(7); // attaches the servo on pin 9 to the servo object 49 50} 51 52void loop() { 53 digitalWrite(13, HIGH); // スイッチをOFFする 54 55 56 57 for(int i = 0 ; i < LED_COUNT ; i++ ) 58{ 59led.setPixelColor(19+i,led.Color(255,255,255)); 60led.setPixelColor(20+i,led.Color(0,0,0)); 61 62led.setPixelColor(19-i,led.Color(255,255,255)); 63led.setPixelColor(18-i,led.Color(0,0,0)); 64 65 66led.show(); 67delay(20); 68} 69 70 int status ; 71 int status2 ; 72 73 74 status = digitalRead(input_pin) ; //スイッチの状態を読む 75 status2 = digitalRead(input_pin2) ; //スイッチの状態を読む 76 77 78 79 80 if(status == HIGH && status2 == LOW){ 81 for(int i = 0 ; i < LED_COUNT ; i++ ) 82{ 83led.setPixelColor(19+i,led.Color(0,255,0)); 84led.setPixelColor(20+i,led.Color(0,0,0)); 85 86led.setPixelColor(19-i,led.Color(0,255,0)); 87led.setPixelColor(18-i,led.Color(0,0,0)); 88 89 90led.show(); 91delay(20); 92} 93 digitalWrite(13, LOW); // スイッチをONする 94 delay(3000); //3秒待つ 95 96 97 98 99 } else if(status == HIGH && status2 == HIGH){ 100 for(int i = 0 ; i < LED_COUNT ; i++ ) 101{ 102led.setPixelColor(19+i,led.Color(10,10,10)); 103led.setPixelColor(20+i,led.Color(0,0,0)); 104 105led.setPixelColor(19-i,led.Color(10,10,10)); 106led.setPixelColor(18-i,led.Color(0,0,0)); 107 108 109led.show(); 110delay(20); 111} 112 113 114 for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees 115 // in steps of 1 degree 116 myservo.write(pos); // tell servo to go to position in variable 'pos' 117 delay(15); // waits 15ms for the servo to reach the position 118 } 119 for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees 120 myservo.write(pos); // tell servo to go to position in variable 'pos' 121 delay(15); // waits 15ms for the servo to reach the position 122 } 123 124 125 126 while(1){ 127 int status3 ; 128 int status4 ; 129 int status5 ; 130 status3 = digitalRead(input_pin3) ; //スイッチの状態を読む 131 status4 = digitalRead(input_pin4) ; //スイッチの状態を読む 132 status5 = digitalRead(input_pin5) ; //スイッチの状態を読む 133 134int t = 0; 135int l = 0; 136int m = 0; 137 138 if(status3 == HIGH){ 139 digitalWrite(13, LOW); // スイッチをONする 140 141 while(t<250){ 142 for(int i = 0 ; i < LED_COUNT ; i++ ) 143{ 144led.setPixelColor(19+i,led.Color(0,0,255)); 145led.setPixelColor(20+i,led.Color(0,0,0)); 146 147led.setPixelColor(19-i,led.Color(0,0,255)); 148led.setPixelColor(18-i,led.Color(0,0,0)); 149 150 151led.show(); 152delay(20); 153t++; 154} 155 } 156 157 158 159 160 goto label; 161 }else if(status4 == HIGH){ 162 163digitalWrite(13, LOW); // スイッチをONする 164 165 while(l<500){ 166 167 for(int i = 0 ; i < LED_COUNT ; i++ ) 168{ 169led.setPixelColor(19+i,led.Color(255,0,0)); 170led.setPixelColor(20+i,led.Color(0,0,0)); 171 172led.setPixelColor(19-i,led.Color(255,0,0)); 173led.setPixelColor(18-i,led.Color(0,0,0)); 174 175 176led.show(); 177delay(20); 178l++; 179} 180 } 181 182 183 184 goto label; 185 186 }else if(status5 == HIGH){ 187 188digitalWrite(13, LOW); // スイッチをONする 189 190int m = 0; 191while(m<1000){ 192 uint16_t i, j; 193 194 for(j=0; j <256; j++) { 195 for(i=0; i < led.numPixels(); i++) { 196 led.setPixelColor(i, rotateColor((((i) * 256 / led.numPixels()) + j) & 255)); 197 } 198 led.show(); 199 delay(10); 200m++; 201} 202} 203 204 205 206 goto label; 207 } 208 209 210 } 211 } 212label:; 213} 214 215//RGBの色の移り変わり関数 216uint32_t rotateColor(byte WheelPos) { 217 if(WheelPos < 85) { 218 return led.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 219 } else if(WheelPos < 170) { 220 WheelPos -= 85; 221 return led.Color(255 - WheelPos * 3, 0, WheelPos * 3); 222 } else { 223 WheelPos -= 170; 224 return led.Color(0, WheelPos * 3, 255 - WheelPos * 3); 225 } 226}

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

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

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

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

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

y_waiwai

2019/03/21 09:09

このままではコードが見づらいので、質門を編集し、<code>ボタンで、出てくる’’’の枠の中にコードを貼り付けてください
y_waiwai

2019/03/21 09:14

そんで、Arduinoは何を使ってるんでしょう、回路構成はどういうものでしょうか。回路図を提示してください。
thkana

2019/03/21 13:06

質問の内容にC#は全く関係ありません。C#タグは外しましょう。
guest

回答3

0

ベストアンサー

先に2,3の方から。
全部組み上げて、動かなくて何が悪いかわからない...なら、ひとつずつ確実に動かしてみて下さい。
余計なパーツ、プログラムは無し。サーボを動かすだけ...出来た?
テープLEDを白く光らせるだけ...出来た?
(Arduino LEDテープについてで白を設定してみればいいですね。)
それが出来たら、組み合わせ...出来た?

LEDテープは持っていないので確認できませんけれど、少なくとも私の手元でサーボだけは動きましたが、質問のプログラムではサーボが異常動作しました。
前述のようにLEDテープを持っていないので確認できませんが、LEDライブラリの方もServoとの干渉で異常動作して白が出ていないんじゃないか、と想像します。
NeoPixel and Servo libraries won’t work together in the same Arduino sketch
だそうです。同ページで、別のServoライブラリの使用を提案して、そこからのリンク先で使い方を説明しています(Arduino m0はすでに製造中止になっちゃった)。手元でServoライブラリの差し替えでサーボモーターの動作は確認しました。

別件。
まさかと思いますが、スイッチを5Vと入力ピン間に繋いだだけで、オープンではLOW、なんて思い込んでいませんね?入力ピンを単純にオープンしたら「どうなるかわからない」ですから。スイッチを入力端子に付けるなら、プルアップまたはプルダウン抵抗と併用するなど適切な回路にして下さい。(プルアップ/プルダウンで検索すれば山程の例が見つかるはずですが、見つからない/理解できないということならまた聞いて下さい)

で、1.
割り込みを使わずにリアルタイム(一定時間内に刺激に反応することが保証されている、という意味)システムを組みたいのなら、直接的に長時間のdelayや、結果として長時間になるループ中でのdelayの使用は出来ません。(結局、ごく短い時間以外のdelayはダメだよ、ということ)
質問のプログラムを書き換える気力はとてもありませんから、考え方を単純なプログラムで説明しましょう。

例えば、3秒点灯1秒消灯の周期で点滅しているLEDがあって、スイッチを押すと押している間消灯する、というものを考えてみましょう。
まずダメダメな例。

Arduino

1const int SW = 4; 2//スイッチは入力ピンとGNDの間につなぐ。 3//入力端子は内部プルアップを使って定常HIGHレベルを確保する 4//スイッチ押すとLOW, 離すとHIGH 5const int LED = 13; 6 7const int ON_PERIOD = 3000; 8const int OFF_PERIOD = 1000; 9 10void setup() { 11 pinMode(SW, INPUT_PULLUP); 12 pinMode(LED, OUTPUT); 13} 14 15void loop() { 16 digitalWrite(LED, HIGH); 17 delay(ON_PERIOD); 18 digitalWrite(LED, LOW); 19 delay(OFF_PERIOD); 20 bool swState; 21 do { 22 swState = digitalRead(SW) == LOW; // 23 if (swState) { 24 digitalWrite(LED, LOW); 25 } 26 } while (swState); 27}

4秒周期のひと仕事が終わった瞬間しかスイッチを検査していません。それ以外は何が起ころうとプログラムは検知出来ず、当然反応も出来ません。長時間delayを使い割り込みを使わないなら、どうしようもない動作です。ではどうするか...長時間delayを短時間delayの積み重ねにします。まずはその方法で点滅だけやってみましょう。

Arduino

1const int LED = 13; 2 3const int ON_PERIOD = 3000;//ON時間 4const int OFF_PERIOD = 1000;//OFF時間 5const int TICK=10; //単位時間 6int count=0; //時間計測用変数 7 8//状態変数設定 9const int LED_ON = 0;//状態名1 10const int LED_OFF= 1;//状態名2 11int stat=LED_ON;//状態を保持する変数 12/* 13 * enum STAT{ 14 * LED_ON, 15 * LED_OFF, 16 * } stat; 17 * としたほうが好ましいけど... 18 */ 19 20void setup() { 21 pinMode(SW, INPUT_PULLUP); 22 pinMode(LED, OUTPUT); 23} 24 25void loop() { 26 int ledStat=LOW; 27 if(stat==LED_ON){ 28 //LED_ON状態のときの動作を記述 29 ledStat=HIGH; 30 if(++count>ON_PERIOD/TICK){ 31 //ON_PERIOD時間が経過したら 32 //LED_OFF状態に移行 33 count=0; 34 stat=LED_OFF; 35 } 36 } else if(stat==LED_OFF){ 37 //LED_OFF状態のときの動作を記述 38 ledStat=LOW; 39 if(++count>OFF_PERIOD/TICK){ 40 //OFF_PERIOD時間が経過したら 41 //LED_OFF状態に移行 42 count=0; 43 stat=LED_ON; 44 } 45 } 46 digitalWrite(LED,ledStat); 47 delay(TICK); 48}

loop()関数自体はTICKのdelayだけでさっさと抜けてしまいます。逆に言うと、TICK時間毎にloop()に仕込んだ仕事を一通りやってくれるということなので、スイッチの検査を仕込めばTICK時間毎にスイッチ動作を行うことが出来る、つまり「即反応する」ということになります。

Arduino

1const int SW = 4; 2const int LED = 13; 3 4const int ON_PERIOD = 3000;//ON時間 5const int OFF_PERIOD = 1000;//OFF時間 6const int TICK = 10; //単位時間 7int count = 0; //時間計測用変数 8 9//状態変数設定 10const int LED_ON = 0;//状態名1 11const int LED_OFF = 1; //状態名2 12int stat = LED_ON; //状態を保持する変数 13 14void setup() { 15 pinMode(SW, INPUT_PULLUP); 16 pinMode(LED, OUTPUT); 17} 18 19void loop() { 20 int ledStat = LOW; 21 int swStat = digitalRead(SW); 22 if (swStat != LOW) {//スイッチの検査 23 //押されていなかったら点滅処理 24 if (stat == LED_ON) { 25 ledStat = HIGH; 26 if (++count > ON_PERIOD / TICK) { 27 count = 0; 28 stat = LED_OFF; 29 } 30 } else if (stat == LED_OFF) { 31 ledStat = LOW; 32 if (++count > OFF_PERIOD / TICK) { 33 count = 0; 34 stat = LED_ON; 35 } 36 } 37 }else{ 38 ledStat=LOW; 39 } 40 digitalWrite(LED, ledStat); 41 delay(TICK); 42}

あるいは、Arduinoには経過時間を知るmillis()という関数があるので、これを時間経過を知るのに使えばdelay()を完全に排することも出来て

Arduino

1const int SW = 4; 2const int LED = 13; 3 4const int ON_PERIOD = 3000;//ON時間 5const int OFF_PERIOD = 1000;//OFF時間 6long tRef = 0; //時間計測用変数 7 8//状態変数設定 9const int LED_ON = 0;//状態名1 10const int LED_OFF = 1; //状態名2 11int stat = LED_ON; //状態を保持する変数 12 13void setup() { 14 pinMode(SW, INPUT_PULLUP); 15 pinMode(LED, OUTPUT); 16 tRef=millis();//状態に入る基準の「時刻」を記録 17} 18 19void loop() { 20 int ledStat = LOW; 21 int swStat = digitalRead(SW); 22 long t=millis();//現在の「時刻」を取得 23 if (swStat != LOW) {//スイッチの検査 24 if (stat == LED_ON) { 25 ledStat = HIGH; 26 if (t-tRef > ON_PERIOD) {//現在時刻-基準時刻即ち経過時間 27 tRef = t; 28 stat = LED_OFF; 29 } 30 }else if (stat == LED_OFF) { 31 ledStat = LOW; 32 if (t-tRef > OFF_PERIOD) { 33 tRef = t; 34 stat = LED_ON; 35 } 36 } 37 }else{ 38 ledStat=LOW; 39 } 40 digitalWrite(LED, ledStat); 41} 42

ただし、これは「原理」に過ぎません。

あなたのプログラムにどんな「状態」があるのかを考えて、その状態間をどのようなトリガで移行するのか(スイッチであったり時間であったり)、というのを積み上げていけば、あなたのプログラムも応答性をよく出来る...はずです。ただ、漠然とdelayするプログラムと比べて「自分が何をやりたいのか」をきちんと把握しないとなかなか形に出来ないかも知れません。まぁ、頑張って下さい。

--追記--
BA選択後になりますが。

この機にAmazonでLEDテープをポチって遊んでみています。
で、

Arduino

1#include <Servo.h> 2#include <Adafruit_NeoPixel.h> 3 4const int LED_COUNT=60; 5const int DIGITAL_PIN=6; 6 7Adafruit_NeoPixel led = Adafruit_NeoPixel( LED_COUNT, DIGITAL_PIN , NEO_GRB + NEO_KHZ800); 8Servo sv; 9 10void setup() { 11 led.begin(); 12 led.show(); 13 sv.attach(7); 14} 15 16int lvl; 17void loop() { 18 lvl=(lvl+1)%256; 19 led.setPixelColor(0,led.Color(lvl,lvl,lvl)); 20 led.show(); 21 delay(10); 22}

としてみました。サーボモーターはやはりひくひくしますが、LEDは白く光ります(セル内で各色がバラけて見えるのは仕方ないとして)。
このプログラムだとあなたの環境でも白になる、とかいうことはないでしょうか。電源が弱くて、LEDを1個だけ点灯しても大丈夫だけどたくさん点けると電圧降下を起こして、LEDのVfの大きい青とか緑のLEDの発光が弱くなる、とかいうことはあり得そうな気がします。試しに手元に転がっていた330Ωの抵抗をLEDテープの電源ラインにいれて上記プログラムを走らせてみたところ、赤LEDのみが点灯する(で明るさが変わる)状態になりました。そのモードであれば、LEDテープに供給する電源の強化が対策になりそうに思います。LEDテープの電源を3.3Vにしてみてもまだ白で光るので、それよりも下がっているとすると相当なものですけれど...

まぁ、いろいろやってみて下さい。

投稿2019/03/23 06:17

編集2019/03/24 08:11
thkana

総合スコア7610

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

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

shincra

2019/03/24 07:52

サーボとLEDテープは一緒に使えないのですね。ソレノイドでも代用出来る動作ですので、使ってみます!また、即時反応については回答を参考にしつつ、その後自分でも動作を考えてみて、while文を使って解決できました。丁寧な回答、ありがとうございました。
thkana

2019/03/24 07:56

リンク先はご覧になっていないのでしょうか。Adafruitのサーボライブラリを使えば同時利用出来ます。まぁ、代案があるのならそれでも構いませんが。 それと、LEDテープを買ってみたのでただ今追記を書いています。
shincra

2019/03/24 23:12

サーボも動かせるのですね、試してみます。それと、LEDわざわざありがとうございます。確かに1つだけだと白くなりました。電流が小さいからということはないのでしょうか。
thkana

2019/03/25 11:20

「電源が弱い」という表現がわかりにくかったですかね。おっしゃる通り、電流が少なければ正常に動作しても、電流をたくさん流そうとすると電圧が下がっちゃう、という疑念です。 40個の3色LEDで各色各20mAずつ流せば2.4Aですから、それに耐える電源を選ばないと。PCのUSBコネクタからなんかじゃ全然足りません(USB2で500mA以下、USB3でも900mA以下です)。
shincra

2019/03/26 15:13

原因はそこにあったのですね。早速、電圧の大きい電源を買ってみます!色々ありがとうございます。
thkana

2019/03/26 22:30

電圧じゃなくて電流、ね。 一般的に「電源」はある一定の電圧を出力する装置です。しかし、想定以上の電流を取り出そうとして、電圧を維持できなくなって下がってしまった、のが今回の事態。だから、より大きな電流を取り出しても電圧が維持できる電源を使いましょう、ということ。
guest

0

直接的な回答ではないですが。

1について
attachInterruptを使うことで、IOに変化等があった場合、割り込み処理を行えます。
ただし、loop()内でdelayによる時間待ちが結構あるのでうまく実装できるかどうかは不明です。
まずdelayを呼ばないような実装にすれば、loop内の処理が速くなるのでは。

1、Interruptを使うとdelayが使えなくなってしますが、delayを使いたいです。

スイッチの検知のタイミングをもっと短くするには、loop内の処理時間をもっと短くする必要があります。
delayを使う理由を明確にし、それを実現しかつloop内の処理時間を短くするように設計をするしかないです。
例えば、スイッチを押した時間からの経過時間を利用して、LEDやサーボを回すような設計にするとか。

2について
コードを見る限り、input_pinとinput_pin2がHIGHの間5秒位サーボが0~180度の間を往復しているようなので、もしかしたらコード通りの動作をしているのでは。

2、何故かinput_pin1,2がLOWの時は微動します...試してみると、LEDテープを動かす間にサーボモーターが微動しました。

LEDの駆動でノイズとかが入っているのではないですか。
LED部分を外してみて想定した動作になるか確認し、想定通りであれば、LED部分が悪いということになります。まあそうであれば、これ以上は、ハードよりの話になるため、ちょっと回答は難しいかも。

3について
led周りの実装がちょっとおかしい感じがします。
showは全部のledの色の設定が終わったら1回だけやればいいはず(for分の外にshowがあるべき?)
それとも、40個のLEDを中心から流れるような感じに表示させたいのかな。

一応、オレンジというとr,g,bが(255,165,0)近辺ですが、もしあるとすると、rotateColorに渡すWheelPosが60近辺が比率的に近い値になるかも。

とりあえず、現在どこが動いているかをSerial.printなどで出力しながら動作確認をしたらどうですか。

3、その通りで、自分は真ん中から流れるものを作りたいのですが、白色だけがどうしても出ないんです。

自分もマイコン内蔵のフルカラーLED(PL9823)を動かしたときがあるのですが、結構タイミングがシビアで決まった色にならない場合がありました。
こっちもLED40個をドライブするのではなく、初めに5個とか10個とかから始めてみたらどうですか。
もし、それでうまくいけば、複数ピンで40個を制御すればいいのでは。

投稿2019/03/21 12:58

編集2019/03/22 01:08
ta.fu

総合スコア1664

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

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

shincra

2019/03/21 22:45

1、Interruptを使うとdelayが使えなくなってしますが、delayを使いたいです。 2、何故かinput_pin1,2がLOWの時は微動します...試してみると、LEDテープを動かす間にサーボモーターが微動しました。 3、その通りで、自分は真ん中から流れるものを作りたいのですが、白色だけがどうしても出ないんです。 2、3に関しては回路がおかしいというのも十分有り得ますか?(結構ぐちゃぐちゃしてて自分はそんな気がします、、)
guest

0

コードを見てるとなかなかデタラメなので、これをこうしたら、というアドバイスはできかねます

まずは、配線をしっかりチェックして、あなたが想定する出力をしたら想定している結果が出るように、基本的な動作をチェックしましょう
・サーボモータは想定される出力で想定される動作をするかどうか
・LED出力も想定された出力で想定された色で光るのかどうか

いきなり動かすようなコードを書くのではなく、個別にこれらの動作をさせるコードを走らせ、どうなるか見てみることですね

投稿2019/03/21 09:40

y_waiwai

総合スコア87719

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問