Sending Integers over Serial to Processing

Hi. I’m trying to send integers as 2 bytes to Processing, and getting strange results. Here’s the code I’m using:
Arduino:

  int range = 100;
  for ( int i = -range; i < range; i++ ) {
  
    Serial.print( ( i & 0xFF ), BYTE );
    Serial.println( ( i >> 8 ) & 0xFF, BYTE );
  
    delay( 100 );
  }

Processing:

void serialEvent( Serial serial ) {
  strLine = serial.readStringUntil( 10 );

  if ( strLine != null && strLine.length() >= 2 ) {
    
    int msb = (int) strLine.charAt(1);
    int lsb = (int) strLine.charAt(0);

    int in = ( msb << 8 ) | lsb;

    if ( msb >> 7 == 1 ) {
      in = (int) 0xFFFF0000 | ( msb << 8 ) | lsb;
    }

    println( trim(strLine) + "  " + in );

  }
}

it sometimes works, and sometimes has very strange values. For example:
-100 becomes 83
-99 becomes -3
-98 becomes 126
-97 becomes 120
but -96 and up works fine.

It’s like the Arduino isn’t sending the proper characters, or Processing isn’t reading them properly. Things get even weirder when I expand the range to ±500:
384 becomes 8620
385 becomes 65533

Any thoughts? This is driving me crazy.

maybe try serial.write() iso print() - http://arduino.cc/en/Serial/Write -

Hi. Thanks, tried that, but the result is the same.

OK, got it working now. Reading in as bytes works much better.
Processing:

  char inByte;
  while ( serial.available() > 0 ) {
    inByte = serial.readChar();
    if ( inByte == '~' ) {
      byte[] bytes = new byte[2];
      serial.readBytes( bytes );

      int in = ( ( bytes[1] & 0xFF ) << 8 ) | ( bytes[0] & 0xFF );
      if ( ( bytes[1] & 0xFF ) >> 7 == 1 ) {
        in |= 0xFFFF0000;
      }
      println( in );
    }
  }

I know you fixed this, but I believe the problem was caused by different ASCII interpretation - if you go to just before 5 minutes into this video: http://www.youtube.com/watch?v=g0pSfyXOXj8 it explains it. It basically shows you that you would put

int val = Serial.read() - '0';

make sure the '0' is in quotation or apostrophe things.

Hope that explains your problem!

Maybe you need to watch the whole video...

I'm curious why you're breaking them up into two bytes. I've been sending them whole without any issues.

I send them (four ints) as a string with "," between each, and then have processing split the string into integer variables.

If the int contains the value 32000, sending it as two bytes requires sending two bytes. Sending it as a string requires sending 5 bytes ('3', '2', '0', '0', and '0'). If speed is critical, not needing to parse the string and convert the string back to an int can represent significant savings in time.

Mixing negative numbers and bitwise operators can be tricky - but since the problem is happening with positives as well, it might be your packaging.

I’d recommend rewriting the packed format in unsigned int. Just before splitting the bytes convert:

unsigned int xmit=(unsigned int)input;
BYTE lsb=xmit & 0xFFu;
BYTE msb=(xmit>>8) & 0xFFu;

And when received, convert back:

BYTE lsb=0, msb=0;
/// get msb, lsb
unsigned int xmit=(msb<<8)|lsb;
int result=(int)xmit;