Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 22 of 22

Thread: Skewed Data from I2C Sensor - Did I fry my board?.....

  1. #1
    Junior Member
    Join Date
    Feb 2018
    Posts
    15

    Skewed Data from I2C Sensor - Did I fry my board?.....

    Hello everyone,

    I'm fairly new at this, having tinkered quite a bit, but never taking a full project from start to finish....

    I need to detect a few strings vibrations (heavy metal strings) for which I bought the MMA8452Q accelerometer, and planning to use the teensy for simulating a string being plucked....

    The sensor works beautifully on an Arduino (showing smooth, sensible data -- having worked with accelerometers before, I know what to expect)
    Yet, when changing nothing in the sketch, and only changing the 4 wires (3.3v, GND, SCL, SDA) from the Arduino to the Teensy, I'm suddenly getting insensible data, only showing very low results 0.xxx to very high 15.9xxxx (which is double the expected range) and nothing in between these extremes for even small movements across all 3 axis........ In short, data that does not make sense, seems perhaps clipped.

    You can see this data in the photo attached. as well as my wiring and the code I downloaded online....

    I am using 2 pull-up resistors (5K as recommended here) .....

    I'm wondering if this could be due to different I2C configurations between the Arduino (Mega) & Teensy 3.2 , or is the only logical possibility is damage to the hardware?....

    What am I missing?..... H E L P !



    Thanks,
    Ariel
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	IMG_4833.jpg 
Views:	42 
Size:	132.5 KB 
ID:	12921   Click image for larger version. 

Name:	IMG_4834.jpg 
Views:	29 
Size:	88.4 KB 
ID:	12922  

    Click image for larger version. 

