Serial port help

Hello,

I've been trying to write a simple program for my arduino that would read keep reading the Serial port.
Problem is that serial reads char by char and it got me confused.
I have a processing code that streams some RGB values to my arduino in a while(true) loop.
I'm trying to make arduino read these RGB values somehow and light up my LEDs acordingly. What seemed a simple project turned into a nightmare.
I tryed reading characters from serial port and writing them to a buffer but it just wount work :frowning:
I tryed to fill an integer array of fixed length (9), three spaces for each value from 0 -255, but i ended up with some wierd values that make no sence.

Any idea how to get this working?
thanks!

Any idea how to get this working?

Well without seeing the code my physic powers say it is an error on line 35. However if you post the code I might be able to do better. (use the # icon)

I'm doing something terribly wrong.
What i tryed doing here is reading the serial 9 times and putting the values in an int array.
Later just getting the numbers out and multiplying if needed to get each RGB value from 0-255 in seperate variables.

int analogPinR = 9;   
int analogPinG = 10;   
int analogPinB = 11;   
//the buffer
int RGB[9];
//VALUES OF Red green and blue
int R=0;
int G=0;
int B=0;

void setup()
{
  pinMode(ledPin, OUTPUT); // sets the digital pin as output
  Serial.begin(9600);
} 

void loop(){
  if(Serial.available()){
    for(int i =0;i<9;i++){
     RGB[i]=Serial.read();
     }
     R= RGB[0]*100+RGB[1]*10+RGB[2];
     G= RGB[3]*100+RGB[4]*10+RGB[5];
     B= RGB[6]*100+RGB[7]*10+RGB[8];
     
    Serial.println(R);
        Serial.println(G);
            Serial.println(B);
  }   
}

How do you synchronise with the source of the data? If the Arduino comes in at any position except the very first byte your values will be all over the place and will never be right.


Rob

Point taken.
I guess i would need a delimiter or something to keep track of each set of data.
Problem is that the code above dosen't work at all not to mention the synh.
I'm suprised to see that i can't find any posts on arduino comunication with processing that would solve this.
Maybe i'm looking the wrong way ?

Problem is that the code above dosen't work at all

So the Serial.prints don't return anything. The program is totally dead?


Rob

They do work but make no sence.
Here's an example.
The input was 123123123 (each 3 digits for one value of RGB)
Arduino returned
4889
-111
-111
5559
5559
5509

No idea how he got those numbers :frowning:

Looks like you need to convert your ASCII character to a numeric type. The byte value of '0' is 48 decimal (0x30 hex). The other numbers are
'1': 49
'2': 50

and so on.

if we have
char c = Serial.read();

and we know it is an ASCII digit we can convert to the numeric value as

int d = c - '0';

Now you should be able to do this:
R= (RGB[0] - '0')*100+(RGB[1] - '0')*10+(RGB[2] - '0');

Let me know if this works.

Justin

Time to reduce the variables.

Are you printing correctly? try

Serial.println(1);
Serial.println(2);
Serial.println(3);

Are you receiving the data correctly, try

for(int i =0;i<9;i++){
     Serial.print(Serial.read());
}

(Assuming you can run reads and prints concurrently)

Is the data in the array correctly

for(int i =0;i<9;i++){
     RGB[i]=Serial.read();
}
for(int i =0;i<9;i++){
     Serial.print(RGB[i]);
}

In the above comment out the other prints.

If the input is right, the data is in the array correctly, and the output is working, the only thing left is the maths in the middle.

Looks like you need to convert your ASCII character to a numeric type.

Good point, I assumed binary data, if it's ASCII the maths is all wrong.


Rob

I tryed te conversion to numeric like you adviced. The data changed but it' still wrong.

for input of 123123123
arduino returned
-439
-5439
-5439
231
231
181

Now i checked the separate code chunks and it appears i'm reading ok and printing ok the loop is ok everything is fine but the fact that the numbers returned by
Serial.println(Serial.read()) for example aren't numeric
for input 123123123
arduino returned
49
50
51
52
53
54
55
56
57

Thanks for the help so far :slight_smile:

Oh one more thing that was out of the ordinary.
code:

int analogPinR = 9;  
int analogPinG = 10;  
int analogPinB = 11;  
//the buffer
int RGB[9];
//VALUES OF Red green and blue
int R=0;
int G=0;
int B=0;

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

void loop(){
  if(Serial.available()){
    for(int i =0;i<9;i++){
     RGB[i]=Serial.read();
     
     }
for(int i =0;i<9;i++){
     Serial.println(RGB[i     ]);
     }
}  
  
}

for input 123123123
arduino returned
49
-1
-1
-1
-1
-1
-1
-1
-1
50
51
49
50
51
49
50
51
-1

Any idea what the -1 are for?

ASCII DEC
49 = 1
50 = 2
51 = 3

That might give you a hint :slight_smile:

Doesn't explain the -1s though.

Actually

Serial.available()

will return true for the first char

shouldn't that be

if (Serial.available() == 9)

I suspect the loop is running on one character. That's probably your main problem.


Rob

Sounds simple, i just need to parse my data to decimal, but before i do that i need to solve the -1 thing...
I tryed if(Serial.available()==9) but i got identical resoults :frowning:

Any suggestions? :slight_smile:

Btw the exempla code i posted declears an array RGB of length 9.
Its pritty wierd that looping trugh the array where the loop goes from 0 to 9 printed like 18 values or something.
How is that posible?

No that doesn't make sense, can you post the EXACT code you're running now and the results.


Rob

I just tried it and got 49,50,51 etc. It worked just fine.


Rob

I posted it above its the same one im running.
I tryed a modification to get rid of the -1.
I took note that serial reads char by char and i tryed reading each char individualy and if the char read was different from -1 i would put it in RGB array.
When RGB array is filled with 9 values i would print it.
It works if i enteter each intiger individualy in the serial monitor.
But it only prints the array once. Wierd again.
The modification

int analogPinR = 9;  
int analogPinG = 10;  
int analogPinB = 11;  
//the buffer
int RGB[9];
//VALUES OF Red green and blue
int R=0;
int G=0;
int B=0;
int k=0;
int j=0;
void setup()
{
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()
  ){  
     k=Serial.read(); //read the char

if(k!=-1){//if the char was read properly
RGB[j]=k;//put it in the array
j++;//move the pointer
}
//if the array is full and we read 9 values
if(j==9
){
 for(int i =0;i<9;i++){
//print the values
     Serial.println(RGB[i      ]);
     }
    }  
  }  
}

for input
1
2
3
4
5
6
7
8
9
arduino returned
49
50
51
52
53
54
55
56
57

But it only does that once.
If i input the same or diferent thing again i get no responce even tough the code is in a loop.

Now I've tried the original code with ==9 and -'0'

int analogPinR = 9;
int analogPinG = 10;
int analogPinB = 11;
//the buffer
int RGB[9];
//VALUES OF Red green and blue
int R=0;
int G=0;
int B=0;

void setup()
{

  Serial.begin(9600);
}

void loop(){
  if(Serial.available()[glow]==9[/glow]){
    for(int i =0;i<9;i++){
     RGB[i]=Serial.read() [glow]- '0'[/glow];
     }
     R= RGB[0]*100+RGB[1]*10+RGB[2];
     G= RGB[3]*100+RGB[4]*10+RGB[5];
     B= RGB[6]*100+RGB[7]*10+RGB[8];
    
    Serial.println(R);
    Serial.println(G);
    Serial.println(B);
  }  
}

That works correctly, returns

123
123
123


Rob

Honestly i don't know why mine didn't work but when i copyed yours it works like a charm!

You made my day, thanks a bunch !!! :smiley:

I took note that serial reads char by char and i tryed reading each char individualy and if the char read was different from -1 i would put it in RGB array.

That's just sweeping the symtoms under the carpet, not fixing the problem.

The last version I posted works and continues to work for every 9 characters typed.


Rob

Glad to help, now you've got to organize syncing with the input stream, unless you plan to type in 9 characters all the time :slight_smile:


Rob