Issues reading Parallax OFN module values
brandonlynne
Posts: 2
I"m trying to read values from a Parallax OFN module over I2C with an arduino. I am not quite qualified to be doing this, as dealing with bits and registers is definitely breaking the limit of my understanding, but I'm encouraged by how far I've come in the last two days.
Here's the data sheet for the OFN module: http://www.parallax.com/Portals/0/Downloads/docs/prod/acc/27903-OFNModule-v1.1.pdf
So far I'm able to power up the module, read in the motion data from register 0x02, check the MOT bit, and read the Delta_X (register 0x03) and Delta_Y (register 0x04) values into variables of type byte, and send them to my computer over serial. My problem is that I don't undertand the data I'm getting back from Delta_X and Delta_Y. It seems to generally be a value from 0 to 255, and it's never negative. In general, I"m only seeing positive values if I move in one direction on x and y axes, but not both. Since the variables are called Delta_X and Delta_Y, this makes sense, but how would I determine which direction that delta is referring to? Should I expect a negative value for the opposite direction, instead of zero? The documentation isn't clear (to my novice eyes) in terms of the type of data I should be expecting, so I'm not sure how to handle it. Could someone explain how this data should be interpreted?
Any help is greatly appreciated, and Here's my Arduino code below if you're interested:
Here's the data sheet for the OFN module: http://www.parallax.com/Portals/0/Downloads/docs/prod/acc/27903-OFNModule-v1.1.pdf
So far I'm able to power up the module, read in the motion data from register 0x02, check the MOT bit, and read the Delta_X (register 0x03) and Delta_Y (register 0x04) values into variables of type byte, and send them to my computer over serial. My problem is that I don't undertand the data I'm getting back from Delta_X and Delta_Y. It seems to generally be a value from 0 to 255, and it's never negative. In general, I"m only seeing positive values if I move in one direction on x and y axes, but not both. Since the variables are called Delta_X and Delta_Y, this makes sense, but how would I determine which direction that delta is referring to? Should I expect a negative value for the opposite direction, instead of zero? The documentation isn't clear (to my novice eyes) in terms of the type of data I should be expecting, so I'm not sure how to handle it. Could someone explain how this data should be interpreted?
Any help is greatly appreciated, and Here's my Arduino code below if you're interested:
/* Trying a new I2C library that simplifies communication compared to wire.h https://github.com/DSSCircuits/I2C-Master-Library */ #include <I2C.h> //each device has a custom ID (parallax Unit is ID# ?) char deviceID = 0x33; int result = 0; boolean MOT = false; boolean OVF = false; byte deltaX = 0; byte deltaY = 0; void setup() { I2c.begin(); // join i2c bus (address optional for master) I2c.write(deviceID, 0x02); //send Register 2 address which is what we'd like to read I think Serial.begin(9600); // start serial for output } void loop() { //read the Motion register to evaluate if MOT is set I2c.read(deviceID, 1); result = I2c.receive(); //Serial.print("Result is: "); //Serial.println(result); //check if MOT bit is set //this works by shifting the bits over 7 spaces and checking if the result is 1 or 0 if ((result & (1 << 7))) { Serial.println("The Motion Bit is set."); MOT = true; } else MOT = false; //check if OVF bit is set //this works by shifting the bits over 4 spaces and checking if the result is 1 or 0 if ((result & (1 << 4))) { Serial.println("The OVF Bit is set."); OVF = true; } //If Motion has occurred, then read the Delta_X (0x03) and Delta_Y (0x04) registers if (MOT) { //set the Delta_X register I2c.write(deviceID, 0x03); //read one byte of data I2c.read(deviceID, 1); deltaX = I2c.receive(); //set the Delta_Y register I2c.write(deviceID, 0x04); //read one byte of data I2c.read(deviceID, 1); deltaY = I2c.receive(); Serial.print("delataX, DeltaY: "); Serial.print(deltaX, BIN); Serial.print(","); Serial.println(deltaY, BIN); //reset the OFN by writing anything to the Motion Register //I2c.write(deviceID, 0x02, 0); } //end if }
Comments
That's exactly it, it's how you interpret that information...
Please be patient, let me explain...
8 bits is a byte.
an unsigned byte will go in value from 0 to 255
a signed byte can range from 0 to 127, then wrap around from -128 to -1 (range is -128 to 127)
a byte could also be 8 individual ON's or OFF's (something like binary 10011011)
It's all the same, it's just how you interpret it.
You are saying that want your byte treated as a signed integer, basically.
Okay, so what should you do?
Try:
If that doesn't work (still prints 0 to 255), try casting:
http://www.arduino.cc/en/Reference/Cast
(I don't know if this is the allowed syntax):
It's totally normal programming to have to do stuff like this, what makes it frustrating is every language has its own way of typing out the casting from one data type to another, although the concept is the same.
If this still doesn't work, try declaring deltaX as the char data type. Maybe that will work?
Somehow there has to be an easy way to get that minus sign to show up.
This corrects for the way the signed byte data is stored, and now the sensor is providing values from about -30 to 30 on each axis. I have to move pretty fast to get the sensor to report movement, which may not work too well for my application, but next I'll try to change the cpi of the sensor to a more sensitive setting (1000 vs 500) to see if that increases the effective sensitivity.