Thanks to codLink i have read data from accelerometer with success, but i have a little problem, i read X register and write data on LCD but this data not update during the while loop, why???
If i have understand what say the datasheet, the registers content not updates untill the accelerometer is in active mode, but it have to be toggle from active to standby and so in active again to update register content.
I have well understand???
Thak you for your help.
Here is my code:
Accelerometer.cpp
#include <avr/io.h>
#include <avr/interrupt.h>
#include "MrLCD.h"
#include "defs.h"
#include "i2c.h"
#include "i2c.c"
#include "types.h"
#define ACC_ADDRESS_R 0x3b
#define ACC_ADDRESS_W 0x3a
#define ACC_XYZ_REGISTER 0x01
//Metodi
uint8_t readRegister(uint8_t registro);
uint8_t* readMultipleDataFromRegister(uint8_t registro);
void writeDataOnLcd(uint8_t position_row, uint8_t position_column, uint8_t data, uint8_t base);
void putAccelerometerToActiveMode();
void putAccelerometerToStandByMode();
int main(void) {
uint8_t receivedByte, receivedByte2, receivedByte3, received_who_am_i;
uint8_t who_am_i, registerToRead, registerToRead2, registerToRead3;
/* Inizializzo monitor lcd e scrivo il titolo */
InitializeMrLCD();
/* Inizializzo la comunicazione i2C */
initI2C();
while (1) {
who_am_i = 0x0D;
received_who_am_i = readRegister(who_am_i);
registerToRead = 0x01;
receivedByte = readRegister(registerToRead);
uint8_t* dataX = readMultipleDataFromRegister(registerToRead);
uint8_t i;
if(received_who_am_i = 0x2A) {
/* Controllo stato accelerometro */
GotoMrLCDsLocation(1,1);
Send_A_String("Status: OK");
for (i=0; i<100; i++) {
/* Print X POSITION */
GotoMrLCDsLocation(1,2);
Send_A_String("MSB:");
writeDataOnLcd(2,5,dataX[i],10);
GotoMrLCDsLocation(9,2);
Send_A_String("LSB:");
writeDataOnLcd(2,7,dataX[i+1],10);
_delay_ms(1000);
}
} else {
GotoMrLCDsLocation(1,1);
Send_A_String("Status: NO");
}
return(0);
}
}
/* Metodo che scrive un dato sul monitor LCD */
void writeDataOnLcd(uint8_t position_row, uint8_t position_column, uint8_t data, uint8_t base) {
GotoMrLCDsLocation(position_column,position_row);
char snum[8];
//Converto il valore in formato intero preso dal pin ADC in string
itoa(data, snum, base);
Send_A_String(snum);
}
/* Metodo che legge un registro dall'accelerometro */
uint8_t readRegister(uint8_t registro) {
i2cStart();
i2cSend(ACC_ADDRESS_W);
i2cSend(registro);
i2cStart();
i2cSend(ACC_ADDRESS_R);
uint8_t data = i2cReadNoAck();
//receivedByte2 = i2cReadNoAck();
i2cStop();
return data;
}
/* Metodo che legge un registro dall'accelerometro */
uint8_t* readMultipleDataFromRegister(uint8_t registro) {
uint8_t data[100];
uint8_t j;
i2cStart();
i2cSend(ACC_ADDRESS_W);
i2cSend(registro);
i2cStart();
i2cSend(ACC_ADDRESS_R);
for(j=0; j<100; j++) {
data[j]= i2cReadAck();
}
//uint8_t data = i2cReadAck();
//receivedByte2 = i2cReadNoAck();
i2cStop();
return data;
}
/* Metodo che legge un registro dall'accelerometro */
uint8_t* readMultipleDataFromMultipleRegisters(uint8_t registro, uint8_t registro2) {
uint8_t data[100];
uint8_t j;
i2cStart();
i2cSend(ACC_ADDRESS_W);
i2cSend(registro);
i2cStart();
i2cSend(ACC_ADDRESS_R);
for(j=0; j<50; j+2) {
data[j]= i2cReadAck();
}
//uint8_t data = i2cReadAck();
//receivedByte2 = i2cReadNoAck();
i2cStop();
_delay_ms(100);
i2cStart();
i2cSend(ACC_ADDRESS_W);
i2cSend(registro);
i2cStart();
i2cSend(ACC_ADDRESS_R);
for(j=1; j<50; j+2) {
data[j]= i2cReadAck();
}
//uint8_t data = i2cReadAck();
//receivedByte2 = i2cReadNoAck();
i2cStop();
return data;
}
/* Metodo che mette l'accelerometro in stand by mode */
void putAccelerometerToStandByMode() {
uint8_t standByRegister = 0x2A;
uint8_t command = 00000001;
i2cStart();
i2cSend(ACC_ADDRESS_W);
i2cSend(standByRegister);
//i2cStart();
i2cSend(command);
i2cStop();
}
/* Metodo che mette l'accelerometro in active mode */
void putAccelerometerToActiveMode() {
uint8_t activeRegister = 0x2A;
uint8_t command = 00000000;
i2cStart();
i2cSend(ACC_ADDRESS_W);
i2cSend(activeRegister);
//i2cStart();
i2cSend(command);
i2cStop();
}
i2c.c
#include "i2c.h"
void initI2C(void) {
TWBR = 32;
TWCR |= (1 << TWEN);
}
void i2cWaitForComplete(void) {
loop_until_bit_is_set(TWCR, TWINT);
}
void i2cStart(void) {
TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTA));
i2cWaitForComplete();
}
void i2cStop(void) {
TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTO));
}
uint8_t i2cReadAck(void) {
TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWEA));
i2cWaitForComplete();
return (TWDR);
}
uint8_t i2cReadNoAck(void) {
TWCR = (_BV(TWINT) | _BV(TWEN));
i2cWaitForComplete();
return (TWDR);
}
void i2cSend(uint8_t data) {
TWDR = data;
TWCR = (_BV(TWINT) | _BV(TWEN));
i2cWaitForComplete();
}
i2c.h
// Functions for i2c communication
#include <avr/io.h>
/* Sets pullups and initializes bus speed to 100kHz (at FCPU=8MHz) */
void initI2C(void);
/* Waits until the hardware sets the TWINT flag */
void i2cWaitForComplete(void);
/* Sends a start condition (sets TWSTA) */
void i2cStart(void);
/* Sends a stop condition (sets TWSTO) */
void i2cStop(void);
/* Loads data, sends it out, waiting for completion */
void i2cSend(uint8_t data);
/* Read in from slave, sending ACK when done (sets TWEA) */
uint8_t i2cReadAck(void);
/* Read in from slave, sending NOACK when done (no TWEA) */
uint8_t i2cReadNoAck(void);
MrLCD.h
#ifndef MrLCD
#define MrLCD
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#define MrLCDsCrib PORTB
#define DataDir_MrLCDsCrib DDRB
#define MrLCDsControl PORTD
#define DataDir_MrLCDsControl DDRD
#define LightSwitch 5
#define ReadWrite 7
#define BiPolarMood 2
char firstColumnPositionsForMrLCD[4] = {0, 64, 20, 84};
void Check_IF_MrLCD_isBusy(void);
void Peek_A_Boo(void);
void Send_A_Command(unsigned char command);
void Send_A_Character(unsigned char character);
void Send_A_String(char *StringOfCharacters);
void GotoMrLCDsLocation(uint8_t x, uint8_t y);
void InitializeMrLCD(void);
void Check_IF_MrLCD_isBusy()
{
DataDir_MrLCDsCrib = 0;
MrLCDsControl |= 1<<ReadWrite;
MrLCDsControl &= ~1<<BiPolarMood;
while (MrLCDsCrib >= 0x80)
{
Peek_A_Boo();
}
DataDir_MrLCDsCrib = 0xFF; //0xFF means 0b11111111
}
void Peek_A_Boo()
{
MrLCDsControl |= 1<<LightSwitch;
asm volatile ("nop");
asm volatile ("nop");
MrLCDsControl &= ~1<<LightSwitch;
}
void Send_A_Command(unsigned char command)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = command;
MrLCDsControl &= ~ ((1<<ReadWrite)|(1<<BiPolarMood));
Peek_A_Boo();
MrLCDsCrib = 0;
}
void Send_A_Character(unsigned char character)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = character;
MrLCDsControl &= ~ (1<<ReadWrite);
MrLCDsControl |= 1<<BiPolarMood;
Peek_A_Boo();
MrLCDsCrib = 0;
}
void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}
void GotoMrLCDsLocation(uint8_t x, uint8_t y)
{
Send_A_Command(0x80 + firstColumnPositionsForMrLCD[y-1] + (x-1));
}
void InitializeMrLCD()
{
DataDir_MrLCDsControl |= 1<<LightSwitch | 1<<ReadWrite | 1<<BiPolarMood;
_delay_ms(15);
Send_A_Command(0x01); //Clear Screen 0x01 = 00000001
_delay_ms(2);
Send_A_Command(0x38);
_delay_us(50);
Send_A_Command(0b00001110);
_delay_us(50);
}
#endif