Good evening people. I really need help with this, i am using a bluetooth module HC-06 to control a servo motor and what i wanna do is: i want it on first command to rotate 90 degrees, and actually stay right there. After, on second command i want it to go back to 0 degrees. I've been looking up other sources for this maneuver and found many instructions, but no logical explanation that'll guide step-by-step on how to do it. Heres how i've been trying to do it
Thanks for your reply, as i have read your thread, it just explains the concept behind the names, not exactly what im looking for. To make it better, sorry if it wasnt clear, what i wanna do is just push forward and backwards a styrofoam door thats like 5cm, basically its just a small application. I was reading about servo.write and it says its just to control the speed and some people uses it to define as distance, mathmatically speaking they arent different concepts, but, thats still not what im looking for. To be very accurate i just wanna move it 90 degrees and then move it back and my code doesnt work.
Hi there -
Reply #1 by @blh64 goes a long way to addressing your issue.
(I wasn't judging your effort - just the Subject should refer to a servo - not a servo-motor...!)
I can see some growth issues in your future by using delay()
Once you address the original problem, look into a simple state-machine timed using millis() with various conditions enumerated -
e.g....
SERVO_IDLE (the default before 'attach' and setting the first position 'state')
SERVO_OPEN
SERVO_CLOSED
There's not ,much more you can do unless you implement partial positions later - just add more states, and code to transition between them.
if (Serial.available() > 0)
{
val = Serial.read();
} else {
//Serial.println("Indisponível");
}
Because val only changes when serial data is received, your code based on the value of val will keep on repeating everytime loop() is called. Is that the intention? Or does the action have to be a once-off?
For the latter, you can 'reset' val in the beginning of loop to e.g. zero.
2)
if (val == 'O')
{
if (porta)
{
...
...
}
if (val == 'P')
{
if (!porta)
What do you think the chances are that val equals 'O' and a little later equals 'P'? if (val == 'P') will never evaluate to true. You possibly have a } in the wrong place; properly indenting using tools->autoformat in the IDE might help you to visualise the flow of your program better.
{
val = Serial.read();
} else { //Serial.println("Indisponível");
}
Because *val* only changes when serial data is received, your code based on the value of *val* will keep on repeating everytime loop() is called. Is that the intention? Or does the action have to be a once-off?
For the latter, you can 'reset' *val* in the beginning of loop to e.g. zero.
**2)**
if (val == 'O')
{
if (porta)
{
...
...
}
if (val == 'P')
{
if (!porta)
What do you think the chances are that *val* equals 'O' and a little later equals 'P'? *if (val == 'P')* will never evaluate to true. You possibly have a } in the wrong place; properly indenting using tools->autoformat in the IDE might help you to visualise the flow of your program better.
Hey man thanks for your reply, reason why the code looks weird its because its how im doing it to read via the bluetooth module i use the val to check if any characters were sent to start enabling leds on my project, the reason why theres a missplaced } its probably from when i edited to code to post it here.
Now following the #1 post, made blh64, i tried again here's how i tried this time:
#include <Servo.h>
Servo myservo;
bool porta = false;
int pos = 0;
void setup() {
myservo.attach(7);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0)
{
val = Serial.read();
} else {
//Serial.println("IndisponÃvel");
}
if (val == 'O')
{
switch (porta)
{
if (pos < 90)
{
case false:
porta = true;
for (int x = 0; x < 90; x++)
{
myservo.write(x);
delay(15);
}
}
else if (pos >= 90)
{
case true:
porta = false;
for (int y = 90; y > 0; y--)
{
myservo.write(y);
delay(15);
}
}
}
}
}
whats this code doing now is: it goes from position 0 to 90 continuosly, but thats not what i want, i would like it to toggle positions, for instance: when it reads 'O' i need it to go to 90 and stay here, if it reads 'O' again i need it to go back to 0, and as long as i press 'O' it repeats the process.
I figured it out, after a few more attempts this is how it works:
#include <Servo.h>
Servo myservo;
bool porta = false;
int pos = 0;
void setup() {
myservo.attach(7);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0)
{
val = Serial.read();
} else {
//Serial.println("IndisponÃvel");
}
if (val == 'O')
{
switch (porta)
{
if (pos < 90)
{
case false:
porta = true;
for (int x = 0; x < 90; x++)
{
myservo.write(x);
delay(15);
}
}
break;
}
}
if(val == 'P')
{
switch(porta)
{
if(pos >= 90)
{
case true:
porta = false;
for(int y = 90; y > 0; y--)
{
myservo.write(y);
delay(15);
}
}
break;
}
}
if(val == 'P')
{
switch(porta)
{
if(pos >= 90)
{
case true:
porta = false;
for(int y = 90; y > 0; y--)
{
myservo.write(y);
delay(15);
}
}
break;
}
}
}
Edit: added Serial.begin(0); as i had forgotten
@UKHeliBob as long as i dont send messages to the serial monitor it works just fine, but that wasnt really impacting on the code as it deals mostly with the bluetooth part. But anyways, thats about it, thanks for directing me towards the right direction, guys!
Your code does not compile; it's missing the declaration of val. And my comment about val still stands; it's remembered till you change it. You can remove val from the globals and use
void loop()
{
char val = 0;
...
...
}
Further I have big doubts of you can use an if inside a switch in the way you do. The syntax
switch(porta)
{
case true:
...
...
break;
case false:
...
...
break;
}
You can use if statements inside the cases.
In reply to reply#8
Same comments, it does not compile for the same reason stated above. Below a reworked version; not tested. Remove your char val; from the global 'section'.
void loop()
{
// val is now a local variable
char val = 0;
if (Serial.available() > 0)
{
val = Serial.read();
}
else
{
//Serial.println("IndisponÃvel");
}
if (val == 'O')
{
if (porta == false && pos < 90)
{
porta = true;
for (int x = 0; x < 90; x++)
{
myservo.write(x);
delay(15);
}
}
}
if (val == 'P')
{
if (porta == true && pos >= 90)
{
porta = false;
for (int y = 90; y > 0; y--)
{
myservo.write(y);
delay(15);
}
}
}
}
And the below will probably do the same (again not tested)
void loop()
{
char val = 0;
if (Serial.available() > 0)
{
val = Serial.read();
}
else
{
//Serial.println("IndisponÃvel");
}
if (val == 'O' && pos < 90)
{
for (int x = 0; x < 90; x++)
{
myservo.write(x);
delay(15);
}
}
if (val == 'P' && pos >= 90)
{
for (int y = 90; y > 0; y--)
{
myservo.write(y);
delay(15);
}
}
}