I am doing a project for my university, i made the code and it worked perfectly in tinkercad but when i sent them the code they reported that "after pressing A it woudlnt go back" or "it looks like its stuck trying to go to 180 degrees" so i was wondering if something was wrong with my code.
#include <Servo.h> //Libreria
Servo servo2; // objeto servomotor
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
const int led1 = 7; //Los ojos
const int piezo = 8; //Buzzer
const int pump = 9; //Bomba de agua
int angulo=0; //angulo de los motores
//30,45,60,90,120,135,150,180 grados
void setup(){
Serial.begin(9600);
servo2.attach(2); //la senal pwm se genera en el pin 2
servo3.attach(3); //la senal pwm se genera en el pin 3
servo4.attach(4); //la senal pwm se genera en el pin 4
servo5.attach(5); //la senal pwm se genera en el pin 5
servo6.attach(6); //la senal pwm se genera en el pin 6
pinMode(piezo, OUTPUT);
}
void loop () {
servo2.write(90);
servo3.write(90);
servo4.write(90);
servo5.write(90);
servo6.write(90);
digitalWrite(led1,HIGH);
digitalWrite(pump,LOW);
char x = Serial.read();
if (x == 'A'){//MOver patas frontales a la derecha
servo2.write(180);
servo3.write(180);
delay(300);
servo2.write(30);
servo3.write(30);
delay(600);
}
if (x == 'B'){ //MOver patas frontales a la izquierda
servo2.write(30);
servo3.write(30);
delay(300);
servo2.write(180);
servo3.write(180);
delay(600);
}
if (x == 'C'){ //MOver patas traseras a la derecha
servo4.write(180);
servo5.write(180);
delay(300);
servo4.write(30);
servo5.write(30);
delay(600);
}
if (x == 'D'){ //MOver patas traseras a la izquierda
servo4.write(30);
servo5.write(30);
delay(300);
servo4.write(180);
servo5.write(180);
delay(600);
}
if (x == 'E'){ //MOver la cola
servo6.write(30);
delay(300);
servo6.write(180);
delay(600);
servo6.write(30);
delay(900);
servo6.write(120);
delay(1100);
}
if (x == 'F'){ // Apaga sus ojos
digitalWrite(led1,LOW);
delay(500);
digitalWrite(led1,HIGH);
delay(500);
digitalWrite(led1,LOW);
}
if (x == 'H'){//agacharse(en caso de error inviertan los angulos)
servo2.write(130);
servo3.write(45);
servo4.write(130);
servo5.write(45);
delay(1000);
}
if (x == 'I'){//Ladrar
tone(piezo,261.63,200); //Do durante 0,1 s
delay(100);
tone(piezo,293.66,200); //Do durante 0,1 s
delay(100);
}
if (x == 'L'){//Bomba de agua
digitalWrite(pump,HIGH);
delay(500);
}
}
In real life your circuit would not work because the servos take way more current than you can get from an Arduino 5V pin. The USB can only supply up to 500mA and each individual servo needs at least an amp capacity to handle switch on surges. Also you have no decoupling capacitors on these servos.
I don't use tinkercad or any other sort of emulator.
So ask them why they say that, because apart from the your incorrect use of the serial read the only thing that would stop it from not returning would be that the delay you give it to move to the required position is not long enough.
It depends on how long you want it to run before you have to have new batteries or recharge the ones you have.
A servo motor like the one in the pic can draw up to 800mA of current. I round that to 1 amp per servo. Just to run the servos you'll need 5+ amps available.
Running that much power through a breadboard will not work out well. I build my own servo power distribution boards. If you cannot do such I recommend using a power distribution board of some sort.
the following will always return all your servos to 90deg. shouldn't this only be done once in setup()
there is a read regardless of whether there is anything available. shouldn't this be done after checking if (Serial.available()) { as well as the processing of any received char
you could just do to skip any processing until there is serial input
yes ,
hopefully it's clear that this is somewhat simpler than putting all that code inside the if (Serial.available()) condition (or possibly in a sub-function)
Alright, i placed the servowrites on te setup and placed my code under the !serial.aviable and it works and although i need to return the servomotors to the neutral pose (90) in all of my functions i think this is way more stable and better.
The original use of Serial.read() is fine. The 0xFFFF returned when the buffer is empty will get truncated to 0xFF when saved in 'x' and that will not match any of the letters being tested for. The loop() will repeat. There is very little advantage to either checking Serial.available() or explicitly checking the value returned by Serial.read() for -1.