Go Down

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

njkl44




Are you talking about something like this?



Why do you keep ignoring what Nick Gammon tells you? You code looks nothing like what he is suggesting.

I'm trying to understand what he's saying and learn. I need to start somewhere

PaulS

Quote
I'm trying to understand what he's saying and learn.

He's telling you that you can't check to see that there is at least one character available to read, and then assume that that means you can read as many as you want. What's so hard to understand about that?
The art of getting good answers lies in asking good questions.

njkl44

What do you suggest about doing it a different way? I need this to work for a few hours or so. I had code that worked before but after a few minutes it got all weird.

PaulS

Quote
but after a few minutes it got all weird.

Because you are not checking that there IS something to read before EVERY read.
The art of getting good answers lies in asking good questions.

njkl44


Quote
but after a few minutes it got all weird.

Because you are not checking that there IS something to read before EVERY read.


So something like this?
Code: [Select]
   


   if (Serial.available())
   vals[0] = Serial.read();
if (Serial.available())
   Serial.read();
if (Serial.available())
   vals[1] = Serial.read();

   

PeterH

You are not thinking about this, you are trying stuff at random.

Look at that code and work through in your mind what will happen when it runs, bearing in mind that the code runs much faster than the serial port can receive data. Think about it in terms of a real-world analogy if it helps.

Somebody is sending you postcards. You can check the letterbox as often as you like. Sometimes there will be a postcard there, sometimes there won't. Now, how are you going to make sure you receive the complete set of cards and keep them all in order?

Nick Gammon has told you what you're doing wrong and how to do it right. Either take his advice and do it like he showed you, or stop and THINK about what you need to do to read a sequence of bytes from a serial port.

njkl44


You are not thinking about this, you are trying stuff at random.

Look at that code and work through in your mind what will happen when it runs, bearing in mind that the code runs much faster than the serial port can receive data. Think about it in terms of a real-world analogy if it helps.

Somebody is sending you postcards. You can check the letterbox as often as you like. Sometimes there will be a postcard there, sometimes there won't. Now, how are you going to make sure you receive the complete set of cards and keep them all in order?

Nick Gammon has told you what you're doing wrong and how to do it right. Either take his advice and do it like he showed you, or stop and THINK about what you need to do to read a sequence of bytes from a serial port.


Great! thank you this helped! i think im understanding it now. Would something like this work?

Send:
Code: [Select]

   Serial.print(".");
   Serial.print(servoVal1);
   Serial.print(",");
   Serial.print(servoVal2);
   Serial.print(",");
   Serial.print(servoVal3);
   Serial.print(",");
   Serial.print(servoVal4);
   Serial.print(",");
   Serial.print(RotationV1);
   Serial.print("/");


Receive:
Code: [Select]
   while((char)Serial.read() !='.');
   
   if (Serial.available() >8)
   {
   
   vals[0] = Serial.read();
   Serial.read();
   vals[1] = Serial.read();
   Serial.read();
   vals[2] = Serial.read();
   Serial.read();
   vals[3] = Serial.read();
   Serial.read();
   vals[4] = Serial.read();
   }
   while((char)Serial.read() !='/')
   {
    myservo1.write(vals[0]);
    myservo2.write(vals[1]);
    myservo3.write(vals[2]);
    myservo4.write(vals[2]);
    myservo5.write(vals[3]);
    myservo7.write(vals[4]);
   }

nickgammon

#22
Jan 29, 2012, 02:31 am Last Edit: Jan 29, 2012, 02:35 am by Nick Gammon Reason: 1
Hmmm ....

From your first post:

Code: [Select]
byte servoVal1 = map(FingerV1,30, 80, 0, 255);//middle
  byte servoVal2 = map(FingerV2,69, 45, 0, 100);//thumb
  byte servoVal3 = map(FingerV3,87, 22, 0, 255);//ring
  byte servoVal4 = map(FingerV4,12, 62, 0, 255);//pointer
  byte servoVal5 = map(RotationV1,300, 600, 0, 255);//Rotation
 
  Serial.print(".");
  Serial.print(servoVal1);
  Serial.print(",");
  Serial.print(servoVal2);
  Serial.print(",");
  Serial.print(servoVal3);
  Serial.print(",");
  Serial.print(servoVal4);
  Serial.print(",");
  Serial.print(RotationV1);


So most numbers are in the range 0 to 255, right?

So let's work through an example. You send:

Code: [Select]
.123,100,92,42,99/

Now once you get the first dot you read like this:

