Pages: 1 [2] 3   Go Down
Author Topic: Arduino Serial Read issue  (Read 1424 times)
0 Members and 1 Guest are viewing this topic.
Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 34478
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you post code in a box using the #icon

Quote
I cannot figure out where I am going wrong.
If you explained what was wrong it would help.

I can think of two things:-
1) You are treating the bytes that arrive as numbers where as they will normally be in ASCII
2) You assume you are always going to get two characters for the first one and three for the second, is this true?

If you send the whole MIDI message like I said earlier it would be much easier to extract the tings you want.

also there are some fundamental errors in the code:-
Code:
for(int a = 0; a > 2; a++)
will not loop.
You are checking that there is at least one byte in the serial buffer but are then reading lots. The first one might have arrived but have the others?

Code:
array2 = inChar;
is wrong.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 630
Posts: 50009
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if(Serial.available() > 0)
  {
    for(int a = 0; a > 2; a++){
//read first character of int1
      inChar = Serial.read();
//place characters into array1
      array1[a] = inChar;
    }
If there is at least one byte of serial data to read, read both of them.

Code:
      for(int b = 0; b > 3; b++){
      inChar = Serial.read();
      if(inChar = ','){
        break;
      }
Then read 3 more.

So, one byte shows up and you read all 5 of them. Got it. How's that working for you?
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Although, as Mike said, it won't actually try and read any of them, as the for loops won't do anything.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 630
Posts: 50009
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Although, as Mike said, it won't actually try and read any of them, as the for loops won't do anything.
Good thing that there is more than one person reading the code, isn't it? I missed that.
Logged

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

I realized my mistake using a greater than instead of less than sign.  The first number will always be two digits and the second number will be 2 or 3 digits.  The 3 digit number will always be below 255 which is why I used byte and not int.  However, I am sending it as an int from Processing so I should probably keep it as an int on the Arduino.  I guess my problem is that I don't understand how Arduino communicates with Processing over serial.  If Processing sends int "234" how will that be read on the Arduino?  I can't figure it out because I can't use the Arduino serial monitor because Processing is using serial.  I was trying to write my code as if it sent "2" then "3" then "4" because the Serial.read reference states that only a byte is read at a time.  So if I received "2" I would put that in a variable and multiply it by 100, then put 3 in a separate variable and multiply by 10 and add those two variable to the 4.  Am I way off here?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 34478
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That is right but all your other stuff is wrong, the stuff I already told you about.
Logged

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

Mike,
In your previous post you asked if the first number would be 2 digits and the second would be 3 which I confirmed.  You also alerted me about the greater than sign which I fixed.  I am unsure what other instructions you want me to follow.  So to confirm, if I write int 234 to serial from processing, and call inByte = Serial.read in Arduino one time, I will have int 2 in inByte?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 34478
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I also said:-
Quote
1) You are treating the bytes that arrive as numbers where as they will normally be in ASCII
and
Quote
You are checking that there is at least one byte in the serial buffer but are then reading lots.
These need to be addressed. When you have done post the code again using the #icon and say what is happening.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 630
Posts: 50009
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So to confirm, if I write int 234 to serial from processing, and call inByte = Serial.read in Arduino one time, I will have int 2 in inByte?
NO! Look at your code. inByte is declared as a char. After the read(), it will contain '2', NOT 2. Huge difference.
Logged

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

Ah I see.  So it would be '2' which is equal to 50 decimal?  Also, what if I change inByte to int?  Then would it have 234 decimal in inByte, or would it have 505152?  Thanks to everyone for their help.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 34478
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also, what if I change inByte to int?
No it would still contain the same number.

Why are you ignoring advice? If you don't know what the advice means then say so but don't just ignore it or we will never get anywhere.
How many time must I tell you:-
Quote
) You are treating the bytes that arrive as numbers where as they will normally be in ASCII
PaulS says the same thing:-
Quote
it will contain '2', NOT 2. Huge difference.

You NEED to convert the number from ASCII to a numeric value!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 630
Posts: 50009
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You NEED to convert the number from ASCII to a numeric value!
Which, of course, is trivial

byte inVal = Serial.read() - '0';
If '2' arrives on the serial port, inVal will contain 2.

Then, when another character arrives, '3', you need to accumulate that value in a variable:
Code:
int val = 0;
while(Serial.available() > 0)
{
  char inChar = Serial.read();
  if(inChar >= '0' && inChar <= '9')
  {
     val *= 10;
     val += (inChar - '0');
  }
  else
     break;
}
// Here, if "234" was sent, and all arrived before the block began, val will equal 234.

Of course, the last comment explains the problem you are most likely to encounter, and that is that the Arduino is far faster at reading serial data than it is at receiving serial data.\

You really need to use start- and end-of packet markers around your packets, and read and store the characters as they arrive, and process them only when you get the end-of-packet marker.

When you get tired of beating your head against the wall, say so, and I'll post some code. Or, you can search for "started && ended" and find prior posts with the code in it.
Logged

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

Paul said that because inByte is declared is char, it will receive an ASCII character.  This led me to think that if I declared inByte as int, it will receive an int.  I apologize for my assumption.  Just to clarify, it is not a steady stream of data that is sent, it is int1 followed by int2 for every time a key is pressed.  Also, I tried just sending a single int at a time which is a number between 36 and 96 (corresponding to the key pressed).  I then read that using Serial.Read and followed that by some if and if else statements.  For example, if inByte is between 36 and 50, turn on red LED, if inByte is between 50 and 65, turn on green LED, etc.  This worked.  I am not sure how this would work based on your advice because you stated that when I Serial.read, and the int sent from processing is 37, inByte would only have '3' in it.  However, the red LED lit up indicating the received number was between 36 and 50.
Logged

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

I think the confusion is that when I said int 234, I don't mean separate ints for 2, 3, and 4.  I mean the number two hundred and thirty four.  So the first piece of data is a 2 digit number (36-96) and the second piece of data is a 2 or 3 digit number (1-200).
Logged

Austin, TX
Offline Offline
Full Member
***
Karma: 0
Posts: 134
I make my own electricity.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the confusion is that when I said int 234, I don't mean separate ints for 2, 3, and 4.  I mean the number two hundred and thirty four.  So the first piece of data is a 2 digit number (36-96) and the second piece of data is a 2 or 3 digit number (1-200).

Sure, not a problem.

Code:
int value = 0;

while(Serial.available())
    value = value * 10 + Serial.read() - '0';

Add more code to strip out junk and so forth.
Logged

Pages: 1 [2] 3   Go Up
Jump to: