ディップスイッチによるサーボ制御

私はArduinoとプログラミングにもかなり新しいです。 私はディップスイッチを使ってサーボをスイープしたい。現在のところ、4ポジションディップスイッチを使用しています。各スイッチには、サーボを実行する回数を設定します。例えば、DIPスイッチのPos1には、5回スイープが表示されます。ポジ2は言う、10回掃引など

私は次のコードを書いた:

#include 

Servo myservo;  
int pos = 0; 
int count = 0;  //might need later
int runXTimes = 0;

#define S1 2
#define S2 3
#define S3 4
#define S4 5

int s1state = HIGH;
int s2state = HIGH;
int s3state = HIGH;
int s4state = HIGH;


void setup() {
   myservo.attach(9);
   pinMode(S1, INPUT_PULLUP);
   pinMode(S2, INPUT_PULLUP);
   pinMode(S3, INPUT_PULLUP);
   pinMode(S4, INPUT_PULLUP);
   pinMode(9, OUTPUT);
}

void loop() {

   s1state = digitalRead(S1);
   s2state = digitalRead(S2);
   s3state = digitalRead(S3);
   s4state = digitalRead(S4);


  //Servo control through Switch 1
   if (s1state == LOW) {    //read the input pin
      for (int runXTimes = 0; runXTimes < 5; runXTimes++) {   //Servo to     sweep for 5 times
         for (pos = 0; pos <= 80; pos += 1) //goes from 0 degrees to 80 degrees in steps of  degree

         {                                   
            myservo.write(pos);             //tell servo to go to position in variable 'pos'
            delay(5);
         }

         for(pos = 80; pos>=0; pos-=1)    //goes from 80 degrees to 0 degrees
         {                               
            myservo.write(pos);             //tell servo to go to position in variable 'pos'
            delay(5);
         }

      }

   }

  //Servo control through Switch 2. Used servo detach here
   else if (s2state == LOW) { //read the input pin
      for (int runXTimes = 0; runXTimes < 10; runXTimes++) { //Servo to sweep for 10 times
         for (pos = 0; pos <= 80; pos += 1) //goes from 0 degrees to 80 degrees in steps of  degree
         {                                  
            myservo.write(pos);             //tell servo to go to position in variable 'pos'
            delay(5); 
         }

         for(pos = 80; pos>=0; pos-=1)    //goes from 80 degrees to 0 degrees
         {                               
            myservo.write(pos);             //tell servo to go to position in variable 'pos'
            delay(5);  
         }

      }
      myservo.detach();
   }

  //Servo control through Switch 3
   else if (s3state == LOW) { //read the input pin
      for (pos = 0; pos <= 80; pos += 1) //goes from 0 degrees to 80 degrees in steps of  degree
      {                                 //
         myservo.write(pos);             //tell servo to go to position in variable 'pos'
         delay(5); 
      }

      for(pos = 80; pos>=0; pos-=1)    //goes from 80 degrees to 0 degrees
      {                               
         myservo.write(pos);             //tell servo to go to position in variable 'pos'
         delay(5);  
      }
   }

  //Servo control through Switch 4
   else if (s4state == LOW) { //read the input pin
      for (pos = 0; pos <= 80; pos += 1) //goes from 0 degrees to 80 degrees  in steps of  degree
      {                                 
         myservo.write(pos);             //tell servo to go to position in variable 'pos'

         delay(5); 
      }

      for(pos = 80; pos>=0; pos-=1)    //goes from 80 degrees to 0 degrees
      {                               
         myservo.write(pos);             //tell servo to go to position in variable 'pos'
         delay(5);  
      }

   }
}