Code: [Select]
if (Serial.available() >8)
  {
 
  vals[0] = Serial.read();  // <-- this will be 1
  Serial.read();            // skip the 2
  vals[1] = Serial.read();  // <-- this will be 3
  Serial.read();            // skip the comma
  vals[2] = Serial.read();  // <-- this will be 1
  Serial.read();            // skip the 0
  vals[3] = Serial.read();  // <-- this will be 0
  Serial.read();            // skip the comma
  vals[4] = Serial.read();  // <-- this will be 9
  }


So you get the values: 1, 3, 1, 0, 9.

Is that really what you want?

(edit)

Plus the values are ASCII values (so '1' is really 49, '3' is 52, '0' is 48 and '9' is 57).

So you will set your 5 servos to: 49, 52, 49, 48 and 57.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

njkl44


Hmmm ....

From your first post:

Code: [Select]
byte servoVal1 = map(FingerV1,30, 80, 0, 255);//middle
  byte servoVal2 = map(FingerV2,69, 45, 0, 100);//thumb
  byte servoVal3 = map(FingerV3,87, 22, 0, 255);//ring
  byte servoVal4 = map(FingerV4,12, 62, 0, 255);//pointer
  byte servoVal5 = map(RotationV1,300, 600, 0, 255);//Rotation
 
  Serial.print(".");
  Serial.print(servoVal1);
  Serial.print(",");
  Serial.print(servoVal2);
  Serial.print(",");
  Serial.print(servoVal3);
  Serial.print(",");
  Serial.print(servoVal4);
  Serial.print(",");
  Serial.print(RotationV1);


So most numbers are in the range 0 to 255, right?

So let's work through an example. You send:

Code: [Select]
.123,100,92,42,99/

Now once you get the first dot you read like this:

Code: [Select]
if (Serial.available() >8)
  {
 
  vals[0] = Serial.read();  // <-- this will be 1
  Serial.read();            // skip the 2
  vals[1] = Serial.read();  // <-- this will be 3
  Serial.read();            // skip the comma
  vals[2] = Serial.read();  // <-- this will be 1
  Serial.read();            // skip the 0
  vals[3] = Serial.read();  // <-- this will be 0
  Serial.read();            // skip the comma
  vals[4] = Serial.read();  // <-- this will be 9
  }


So you get the values: 1, 3, 1, 0, 9.

Is that really what you want?

(edit)

Plus the values are ASCII values (so '1' is really 49, '3' is 52, '0' is 48 and '9' is 57).

So you will set your 5 servos to: 49, 52, 49, 48 and 57.

Hmmm alright. I understand this better now. But with that said hows the best way to read the values?

nickgammon

Capture the whole lot into a buffer. You could look for a terminating "/" character, since that is what you are sending.

There's an example of doing that here: http://gammon.com.au/serial

Then you could use strtok to break the resulting string apart at the commas, and use atoi to convert the ASCII strings into numbers you can send to the servos.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

njkl44


Capture the whole lot into a buffer. You could look for a terminating "/" character, since that is what you are sending.

There's an example of doing that here: http://gammon.com.au/serial

Then you could use strtok to break the resulting string apart at the commas, and use atoi to convert the ASCII strings into numbers you can send to the servos.

Ahh didn't scroll all the way to the bottom :)

njkl44


Capture the whole lot into a buffer. You could look for a terminating "/" character, since that is what you are sending.

There's an example of doing that here: http://gammon.com.au/serial

Then you could use strtok to break the resulting string apart at the commas, and use atoi to convert the ASCII strings into numbers you can send to the servos.

So i have this now:

Code: [Select]

void loop()
{

   while((char)Serial.read() !='.');
   
   if (Serial.available() >8)
   {
   
   vals[0] = Serial.read();
   flash ();
   Serial.read();
   flash ();
   
   vals[1] = Serial.read();
   flash ();
   Serial.read();
   flash ();
   
   vals[2] = Serial.read();
   flash ();
   Serial.read();
   flash ();
   
   vals[3] = Serial.read();
   flash ();
   Serial.read();
   flash ();
   
   vals[4] = Serial.read();
   flash ();
   }
   while((char)Serial.read() !='/')
   {
    myservo1.write(vals[0]);
    myservo2.write(vals[1]);
    myservo3.write(vals[2]);
    myservo4.write(vals[2]);
    myservo5.write(vals[3]);
    myservo7.write(vals[4]);
   }


Whats the easiest way to use atoi and strok with this?

PaulS

Why are you still calling Serial.read(), and throwing away the character read?
The art of getting good answers lies in asking good questions.

njkl44


Why are you still calling Serial.read(), and throwing away the character read?

oh so i dont need the Serial.read(), i used it to get rid of the comma. How am i throwing away the character read?

PaulS

Quote
How am i throwing away the character read?

You call Serial.read() to get the next value in the buffer. If you don't store the value, what do you think happens to it?
The art of getting good answers lies in asking good questions.

Go Up