TM4C123 I2C Library to Arduino Wire Library for MPU6050 - c++

I study to read MPU6050 gyro data but the main problem is that I could not achieve. Let me to explain why this problem happen.
I found MPU6050 example for Arduino MPU6050BasicExample.
I have started to change basic Arduino example. Then I applied all codes to my project except of these "writeByte", "readByte", "readBytes" functions.
I have tried to change these code according to Arduino as follow;
These are Arduino codes;
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.write(data); // Put data in Tx buffer
Wire.endTransmission(); // Send the Tx buffer
}
uint8_t readByte(uint8_t address, uint8_t subAddress)
{
uint8_t data; // `data` will store the register data
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
Wire.requestFrom(address, (uint8_t) 1); // Read one byte from slave register address
data = Wire.read(); // Fill Rx buffer with result
return data; // Return data read from slave register
}
void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
uint8_t i = 0;
Wire.requestFrom(address, count); // Read bytes from slave register address
while (Wire.available()) {
dest[i++] = Wire.read(); } // Put read results in the Rx buffer
}
These are my codes I have tried to change;
void writeByte(uint16_t address, uint16_t subAddress, uint8_t data)
{
writeI2C0(address, subAddress, data);
}
uint8_t readByte(uint16_t address, uint16_t subAddress)
{
uint8_t data;
return readI2C0(address, subAddress);
}
void readBytes(uint16_t address, uint16_t subAddress, uint8_t count, uint8_t * dest)
{
writeByte(address, subAddress, count);
uint8_t i = 0;
while (I2CMasterBusy(I2C0_BASE)) {
dest[i++] = readByte(address, subAddress); }// Put read results in the Rx buffer
}
In my opinion, if I port Arduino codes to Tiva-c codes, I will achieve to read gyro data.

Related

