Servo won't stay in position

Hello there,

I am currently trying to successfully write a script for two HC-12 Wireless Serial Port Communication Modules that will move a servo 90 degrees when a pushbutton is pressed. This requires the use of two arduino unos. The first arduino (the sender) is wired up to a button as well as an HC-12 module. The second arduino (the receiver) is hooked up to a servo (with an external 6v source) as well as another HC-12 module. When the button is pressed a wireless signal is sent from one arduino to the other.

The problem that I am having is the servo will not stay in a position when I push the button, it just quickly moves to that position and then goes back to its original position. I want the servo to move to 90 degrees when the button is pressed once and stay in that position. Now when I press the button a second time I want the servo to move to 10 degress and stay in that position.

Could anyone help me out and show me what I am doing wrong?

Here is my code for the receiving arduino:

#include <SoftwareSerial.h>

#include <Servo.h>

SoftwareSerial mySerial(2, 3); // RX, TX

int servopin = 9;

Servo servo1;

void setup() {
  mySerial.begin(9600);
  pinMode(servopin, OUTPUT);
  servo1.attach(9);
}

void loop() {
   
  if(mySerial.available() > 1){    
    int input = mySerial.parseInt();//read serial input and convert to integer (-32,768 to 32,767)    
    if(input == 1111){//if on code is received
      servo1.write(90);
      delay(5);
    }
    if(input == 0000){//if off code is received
      servo1.write(10);
      delay(5);
    }
  }
  mySerial.flush();//clear the serial buffer for unwanted inputs     
  
  delay(20);//delay little for better serial communication
 
}

And here is the code for the sending arduino:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); //RX, TX

int buttonPin = 8;
boolean onOff = 0;
void setup() {
  pinMode(buttonPin, INPUT);
  mySerial.begin(9600);
}

void loop() {
 
  int buttonState = digitalRead(buttonPin);//read button state
  
  if(buttonState == 1){//if button is down
    mySerial.println(1111);//send unique code to the receiver to turn on. In this case 1111
    onOff = 1;//set boolean to 1
  }
  if(buttonState == 0 && onOff == 1){//Verifier to send off signal once
    mySerial.println(0000);//send unique code to the receiver to turn off. In this case 0000
  }
  delay(20);//delay little for better serial communication
}

Thank you!

What's the point of this

if(buttonState == 0 && onOff == 1)

Thank you for pointing that out. I tested out the script without that line and the servo will stay in position for about 5 seconds and then moves back.

You're needlessly endlessly sending '1111' when the button is down, and I think you were trying to limit the inundation when the button is up with that little bit.
But after you press the button, "onOff = 1" and stays that way forever. Nothing ever changes it, so it's not doing what you imagine it doing.

You don’t want to tie your variable to the ever-changing digitalRead(buttonPin).

Look up the info on state change detection, the code is super short and will do what you want it to do. Basically says “if this new reading of the button state is different than what it was previously, do stuff”

It will then only send your ‘1111’ or ‘0000’ once per button push. You can make it send a few times if you need the redundancy for reliability but highly likely unnecessary.

Thank you very much for all of your information. I am looking into state change detection right now. Hopefully I can get this to work.

Why have you started another thread on this subject? You already started one two days ago, then came back to it and added your code today. You didn't need this second thread.
HC-12 and Servo

Sorry about that. It wont happen again.

Okay so I have looked into state change detection and I have incorporated into my sender sketch. So now what is happening is when I press the button one time the servo moves back and forth continuously until I press the button again, and the servo will then stay in its initial position.

Does anybody know why my servo will not stay at 90 degrees after I push the button once?

Here is my new sketch for the sender:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); //RX, TX

const int buttonPin = 8;

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  pinMode(buttonPin, INPUT);
  mySerial.begin(9600);
}

void loop() {
 
  int buttonState = digitalRead(buttonPin);//read button state
  
    // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
 
 
  if (buttonPushCounter % 2 == 0) {

    mySerial.println(1111);//send unique code to the receiver to turn on. In this case 1111
     
} else {
    mySerial.println(0000);
  }

  delay(20);//delay little for better serial communication
}

Here is my new sketch for the receiver:

#include <SoftwareSerial.h>

#include <Servo.h>

SoftwareSerial mySerial(2, 3); // RX, TX

int servopin = 9;

Servo servo1;


void setup() {
  mySerial.begin(9600);
  pinMode(servopin, OUTPUT);
  servo1.attach(9);
}

void loop() {
   
  if(mySerial.available() > 1){    
    int input = mySerial.parseInt();//read serial input and convert to integer (-32,768 to 32,767)    
    if(input == 1111){//if on code is received
      servo1.write(90); 
    }
  if(input == 0000){
      servo1.write(0);
  }
  mySerial.flush();//clear the serial buffer for unwanted inputs     
  
  delay(50);//delay little for better serial communication
 
}
}

Thank you

Your sender seems more or less fine.

Try a noticeably long delay before you flush. See what that does.

I have tried a few different delays and still no luck.

I am still having a tough time trying to figure out why the servo is doing this and won't stay at 90 degrees.

take out

if(input == 0000){
servo1.write(0);

After some trial and error I have figured out that it does not want to work with certain servo positions. If I use 170 degrees instead of 90 degrees everything works smoothly. I wonder why that is..