上記のコードで発生するアクションは次のとおりです。 1)スイッチ1によるサーボ制御 - 直ちにON(0)、OFF(1)を行うと、サーボは5回掃引します。ボタンスイッチのように機能します。私がもう一度オンとオフを切り替えると、私は5回掃引することができます。しかし、スイッチを1のままにしておくと、5回後にスイープが停止することはありません。
2)スイッチ2を介したサーボ制御:スイッチをONにすると、サーボは10回掃引し、私の興味のために停止する。しかし、スイッチを再び0と1に変更すると、シーケンスは開始しません。実際、他のスイッチは動作しません。私は再びプログラムを実行するためにArduinoの電源を切る必要があります。 3)スイッチ3(=スイッチ4)によるサーボ制御:スイッチが1の場合、サーボが掃引します。私のスイッチが0の場合、サーボは停止します。

あなたはお勧めしますか: 1)スイッチが常に1になっていても、または0と1の間を切り替えるときでも、設定した回数だけ自分のサーボが掃引するようにコードを書き込む方法はありますか? 2)私はシリアル通信(通常はPC)を使いたくない。 7セグメントまたはLCDをインターフェースして、完了した、またはまだ残っているスイープの数を表示できますか?

前もって感謝します。

1
追加された 編集された
ビュー: 2

3 答え

これは現時点では自分自身でテストすることができないので、想像力に基づいていますが、何かが正しくないかどうか尋ねることは自由です。

int readswitch()
{
 int S1,S2,S3,S4;
 uint8_t data = 255;
 data |= digitalRead(S4)<<3;
 data |= digitalRead(S3)<<2;
 data |= digitalRead(S2)<<1;
 data |= digitalRead(S1)<<0;

  if (data==0b11111110) return 1; else
  if (data==0b11111101) return 2; else
  if (data==0b11111011) return 3; else
  if (data==0b11110111) return 4; else
  //add another condition here if you want
  return 0;
}

int laststate = 0;
int state = 0;
int rotation;

void setup()
{
  //setup here, including LCD initialization
  //..
  //..
  //..
}

void updateLCD(int x,int y)
{
  lcd.clear();
  //displaying pin status
  lcd.print("dip : ");
  lcd.print(x,DEC);
  lcd.print(" rot : ");
  lcd.print(y,DEC); 
}

void loop()
{
  state = readswitch();
  if (state!=laststate)
  {
    if (state == 1) 
    {
      rotation = 5;
      for (int i = 0; i< rotation; i++)
        {
         //update lcd
         updateLCD(state,(rotation-i));

         //.. servo rotation
         //..
        }
      //...
    } else

    if (state == 2) 
    {
      //do what you want here if switch 2 == LOW
      //...
    } else

    if (state == 3) //switch 1 == LOW
    {
      //do what you want here if switch 3 == LOW
      //...
    } else

    if (state == 4) //switch 1 == LOW
    {
      //do what you want here if switch 4 == LOW
      //...
    } 
  }
  laststate = state;

}

For more information about LCD, you can refer to this documentation

1
追加された

スイープコードをsetup関数に入れると、setup()は一度しか呼び出されないため、一度実行され、期待どおりに表示されます。

しかし、それはloop()関数内にあるので、loop()関数が実行されるたびに実行されます。つまり、loop()関数のポイントです。もう一つの選択肢として、無限ループまたは永遠ループを置くことができます

for(;;)
   ;   //program hangs here forever

loop()関数の終わりに戻り、再び呼び出されるのを防ぎます。いずれにしても、コード化したステップを1回通過するだけです。

0
追加された

あなたのスイッチ2のコードには、最後にmyservo.detach()が含まれています。これにより、それ以上のサーバーコードが動作しなくなります。

スイッチ1のコードを1回だけ実行したい場合は、myservo.detach()をブロックに追加することができます。

また、スイッチをクリアすると、適切な回数リサイクルしたいようです。このために、すべてのスイッチが開いているときにmyservo.attach(9)を実行することができます。

別の方法として、detach()とattach()を使用して、条件にワンショットフラグを追加し、条件内にセットし、スイッチがクリアされたときにクリアすることもできます。

例えば:

   if (!s1state & !s2state & !s3state & !s4state) armed = 1;
   ...

   if (armed & s1state == LOW) {    //read the stored input pin value
       armed = 0;
       ...
0
追加された