I’m still seeing the freezing with these fixes. The freeze happening when i call accelemeter.getAcceleration(&ax,&ay,&az);
The code runs fine if I comment this out
And are there backets missing from the below function after “while(Wire.available() > 0)
”
void MMA7660::getXYZ(int8_t *x,int8_t *y,int8_t *z)
{
unsigned char val[3];
int count = 0;
val[0] = val[1] = val[2] = 64;
while(Wire.available() > 0)
Wire.read();
Wire.requestFrom(MMA7660_ADDR,3);
while(Wire.available())
{
if(count < 3)
{
while ( val[count] > 63 ) // reload the damn thing it is bad
{
val[count] = Wire.read();
}
}
count++;
}
*x = ((int8_t)(val[0]<<2))/4;
*y = ((int8_t)(val[1]<<2))/4;
*z = ((int8_t)(val[2]<<2))/4;
}
Reading some more the data sheet says that the x; 00, y: 01, z: 02 registers are 6 bit with and Alert bit as the 6th or 1st bit. If the the alert bit is set the register must be read again. I do not see any code that does this. Could this have anything to do with it?
@wesner0019, I don’t like that while statement cause it will keep doing val[count] == Wire.read() even though a total 3 bytes were requested.
I have rewritten the code to use the new (previously commented out) function and I’m trying to update the github files but it’s not allowing me. I’ll update as soon as its down.
UPDATE: I merged the branch back into the master and the code is available here. Hopefully, this version works. 
I just tried the update. Something is blocking the i2c line as now the OLED Screen doesn’t refresh. I connected to a serial terminal to see the output of the accl. it is outputting 0.00 only.
Well this sucks! I guess that experiment did not work
It’s always a challenge working with a sensor when you don’t actually have one! Let me think about this and think about what to do next.
Thanks for your work/help on this. I would send you one if I had an extra.
Edit: I just thought of this. I can solder an MMA7660 chip to a spare breakout board and send you one cause OSA Park send out three and I already need to do a rev change on this board. If you want it you can PM @ wesner0019@gmx.com with your address to ship to.
I came across another thread that confirms there is a bug in the arduino wire library (not sure if this would apply to the sparkcore library but thought I would mention it).
http://forum.arduino.cc/index.php?PHPSESSID=4dqaosbvaku0pg0079o4bjn081&topic=144700.0
https://github.com/arduino/Arduino/issues/1976
1 Like
Hi Peekay123, just wondering if you were to think about this one since the last post. Also I will send you a break out board for the accelerometer if it’ll help.
1 Like
@wesner0019, I looked over everything and I really can’t do much without one these boards and my logic analyzer. I’ll PM you with my address details.
1 Like
Got your PM and I have soldered the new board to send to you. I used the same code and repeated the issue on this one too. This board just has the MMA7660 on it so there’[s no interference from other electronics. So this verifies something in the library is causing this. I’ll get this board mailed to you tomorrow.
2 Likes
@wesner0019, I just received the MMA7660 board today so I’ll be looking at it over the next few days. Thanks!
@wesner0019, to do the tests, I soldered a header here the I2C and GND come out on the side of the board (oled). I first tested the code we had last worked on and nothing worked. Then I decided to download a library from Seeedstudio that used timeouts for reading the data which I thought was excellent. It took all of 2 seconds to port, compile on the CLI, flash it over and test it. AND IT WORKED!!
I updated the code in my repo with the working code so you can test it. 
1 Like
Nice!. I’ve got it loaded and working at 120 sample rate. So far so good, now the endurance test. I’ll let it run all day to make sure it doesn’t freeze. From the previous code if I set the same rate to 120 it would freeze within 20 seconds.
I did have to make the changes (below) to your code that we already talked about in this post earlier.
I’ll let you know if this passes the endurance test but I’m confident it will.
Thanks again!
In the.cpp file changed (char) to (int8_t)
*x = ((int8_t)(val[0]<<2))/4;
*y = ((int8_t)(val[1]<<2))/4;
*z = ((int8_t)(val[2]<<2))/4;
and
included (float),
*ax = (float)(x/21.00);
*ay = (float)(y/21.00);
*az = (float)(z/-21.00); //added - to 21 to switch up z valued for accel.
@wesner0019, great stuff! Keep me posted on the sampling. Part of the problem may be the existing I2C limitation of 100KHz bus speed. I know that @timb and @pra have done a lot of work on a new I2C library that can support the standard 400KHz bus speed and higher!. Hopefully, we will see something from them soon. 
Good news! Its been running reliably since this morning. Thanks for all your help.
3 Likes
@wesner0019, great news! Super glad I could help 
2 Likes
@peekay123, after testing this library with the P1, I find that it is now giving me basically the same problem as above, where I2C stops communication with the accelerometer and just reads 0 after a random amount of time. I’ve tried adjusting the call rate and the sample rate and no stability improvements were seen.
After a power cycle, it reads correctly for a short amount of time again.
Any ideas?
Heres the code: https://github.com/wesner0019/MMA7660-accelerometer
#include "MMA7660.h"
int8_t x;
int8_t y;
int8_t z;
float ax,ay,az;
MMA7660 accelemeter;
unsigned long startAccl = 0;
void setup()
{
Serial.begin(9600);
accelemeter.init();
}
void loop()
{
if(millis() - startAccl > 500){
accelemeter.getAcceleration(&ax,&ay,&az);
Serial.print(az);
Serial.println(" z");
startAccl = millis();
}
}
@wesner0019 Can you try updating the code in MMA7660.cpp to this and try again? it should give status of 0 every time, but i think when it stops you may see status = 4… let me know and we can do some more tests
/*****************************************************************************/
// Function: Cpp file for class MMC7660
// Hardware: Grove - 3-Axis Digital Accelerometer(±1.5g)
// Arduino IDE: Arduino-1.0
// Author: Frankie.Chu
// Date: Jan 10,2013
// Version: v0.9b
// by www.seeedstudio.com
//
// modify by loovee
// 2013-9-25
// add time out funtion in getXYZ
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
/*******************************************************************************/
//#include <Wire.h>
//#include <Arduino.h>
#include "MMA7660.h"
/*Function: Write a byte to the register of the MMA7660*/
void MMA7660::write(uint8_t _register, uint8_t _data)
{
uint8_t status = 0;
Wire.begin();
Wire.beginTransmission(MMA7660_ADDR);
Wire.write(_register);
Wire.write(_data);
status = Wire.endTransmission();
Serial.print(" Write Status: ");
Serial.println(status);
}
/*Function: Read a byte from the regitster of the MMA7660*/
uint8_t MMA7660::read(uint8_t _register)
{
uint8_t status = 0;
uint8_t data_read;
Wire.begin();
Wire.beginTransmission(MMA7660_ADDR);
Wire.write(_register);
Wire.endTransmission();
Wire.beginTransmission(MMA7660_ADDR);
Wire.requestFrom(MMA7660_ADDR,1);
while(Wire.available())
{
data_read = Wire.read();
}
status = Wire.endTransmission();
Serial.print(" Read Status: ");
Serial.println(status);
return data_read;
}
void MMA7660::init()
{
setMode(MMA7660_STAND_BY);
setSampleRate(AUTO_SLEEP_4);
//write(MMA7660_INTSU,0x03);
setMode(MMA7660_ACTIVE);
}
void MMA7660::setMode(uint8_t mode)
{
write(MMA7660_MODE,mode);
}
void MMA7660::setSampleRate(uint8_t rate)
{
write(MMA7660_SR,rate);
}
/*Function: Get the contents of the registers in the MMA7660*/
/* so as to calculate the acceleration. */
unsigned char MMA7660::getXYZ(int8_t *x,int8_t *y,int8_t *z)
{
unsigned char val[3];
int count = 0;
val[0] = val[1] = val[2] = 64;
long timer1 = millis();
long timer2 = 0;
while(Wire.available() > 0)
{
timer2 = millis();
if((timer2-timer1)>500)
{
return 0;
}
}
Wire.read();
Wire.requestFrom(MMA7660_ADDR,3);
timer1 = millis();
while(Wire.available())
{
if(count < 3)
{
timer1 = millis();
while ( val[count] > 63 ) // reload the damn thing it is bad
{
val[count] = Wire.read();
timer2 = millis();
if((timer2-timer1)>50)
{
return 0;
}
}
}
count++;
timer2 = millis();
if((timer2-timer1)>500)
{
return 0;
}
}
*x = ((int8_t)(val[0]<<2))/4;
*y = ((int8_t)(val[1]<<2))/4;
*z = ((int8_t)(val[2]<<2))/4;
return 1;
}
unsigned char MMA7660::getAcceleration(float *ax,float *ay,float *az)
{
int8_t x,y,z;
if(!getXYZ(&x, &y, &z))return 0;
*ax = (x/21.00);
*ay = (y/21.00);
*az = (z/21.00); //added - to 21 to switch up z valued for accel.
return 1;
}
@Hootie81, @wesner0019, is it safe to say you updated your photons to 0.4.3rc2?
yep tried every release there is… many many times! except the develop branch as of today… because i cant get it to compile
and tonight im testing with 0.4.3rc2
i know exactly where it hangs, i just cant figure out why!
this is the line, and a Google shows a few others with stm32fxxx with the same issue.
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
anyway, once it fails the bus kinda locks up, both SDA and SCL high with a occasional blip (SCL low, SDA low, SDA high SCL high) ill try and catch it with the scope… its hard its super random.
I tracked it down by reading the status returned from the end transmission and then changed the return codes to 5 and 6 in i2c_hal.c around line 280.
so im wondering if there is some error we need to clear before the stm32 will start talking again.
edit: @peekay123 i think im getting close… ive added a few lines of code to the library I’m using, to print the error code (based on info in stm32f2xx_i2c.h)
uint32_t error = 0;
error = I2C_GetLastEvent(I2C1);
Serial.print("Error.");
Serial.println(error);
So now right when it dies i get an error code 64… i think thats 0x01000000 so based on the below defines… what does that add up to?
/**
* @brief SR2 register flags
*/
#define I2C_FLAG_DUALF ((uint32_t)0x00800000)
#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000)
#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000)
#define I2C_FLAG_GENCALL ((uint32_t)0x00100000)
#define I2C_FLAG_TRA ((uint32_t)0x00040000)
#define I2C_FLAG_BUSY ((uint32_t)0x00020000)
#define I2C_FLAG_MSL ((uint32_t)0x00010000)
/**
* @brief SR1 register flags
*/
#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000)
#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000)
#define I2C_FLAG_PECERR ((uint32_t)0x10001000)
#define I2C_FLAG_OVR ((uint32_t)0x10000800)
#define I2C_FLAG_AF ((uint32_t)0x10000400)
#define I2C_FLAG_ARLO ((uint32_t)0x10000200)
#define I2C_FLAG_BERR ((uint32_t)0x10000100)
#define I2C_FLAG_TXE ((uint32_t)0x10000080)
#define I2C_FLAG_RXNE ((uint32_t)0x10000040)
#define I2C_FLAG_STOPF ((uint32_t)0x10000010)
#define I2C_FLAG_ADD10 ((uint32_t)0x10000008)
#define I2C_FLAG_BTF ((uint32_t)0x10000004)
#define I2C_FLAG_ADDR ((uint32_t)0x10000002)
#define I2C_FLAG_SB ((uint32_t)0x10000001)
3 Likes
@Hootie81, I tried your code but did not get a 4 when it stopped. I have noticed that when I use the sample rate of 120 that it the I2C lines stays working. I’ve had it running for a while now. Any other sample rate, the I2C stops working randomly.