Go Down

Topic: Wireless control system problem (Read 5 times) previous topic - next topic

Nick Gammon

This works with what I presume is your data:

Code: [Select]
/*

Author: Nick Gammon
Date:   2nd February 2012

example input: .123,100,92,42,99/

*/

// how much serial data we expect before a terminator
const unsigned int MAX_INPUT = 100;
const char TERMINATOR = '/';
const char STARTER = '.';

void setup ()
{
  Serial.begin(115200);
} // end of setup

int middle, thumb, ring, pointer, rotation;

// here to process incoming serial data after a terminator received
void process_data (char * data)
  {

  // convert strings into numbers:

  middle = atoi (strtok (data, ","));
  thumb = atoi (strtok (NULL, ","));
  ring = atoi (strtok (NULL, ","));
  pointer = atoi (strtok (NULL, ","));
  rotation = atoi (strtok (NULL, ","));
 
// control the servos here!

// for now I am displaying what I got ...

  Serial.print ("middle = ");
  Serial.println (middle);
  Serial.print ("thumb = ");
  Serial.println (thumb);
  Serial.print ("ring = ");
  Serial.println (ring);
  Serial.print ("pointer = ");
  Serial.println (pointer);
  Serial.print ("rotation = ");
  Serial.println (rotation);
 
  }  // end of process_data
 