Name:	insensible-data.jpg 
Views:	22 
Size:	72.3 KB 
ID:	12923  
    Attached Files Attached Files

  2. #2
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    Your pullup resistors should be connected to 3.3v, not inline. However, most breakouts have onboard pullups (do you have URL for the breakout board), so you may not need your pullup resistors.

    https://www.sparkfun.com/products/12756 has pullup resistors on breakout board.

  3. #3
    Junior Member
    Join Date
    Feb 2018
    Posts
    15

    Still stuck.... giving up .....

    You think it's the pull-up resistors then?....


    I'm really close to giving up , I've tried it already with 3 different Teensy's , 2 X 3.2 and 1 X 3.6 -- always the same weird data...
    To reiterate, this works fine on an Arduino....
    I think it worked yesterday for a few moments somehow, before returning to its odd behavior...

    I'm really at a loss, I wanted to use the Teensy for its audio capabilities but truly have no idea how to proceed.....

  4. #4
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    Get rid of any resistors. Hook Teensy SDA and SCL to the breakout's SDA and SCL. Power with 3v3 and GND.

    It's possible the library has some 8-bit processor data types incompatible with Teensy 32-bit data types, but I didn't see any in a quick review of library source.

    You might try from the IDE the Examples > Wire > Scanner sketch and see if the scanner sees the I2C address of the breakout board.

  5. #5
    Junior Member
    Join Date
    Feb 2018
    Posts
    15
    Thanks man........

    I've tried omitting the pull-up resistors, to no avail..... Still the same weird freaking data I can't make sense of.

    I have here 3 Teensy's and 4 sensors, all sensors work on Arduino, and I can't get any of the same results on the Teensy..
    At least I know it's not a hardware/soldering issue....

    thanks for the scanner sketch, that will surely come in handy within the next few days (it does find the device by the way... [it is showing the data ....])

    Big Up!

  6. #6
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,070
    your 5k resistors should go from sda to 3.3v and scl to 3.3v, then your breakout connects to the sda/scl line directly, not the vcc 3.3v side

  7. #7
    Junior Member
    Join Date
    Feb 2018
    Posts
    15

    Big Development....

    Quote Originally Posted by tonton81 View Post
    your 5k resistors should go from sda to 3.3v and scl to 3.3v, then your breakout connects to the sda/scl line directly, not the vcc 3.3v side
    Thanks again !

    I just did that...

    It did not solve the problem, yet, I found something very strange......

    I've measured 3.3V comparing the 3.3Vout from Arduino with the GND, yet when I measure the 3.3Vin on the sensor with the sensor's GND, I am reading 5V........
    Could this somehow be related to all the problems I'm having?

    This I really don't get!.......

    How is this possible?!

    The I2C bus is somehow upping the voltage to 5V (If I disconnect sensor's SDA, SCL from arduilno's SDA, SCL -- voltage on sensor returns to normal --3.3V)
    I found this out because I first measured the voltage on the sensor when fed by the Teensy, and it showed 2.9V , which made me think it could be a powering issue....

    I guess I'll bring in tomorrow some analog sensors and be done with it....



    Any help appreciated!

  8. #8
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,070
    on arduino, it has built in pullups that drive it to 5volts, thats why, on teensy itll still be 3.3v with pullups..

  9. #9
    Junior Member
    Join Date
    Feb 2018
    Posts
    15
    Oh I see..:
    but the sensor needs 3.3v .....
    so shouldn't i have gotten opposite results?...

  10. #10
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,070
    the sensor was probably 5v “tolerant” or had a built in level shifter

  11. #11
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    The original sketch for UNO suggests 330 ohm in-line resistors for level shifting, but you'd still see 5v with meter on SDA or SCL
    Code:
    Hardware hookup:
      Arduino --------------- MMA8452Q Breakout
        3.3V  ---------------     3.3V
        GND   ---------------     GND
      SDA (A4) --\/330 Ohm\/--    SDA
      SCL (A5) --\/330 Ohm\/--    SCL
    
    The MMA8452Q is a 3.3V max sensor, so you'll need to do some 
    level-shifting between the Arduino and the breakout. Series
    resistors on the SDA and SCL lines should do the trick.
    with the teensy and the board powered at 3v3 and gnd, you should verify you are seeing 3.3v with meter on breakout's SDA or SCL. Though the fact that the Scanner sketch finds the device, suggests I2C should be working.

  12. #12
    Senior Member
    Join Date
    May 2017
    Posts
    208
    >>> only showing very low results 0.xxx to very high 15.9xxxx (which is double the expected range) and nothing in between these extremes for even small movements across all 3 axis........ In short

    It seems your expected data should be in a range of +-8 and you are seeing a range of zero to 16? If so it would appear the sign of your data has been lost and has become the MSB of just a positive number. I suspect it happens in these calculations in the library, but I cannot say why without some investigation into the size of the short type on teensy.

    Here maybe....
    Code:
    void MMA8452Q::read()
    {
    	byte rawData[6];  // x/y/z accel register data stored here
    
    	readRegisters(OUT_X_MSB, rawData, 6);  // Read the six raw data registers into data array
    	
    	x = ((short)(rawData[0]<<8 | rawData[1])) >> 4;
    	y = ((short)(rawData[2]<<8 | rawData[3])) >> 4;
    	z = ((short)(rawData[4]<<8 | rawData[5])) >> 4;
    	cx = (float) x / (float)(1<<11) * (float)(scale);
    	cy = (float) y / (float)(1<<11) * (float)(scale);
    	cz = (float) z / (float)(1<<11) * (float)(scale);
    }

  13. #13
    Junior Member
    Join Date
    Feb 2018
    Posts
    15
    Quote Originally Posted by rcarr View Post
    >>> only showing very low results 0.xxx to very high 15.9xxxx (which is double the expected range) and nothing in between these extremes for even small movements across all 3 axis........ In short

    It seems your expected data should be in a range of +-8 and you are seeing a range of zero to 16? If so it would appear the sign of your data has been lost and has become the MSB of just a positive number. I suspect it happens in these calculations in the library, but I cannot say why without some investigation into the size of the short type on teensy.

    Here maybe....
    Code:
    void MMA8452Q::read()
    {
    	byte rawData[6];  // x/y/z accel register data stored here
    
    	readRegisters(OUT_X_MSB, rawData, 6);  // Read the six raw data registers into data array
    	
    	x = ((short)(rawData[0]<<8 | rawData[1])) >> 4;
    	y = ((short)(rawData[2]<<8 | rawData[3])) >> 4;
    	z = ((short)(rawData[4]<<8 | rawData[5])) >> 4;
    	cx = (float) x / (float)(1<<11) * (float)(scale);
    	cy = (float) y / (float)(1<<11) * (float)(scale);
    	cz = (float) z / (float)(1<<11) * (float)(scale);
    }

    Hey Rcarr, big thanks to you and everyone who helped out and provided reference, I am so much smarter already.....

    Yes, rcarr, I totally agree - what yoy are suggesting sounds very plausible.... I also thought that 0-16 is a -8 ó +8 range with an offset , but as i said, all the data seems to be centered around the edges?..

    Should I try to write my ownbinary decrypting function? How is it possible that the cpp file produces different results across different MCUs?

    anyhow - thanks a lot - i think ill go for analog sensors forthis project to save the trouble but would definitely come back to this later.....

    gratefully!!)
    A

  14. #14
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,530
    One problem could be that denominations like "short", "unsigned int", etc. might look and behave differently on different platforms, i.e. depending on that platform's native support which is 8bit for the old AVR based Arduino stuff, 32bit for the modern Teensy 3.x and LC platforms, and 64bit for most PCs.

    Many of the Arduino libraries are very poorly coded, their developers never anticipated the possible use on something more advanced than the outdated 8bit AVR platform. And thus, there are lots of ambiguities, especially when it comes to variable declarations (or to direct hardware register access but this is another problem).

    But that can be easily fixed by going through the library's code and replacing the ambiguous declarations with the universally accepted and defined ones, like uint8_t, int16_t, *int32_t, and so on. In order to do so successfully, you'll have to go through the code line by line and try to understand which type and width is needed or required for each variable.

  15. #15
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    I don't have one of the breakout boards, so I can't properly test all theories. I did a quick review of the library looking for AVR vs ARM data-type problems, but haven't found any (yet). I did a test of data handling in MMA8452Q::read() on UNO and T3.2
    Code:
    void setup() {
     Serial.begin(9600); while(!Serial);
     delay(2000);
     short x;
     byte rawData[6];
    
     rawData[0] = 0x7f;
     rawData[1] = 0xf0;
    
     x = ((short)(rawData[0]<<8 | rawData[1])) >> 4;
     Serial.println(x); 
     float cx = (float) x / (float)(1<<11) * (float)(8);
     Serial.println(cx,3);
    }
    
    void loop() {
    }
    and the signed 12-bit numbers seems to be handled the same.

    @ArielsAngels, in your sketch, you might print out accel.x, y, and z with Serial.println() in loop() and see how the values compare between Teensy and Arduino. (Don't use printAccels() or at least don't use the " , 3").

    I presume the accelerator values are changing on the Teensy when you move the breakout board.
    Last edited by manitou; 02-15-2018 at 01:24 PM.

  16. #16
    Senior Member
    Join Date
    May 2017
    Posts
    208
    Don't give up now. You're almost at a solution. My suspicion is that a short is 32 bits on teensy. My teensy is packed away somewhere in a box from when I cleaned up for company. I will find it after breakfast and test that theory. In the meantime, you could edit the library .h and .cpp and replace all occurrences of the word 'short' with 'int16_t' and give that a try.

  17. #17
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    short is int16_t on both Teensy and Arduino AVRs

  18. #18
    Senior Member
    Join Date
    May 2017
    Posts
    208
    If you look on github for the library you see this function as

    Code:
    void MMA8452Q::read()
    {
    	byte rawData[6];  // x/y/z accel register data stored here
    
    	readRegisters(OUT_X_MSB, rawData, 6);  // Read the six raw data registers into data array
    	
    	x = ((short)(rawData[0]<<8 | rawData[1])) >> 4;
    	y = ((short)(rawData[2]<<8 | rawData[3])) >> 4;
    	z = ((short)(rawData[4]<<8 | rawData[5])) >> 4;
    	cx = (float) x / (float)(1<<11) * (float)(scale);
    	cy = (float) y / (float)(1<<11) * (float)(scale);
    	cz = (float) z / (float)(1<<11) * (float)(scale);
    }
    If you download the zipfile from the sparkfun site you see this function as:

    Code:
    void MMA8452Q::read()
    {
    	byte rawData[6];  // x/y/z accel register data stored here
    
    	readRegisters(OUT_X_MSB, rawData, 6);  // Read the six raw data registers into data array
    	
    	x = (rawData[0]<<8 | rawData[1]) >> 4;
    	y = (rawData[2]<<8 | rawData[3]) >> 4;
    	z = (rawData[4]<<8 | rawData[5]) >> 4;
    	cx = (float) x / (float)(1<<11) * (float)(scale);
    	cy = (float) y / (float)(1<<11) * (float)(scale);
    	cz = (float) z / (float)(1<<11) * (float)(scale);
    }
    So you can see that the casts to short are missing in the zipfile version. x, y and z are declared as int in the header file.

    To the OP, download the library using the link to github on the sparkfun site and replace your current version of the library.

  19. #19
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    Do you have a link to the sparkfun zip file, all i find is the github stuff.

    removing (short) from the test sketch in post #15 has no effect. both teensy and arduino give the same result with or without the cast. maybe there are other differences in the zip file.

  20. #20
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,191
    ah, i found the link to zip version https://cdn.sparkfun.com/assets/lear...2Q-library.zip
    and looking at the sketch Acc-Basic.ino in post #1, it is apparent that the sketch is using SFE_MMA8452Q.h, which has x,y, z declared as int. the example in post #15 does get different numbers on teensy if x is declared int and there is no short cast. (for the OP: int on Arduino AVR is 16-bits, whereas int on teensy is 32-bits)

    Sooo, as you suggest, using the github version of library and sample sketch is worth a try! good work
    Last edited by manitou; 02-15-2018 at 04:07 PM.

  21. #21
    Junior Member
    Join Date
    Feb 2018
    Posts
    15
    Wow wow wow !!
    Big thanks to u all- rcarr - manitou - theremingenieur !!!
    huge appreciation for the help thus far....

    it all sounds very promising and id definitely give it a try / look into it / write my own function to read and decrypt the binary data...

    maybe i could even apply the motion detection wih the binary data thinking of the bit distance between the last 1 and the MSB as a simplification of acceleration - this may work well for my application.

    however, since this thing needs to be done by next sunday, and i still actually need to code a synth, conjure motion detection AND set the whole physical construction including a mini-controller , iím gonna switch to analog accelerometers at this stage, using only two axis and a teensy 3.6 for the extra pins.....

    so many thanks for everybody who helped out - ill post here when i have an update ....

  22. #22
    Senior Member
    Join Date
    May 2017
    Posts
    208
    Hey manitou, I find that interesting that you get different results depending upon the size of the destination variable. I wonder if that is one of those undefined behavior things in C. I just figured teensy would be doing all integer calculations in 32 bit and the cast to short would always be needed.

    To the OP if you are still with us and still wondering why your data all hovers near zero or 16, I will see if I can explain:
    The data is 2's compliment and read out in bytes. There are 12 bits and in byte form they look like sddd dddd and dddd 0000. The data is shifted as far to the left as possible. s is the sign bit.

    The smallest movement in the positive direction will come out as 0000 0000 0001 0000. Shifted left 4 places 0000 0000 0000 0001. one. 1
    The smallest movement in the negative direction will come out as 1111 1111 1111 0000. Shifted left 4 places 1111 1111 1111 1111. minus one. -1
    If you loose the fact that the most significant bit, the s bit, is a sign bit and interpret that as a positive number, when you shift it left 4 places you get
    0000 1111 1111 1111. That is 0xfff or 4095. When you divide that by 2048 and multiply by 8 you get 15.996. ( instead of -0.004 ).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •