0

I am working on a project to wirelessly control a continuous rotation servo...something like a wireless vending machine. The problem I am having is controlling how many revolutions the servo is making. During testing I used a button and had no issues getting the delay to work properly. Now that it's connected to the HC-12 RF module I can't get the delay to control how many rotations the servo makes. The servo I'm using is the FS90R.

#include <SoftwareSerial.h>
#include <Servo.h>
SoftwareSerial mySerial(2, 3); // RX, TX
Servo badservo;

int pos = 92;
unsigned long last = millis();

void setup() {
  mySerial.begin(9600);
  badservo.attach(9);
  badservo.write(pos);
}

void loop() {
  if(mySerial.available() > 1){
    int input = mySerial.parseInt();//read serial input and convert to integer (-32,768 to 32,767)
    int servpos = badservo.read();
    if(millis() - last > 250){
      if(servpos == 92 && input == 1234){
        badservo.write(0);
        delay(470);
        //mySerial.println(8894);
      }
      else{
        badservo.write(pos);
        //mySerial.println(8894);
      }
    }
  mySerial.flush();//clear the serial buffer for unwanted inputs
  last = millis();
  }
  delay(20);//delay little for better serial communication
}

With the servo that I'm using has a stop position of 92, meaning when I do servo.write(92); it will stop the servo. Also, the 470 delay was tested with a button and was a single full rotation.

Now, with the HC-12 module, I can't get the servo to rotate less than 2.5 times. Anyone have any idea what I'm doing wrong? The goal is to get the servo to rotate only once when the RF module receives the proper signal.

  • Feeling that adding a delay to a serial receive routine will result in "better serial communication" is pretty much always a bad idea, and indicates a severely broken underlying design. You probably don't want to call flush() either - what you want, is sound event-driven code. – Chris Stratton Jun 12 '17 at 16:43
0

You can't rely on a specific delay being one rotation - especially when you are using SoftwareSerial. SoftwareSerial breaks many things, and anything that uses interrupts (such as the Servo library) gets broken by it. It's a real interrupt hog.

The proper way of doing it is to use a rotary encoder on the servo to report the position (or change in position) so that you know where the servo is. That's really the only reliable method of getting the servo to perform precise operations.

By the way:

mySerial.flush();//clear the serial buffer for unwanted inputs

does absolutely nothing. The operation of flush() changed when the Arduino API turned one. It is now supposed to wait until both the TX circular buffer and the UART TX FIFO are empty. It has nothing to do with emptying any inputs. Instead you want:

while (mySerial.read() != -1);
  • Thanks for clearing that up! Which library would you recommend for communication with the HC-12 wireless device? – user1675042 Jun 12 '17 at 14:47
  • There are numerous alternatives to SoftwareSerial, and most of them are considerably better - but all software serial implementations suck. You really want to use hardware serial, but most small Arduino boards only have one UART which is used by the USB interface. – Majenko Jun 12 '17 at 14:53
  • Ah. I should note that I'm using a Arduino Pro Mini for this project as everything has to be very compact. Can you point me to any resources that will help with this? There's a lot of info out there in the few Google searches I just did. – user1675042 Jun 12 '17 at 15:03
  • You might consider the Teensy-LC instead; I believe it has multiple hardware serial ports, and is quite small. However, it introduces the complexity of its own IDE plugin. It should be possible to get this to work, if awkwardly, with an ordinary Arduino and soft serial. – Chris Stratton Jun 12 '17 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.