伺服电机不适用于特定代码

时间:2021-04-24 20:58:24

标签: interrupt arduino-uno servo

我编写了一个带有中断的代码来控制伺服,但我的伺服不工作。一个用于中断工作,但另一个必须简单地移动但它也不起作用。即使串行窗口显示代码工作正常,但伺服器没有移动我已经用相同的连接检查了我的两个伺服器和 Arduino 的扫描示例,两者都工作正常。

struct ContentView : View {
    @State var birthyear = 1999
    @State var stringBirthyear = ""
    
    var birthyearBinding : Binding<String> {
        .init {
            print("returning",birthyear)
            return "\(birthyear)"
        } set: { (newValue) in
            if let intVal = Int(newValue) {
                DispatchQueue.main.async {
                    print("Setting birthyear to",intVal)
                    self.birthyear = intVal
                }
            }
        }
    }
    
    var body: some View {
        Text("\(birthyear)")
        TextField("Birth Year", text: $stringBirthyear)
            .keyboardType(.numberPad)
            .onReceive(Just(stringBirthyear)) { newValue in
                let filtered = newValue.filter { "0123456789".contains($0) }
                if filtered != newValue {
                    print(filtered,newValue)
                    stringBirthyear = filtered
                }
                if let intVal = Int(filtered) {
                    birthyear = intVal
                }
            }
            .onAppear {
                stringBirthyear = "\(birthyear)"
            }
    }
}

我用这段代码一一测试了我的电机,它们工作得非常好:

   #include <TimerOne.h>                                 // Header file for TimerOne library
#include <Servo.h>
#define trigPin 12                                    // Pin 12 trigger output
#define echoPin 2                                     // Pin 2 Echo input

#define echo_int 0                                    // Interrupt id for echo pulse

#define TIMER_US 50                                   // 50 uS timer duration 
#define TICK_COUNTS 4000                              // 200 mS worth of timer ticks

volatile long echo_start = 0;                         // Records start of echo pulse 
volatile long echo_end = 0;                           // Records end of echo pulse
volatile long echo_duration = 0;                      // Duration - difference between end and start
volatile int trigger_time_count = 0;                  // Count down counter to trigger pulse time
volatile long range_flasher_counter = 0;              // Count down counter for flashing distance LED


int sound = 250;

Servo servo1; //Servos
Servo servo2;


const int button1 = 10; //Buttons
const int button2 = 8;
const int button3 = 13;
const byte interruptPin = 3;
int pos;


void setup() {
  servo1.attach(9); // servo for arm
  servo2.attach(5); // servo for base
  pinMode(trigPin, OUTPUT);                           // Trigger pin set to output
  pinMode(echoPin, INPUT);                            // Echo pin set to input
                      // Onboard LED pin set to output
  
  Timer1.initialize(TIMER_US);                        // Initialise timer 1
  Timer1.attachInterrupt( timerIsr );                 // Attach interrupt to the timer service routine 
  attachInterrupt(echo_int, echo_interrupt, CHANGE);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin),Metal_detected, HIGH);

  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly: 


  servo1.write(0); // These will make the servos move to the mapped angles
  servo2.write(90);
  
  distance_checking();
  if(digitalRead(button1) == HIGH)
  {
   
      while(digitalRead(button2) == LOW)
        {
          Serial.println("Entering Sweeping mode");
       for (pos = 30; pos <= 150; pos += 1)
       { Serial.print("Angle is :");
         Serial.println(pos);
         servo2.write(pos);              
         distance_checking();
         //delay(0.1);                       // waits 15ms for the servo to reach the position
         if(digitalRead(button2) == HIGH)
          { 
            Serial.print("Exiting Sweeping");
            goto label;}
          }
          for (pos = 150; pos >= 30; pos -= 1) { // goes from 180 degrees to 0 degree
          Serial.print("Angle is :");
          Serial.println(pos);
          servo2.write(pos);              // tell servo to go to position in variable 'pos'
          distance_checking();
          //delay(0.1);                       // waits 15ms for the servo to reach the position
          if(digitalRead(button2) == HIGH)
          {
            goto label;
            Serial.print("Exiting Sweeping");}
          }

 }
 }
//reset th
label:
  if(digitalRead(button2) == HIGH){ 
    
    servo1.write(0);
    servo2.write(90);
    Serial.println("press the sweeping button to enter sweeeping mode");
    delay(300);
  }

} 


void distance_checking()
{ 

if (echo_duration/58 <= 20) 
{
Serial.println("the servo angle is 30");
servo1.write(30);
delay(1500);
}

else {
servo1.write(0);
}

delay(500);
}





void Metal_detected()
{if(digitalRead(button2) == LOW)
{delay(5000);
  Serial.print("Metal detected at servo angle:");
Serial.println(servo2.read());
servo1.write(servo1.read());
servo2.write(servo2.read());
Serial.println("Motion is stopped");
Serial.println("Press reset to go to the home position");


}
//while(digitalRead(button2) == HIGH)
// {
//  Serial.print("Reseting");
//  return 0;}
 }
void timerIsr()
{
    trigger_pulse();                                 // Schedule the trigger pulses
                             // Flash the onboard LED distance indicator
}

// --------------------------
// trigger_pulse() called every 50 uS to schedule trigger pulses.
// Generates a pulse one timer tick long.
// Minimum trigger pulse width for the HC-SR04 is 10 us. This system
// delivers a 50 uS pulse.
// --------------------------
void trigger_pulse()
{
      static volatile int state = 0;                 // State machine variable

      if (!(--trigger_time_count))                   // Count to 200mS
      {                                              // Time out - Initiate trigger pulse
         trigger_time_count = TICK_COUNTS;           // Reload
         state = 1;                                  // Changing to state 1 initiates a pulse
      }
    
      switch(state)                                  // State machine handles delivery of trigger pulse
      {
        case 0:                                      // Normal state does nothing
            break;
        
        case 1:                                      // Initiate pulse
           digitalWrite(trigPin, HIGH);              // Set the trigger output high
           state = 2;                                // and set state to 2
           break;
        
        case 2:                                      // Complete the pulse
        default:      
           digitalWrite(trigPin, LOW);               // Set the trigger output low
           state = 0;                                // and return state to normal 0
           break;
     }
}

// --------------------------
// echo_interrupt() External interrupt from HC-SR04 echo signal. 
// Called every time the echo signal changes state.
//
// Note: this routine does not handle the case where the timer
//       counter overflows which will result in the occassional error.
// --------------------------
void echo_interrupt()
{
  switch (digitalRead(echoPin))                     // Test to see if the signal is high or low
  {
    case HIGH:                                      // High so must be the start of the echo pulse
      echo_end = 0;                                 // Clear the end time
      echo_start = micros();                        // Save the start time
      break;
      
    case LOW:                                       // Low so must be the end of hte echo pulse
      echo_end = micros();                          // Save the end time
      echo_duration = echo_end - echo_start;        // Calculate the pulse duration
      break;
  }
}

0 个答案:

没有答案