Go Down

Topic: Arduino Serial Read issue (Read 1 time) previous topic - next topic

Grumpy_Mike

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: [Select]
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: [Select]
array2 = inChar;
is wrong.

PaulS

Code: [Select]
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: [Select]
      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?

dxw00d

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

PaulS

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.

artvandalay113

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?

Grumpy_Mike

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

artvandalay113

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?

Grumpy_Mike

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.

PaulS

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.

artvandalay113

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.

Grumpy_Mike

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!

PaulS

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: [Select]
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.

artvandalay113

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.

artvandalay113

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).

jfhaugh


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: [Select]

int value = 0;

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


Add more code to strip out junk and so forth.

Go Up