text control servo

hi

i'd like to control my servo by typing the angle of rotation on my keyboard and sending this number over a serial connection to my arduino,

'till so far i came up with a (very simple, partially copy-pasted) code
though the problem is that the servo turns to the ascii value of the number i typ in my serial monitor

how can i convert this string of ascii value to a proper int?

#include <Servo.h>

Servo pietje;

int servoangle;

void setup()
{
pietje.attach(9);
Serial.begin(9600);
Serial.println(" at least there's a connection ");
Serial.println(" so therefor hi ");
}

void loop()
{ if (Serial.available() > 0)

servoangle = Serial.read();
pietje.write(servoangle);
delay(15);
}

You'll need to accumulate serial characters into a character array, and then, when you get a RETURN, terminate the string and convert it to an integer with 'atoi()'. Start with a character array declaration:

char buf[32];

Then:

buf[i++] = ch;

And:

buf[i] = '\0';
val = atoi(buf);

Hope that helps!

There is some example code for doing this in the playground : Arduino Playground - Servo

You may need to modify the code slightly for the servo library you are using but this should give you one idea on how to do what you want.

tnx so far

i'm going to have a look right away

Hello again,

Still working on the pietje servo script.
So far i've got it working. The serial.read values get pushed in to an array. The storage value expected by this array is 3. I want to be able to leave the storage value varaiable (between 2 and 4). The way it works now is as followed:

if i type 1 and send it through the serial interface the buffer array doesn't get printed until it has 2 values in storage.

char buffer[3];

i want to be able to type in 1 and the servo rotates to 1 degrees.
If i type 180 the servo rotates to 180 degrees, if i type 67 the servo rotates to 67 degrees and so on.

The buffer value needs to be read each time after a value get send through the serial interface.

Hope it makes sense

Thanks in advance.

#include <Servo.h>
#include <stdlib.h>     // needed for atoi
char buffer[3];
int received;

Servo pietje;  


 

void setup()
{
 pietje.attach(9);  
 Serial.begin(9600);
 Serial.println(" ready ");

}

void loop()
{ 
  
  if (Serial.available())
    {
        buffer[received++] = Serial.read();
        buffer[received] = '\0';
        if (received >= (sizeof(buffer)-1))
        {
          int servoangle = atol(buffer);
            Serial.println(buffer);
            received = 0;
            //servoangle = map(servoangle, 0, 99, 0, 179); // this scales the value 0 to 99 between 0 to 180. So 99 = 180 and 00 = 0.
            pietje.write(servoangle); 
          }
    }        
  delay(15);                          
}

i want to be able to type in 1 and the servo rotates to 1 degrees.
If i type 180 the servo rotates to 180 degrees

You can't really do that without having some method to differentiate between '1' meaning 1 degree and '1' as the first digit in '180'.

The code linked in my previous post shows one way of doing that. It collects digits from the serial port until it finds a value that can't be a digit which terminates the digit collection and writes the value.

I think your code waits for two digits and uses this as a percentage of movement between 0 and 180 degrees. Is that what you want?

Hello

So i have figured some stuff out and created the following:

#include <Servo.h>
#include <stdlib.h>     // needed for atoi

char buffer[3];
int received;

Servo pietje;  

void setup()
{
 pietje.attach(9);  
 Serial.begin(9600);
 Serial.println(" ready ");
 
}

void loop()
{ 
  
  if (Serial.available())
    {
        buffer[received++] = Serial.read();
        buffer[received] = '\0';
         
        if (received == (sizeof(buffer)))
        {
          Serial.print("buffer");
            Serial.println(buffer);
            Serial.print("first buffer pointer after R of L ");
            Serial.println(buffer[1]);
            Serial.print("second buffer pointer after R of L ");
            Serial.println(buffer[2]);
            int firstletter = buffer[0];
            char finalval[2] = {buffer[1], buffer[2]};
            int servoangle = atol(finalval);
            Serial.print("finalval in char typecast =");
            Serial.println(finalval);
            Serial.print("ascii value of firstletter = ");
            Serial.println(firstletter);
            Serial.print("servoangle in int typecast=");
            Serial.println(servoangle);     
            
           if(firstletter == 82){
              Serial.println("waarde was R");
              int angle = 90 + servoangle;
              Serial.print("angle =");
              Serial.print(angle);
              pietje.write(angle); 
            }
            
           if(firstletter == 76){
             Serial.println("waarde was L");
             int angle = 90 - servoangle;
             Serial.print("angle =");
             Serial.print(angle);
             pietje.write(angle);    
           }
           
           if(firstletter == 48){
            Serial.println("Waarde was 0");
            int angle = 90; 
            pietje.write(angle);
           }
           received = 0; 
      }  // end if received sizeof buffer
// this is where i tried to create some sort or reset function but it didn't work.
     /* else   
      {
       memset(buffer, 0, 2); 
      }*/
   }  // end if serial.availeble
  delay(10);                          
}

It reacts pretty well
if i type R90 it rotates to 180 degrees
if i type L90 it rotates to 0 degrees
if i type 000 it rotates to 90 degrees

The thing is that if i accidently typ R7 (only 2 characters) it doesn't
work anymore.

So to overcome this problem i would like to build in a reset function.
to clear all the characters in the buffer[3] array.

i can't figure out wher to put this reset function or what if statement i should create to get this going.

Thanx in advance

to reset the buffer you just need to set the variable received to 0.

First, your buffer is too small. You reserve three bytes for incoming characters, and when you receive a character, you write a '\0' to terminate the string. The third time you do this, you put a 0 byte into memory beyond the end of the buffer, probably inside the memory that stores the received variable.

Second, it's not a good idea to use constants like 82 or 76. If you type the letter 'R' or 'L' in single quotes, it uses the number for that character. Then you don't have to explain things in comments or prints. The code functions the same, but now it's more readable for humans. Source code is for humans.

As mem explained, if you want to reset the buffer, you just need to reset your integer received = 0, so the next time you type a character, you put it at the right spot. Otherwise, you'll be messing up more and more memory beyond the end of the buffer. Personally, I would also return to a zero-length string at that time, with a buffer[0] = '\0'; statement.