void loop()
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;

  if (Serial.available () > 0)
    {
    char inByte = Serial.read ();

    switch (inByte)
      {

      case TERMINATOR:   // end of text
        input_line [input_pos] = 0;  // terminating null byte
       
        // terminator reached! process input_line here ...
        process_data (input_line);
       
        // reset buffer for next time
        input_pos = 0; 
        break;
 
      case STARTER: 
        // reset buffer
        input_pos = 0;       
        break;
 
      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch

  }  // end of incoming data

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop


Quote
if (Serial.available () > 0)            **change this to something like:  if (Serial.available () > 8) because there are 9 characters **


No. It gets a byte at a time. That's the WHOLE idea.

Quote
char inByte = Serial.read ();              **times this by 9? **


No. It adds to a buffer. You don't do 9 reads. How do you know it is 9? How do you know in advance if you are getting 1-digit, 2-digit, 3-digit numbers? Try to think through what you are sending.

njkl44


This works with what I presume is your data:

Code: [Select]
/*

Author: Nick Gammon
Date:   2nd February 2012

example input: .123,100,92,42,99/

*/

// how much serial data we expect before a terminator
const unsigned int MAX_INPUT = 100;
const char TERMINATOR = '/';
const char STARTER = '.';

void setup ()
{
  Serial.begin(115200);
} // end of setup

int middle, thumb, ring, pointer, rotation;

// here to process incoming serial data after a terminator received
void process_data (char * data)
  {

  // convert strings into numbers:

  middle = atoi (strtok (data, ","));
  thumb = atoi (strtok (NULL, ","));
  ring = atoi (strtok (NULL, ","));
  pointer = atoi (strtok (NULL, ","));
  rotation = atoi (strtok (NULL, ","));
 
// control the servos here!

// for now I am displaying what I got ...

  Serial.print ("middle = ");
  Serial.println (middle);
  Serial.print ("thumb = ");
  Serial.println (thumb);
  Serial.print ("ring = ");
  Serial.println (ring);
  Serial.print ("pointer = ");
  Serial.println (pointer);
  Serial.print ("rotation = ");
  Serial.println (rotation);
 
  }  // end of process_data
 

void loop()
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;

  if (Serial.available () > 0)
    {
    char inByte = Serial.read ();

    switch (inByte)
      {

      case TERMINATOR:   // end of text
        input_line [input_pos] = 0;  // terminating null byte
       
        // terminator reached! process input_line here ...
        process_data (input_line);
       
        // reset buffer for next time
        input_pos = 0; 
        break;
 
      case STARTER: 
        // reset buffer
        input_pos = 0;       
        break;
 
      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch

  }  // end of incoming data

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop


Quote
if (Serial.available () > 0)            **change this to something like:  if (Serial.available () > 8) because there are 9 characters **


No. It gets a byte at a time. That's the WHOLE idea.

Quote
char inByte = Serial.read ();              **times this by 9? **


No. It adds to a buffer. You don't do 9 reads. How do you know it is 9? How do you know in advance if you are getting 1-digit, 2-digit, 3-digit numbers? Try to think through what you are sending.

Alright. So do i even need to send the commas? So i am sending 5 sensor values, once it reads those it store them in a buffer? but then how do i access them and move the servos with them?

PaulS

Quote
So do i even need to send the commas? So i am sending 5 sensor values, once it reads those it store them in a buffer? but then how do i access them and move the servos with them?

Yes, you need to send the commas. If you didn't, how would you know where one value ended and the next began. Here is a string of servo values. Move your servos to the correct positions:
125678011

Now, here is another string:
125,67,8,0,11

The second string allows you to know where to break it, using strtok() to get tokens. With the tokens, you can call atoi() to get integer values that the servos can be moved to.

njkl44


This works with what I presume is your data:

Code: [Select]
/*

Author: Nick Gammon
Date:   2nd February 2012

example input: .123,100,92,42,99/

*/

// how much serial data we expect before a terminator
const unsigned int MAX_INPUT = 100;
const char TERMINATOR = '/';
const char STARTER = '.';

void setup ()
{
  Serial.begin(115200);
} // end of setup

int middle, thumb, ring, pointer, rotation;

// here to process incoming serial data after a terminator received
void process_data (char * data)
  {

  // convert strings into numbers:

  middle = atoi (strtok (data, ","));
  thumb = atoi (strtok (NULL, ","));
  ring = atoi (strtok (NULL, ","));
  pointer = atoi (strtok (NULL, ","));
  rotation = atoi (strtok (NULL, ","));
 
// control the servos here!

// for now I am displaying what I got ...

  Serial.print ("middle = ");
  Serial.println (middle);
  Serial.print ("thumb = ");
  Serial.println (thumb);
  Serial.print ("ring = ");
  Serial.println (ring);
  Serial.print ("pointer = ");
  Serial.println (pointer);
  Serial.print ("rotation = ");
  Serial.println (rotation);
 
  }  // end of process_data
 

void loop()
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;

  if (Serial.available () > 0)
    {
    char inByte = Serial.read ();

    switch (inByte)
      {

      case TERMINATOR:   // end of text
        input_line [input_pos] = 0;  // terminating null byte
       
        // terminator reached! process input_line here ...
        process_data (input_line);
       
        // reset buffer for next time
        input_pos = 0; 
        break;
 
      case STARTER: 
        // reset buffer
        input_pos = 0;       
        break;
 
      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch

  }  // end of incoming data

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop


Quote
if (Serial.available () > 0)            **change this to something like:  if (Serial.available () > 8) because there are 9 characters **


No. It gets a byte at a time. That's the WHOLE idea.

Quote
char inByte = Serial.read ();              **times this by 9? **


No. It adds to a buffer. You don't do 9 reads. How do you know it is 9? How do you know in advance if you are getting 1-digit, 2-digit, 3-digit numbers? Try to think through what you are sending.

So luckily i was reading this over and i saw that there was more code that you posted. code doesnt seem to be very mobile friendly. I added in the servo part and everything. does this look good? do i need the flash(); function if im going to send at 9600?
Code: [Select]
#include <Servo.h>

Servo myservo1;  // create servo object to control a servo
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
Servo myservo6;
Servo myservo7;

// how much serial data we expect before a terminator
const unsigned int MAX_INPUT = 100;
const char TERMINATOR = '/';
const char STARTER = '.';

void setup ()
{
  Serial.begin(9600);
 
   myservo1.attach(2); //middle
   myservo2.attach(3); //thumb
   myservo3.attach(4); //ring
   myservo4.attach(5); //pinky
   myservo5.attach(6); //pointer
   myservo7.attach(7); //swivel
} // end of setup

int middle, thumb, ring, pointer, rotation;

// here to process incoming serial data after a terminator received
void process_data (char * data)
  {

  // convert strings into numbers:

  middle = atoi (strtok (data, ","));
  thumb = atoi (strtok (NULL, ","));
  ring = atoi (strtok (NULL, ","));
  pointer = atoi (strtok (NULL, ","));
  rotation = atoi (strtok (NULL, ","));
 
    myservo1.write(middle);
    myservo2.write(thumb);
    myservo3.write(ring);
    myservo4.write(ring);
    myservo5.write(pointer);
    myservo7.write(rotation);

// for now I am displaying what I got ...

  Serial.print ("middle = ");
  Serial.println (middle);
  Serial.print ("thumb = ");
  Serial.println (thumb);
  Serial.print ("ring = ");
  Serial.println (ring);
  Serial.print ("pointer = ");
  Serial.println (pointer);
  Serial.print ("rotation = ");
  Serial.println (rotation);
 
  }  // end of process_data
 

void loop()
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;

  if (Serial.available () > 0)
    {
    char inByte = Serial.read ();

    switch (inByte)
      {

      case TERMINATOR:   // end of text
        input_line [input_pos] = 0;  // terminating null byte
       
        // terminator reached! process input_line here ...
        process_data (input_line);
       
        // reset buffer for next time
        input_pos = 0; 
        break;
 
      case STARTER: 
        // reset buffer
        input_pos = 0;       
        break;
 
      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch

  }  // end of incoming data

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop

Nick Gammon


So luckily i was reading this over and i saw that there was more code that you posted. code doesnt seem to be very mobile friendly.


It was indeed lucky that you read the code I posted. Otherwise my time would have been wasted.

Go Up