Pages: [1]   Go Down
Author Topic: Sending several integers through serial  (Read 516 times)
0 Members and 1 Guest are viewing this topic.
Brussels, BE
Offline Offline
Jr. Member
**
Karma: 1
Posts: 62
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello all,

I'm trying to send the values taken from the analog inputs read by one Arduino to another Arduino via Xbee. I have a working code for only one value, but I am unable to send several ones.

I tried by sending an array; here is my non-working code (shortened to two inputs for simplicity) :
Code:
//Define Pins
int DirectionPot = A5;
int ThrottlePot = A3;
int Coords[2];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  delay(100);
 
  int dir = map(analogRead(DirectionPot), 0, 1024, 90, 140);
  int thr = analogRead(ThrottlePot);
  Coords[0] == dir;
  Coords[1] == thr;
 
  Serial.write(Coords);
}

The error message reads : invalid conversion from 'int*' to 'uint8_t', with Serial.write(Coords); highlighted. Could you explain me the reason of this error, and how to acheive what I'm trying to do ?

In advance, thank you.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi.

I am having a similar issue.Have a look at this post, especially the parsing part:
http://arduino.cc/forum/index.php?topic=88647.0

Maybe this helps..

I am very interested in your code with just one value being transmitted. Could you post it here or maybe in my question thread:
http://arduino.cc/forum/index.php/topic,145137.0.html
Thanks!
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 651
Posts: 50845
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  Coords[0] == dir;
  Coords[1] == thr;
= and == are not interchangeable.

Serial.write() expects to write bytes, as binary data, not ints. It expects, too, to write ONE byte. If it is to write more than one, when the 1st argument is an array, the number of bytes to write must be supplied as the second argument.
Logged

Brussels, BE
Offline Offline
Jr. Member
**
Karma: 1
Posts: 62
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Serial.write() expects to write bytes, as binary data, not ints. It expects, too, to write ONE byte. If it is to write more than one, when the 1st argument is an array, the number of bytes to write must be supplied as the second argument.
Thank you. I have rescaled the analog inputs so that they fit in a byte, and asked Serial.write to send 2 bytes. I got no error message on this one:
Code:
int DirectionPot = A5;
int ThrottlePot = A3;
byte Coords[2];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  delay(100);
 
  byte dir = map(analogRead(DirectionPot), 0, 1024, 90, 140);
  byte thr = map(analogRead(ThrottlePot),0,1024,0,255);
  Coords[0] = dir;
  Coords[1] = thr;
 
  Serial.write(Coords,2);   
}
Is this the "standard way" to send an arbitrary number of values via serial ? And how do I have the second Arduino to discriminate between these two bytes ?

Quote
I am very interested in your code with just one value being transmitted.
I got the working code for a single byte on this topic : http://arduino.cc/forum/index.php/topic,123820.0.html, reply #6. I was basically trying to emulate Blum's tutorial about how to control a servo wirelessly. Hope this helps !
Logged


Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 651
Posts: 50845
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is this the "standard way" to send an arbitrary number of values via serial ?
No. The "standard" way is to use highByte() and lowByte() to extract the MSB and LSB, and send all 4 bytes.

Quote
And how do I have the second Arduino to discriminate between these two bytes ?
Well, now, there's the rub. You can't. Serial data is not guaranteed to be delivered. That is why using serial to send binary data is such a challenge. Sending ASCII data is far simpler to parse and error-check.

Is there a need to send a value like 1024 as 2 bytes instead of 4? Or 1 byte, instead of three?
Logged

Brussels, BE
Offline Offline
Jr. Member
**
Karma: 1
Posts: 62
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Is there a need to send a value like 1024 as 2 bytes instead of 4? Or 1 byte, instead of three?
Nope, actually I proceeded that way because I thought sending two separate values would be recieved as such on the other end.

A quick search led me to Serial.print(), is that correct ? Now, to send my Coord[n] vector, I just have to send it "as is", and have the second Arduino to extract the different entries once received ?
Logged


Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 651
Posts: 50845
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
A quick search led me to Serial.print(), is that correct ? Now, to send my Coord[n] vector, I just have to send it "as is", and have the second Arduino to extract the different entries once received ?
Yes, and mo. Using Serial.print() is a better idea. But, you can't Serial.print() an array of anything except characters.

You can use a loop to Serial.print() one element at a a time.

But, suppose that dir was 541 and thr was 82. If you use this code:
Code:
Serial.print(dir);
Serial.print(thr);
the two values would be sent as a collection of characters: "54182". Now, how are you going to take them apart? Are the numbers that were sent 541 and 83? Or, were they 54 and 182?

Sending delimiters between the value removes the ambiguity.
Code:
Serial.print(dir);
Serial.print(",");
Serial.print(thr);

But, now, loop() runs twice, and you send "541,82541,82".

Now, you have a different, but similar problem. I'll leave it to you to figure out how to deal with this conundrum. A hint, though. Don't use the same delimiter to mark the end of the packet.
Logged

Brussels, BE
Offline Offline
Jr. Member
**
Karma: 1
Posts: 62
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It works ! Thank you.

Controlling end:
Code:
//Define Pins
int DirectionPot = A5;
int ThrottlePot = A3;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  delay(100);
  
  int dir = map(analogRead(DirectionPot), 0, 1024, 90, 140);
  int thr = map(analogRead(ThrottlePot), 0, 1024, 0, 255);
  
  Serial.print("i");
  Serial.print(dir);
  Serial.print("i");
  Serial.print(thr);
  Serial.print("e");
}

Receiving end:
Code:
#include <Servo.h>

//Define Pins
int servoPin = 9;
int pwma = 3;

//Create Servo Object
Servo directionServo;

void setup()
{
 Serial.begin(9600);
 directionServo.attach(servoPin);
 pinMode(pwma,OUTPUT);
 delay(100);
}

void loop()
{  
  while( Serial.available() == 0);
  {
    while(Serial.findUntil("i", "e"))
    {
      byte pos = Serial.parseInt();
      directionServo.write(pos);
      byte spd = Serial.parseInt();
      analogWrite(pwma, spd);
    }
  }
}

Suggestions for improvement welcome.
« Last Edit: January 27, 2013, 05:24:11 pm by N_Tesla » Logged


Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 651
Posts: 50845
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Suggestions for improvement welcome.
This part:
Quote
It works !
says that they really aren't needed. But...

Code:
 Serial.print("i");
  Serial.print(dir);
  Serial.print("i");
  Serial.print(thr);
  Serial.print("e");
I prefer < as the start of packet marker, comma as the field separator, and > as the end of packet marker. To me, "<540, 167>" is easier to read than "i540i167e".

To the receiving computer, it makes no difference (unless the start of packet marker is important (as it is in my code), but to humans, it does.

By the way, congratulations on persevering to achieve your goal.
« Last Edit: January 27, 2013, 05:49:30 pm by PaulS » Logged

0
Offline Offline
Tesla Member
***
Karma: 147
Posts: 9741
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A way I capture a string to operate various servos.

Code:
//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added

String readString;
#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    } 
    else {     
      readString += c; //makes the string readString
    }
  }
}

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Pages: [1]   Go Up
Jump to: