Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
11 years, 8 months ago.
how to store data from KL25Z onboard accelerometer to an external EEPROM
hi, i am trying to store data read from an KL25Z accelerometer into an 24AA02E48 EEMPROM. have tried to try different codes but couldnt get to store the data. can anyone help please. /media/uploads/djonward/mbed.txt
2 Answers
11 years, 8 months ago.
You could try using the eeprom.h library from here:
http://mbed.org/users/bborredon/code/eeprom/
I tried your code using this as below with a 24c32 eeprom, recording accelerometer values sequentially until eeprom is full (128 8bit bytes in your case). The 32bit float value is stored over 4 x 8 bit bytes, hence the memory address pointer moving by 4 bytes per reading.
The output will show the accelerometer reading and the stored eeprom values with any error eeprom code on the next line, that will be zero if the eeprom is working.
The RomAddress can be set to any valid eeprom address if you just want to store one reading.
using eeprom.h lib
#include "mbed.h"
#include "MMA8451Q.h"
#include "eeprom.h"
#define EEPROM_CONTROL_BYTE 0xA0
#define I2C_READ 0x01
#include "WakeUp.h"
#define OFF 1
#define ON 0
DigitalOut led2(LED_GREEN);
void wakeirq(void)
{
led2 = ON;
wait(0.2);
led2 = OFF;
}
#if defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
PinName const SDA = PTE25;
PinName const SCL = PTE24;
#else
#error TARGET NOT DEFINED
#endif
#define MMA8451_I2C_ADDRESS (0x1d<<1)
EEPROM i2c(PTE0, PTE1, 0, EEPROM::T24C32); // T24C01 should work for the 24AA02E48 eeprom
//I2C i2c(PTE0, PTE1); // sda, scl on KL25Z
Serial pc(USBTX, USBRX); // tx, rx
int n;
char data;
char offset= 0;
char mac[6];
int main(void) {
wait(2);
MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
PwmOut rled(LED1);
PwmOut gled(LED2);
PwmOut bled(LED3);
pc.printf("MMA8451 ID: %d\n", acc.getWhoAmI());
WakeUp::calibrate();
WakeUp::attach(wakeirq);
WakeUp::set(10);
led2 = OFF; // turn off the leds
pc.printf("\n\nStart\n");
int RomAddress=0;
float xrom,yrom,zrom;
float x, y, z;
while (RomAddress<128) { // keep loading eeprom with data until full 128 bytes for the 24AA02E48 eeprom
x = rled = 1.0 - abs(acc.getAccX());
y = gled = 1.0 - abs(acc.getAccY());
z = bled = 1.0 - abs(acc.getAccZ());
wait(0.1);
pc.printf("X: %1.2f, Y: %1.2f, Z: %1.2f\r\n", x, y, z);
i2c.write(RomAddress,x); wait_ms(1);
RomAddress=RomAddress+4; // 4 x 8 bit bytes used for 32bit float value
i2c.write(RomAddress,y); wait_ms(1);
RomAddress=RomAddress+4;
i2c.write(RomAddress,z); wait_ms(1);
RomAddress = RomAddress - 8; // rewind to begining of current Accel' read
i2c.read(RomAddress,xrom);
RomAddress=RomAddress+4;
i2c.read(RomAddress,yrom);
RomAddress=RomAddress+4;
i2c.read(RomAddress,zrom);
pc.printf("Address %04d romX: %1.5f romY: %1.5f romZ: %1.5f Error %d \r\r\n", RomAddress -8, xrom, yrom, zrom, i2c.getError());
RomAddress = RomAddress + 4; // forward to next free rom address
wait(1);
}
}
/*
i2c.start();
i2c.write(EEPROM_CONTROL_BYTE);
i2c.write(0x12); // address to be written
i2c.write(0xAA); // data to be written
i2c.stop();
wait(0.01);
i2c.start();
i2c.write(EEPROM_CONTROL_BYTE);
i2c.write(0x12); // address to be read
i2c.start(); // repeated start
i2c.write(EEPROM_CONTROL_BYTE + I2C_READ); // control byte + Read
data = i2c.read(0); // read one byte of data
i2c.stop();
}
}
*/
11 years, 8 months ago.
You can just copy paste code here, and put it within code tags (<<code>> and <</code>>)
Then, how doesn't it work? What is going wrong? The complete I2C write/read functions are generally easier to use, but this should work too. Did you for example check if you got an ack on the write functions? Then you know if it responds, if it doesn't, it surely won't work.
Finally, it is easier to just start with something very simple without everything else. The accelerometer code doesn't need to be there, and neither does the WakeUp code. It only increases the chances of making a stupid mistake: It can be added again later.
Thank you, it does work, i ve only been able to write a single function into the eemprom which is not data received from the accelerometer. i was able to get an ack responce but my problem is to write the data received from the accelerometer into the EEPROM. i quite new to coding.
posted by 26 Mar 2014Ah like that. The main issue is that a float is returned. The sensor itself returns an integer, which is easier. If you modify the library to return the int16 which the sensor returns, you can store it in two bytes:
char byte1 = data >> 8; char byte2 = data & 0xFF;
The first char stores the topmost 8-bits, the second one the lower 8-bits.
Alternative is that you can save the raw binary data of the float. One option to do that is something like:
union { char data[4]; float val; };
val = x;
After that you can save data[0], data[1], data[2] and data[3] to the EEPROM. After retrieving it you can restore it to a float in the same way.
What a union does is storing several variables in the same piece of memory: So the float is stored in the memory, but that same memory is also used for the 4 chars, which you can save to the EEPROM, in that way storing the binary data of the float.
posted by 26 Mar 2014Thank you for your response, can you please explain this better.
<<code>>
char byte1 = data >> 8;
char byte2 = data & 0xFF;
<</code>>)
That is assuming you got it in 16-bit format from the sensor.
The top command shifts the data 8 positions to the right. So the 8 bits at right side are removed, the 8-bits at left side get placed in the 8-bit char. The second command takes the original data and removes the top 8 bit.
posted by 26 Mar 2014
Thank you Mr Erik Olieman, The problem is C is not my Ist language, i have being able to put up come functions that can right in the eeprom independently. However, writing data recieved from the KL25Z onboard accelerometer into the enternal EEPROM is what am trying to solve. will be grateful if you can present a set of codes that could implement that. thank you
posted by Olanrewaju Oladimeji 26 Mar 2014