Shop OBEX P1 Docs P2 Docs Learn Events
Issues reading Parallax OFN module values — Parallax Forums

Issues reading Parallax OFN module values

brandonlynnebrandonlynne Posts: 2
edited 2013-06-13 16:05 in General Discussion
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:
/*
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

  • FranklinFranklin Posts: 4,747
    edited 2013-06-12 18:42
    It seems to generally be a value from 0 to 255, and it's never negative
    That is what byte data is. A byte is 8 bits and can be a value from 0 to 255 if you need a larger value you need int or long depending on the size of the number you expect.
  • whickerwhicker Posts: 749
    edited 2013-06-12 19:44
    brandonlynne,

    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:
    Serial.print(deltaX, DEC);
    

    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):
    Serial.print((int) deltaX, DEC);
    


    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.
  • brandonlynnebrandonlynne Posts: 2
    edited 2013-06-13 16:05
    Thanks for all of the help. After a little more fiddling around with the sensor today, it's working! To convert the byte data (0-255) into directional signed data I was able to do a very simple calculation. I read the deltaX and DeltaY values into an unsigned byte, then create a deltaXI and deltaYI of type integer. Then just do this simple check to convert the unsigned byte into signed integer data.
    if (deltaX > 127) deltaXI = deltaX - 256;
           else deltaXI = deltaX;
        
        if (deltaY > 127) deltaYI = deltaY - 256;
           else deltaYI = deltaY;
    

    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.
Sign In or Register to comment.