Hi Arduino community.
I have a quite annoying problem which i cannot find a solution for.
I'm trying to read sensor data over i2c bus inside an ISR. I can read the data if the function is called in the main loop, so i assume my i2c-usage is ok. But nonetheless, if i try to use said interrupt to call the exact same function as an ISR, my program always stops at wire.begintransmission, i guess. (tested with serial.print-outputs)
The implementation of the interrupt itself was tested in a dummy program which only says "hello world" if it detects an interrupt. Both things work alone, but combined, they do not.
Can anyone of you help me?
Below is my code, the interrupt-related lines are commented. the readbma020()-function is called manually during loop() at the moment.
#include <AudioShield.h>
#include <SD.h>
#include <Wire.h>
#define SENS_ADDR 0x38
#define FILENAME "values.txt"
byte data[6]; //Byte field for incoming i2c data
int bma020_x; //Current G on X direction
int bma020_y; //Current G on Y direction
int bma020_z; //Current G on Z direction
File myFile;
int counter;
void setup() {
Wire.begin();
Serial.begin(9600);
initBMA020();
counter=0;
Serial.println("Initializing SD card...");
if (!SD.begin(SD_CS)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
myFile = SD.open(FILENAME, FILE_WRITE);
delay(50);
pinMode(2, INPUT);
attachInterrupt(0, readBMA020, RISING);
//reset_INT();
}
void loop() {
//readBMA020();
//Show output
Serial.print(counter);
Serial.print(" X: ");
Serial.print(bma020_x);
Serial.print(" Y: ");
Serial.print(bma020_y);
Serial.print(" Z: ");
Serial.print(bma020_z);
Serial.println();
if (counter==100){
myFile.close();
//detachInterrupt(digitalPinToInterrupt(2);
Serial.println("done.");
}
counter++;
delay(200);
}
void initBMA020() {
byte control;
Serial.println("InitBMA...");
//Init default reg 0x14
writeRegister(0x38, 0x15, 0x80);
//Range Settings
// Range to 2g --> 255 in datafield is ~1g
// Range to 4g --> 127 in datafield is ~1g
// Range to 8g --> 63 in datafield is ~1g
//Set Range + Bandwidth
control = readRegister(0x38,0x14);
control = control & 0xE0; // save bits 7,6,5
control = control | 0x10; // Range to 8g=0x10/4g=0x08/2g=0x00 (<4,3>=XX)
control = control | 0x00; // Bandwidth 25 Hz (<2:1>=000)
writeRegister(0x38, 0x14, control);
//activate new_INT
//control=readRegister(0x38, 0x15);
//control=control|0x20;
//writeRegister(0x38,0x15,control);
Serial.println("Register 0x15:");
Serial.println(readRegister(0x38,0x15),BIN);
delay(50);
Serial.println("Register 0x14:");
Serial.println(readRegister(0x38,0x14),BIN);
delay(50);
Serial.println("InitBMA successful!");
}
byte readRegister(byte addr, byte reg){
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(addr, (byte)1);
return Wire.read();
}
void writeRegister(byte addr, byte reg, byte value){
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
void readBMA020() {
int i;
//read data for registers <0x02:0x07>
Serial.println("INT-Routine");
Wire.beginTransmission(0x38);
Wire.write(0x02);
Wire.endTransmission();
Wire.requestFrom(0x38, 6);
for (i = 0; i < 6; i++) {
data[i]=Wire.read();
myFile.print(data[i],BIN);
myFile.print("#");
}
Serial.println("read OK");
//integer=16bit --> only for output
//Parse data information --> shift MSB to the left and add LSB/unused/new_data
bma020_x = ( (int)data[1] << 8) + (int)data[0];
bma020_y = ( (int)data[3] << 8) + (int)data[2];
bma020_z = ( (int)data[5] << 8) + (int)data[4];
//shift to the right to eliminate newdata+unused bits
bma020_x = bma020_x >> (6);
bma020_y = bma020_y >> (6);
bma020_z = bma020_z >> (6);
}
void reset_INT(){
byte control;
control=readRegister(0x38,0x0A);
//Serial.println(control, BIN);
control=control|0x40;
//Serial.println(control, BIN);
writeRegister(0x38,0x0A,control);
Serial.println("Reset_INT done!");
}