ESP32 build in Arduino IDE: undefined reference to `CLASS::function' error

I tried to write an Library for the Sensirion SFM3000 Flow Sensor in the Arduino IDE for an ESP32. As long as it was one sketch, everything worked. But as I tried to seperate it into an .h and .cpp file and implemented it as a class, I get some weird error when I try to compile the sketch.
sketch\SFM3019_HSKA.cpp.o:(.literal._ZN12SFM3019_HSKA17i2c_read_flow_CRCEv+0x4): undefined reference to `SFM3019_HSKA::crc8(unsigned char, unsigned char)'
sketch\SFM3019_HSKA.cpp.o: In function `SFM3019_HSKA::i2c_read_flow_CRC()':
sketch/SFM3019_HSKA.cpp:124: undefined reference to `SFM3019_HSKA::crc8(unsigned char, unsigned char)'
sketch/SFM3019_HSKA.cpp:128: undefined reference to `SFM3019_HSKA::crc8(unsigned char, unsigned char)'
collect2.exe: error: ld returned 1 exit status
exit status 1
Fehler beim Kompilieren für das Board ESP32 Dev Module.
As I understand the error message, it occurs when the i2c_read_flow_CRC() meethod is calling the crc8() method in the last thrid of SFM3019_HSKA.cpp file. By now I don´t see an error in the syntax. But I have also no other idea on how to continue debugging...
This is the main code im trying to use the library in:
#include "SFM3019_HSKA.h"
#include <Wire.h>
SFM3019_HSKA::SensVal_s SensVal = {0, 0, 0};
SFM3019_HSKA SFM3019(0x2E); //Generate Object SFM3019 of class SFM3019_HSKA
void setup() {
// put your setup code here, to run once:
Serial.begin (115200);
delay(100);
Wire.begin (21, 22); // for ESP32: SDA= GPIO_21 /SCL= GPIO_22
SFM3019.i2c_device_check(); //checks if I2C device is available
SFM3019.i2c_write(0x3608); //write 2Byte to start continuous measurement
delay(100);
}
void loop() {
// put your main code here, to run repeatedly:
SensVal.flow = SFM3019.i2c_read_flow_CRC(); //read only Flow Bytes
Serial.println(SensVal.flow, 10);
delay(100);
SensVal = SFM3019.i2c_read_all(); //read all Sensor Bytes
Serial.print("Flow: ");
if (SensVal.flow >= 0) Serial.print(" "); //just for beauty reasons
Serial.print(SensVal.flow,10);
Serial.print(" Temp: ");
Serial.print(SensVal.temp,3);
Serial.print(" Statusword: ");
Serial.print(SensVal.statusword, HEX);
delay(400);
Serial.println();
}
and those are the library files:
SFM3019_HSKA.h
#ifndef SFM3019_HSKA_H // include guard
#define SFM3019_HSKA_H
#include "Arduino.h"
class SFM3019_HSKA {
public: //can be accessed public
SFM3019_HSKA(uint8_t i2cAddress); //Constructor
//may be nicer in private if it works anyway
typedef struct {float flow; float temp; int16_t statusword;} SensVal_s; //Struct for complete Sensor Readout
SensVal_s SensVal = {0, 0, 0}; //initialize with 0
int8_t i2c_device_check(); //function for Initialisation
int8_t i2c_write(const uint16_t SendData); //function to write 16Bit Data to sensor
SensVal_s i2c_read_all(); //function to read Flow, Temperature and Statusword
float i2c_read_flow(); //function to only read Flow
float i2c_read_flow_CRC(); //function to only read Flow with CRC check
private: //can only be accessed by functions oh same object
uint8_t SFM3019addr = 46; //SFM3019 I2C Adress: 46 / 0x2E
uint8_t crc8(const uint8_t data, uint8_t crc); //fuction for CRC confirmation
};
#endif
and the C++ file leading to the error:
SFM3019_HSKA.cpp:
#include "SFM3019_HSKA.h" //when placed in same folder
//#include <SFM3019_HSKA.h> //when placed in standard library folder
#include <Wire.h>
// some values needed for calculation of physical flow and temperature values
#define SFM3019Offset 24576
#define SFM3019ScaleFactorFlow 170.0 //needs to be a float, otherwise it will not calculate in float
#define SFM3019ScaleFactorTemp 200.0 //needs to be a float, otherwise it will not calculate in float
SFM3019_HSKA::SFM3019_HSKA(uint8_t i2cAddress) //constructor
{
//: mI2cAddress(i2cAddress)
SFM3019addr = i2cAddress;
}
/* checks if a Device at the desired address is responding with an ACK */
int8_t SFM3019_HSKA::i2c_device_check(){
Wire.beginTransmission(SFM3019addr); // Begin I2C transmission Address (i)
if (Wire.endTransmission() == 0) // Receive 0 = success (ACK response)
{
Serial.print ("Found Seosor at address");
Serial.print (SFM3019addr, DEC);
Serial.print (" (0x");
Serial.print (SFM3019addr, HEX); // 7 bit address
Serial.println (")");
return 0; //0=device sent ACK
}else{
Serial.print ("Did not receive Acknowledge from I2C address ");
Serial.print (SFM3019addr, DEC);
Serial.print (" (0x");
Serial.print (SFM3019addr, HEX); // 7 bit address
Serial.println (")");
return 1; //no ACK received
}
}
/* writes a 16bit "SendData" to I2C Bus Device "address" */
int8_t SFM3019_HSKA::i2c_write(const uint16_t SendData) {
Wire.beginTransmission(SFM3019addr);
//fill I2C outbuffer
Wire.write((SendData>>8)& 0xFF); //isolate HighByte
Wire.write(SendData & 0xFF); //isolate LowByte
//send I2C outbuffer
Wire.endTransmission();
return 0;
}
/* reads all 9 measurement bytes for flow, temp and status */
SFM3019_HSKA::SensVal_s SFM3019_HSKA::i2c_read_all(){
SensVal_s SensVal = {0}; //create empty struct
Wire.requestFrom(SFM3019addr, 9, true); // Request 9byte (3x16bit + CRC) from the sensor
//while(Wire.available()<3){}; //wait for all the data to be received //ATTENTION may be critical loop forever, however not using this may lead to an error, as the Buffer may be processed faster, then the input is read on I2C
//get Flow Bytes
int16_t flow = Wire.read()<<8; //get Highbyte and shift 8bit to 8MSB
flow = flow | Wire.read(); //get Lowbyte 8LSB
byte CRCflow = Wire.read(); //get CRC Check Byte (you could do a data validy check with that)
//Serial.println(flow, HEX); //raw values for debugging
SensVal.flow = (flow + SFM3019Offset) / SFM3019ScaleFactorFlow; //calculate the flow in slm as Datasheet mentions
//get Temperature Bytes
int16_t temp = Wire.read()<<8; //get Highbyte and shift 8bit to 8MSB
temp = temp | Wire.read(); //get Lowbyte 8LSB
byte CRCtemp = Wire.read(); //get CRC Check Byte (you could do a data validy check with that)
//Serial.println(temp, HEX); //raw values for debugging
SensVal.temp = temp / SFM3019ScaleFactorTemp; //calculate the flow in slm as Datasheet mentions
//get StatusWord Bytes
int16_t stat = Wire.read()<<8; //get Highbyte and shift 8bit to 8MSB
stat = stat | Wire.read(); //get Lowbyte 8LSB
byte CRCstat = Wire.read(); //get CRC Check Byte (you could do a data validy check with that)
//Serial.println(stat, HEX); //raw values for debugging
SensVal.statusword = temp / SFM3019ScaleFactorTemp; //calculate the flow in slm as Datasheet mentions
//return all data
return SensVal;
}
/* reads only first 3 bytes for flow and does NO CRC!*/
float SFM3019_HSKA::i2c_read_flow(){
Wire.requestFrom(SFM3019addr, 3, true); // Request 9byte (2x16bit + CRC) from the sensor
//while(Wire.available()<3){}; //wait for all the data to be received //ATTENTION may be critical loop forever, however not using this may lead to an error, as the Buffer may be processed faster, then the input is read on I2C
int16_t flow = Wire.read()<<8; //get Highbyte and shift 8bit to 8MSB
flow = flow | Wire.read(); //get Lowbyte 8LSB
byte CRC = Wire.read(); //get CRC Check Byte (you could do a data validy check with that)
//Serial.println(flow, HEX); //raw values for debugging
return (flow + SFM3019Offset) / SFM3019ScaleFactorFlow; //calculate the flow in slm as Datasheet mentions
}
/* reads only first 3 bytes for flow and DOES CRC*/
float SFM3019_HSKA::i2c_read_flow_CRC(){
Wire.requestFrom(SFM3019addr, 3, true); // Request 9byte (2x16bit + CRC) from the sensor
//while(Wire.available()<3){}; //wait for all the data to be received //ATTENTION may be critical loop forever, however not using this may lead to an error, as the Buffer may be processed faster, then the input is read on I2C
uint8_t Highbyte = Wire.read(); //get Highbyte 8MSB
uint8_t Lowbyte = Wire.read(); //get Lowbyte 8LSB
uint8_t CRC = Wire.read(); //get CRC Check Byte
//Confirm CRC
uint8_t mycrc = 0xFF; // initialize crc variable
mycrc = crc8(Highbyte, mycrc); // let first byte through CRC calculation
mycrc = crc8(Lowbyte, mycrc); // and the second byte too
if (mycrc != CRC) { // check if the calculated and the received CRC byte matches
//Serial.println("Error: wrong CRC");
return -10000; //extreme low value, so user knows somethig is wrong
} else {
//Serial.println("Success: identical CRC");
int16_t flow = (Highbyte<<8) | Lowbyte; //stack the to bytes together as signed int16
return (flow + SFM3019Offset) / SFM3019ScaleFactorFlow; //calculate the flow in slm as Datasheet mentions
}
}
/* calculate a CRC Byte, (Cyclic Redundancy Check) */
uint8_t crc8(const uint8_t data, uint8_t crc)
{
crc ^= data; //crc XOR data
for ( uint8_t i = 8; i; --i ) {
crc = ( crc & 0x80 )
? (crc << 1) ^ 0x31
: (crc << 1);
}
return crc;
}
I would be really thankfull for any idea on how to continue...
/* calculate a CRC Byte, (Cyclic Redundancy Check) */
uint8_t crc8(const uint8_t data, uint8_t crc)
{
crc ^= data; //crc XOR data
for ( uint8_t i = 8; i; --i ) {
crc = ( crc & 0x80 )
? (crc << 1) ^ 0x31
: (crc << 1);
}
return crc;
}
Needs to be:
/* calculate a CRC Byte, (Cyclic Redundancy Check) */
uint8_t SFM3019_HSKA::crc8(const uint8_t data, uint8_t crc)
{
crc ^= data; //crc XOR data
for ( uint8_t i = 8; i; --i ) {
crc = ( crc & 0x80 )
? (crc << 1) ^ 0x31
: (crc << 1);
}
return crc;
}
You just forgot to mark the defined method as part of the class. Simple typo error.

communicating state of a potentiometer with a second arduino board

I am trying to get an arduino board to read the state of a potentiometer which is connected to a master arduino board, without connecting the potentiometer to the second board with physical cables
I have tried using Wire.write and Wire.read to just transfer the one value.
The master arduino code:
#include <Wire.h>
const int dial = A0;
int reading = 0;
void setup() {
pinMode(dial, INPUT);
Wire.begin();
}
void loop() {
reading = analogRead(dial);
Wire.beginTransmission(9);
Wire.write(reading);
Wire.endTransmission();
}
The slave arduino code:
#include <Wire.h>
int reading = 0;
void setup() {
Wire.begin(9);
Serial.begin(9600);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int bytes) {
reading = Wire.read();
}
void loop() {
Serial.println(reading);
}
When I read the Serial Monitor, the potentiometer or "reading" in the slave arduino limits at 255 (I don't know why) in 6 intervals (goes from 0 to 255, then drops to 0 and does that 6 times). I expect it to do the full range of the potentiometer to cap out at 1023.
Your ADC is 10bit and won’t fit in a byte. (Wire.write(value) sends value as a single byte). You need to send reading in 2 bytes. Here is how to make 2 bytes.
byte data1 = highByte(reading);
byte data2 = lowByte(reading);
On receiving side, reconstruct an int this way.
byte data1 = Wire.read();
byte data2 = Wire.read();
reading = int(data1) << 8 | data2;

no matching function for call unresolved overloaded function type

First I'm a newbie to C++ so my question might be already answered somewhere but I couldn't find a straightforward answer to it.
I'm creating a simple library for my hardware. I'm using a Scheduler library which is working fine on Arduino IDE (here is the example), but when I compile the code with my own IDE (Atom+PlatformIO) this error comes up:
lib\SRF08\SRF08.cpp:43:30: error: no matching function for call to 'SchedulerClass::startLoop(<unresolved overloaded functi
on type>)'
I removed some of the codes but if you need the rest I can put it.
SRF08.h
#ifndef SRF08_h
#define SRF08_h
#include "Arduino.h"
class SRF08
{
public:
//main constructor
SRF08(uint8_t address=address_1);
// init the sensor
void begin(void);
//change sensor address from oldAddress to newAddress
void changeAddress(uint16_t oldAddress, uint16_t newAddress);
// scan for a single sensor address
int8_t scanner(void);
// scan for multiple sensors and return the table of addresses
struct table_value scan_all(void);
uint16_t output_value;
void read(void);
private:
// the main I2C address of Sensor
uint16_t _address;
//read sansor value base on centimiter
};
#endif
SRF08.cpp
#include "Wire.h"
#include "SRF08.h"
// Include Scheduler since we want to manage multiple tasks.
#include "Scheduler.h"
SRF08::SRF08(uint8_t address)
{
//main constructor, address is the sensor address if u dont know it try scanner first
//address must be an integer number between 1 to 9
if (address == 1) _address = address_1;
else _address = address_1;
}
void SRF08::begin(){
//initilize I2C
Wire.begin();
output_value = 0;
Scheduler.startLoop(SRF08::read); //here is my error
}
void SRF08::read(){
int reading = 0;
// step 1: instruct sensor to read echoes
Wire.beginTransmission(_address); // transmit to device #112 (0x70)
// the address specified in the datasheet is 224 (0xE0)
// but i2c adressing uses the high 7 bits so it's 112
Wire.write(byte(0x00)); // sets register pointer to the command register (0x00)
Wire.write(byte(0x51)); // command sensor to measure in "inches" (0x50)
// use 0x51 for centimeters
// use 0x52 for ping microseconds
Wire.endTransmission(); // stop transmitting
// step 2: wait for readings to happen
delay(70); // datasheet suggests at least 65 milliseconds
// step 3: instruct sensor to return a particular echo reading
Wire.beginTransmission(_address); // transmit to device #112
Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02)
Wire.endTransmission(); // stop transmitting
// step 4: request reading from sensor
Wire.requestFrom(_address, 2); // request 2 bytes from slave device #112
// step 5: receive reading from sensor
if (2 <= Wire.available()) { // if two bytes were received
reading = Wire.read(); // receive high byte (overwrites previous reading)
reading = reading << 8; // shift high byte to be high 8 bits
reading |= Wire.read(); // receive low byte as lower 8 bits
output_value = reading; // print the reading
}
//yield();
}
Scheduler.h
#ifndef _SCHEDULER_H_
#define _SCHEDULER_H_
#include <Arduino.h>
extern "C" {
typedef void (*SchedulerTask)(void);
typedef void (*SchedulerParametricTask)(void *);
}
class SchedulerClass {
public:
SchedulerClass();
static void startLoop(SchedulerTask task, uint32_t stackSize = 1024);
static void start(SchedulerTask task, uint32_t stackSize = 1024);
static void start(SchedulerParametricTask task, void *data, uint32_t stackSize = 1024);
static void yield() { ::yield(); };
};
extern SchedulerClass Scheduler;
#endif
Scheduler.cpp
#include "Scheduler.h"
extern "C" {
#define NUM_REGS 10 // r4-r11, sp, pc
typedef struct CoopTask {
uint32_t regs[NUM_REGS];
void* stackPtr;
struct CoopTask* next;
struct CoopTask* prev;
} CoopTask;
static CoopTask *cur = 0;
...
void yield(void) {
coopDoYield(cur);
}
}; // extern "C"
SchedulerClass::SchedulerClass() {
coopInit();
}
static void startLoopHelper(void *taskData) {
SchedulerTask task = reinterpret_cast<SchedulerTask>(taskData);
while (true)
task();
}
void SchedulerClass::startLoop(SchedulerTask task, uint32_t stackSize) {
coopSpawn(startLoopHelper, reinterpret_cast<void *>(task), stackSize);
}
static void startTaskHelper(void *taskData) {
SchedulerTask task = reinterpret_cast<SchedulerTask>(taskData);
task();
}
void SchedulerClass::start(SchedulerTask task, uint32_t stackSize) {
coopSpawn(startTaskHelper, reinterpret_cast<void *>(task), stackSize);
}
void SchedulerClass::start(SchedulerParametricTask task, void *taskData, uint32_t stackSize) {
coopSpawn(task, taskData, stackSize);
}
SchedulerClass Scheduler;
Thanks to #Someprogrammerdude to help. I needed to declare the read function as static.
SRF08.h
#ifndef SRF08_h
#define SRF08_h
#include "Arduino.h"
class SRF08
{
public:
//main constructor
SRF08(uint8_t address=address_1);
// init the sensor
void begin(void);
//change sensor address from oldAddress to newAddress
void changeAddress(uint16_t oldAddress, uint16_t newAddress);
// scan for a single sensor address
int8_t scanner(void);
// scan for multiple sensors and return the table of addresses
struct table_value scan_all(void);
static uint16_t output_value;
static void read(void);
static uint16_t static_address;
private:
// the main I2C address of Sensor
uint16_t _address;
//read sansor value base on centimiter
};
#endif
SRF08.cpp
#include "Wire.h"
#include "SRF08.h"
// Include Scheduler since we want to manage multiple tasks.
#include "Scheduler.h"
//initilize static members
uint16_t SRF08::output_value;
uint16_t SRF08::static_address;
SRF08::SRF08(uint8_t address)
{
//main constructor, address is the sensor address if u dont know it try scanner first
//address must be an integer number between 1 to 9
if (address == 1) _address = address_1;
else _address = address_1;
static_address = _address;
//begin();
}
void SRF08::begin(){
//initilize I2C
Wire.begin();
output_value = 0;
Scheduler.startLoop(read); //here is my error
}
void SRF08::read(){
int reading = 0;
// step 1: instruct sensor to read echoes
Wire.beginTransmission(static_address); // transmit to device #112 (0x70)
// the address specified in the datasheet is 224 (0xE0)
// but i2c adressing uses the high 7 bits so it's 112
Wire.write(byte(0x00)); // sets register pointer to the command register (0x00)
Wire.write(byte(0x51)); // command sensor to measure in "inches" (0x50)
// use 0x51 for centimeters
// use 0x52 for ping microseconds
Wire.endTransmission(); // stop transmitting
// step 2: wait for readings to happen
delay(70); // datasheet suggests at least 65 milliseconds
// step 3: instruct sensor to return a particular echo reading
Wire.beginTransmission(static_address); // transmit to device #112
Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02)
Wire.endTransmission(); // stop transmitting
// step 4: request reading from sensor
Wire.requestFrom(static_address, 2); // request 2 bytes from slave device #112
// step 5: receive reading from sensor
if (2 <= Wire.available()) { // if two bytes were received
reading = Wire.read(); // receive high byte (overwrites previous reading)
reading = reading << 8; // shift high byte to be high 8 bits
reading |= Wire.read(); // receive low byte as lower 8 bits
output_value = reading; // print the reading
//output_value = reading;
}
yield();
}

Reinjecting modified packets in netfilter module

I have used netfiler_queue to create a NFQUEUE module for iptables that handles all outgoing UDP packets.
I want to modify all UDP packets that match a certain pattern, and reinject them into the network.
Here is some example code:
...
static int Callback( nfq_q_handle *myQueue, struct nfgenmsg *msg, nfq_data *pkt, void *cbData) {
uint32_t id = 0;
nfqnl_msg_packet_hdr *header;
if ((header = nfq_get_msg_packet_hdr(pkt))) {
id = ntohl(header->packet_id);
}
// Get the packet payload
unsigned char *pktData;
int len = nfq_get_payload(pkt, &pktData);
// The following is an example.
// In reality, it involves more parsing of the packet payload.
if (len && pktData[40] == 'X') {
// Modify byte 40
pktData[40] = 'Y';
}
// Pass through the (modified) packet.
return nfq_set_verdict(myQueue, id, NF_ACCEPT, 0, NULL);
}
...
int main(){
...
struct nfq_handle nfqHandle;
nfq_create_queue(nfqHandle, 0, &Callback, NULL)
...
return 0;
}
The modified packet does not get reinjected into the stream. How would I inject the modified version of the packet?
Two things. First:
return nfq_set_verdict(myQueue, id, NF_ACCEPT, 0, NULL);
should be:
return nfq_set_verdict(myQueue, id, NF_ACCEPT, len, pktData);
That tells it you want to send a modified packet. (you might need some type casting)
Second, you just modified the packet. The IP stack isn't helping you out any more at this point, so you'll need to recompute the UDP checksum for that packet, or zero it out so the other end won't even check it.
The UDP checksum will live in bytes 0x1A and 0x1B of your packet, so this will zero them out:
pktData[0x1a] = 0;
pktData[0x1b] = 0;
and then your packet will go through.

Serial communication not working when class is instantiated in Arduino Environment

I'm trying to write code for my Arduino Mega to communicate with ADXL345 accelerometer using c++ style library.
This is my Accelerometer.h file:
#include <Wire.h>
#define ADXL345 (0x53) // I2C Address of ADXL345 accelerometer
struct Acceleration
{
float x;
float y;
float z;
};
class Accelerometer
{
public:
Accelerometer(void); // Constructor
Acceleration readData(void); // Read sensor data
private:
char buffer[6]; // Buffer to store data (x, y, z: LSB and MSB of each)
char DATA_FORMAT; // Address of DATA_FORMAT Register
char POWER_CTL; // Address of POWER_CTL Register
char DATAX0; // Address of X-Axis LSB Data
char DATAX1; // Address of X-Axis MSB Data
char DATAY0; // Address of Y-Axis LSB Data
char DATAY1; // Address of Y-Axis MSB Data
char DATAZ0; // Address of Z-Axis LSB Data
char DATAZ1; // Address of Z-Axis MSB Data
void writeToAccelerometer(char address, char value);
void readFromAccelerometer(char address, int numOfBytes);
};
And this is my Accelerometer.cpp file:
#include "Accelerometer.h"
#include <Wire.h>
Accelerometer::Accelerometer()
{
Wire.begin(); // Initialize I2C bus
writeToAccelerometer(DATA_FORMAT, 0x01); // +/- 4g range
writeToAccelerometer(POWER_CTL, 0x08); // Measurement Mode
DATA_FORMAT = 0x31; // Address of DATA_FORMAT Register
POWER_CTL = 0x2D; // Address of POWER_CTL Register
DATAX0 = 0x32; // Address of X-Axis LSB Data
DATAX1 = 0x33; // Address of X-Axis MSB Data
DATAY0 = 0x34; // Address of Y-Axis LSB Data
DATAY1 = 0x35; // Address of Y-Axis MSB Data
DATAZ0 = 0x36; // Address of Z-Axis LSB Data
DATAZ1 = 0x37; // Address of Z-Axis MSB Data
}
void Accelerometer::writeToAccelerometer(char address, char value)
{
Wire.beginTransmission(ADXL345); // start transmission to ADXL345
Wire.write(address); // send register address
Wire.write(value); // send value to write
Wire.endTransmission(); // end transmission
}
void Accelerometer::readFromAccelerometer(char address, int numOfBytes)
{
Wire.beginTransmission(ADXL345); // start transmission to ADXL345
Wire.write(address); // send register address
Wire.endTransmission(); // end transmission
Wire.beginTransmission(ADXL345); // start transmission to ADXL345
Wire.requestFrom(ADXL345, numOfBytes); // request some bytes from device
int i = 0;
while(Wire.available()) // while there is data
{
buffer[i] = Wire.read(); // receive a byte and save it in the buffer
i++;
}
Wire.endTransmission(); // end transmission
}
Acceleration Accelerometer::readData()
{
Acceleration R;
readFromAccelerometer(DATAX0, 6); // Read data from sensor
// Merge of data and conversion to int format
int x_acceleration = (((int)buffer[1]) << 8) | buffer[0];
int y_acceleration = (((int)buffer[3]) << 8) | buffer[2];
int z_acceleration = (((int)buffer[5]) << 8) | buffer[4];
R.x = x_acceleration*0.0078;
R.y = x_acceleration*0.0078;
R.z = x_acceleration*0.0078;
return R;
}
I'm using this library im my Arduino sketch with this code:
#include <Wire.h>
#include "Accelerometer.h"
Accelerometer accel;
Acceleration Racc;
void setup()
{
Serial.begin(9600); // Start serial for outbut at 9600 bps
}
void loop()
{
Racc = accel.readData();
// Print data
Serial.print("ACCELERATION - X: ");
Serial.print( Racc.x );
Serial.print(" G / Y: ");
Serial.print( Racc.y );
Serial.print(" G / Z: ");
Serial.print( Racc.z );
Serial.print(" G\n");
delay(100);
}
This code is compilated without erros. However, because of the instantiation of Accelerometer class, Serial communication is not working (I can't see any text in Serial Monitor). When I remove the class instance of the code (letting just Serial communication in code), I can see what is print in Serial Monitor.
Does anybody have any idea about what is going on? I would appreciate any help.
As the ADXL345 can operate either SPI or I2C it needs to be configured, as such. In your case of trying to use it as I2C, the CS of the ADXL345 need to be tied to 3.3V
I2C mode is enabled if the CS pinis tied high to VDD I/O. The CS pin
should always be tied high to VDD I/O or be driven by an external
controller because there is nodefault mode if the CS pin is left
unconnected. Therefore, not taking these precautions may result in an
inability to ommunicatewith the part.
Where in your above code I do not see any pins configured as output to drive the CS.
It has been my experience that when the I2C (wire.h) library is not properly connected to a device it can be blocking. Which is similar to your described symptom here.
You may want to reference your code against others, such as https://github.com/jenschr/Arduino-libraries/tree/master/ADXL345. which appears to fully support the many features of the ADXL345 over I2C