Go Down

### Topic: A Problem Restarting A Loop, I Think. (Read 494 times)previous topic - next topic

#### Just_Rhys

##### Jul 12, 2018, 10:02 amLast Edit: Jul 12, 2018, 10:03 am by Just_Rhys
Hello all, I am trying to control a servo using the serial monitor. I want to input a rotational velocity (deg/s) and the motor will hit that within the positional constraints I set. Simple enough. And I have got it to do it once and stay at that velocity oscillating as I want. But I can't get the thing to change its speed again.

I want to be able to type various velocities into the serial monitor and have it change when there is a new input. I'm relatively new to code and very new to Arduino, I know I could achieve this with certain loops in certain places but for the life of me I can't work it out.

Here is my code so far:

Code: [Select]
`#include <Servo.h>Servo myservo;  // create servo object to control a servoint pos = 0;    // variable to store the servo positionlong val = 0; // New Speedint input =0;char incomingByte;void setup() {    Serial.begin(9600);    Serial.println("Enter A New Velocity (deg/s)"); //Write instructions    myservo.attach(9);     //Setting servo pin} void loop() {    if(Serial.available()){ //Checks that there is data in the buffer?      input = 0;       while (1) {      incomingByte = Serial.read();      if (incomingByte == '\n') break; // exit the while(1), we're done receiving       if (incomingByte == -1) continue; // if no characters are in the buffer read() returns -1      input *=10; //shift left 1 decimal place      input = ((incomingByte - 48)+input); //Converting ASCII to integer, add, and shift, left one decimal place           }         Serial.print("New Speed:");      Serial.print(input);      Serial.println("(deg/s)");    }       while(input = input){   for (pos = 0; pos <= 80; pos += input) { // goes from 0 degrees to 180 degrees    // in steps of 1 degree    myservo.write(pos);              // tell servo to go to position in variable 'pos'    delay(15);             // waits 15ms for the servo to reach the position  }  for (pos = 80; pos >= 0; pos -= input) { // goes from 180 degrees to 0 degrees    myservo.write(pos);              // tell servo to go to position in variable 'pos'    delay(15);                       // waits 15ms for the servo to reach the position  }    }}`

I know the connection works as running basic servo code runs everything fine. I am using an Arduino Uno and the standard Tower Pro micro servo motor.

Thank you in advance.

#### teunman

#1
##### Jul 12, 2018, 10:15 am
First of all don't run a servo of just the arduino since this can damage the arduino.

Where and how do you think you are setting the velocity of the servo?

#### wvmarle

#2
##### Jul 12, 2018, 10:23 am
The moment you have a Serial.available() you're going to get stuck in the while(1) loop until you receive a \n character. That's a pretty bad idea.

But after clearing that hurdle you're ending up stuck in the while(input = input) loop forever (no idea what you're really trying to there in the first place as the statement doesn't make sense).
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

#### Just_Rhys

#3
##### Jul 12, 2018, 10:38 am
I understand not to run servos on the Arduino but this is the starter kit servo and it's managed before so it should be fine but I will look into a better power supply later.

I think I am setting the velocity at the bottom where 'input' is the for loop condition. Once it gets there the other for loop takes it back and they go back and fourth, oscillating the servo.

Okay, I'll clear that hurdle and keep trying.

The while input = input loop was an attempt at having the loop run constantly but change when a new input is sent. I realise that probably isn't the best way to do it and it in fact does not do it but I can't think of another way to do it.

#### TomGeorge

#4
##### Jul 12, 2018, 10:42 am
Hi,
Can you post a schematic of how you have connected your project please?

Do you have a DMM to measure some voltages on your project?

Thanks.. Tom..
Everything runs on smoke, let the smoke out, it stops running....

#### Just_Rhys

#5
##### Jul 12, 2018, 10:47 am
Dead easy connections, servo is connected to 5V port, the ground port and the 9 attachment port on the Arduino uno which is connected via USB to my laptop. No way to measure voltages on me I dont think, what are yout thinking I could do with that?

#### wvmarle

#6
##### Jul 12, 2018, 10:49 am
loop() will run constantly by itself.

To check for a change you need to store the old value in a separate variable, comparing something to itself is always correct.

Then you're not comparing, you're assigning. A = is assignment; a == is boolean comparison.

There's a "serial input basics" tutorial around here, look it up.

Don't wait for Serial input - grab characters as they come in, store them in a char array, then when you see your terminating \n you process that string (look at atoi() for easy conversion to int).

So for you the Serial input should look more like this (untested; may have typos):
Code: [Select]
`char input[5]; // store values 0-9999.byte index;int speed;void loop() {  if (Serial.available()) {    char c = Serial.read();    if (c == '\n') {      input[index] = 0; // null termination      speed = atoi(input);      index = 0;    }    else {      input[index] = c;      index++;    }  }  // Servo code here - without while loops, loop() is doing that for you.}`

