edit: Okay, reopened this.
I need to control an iRobot Create. I am using two Sun SPOT devices, which use the Java CLDC 1.1 libraries. All that I am concerned with is controlling its velocity and turning radius. The drive command to do this has a serial sequence like this:
[137] [velocity high byte] [velocity low byte] [radius high byte] [radius low byte]
So I need to separate my velocity and radius integer values into high and low bytes before I can send them to the iRobot. So here is my code to do that:
So I tried controlling the iRobot Create, and it sort of works, but it spins around in place most of the time, when it shouldn't. The iRobot Create manual gives this example for the drive command:
"To drive in reverse at a velocity of -200mm/s while turning at a radius of 500mm, send the following serial sequence:
[137] [255] [56] [1] [244]
velocity = -200 = 0xFF38 = [0xFF] [0x38] = [255] [56]
radius = 500 = 0x01F4 = [0x01] [0xF4] = [1] [244]"
So I wanted to test my above code by hard-coding in velocity = -200 and radius = 500, separating them into high and low bytes, then printing them out to see if the decimal values of the high and low bytes matched the example above (velocity = [255] [56], radius = [1][244]). However, using my above code got these values:
velocity = [-1] [56]
radius = [1][-12]
So, the velocity low byte matches the example, and the radius high byte is correct. However, it doesn't seem like my code is necessarily wrong. For example, -1 in decimal is equal to 0xFF in hex, so the fact that -200 in decimal is equal to 0xFF38 means my above code was correct in separating, since the high byte is [0xFF] = [-1]. However, we also know that 0xFF is equal to 255 in decimal. So it seems like the iRobot Create manual is not using twos complement.
Moreover, the Java documentation states that a Java byte is 8 bits and can be -127 to +128. The drive command serial sequence starts with [137], but 137 is not in the range of a Java byte. Printing (byte) 137 in Java results in a negative number, but it still gets interpreted by the iRobot correctly, since it does indeed the drive.
I think the reason why it spins in place is the iRobot Create manual says this:
"Special cases for radius:
turn in place clockwise = hex FFFF
turn in place counter-clockwise = hex 0001"
Therefore, when I have a negative radius value, the high byte is always 0xFF, so it turns in place.
So it seems weird, but its like the iRobot Create does not use twos complement, but Java on the Sun SPOT and host computers do. And it seems to be the reason why the robot spins in place when it should not (it is nearly impossible for me to orient my controller to get it to intentionally spin in place).
So I guess what I'm asking is if anyone knows of a way to separate a Java integer into high and low bytes, but not use twos complement. Such that instead of -127 to +128 being the valid range, I want 0 to +255 to be the valid range. Let me know if anyone needs clarification. Thanks.
I need to control an iRobot Create. I am using two Sun SPOT devices, which use the Java CLDC 1.1 libraries. All that I am concerned with is controlling its velocity and turning radius. The drive command to do this has a serial sequence like this:
[137] [velocity high byte] [velocity low byte] [radius high byte] [radius low byte]
So I need to separate my velocity and radius integer values into high and low bytes before I can send them to the iRobot. So here is my code to do that:
int velocity, radius;
byte velocityHigh, velocityLow, radiusHigh, radiusLow;
// assume here that velocity and radius get a valid value from somewhere else
// separate parameters into high and low bytes
velocityHigh = (byte) ((velocity & 0xFF00) >> 8);
velocityLow = (byte) (velocity & 0xFF);
radiusHigh = (byte) ((radius & 0xFF00) >> 8);
radiusLow = (byte) (radius & 0xFF);
// send drive parameters to iRobot over UART
// [137] [velocity high] [velocity low] [radius high] [radius low]
spot.sendUART((byte) 137);
spot.sendUART(velocityHigh);
spot.sendUART(velocityLow);
spot.sendUART(radiusHigh);
spot.sendUART(radiusLow);
So I tried controlling the iRobot Create, and it sort of works, but it spins around in place most of the time, when it shouldn't. The iRobot Create manual gives this example for the drive command:
"To drive in reverse at a velocity of -200mm/s while turning at a radius of 500mm, send the following serial sequence:
[137] [255] [56] [1] [244]
velocity = -200 = 0xFF38 = [0xFF] [0x38] = [255] [56]
radius = 500 = 0x01F4 = [0x01] [0xF4] = [1] [244]"
So I wanted to test my above code by hard-coding in velocity = -200 and radius = 500, separating them into high and low bytes, then printing them out to see if the decimal values of the high and low bytes matched the example above (velocity = [255] [56], radius = [1][244]). However, using my above code got these values:
velocity = [-1] [56]
radius = [1][-12]
So, the velocity low byte matches the example, and the radius high byte is correct. However, it doesn't seem like my code is necessarily wrong. For example, -1 in decimal is equal to 0xFF in hex, so the fact that -200 in decimal is equal to 0xFF38 means my above code was correct in separating, since the high byte is [0xFF] = [-1]. However, we also know that 0xFF is equal to 255 in decimal. So it seems like the iRobot Create manual is not using twos complement.
Moreover, the Java documentation states that a Java byte is 8 bits and can be -127 to +128. The drive command serial sequence starts with [137], but 137 is not in the range of a Java byte. Printing (byte) 137 in Java results in a negative number, but it still gets interpreted by the iRobot correctly, since it does indeed the drive.
I think the reason why it spins in place is the iRobot Create manual says this:
"Special cases for radius:
turn in place clockwise = hex FFFF
turn in place counter-clockwise = hex 0001"
Therefore, when I have a negative radius value, the high byte is always 0xFF, so it turns in place.
So it seems weird, but its like the iRobot Create does not use twos complement, but Java on the Sun SPOT and host computers do. And it seems to be the reason why the robot spins in place when it should not (it is nearly impossible for me to orient my controller to get it to intentionally spin in place).
So I guess what I'm asking is if anyone knows of a way to separate a Java integer into high and low bytes, but not use twos complement. Such that instead of -127 to +128 being the valid range, I want 0 to +255 to be the valid range. Let me know if anyone needs clarification. Thanks.