• 締切済み

アルディーノのプログラムについて

アルディーノマイコンでステッピングモーターを回して、ある動作をさせたいのですが、上手く行きません。 動作としては、トグルSWがONでモーターが回り出し、センサーが、ONになると、そこから、1.5秒回って、停止すると言う動作です。 現在のプログラムは uint32_t time=1501; byte dir=2; byte pul=3; byte tgl_sw=6; byte sensor=7; word wait_us=2500;//2500us*2*200→フルステップで約1RPS void setup() { pinMode(dir,OUTPUT); pinMode(pul,OUTPUT); digitalWrite(dir,HIGH); pinMode(tgl_sw,INPUT_PULLUP);//※LOWでON pinMode(sensor,INPUT);//※ } } void loop() { if(digitalRead(tgl_sw)==LOW) digitalWrite(pul,HIGH); delayMicroseconds(wait_us); digitalWrite(pul,LOW); delayMicroseconds(wait_us); if(digitalRead(sensor)==HIGH)time=millis(); digitalWrite(pul,millis()-time<=1500); } です。モーターは動くので、ドライバ、モーターの説明は省略します。

みんなの回答

回答No.1

同じ環境を持っていないので、 テストはできませんが、プログラムとしてのみについてです。 if(digitalRead(sensor)==HIGH)time=millis(); #1 digitalWrite(pul,millis()-time<=1500); #2 #1は、ワンパルス保証されてますか? もしずっとHIGHを返しているなら、毎回 新しいtimeがセットされるので、 #2は常に0なのではないかと。(論理値は1を維持) 以下は、余談です。 millis()-time<=1500 これを (millis()-time)<=1500 の方がいいですね。優先順位として元々の物でも問題はないが、 理想としては、 if ( (millis()-time)<=1500 ) { data=1; }else{ data=0; } にするか data=( (millis()-time)<=1500 ) ? 1:0; と、論理値を出力値にした方が、メンテはしやすいかと (ここは、本件とは関係はない部分ですが)

subaruxv13
質問者

補足

#1は、ワンパルス保証されてますか? もしずっとHIGHを返しているなら、毎回 新しいtimeがセットされるので、 #2は常に0なのではないかと。(論理値は1を維持) 申し訳ございません。どちらもよく理解出来ませんでした。プログラムは具体的にどう直せば良いのでしょうか?

関連するQ&A

  • アルディーノのプログラムについて

    アルディーノのプログラムについてです。 アルディーノのプログラムについてです。 現在はトグルスイッチをON、センサーOFFでモーターが動きだし、センサーがONになるとそこからプラスで3.2秒モーターが動きその後停止し、またセンサーがOFFになるとモーターが動き出すと言うプログラムの動作を確認出来ています。この動作にモーターとセンサーをもう一つ加え、同じ動作をさせたいです。トグルスイッチは共通で、モーターの動きは対応しているセンサーによって独立させたいです。そこでプログラムを作ったのですが、このプログラムだと片方ずつしかモーターが動きません uint32_t time=3201; byte dir=2; byte pul=3; byte dir2=8; byte pul2=9; byte tgl_sw=6; byte sensor=7; byte sensor2=10; word wait_us=2500 ;//2500us*2*200→フルステップで約1RPS void setup() { pinMode(dir,OUTPUT); pinMode(pul,OUTPUT); digitalWrite(dir,HIGH); pinMode(dir2,OUTPUT); pinMode(pul2,OUTPUT);// digitalWrite(dir2,HIGH); pinMode(tgl_sw,INPUT_PULLUP);//※LOWでON pinMode(sensor,INPUT); pinMode(sensor2,INPUT);//※ } } void loop() { if(digitalRead(tgl_sw)==LOW && digitalRead(sensor)==HIGH) delay(2000); time=millis(); while(millis()-time<3200) {//センサがオンになってから1500msまで if(digitalRead(tgl_sw))return; digitalWrite(pul,HIGH);//回す delayMicroseconds(wait_us); digitalWrite(pul,LOW); delayMicroseconds(wait_us); if(digitalRead(sensor)==HIGH)time=millis();//センサがオフなら更新 } {if(digitalRead(tgl_sw)==LOW && digitalRead(sensor2)==HIGH) delay(2000); time=millis(); while(millis()-time<3200) {//センサがオンになってから1500msまで if(digitalRead(tgl_sw))return; digitalWrite(pul2,HIGH);//回す delayMicroseconds(wait_us); digitalWrite(pul2,LOW); delayMicroseconds(wait_us); if(digitalRead(sensor2)==HIGH)time=millis();//センサがオフなら更新 //停止 } } } 修正点を教えていただけるとありがたいです。よろしくお願いします。

  • アルディーノのプログラムについて

    アルディーノで現在、スイッチを押すとLEDが点灯し、センサーが、5回反応をするとLEDが消えると言うプログラムを作りました。 このプログラムにセンサーが10秒間一度も反応しなかったら、LEDが消灯すると言うプログラムを追加したいです。ご教授お願いします。 現在のプログラム #define sensor_ON 1 byte sw=2; byte sensor=3; byte led=13; byte val,last_val=!sensor_ON,num; void setup(){ pinMode(sw,INPUT_PULLUP); pinMode(led,OUTPUT); } void loop(){ if(digitalRead(sw)==LOW)digitalWrite(led,HIGH);//スイッチを押したらLED点灯 if(digitalRead(led)==HIGH){//計測状態なら val=digitalRead(sensor); if(val!=sensor_ON && last_val==sensor_ON){//通過(前回検知&今回非検知)なら num++; if(num==5){//5回通過したら digitalWrite(led,LOW);//LEDを消す num=0;//リセット } } last_val=val; } delay(20); }

  • Arduinoでランダムにモーターを回したい

    【電子工作関連】Arduinoでボタンを押すたびに、ランダムに3つのモーターのうち一つが回転するというスケッチを書きたいのですが、ランダムになりません。どうすればランダムになるでしょう? 下がそのスケッチです。 今のところ、3つ全てのモーターが回ってしまいます。 なお、モータードライバにはTA7291Pを使用。 信号ピンである5番6番ピンをArduino5~10番ピンに振り分けて、それぞれにモーターを接続、 電源やGNDは共有してます。 なお、ボタンを使わず、単純に3つのモーターのうち一つが回転するというというスケッチは出来ていて、実際にその通り動いています。 ------------------------------ //3つのモーターをランダムに動かす int val = 0; //入力ピンの状態がこの変数に記憶される void setup(){ pinMode(2,INPUT); //ボタンを入力に設定 pinMode(5,OUTPUT); //モーター(1)のドライバー5番ピンを出力に設定 pinMode(6,OUTPUT); //モーター(2)のドライバー5番ピンを出力に設定 pinMode(7,OUTPUT); //モーター(3)のドライバー5番ピンを出力に設定 pinMode(8,OUTPUT); //モーター(1)のドライバー6番ピンを出力に設定 pinMode(9,OUTPUT); //モーター(2)のドライバー6番ピンを出力に設定 pinMode(10,OUTPUT); //モーター(3)のドライバー6番ピンを出力に設定 } void loop(){ val = digitalRead(2); //入力を読み取りvalに格納 if (val == HIGH){ digitalWrite(random(5,8),HIGH);//ランダムにモーターを正回転させる } else { digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW);//モータを止める } }

  • Arduinoのスケッチでエラーがでてしまいます。

    【電子工作関連】Arduinoでボタンを押すとランダムに3つのモーターのうち一つが回転するというスケッチを書きたいのですが、エラーが出てしまいます。どこが間違っているのでしょう? Arduinoで、ボタンを押すとランダムに3つのモーターのうち一つが回転するというスケッチを書きたいのですが、コンパイル使用とすると、 「error: expected unqualified-id before numeric constant」 というエラーが出てしまいます。 どこが間違っているのでしょう? 下がそのスケッチです。 なお、モータードライバにはTA7291Pを使用。 信号ピンである5番6番ピンをArduino5~10番ピンに振り分けて、それぞれにモーターを接続、 電源やGNDは共有してます。 なお、ボタンを使わず、単純に3つのモーターのうち一つが回転するというというスケッチは出来ていて、実際にその通り動いています。 ------------------------------ //3つのモーターをランダムに動かす int val = 0 //入力ピンの状態がこの変数に記憶される void setup(){ pinMode(2,INPUT); //ボタンを入力に設定 pinMode(5,OUTPUT); //モーター(1)のドライバー5番ピンを出力に設定 pinMode(6,OUTPUT); //モーター(2)のドライバー5番ピンを出力に設定 pinMode(7,OUTPUT); //モーター(3)のドライバー5番ピンを出力に設定 pinMode(8,OUTPUT); //モーター(1)のドライバー6番ピンを出力に設定 pinMode(9,OUTPUT); //モーター(2)のドライバー6番ピンを出力に設定 pinMode(10,OUTPUT); //モーター(3)のドライバー6番ピンを出力に設定 } void loop(){ val = digitalRead(2); //入力を読み取りvalに格納 if (val == HIGH){ digitalWrite(random(5,8),HIGH);//ランダムにモーターを正回転させる } else { digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW);//モータを止める } }

  • ATTiny13Aが省電力化できない

    ATTiny13Aでフォトカプラを一定時間ONにする回路を作成しましたが、省電力にできません。 仕様としては10分、30分、60分をジャンパー等で選択し、ボタンを押したら一定時間の間、フォトカプラをONにします。 また、途中で再度、割り込みがあっても時間の延長はしません。 LR44電池2個で1年以上、動けばと思っています。 コードも拙い上、回路図もまともに書けない初心者ですが、よろしくお願いいたします。 #include <avr/wdt.h> #include <avr/sleep.h> //LED_PIN #define LED_PIN (5) //interrupt pin #define ACC_IN (2) //Time_select #define TIME_PIN1 (0) #define TIME_PIN2 (4) #define TIME_PIN3 (1) volatile int sleep_flg=0; volatile int counter; int count_max=15;//4second * 15 = 60 second int wait_minutes=1;//wait_time (minutes) //arduino wakeup interrupt void wakeUp() { //wdt_reset(); //sleep end sleep_flg = 0; //counter reset counter = 0; } //watch dog timer setup void wdt_set() { wdt_reset(); cli(); MCUSR = 0; WDTCR |= 0b00011000; //WDCE WDE set WDTCR = 0b01000000 | 0b100000;//WDIE set |WDIF set scale 4 seconds sei(); } //watch dog timer unset void wdt_unset() { wdt_reset(); cli(); MCUSR = 0; WDTCR |= 0b00011000; //WDCE WDE set WDTCR = 0b00000000; //status clear sei(); } //watch dog timer call ISR(WDT_vect) { //wdt_reset(); if(sleep_flg == 1) { counter++; if( counter >= (count_max * wait_minutes)) { //sleep end sleep_flg = 0; //counter reset counter = 0; } } else { } } //status reset void init_status() { counter=0; } //sleep arduino void sleep() { wdt_set(); //watch dog timer set sleep_flg=1; //enable on sleep flag set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set sleep mode attachInterrupt(0,wakeUp, RISING); //set level interrupt while(sleep_flg){ noInterrupts(); //cli(); sleep_enable(); interrupts(); //seii(); sleep_cpu(); //cpu sleep sleep_disable(); byte adcsra_old = ADCSRA; //NEW ADCSRA = 0; //NEW ADCSRA = adcsra_old; //NEW } wdt_unset(); //watch dog timer unset detachInterrupt(0); //unset level interrupt } //set up void setup() { init_status(); pinMode(LED_PIN,OUTPUT); pinMode(ACC_IN, INPUT); pinMode(TIME_PIN1, INPUT); pinMode(TIME_PIN2, INPUT); pinMode(TIME_PIN3, INPUT); } //main loop void loop() { if(!digitalRead(ACC_IN)) { sleep(); //sleep if (digitalRead(0) == HIGH) { digitalWrite(5, HIGH); //delay(1800000); // Wait for 1800 second(s) uint16_t i; for (i = 0; i < 10*60; i++) { _delay_ms(1000); } digitalWrite(5, LOW); delay(1000); // Wait for 1 second(s) } else { if (digitalRead(4) < HIGH) { digitalWrite(5, HIGH); //delay(600000); // Wait for 600 second(s) uint16_t i; for (i = 0; i < 30*60; i++) { _delay_ms(1000); } digitalWrite(5, LOW); delay(1000); // Wait for 1 second(s) } else { if (digitalRead(1) < HIGH) { digitalWrite(5, HIGH); //delay(36000000000); // Wait for 3600 second(s) uint16_t i; for (i = 0; i < 60*60; i++) { _delay_ms(1000); } digitalWrite(5, LOW); delay(1000); // Wait for 1 second(s) } else { delay(1000); // Wait for 1 second(s) } } } sleep(); //sleep } }

  • Arduino のプログラムについて

    下のプログラムはArduinoで、4個のバッテリーの電圧を取得して、あるバッテリー電圧が14.5V以上だったら、充電を停止し、14.5Vよりも低いバッテリーには充電をするようにしたいのです。例えば、4個のバッテリーの取得電圧が下の図の様な状況の時、それぞれのバッテリーに充電、充電停止を行いたいのです。 AnalogPin 0 → 14.8V → digitalPin 10 を充電停止(LOWにする) AnalogPin 1 → 12.8V → digitalPin 11 を充電(HIGHにする) AnalogPin 2 → 13.7V → digitalPin 12 を充電(HIGHにする) AnalogPin 3 → 13.0V → digitalPin 13 を充電(HIGHにする) 質問:下のプログラムでArduinoに書き込んで動作させてみると、バッテリーの電圧は読み取っているのですが、digitalPin10~13のHIGH、LOWがうまくいきません。良い方法を教えてください。 void setup() { Serial.begin(9600); pinMode(10,OUTPUT); pinMode(11,OUTPUT); pinMode(12,OUTPUT); pinMode(13,OUTPUT); } void loop() { float battery_v[4];            for(int i=0;i<4;i++){ float convert_v=analogRead(i)*5./1024; battery_v[i]=convert_v/30*130; delay(100); Serial.print(i); Serial.print(" is "); Serial.println(battery_v[i]); delay(100); for(int r=9;r<14;r++){  // ここから下の命令がうまく動作しません。 if(battery_v[i]>14.5){ // digitalPin は10~13です。 digitalWrite(r,LOW); // すべてのdigitalWriteが }else { // LOWのままか、HIGHのままになってしまいます。 digitalWrite(r,HIGH); // } }   } delay(1000); } 以上、宜しくお願い致します。

  • C言語プログラミングについて…Arduinoを用い

    C言語プログラミングについて…Arduinoを用いて、以下の文でスイッチ「RedSwitch(赤スイッチ)」が押された回数だけ後で光るというプログラミングを作りました。次にその使用した「switch case」文を「if」文、もしくは「if else」に変換して同じプログラミングを作りなさいという課題が出て、いろいろと変えてみたのですが、シリアルモニタを見るとif文を用いた時に「RedSwitch」が押された「回数」ではなく連続的に?押した「秒数」をカウントして困ってます。どうやったら改善できるのでしょうかか?ご教授お願いしたします。 void sw_check(void) { switch(SW_RedSwitch) { case 0: if ( digitalRead(2)==SW_ON ) { SW_RedSwitch=1; } break; case 1: if ( digitalRead(2)==SW_OFF ) { SW_RedSwitch=2; } break; } } void blink(void) { digitalWrite(13,LED_ON); delay(500); digitalWrite(13,LED_OFF); delay(500); } void loop() { unsigned char SW_CNT=0,SW_TIME=0,i; while( (SW_TIME<100) || (SW_CNT==0) ) { sw_check(); if ( SW_RedSwitch==2 ) { SW_RedSwitch=0; SW_CNT++; SW_TIME=0; } SW_TIME++; delay(20); } for (i=1 ; i<=SW_CNT ; i++) { blink(); } }

  • アルディーノでのプログラムについて

    アルディーノで、ステッピングモーターの制御を考えています。 やりたい事は、トグルスイッチをオンすると、スタートで、センサーが反応LOWの時、モーターが回転し、HIGHでモーターが停止、またセンサーがLOWで動き出すと言う動作をさせたいです。モーターは2相の物を使用します。2相励磁でやりたいと思っています。プログラムスケッチを書いていただけると助かります。

  • ARDUINOで5つのLEDをそれぞれ点滅させたり、フェードインさせた

    ARDUINOで5つのLEDをそれぞれ点滅させたり、フェードインさせたりしたい!! ARDUINO初心者です。5つのLEDをそれぞれ上記の様に制御したいと思っています。点滅は点灯、消灯が一定の点滅ではない効果を持たせたく、5つのLEDのうち、2つはフェードインフェードアウトで蛍のような効果にしたいと思っております。 以下、途中まで3つのLEDで試行錯誤してスケッチを構築したのですが、なかなかこれ以上、前へすすみません。 まず、このスケッチでの第一関門はプログラムの並列処理ができない、ということでした。 int ledPina = 9; int ledPinb = 10; int ledPinc = 11; void setup(){ pinMode(ledPina, OUTPUT); pinMode(ledPinb, OUTPUT); pinMode(ledPinc, OUTPUT); //LedPin a b cを出力に設定。 } void loop() { digitalWrite(ledPina, HIGH); // aのLEDをオン delay(500); //待機 digitalWrite(ledPina, LOW); //aをオフ delay(500); digitalWrite(ledPinb, HIGH); // bのLEDをオン delay(800); // 待機 digitalWrite(ledPinb, LOW); //bをオフ delay(300); digitalWrite(ledPinc, HIGH); // cのLEDをオン delay(100); // 待機 digitalWrite(ledPinc, LOW); //cをオフ delay(50); } おわかりの方、いらっしゃいましたら、お教え願えますでしょうか? よろしくお願い致します!!

  • Arduinoのプログラムで質問です。

    お世話になります。 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を消灯 } } }

専門家に質問してみよう