Some things left for you to add: input validation and making sure your buffer doesn't overrun.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

#### Just_Rhys

#7
##### Jul 12, 2018, 11:06 am
Very helpful thank you. I will look into and implement all of that soon and update on my progress.

#### Just_Rhys

#8
##### Jul 12, 2018, 08:50 pm
I still can't get it to work even trying to use your adaption. Below is the code that I am trying to use now except now it isn't even oscillating for any, even the first, input. I have no idea where it's going wrong.

Code: [Select]
`#include <Servo.h>Servo myservo;  // create servo object to control a servoint pos = 0;    // variable to store the servo positionlong val = 0; // New Speedbyte index;char input [3];char incomingByte; void setup() {    Serial.begin(9600);    Serial.println("Enter A New Velocity (deg/s)"); //Write instructions    myservo.attach(9);     //Setting servo pin} void loop() {    if(Serial.available()){ //Checks that there is data in the buffer?      incomingByte = Serial.read();      if (incomingByte == '\n');{ // If we hit enter      val = atoi(input);      input[index] = 0;}    }else {        input[index] = incomingByte;        index++;}            Serial.print("Input Speed:");      Serial.print(val);      Serial.println(); //Giving Space       for (pos = 0; pos <= 80; pos += val) { // goes from 0 degrees to 180 degrees    // in steps of 1 degree    myservo.write(pos);              // tell servo to go to position in variable 'pos'    delay(15);             // waits 15ms for the servo to reach the position  }  for (pos = 80; pos >= 0; pos -= val) { // goes from 180 degrees to 0 degrees    myservo.write(pos);              // tell servo to go to position in variable 'pos'    delay(15);                       // waits 15ms for the servo to reach the position  }    }`

#### MorganS

#9
##### Jul 12, 2018, 09:41 pm
index never gets set back to zero after recognizing the \n.

You set the last byte in the input to the null character AFTER trying to read the input number. Swap the order of those two lines. Otherwise if you entered "12" and the next entry is "3" then the array contains "32".

You never check if you exceed the bounds of the input[3] array. If you entered "123" then you will be writing to a memory location you don't own.

The prompt to enter a speed prints on every oscillation instead of just printing once each time a new number is entered.
"The problem is in the code you didn't post."

#### Just_Rhys

#10
##### Jul 12, 2018, 09:51 pmLast Edit: Jul 12, 2018, 09:52 pm by Just_Rhys
Okay, thank you, that made a lot of sense but I have changed those things around and I'm still not getting an output. And it doesn't like the nestled if statement within the other if statement. Gives an error that '}' is expected before 'else'.

Code: [Select]
`#include <Servo.h>Servo myservo;  // create servo object to control a servoint pos = 0;    // variable to store the servo positionlong val = 0; // New Speedbyte index;char input [3];char incomingByte; void setup() {    Serial.begin(9600);    Serial.println("Enter A New Velocity (deg/s)"); //Write instructions    myservo.attach(9);     //Setting servo pin} void loop() {    if(Serial.available()){ //Checks that there is data in the buffer?      incomingByte = Serial.read();       if (incomingByte == '\n');{ // If we hit enter      Serial.print("Input Speed:");      Serial.println(); //Giving Space      input[index] = 0;      val = atoi(incomingByte);      Serial.print(val);    }    else {        input[index] = incomingByte;        index++;    }      for (pos = 0; pos <= 80; pos += val) { // goes from 0 degrees to 180 degrees    // in steps of 1 degree    myservo.write(pos);              // tell servo to go to position in variable 'pos'    delay(15);             // waits 15ms for the servo to reach the position  }  for (pos = 80; pos >= 0; pos -= val) { // goes from 180 degrees to 0 degrees    myservo.write(pos);              // tell servo to go to position in variable 'pos'    delay(15);                       // waits 15ms for the servo to reach the position  }    }}`

Any more ideas?

#### MorganS

#11
##### Jul 12, 2018, 09:52 pm
Use the control-T auto format feature in the IDE. It will help you find the missing }
"The problem is in the code you didn't post."

#### TolpuddleSartre

#12
##### Jul 12, 2018, 09:55 pmLast Edit: Jul 12, 2018, 09:55 pm by TolpuddleSartre
Code: [Select]
`if (incomingByte == '\n');`Whoops

No amount of ctrl-T is going to find that one.

#### Just_Rhys

#13
##### Jul 12, 2018, 09:59 pm
The error still holds. The only thing I can think is that I'm missing some kind of protocol when putting an if … else statement within another if statement...

Code: [Select]
`if (incomingByte == '\n');`Whoops

No amount of ctrl-T is going to find that one.
Bloody hell :') Thanks for the catch there. I fixed that and still no output mind, hopefully there's another stupid thing like that maybe?

#### MorganS

#14
##### Jul 12, 2018, 09:59 pm
Yes, because the lines below that if(); will not be indented as expected.
"The problem is in the code you didn't post."

Go Up