yellownotblack
Member
Hello
I am trying to use a Accelerometer while recording audio. But I have a problem with interrupts.
First of all, there are multiple ways to check if new data is available for the Accelerometer (check te register or use DRDY PIN. Goes on hi if Data is ready. I found that using the Pin is faster then always checking the register.
I use the ADCL357 Accelerometer with I2C.
In the Setup I configure the sensor (this works without a problem).
I set up an interrupt routine so that I can read the Data:
I have managed to read in 200us intervals (4kHz)
I also set up the SD Card (on the Teensy)
The second task is record audio. That is also no problem. I set up the audio with:
But now the Problem. I want to use a switch/button to start and stop the recording. For this I have also set up an Interrupt:
This works fine for the starting. But the Interrupt gets ignored most of the times or takes ages to take affect while recording.
In the loop is only the continue Recording function (if a recording is running (active == true))
The continueRecording function is from the recorder sample.
But if I remove the continueRecording function than I can stop the recording.
How can it be that the Interrupt is ignored? Is the processor to slow to handle this?
The complete Code:
I have also tired using the Bounce(2) libary without luck
Edit: when I add Serial.println(digitalRead(Switch_pin)); to the loop.
From the moment the recording is started, a change at the input is only detected with an extreme delay. It is even so that nothing more or is output. It seems as if he would no longer run through the loop.
I am trying to use a Accelerometer while recording audio. But I have a problem with interrupts.
First of all, there are multiple ways to check if new data is available for the Accelerometer (check te register or use DRDY PIN. Goes on hi if Data is ready. I found that using the Pin is faster then always checking the register.
I use the ADCL357 Accelerometer with I2C.
In the Setup I configure the sensor (this works without a problem).
I set up an interrupt routine so that I can read the Data:
Code:
pinMode(Data_pin, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(Data_pin), Interrupt_Data, RISING);
I have managed to read in 200us intervals (4kHz)
I also set up the SD Card (on the Teensy)
The second task is record audio. That is also no problem. I set up the audio with:
Code:
AudioMemory(60);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(myInput);
sgtl5000_1.volume(0.5);
sgtl5000_1.micGain(40);
But now the Problem. I want to use a switch/button to start and stop the recording. For this I have also set up an Interrupt:
Code:
pinMode(Switch_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Switch_pin), Interrupt_Start_Stop, CHANGE);
In the loop is only the continue Recording function (if a recording is running (active == true))
Code:
if (active == true)
{
continueRecording();
}
But if I remove the continueRecording function than I can stop the recording.
How can it be that the Interrupt is ignored? Is the processor to slow to handle this?
The complete Code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h>
#if defined(__IMXRT1062__)
extern "C" uint32_t set_arm_clock(uint32_t frequency);
#endif
// GUItool: begin automatically generated code
AudioInputI2S i2s2; //xy=105,63
AudioAnalyzePeak peak1; //xy=278,108
AudioRecordQueue queue1; //xy=281,63
AudioPlaySdRaw playRaw1; //xy=302,157
AudioOutputI2S i2s1; //xy=470,120
AudioConnection patchCord1(i2s2, 0, queue1, 0);
AudioConnection patchCord2(i2s2, 0, peak1, 0);
AudioConnection patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection patchCord4(playRaw1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=265,212
// GUItool: end automatically generated code
//Define Input
const int myInput = AUDIO_INPUT_MIC;
//Define SD Card Pins
#define SDCARD_MOSI_PIN 11
#define SDCARD_SCK_PIN 13
#define SDCARD_CS_PIN BUILTIN_SDCARD
//Define Input Pins
#define Switch_pin 41
#define Data_pin 32
Bounce Switch = Bounce();
Bounce Data = Bounce();
bool active = 0;
int counter = 0;
File File_audio;
File File_accelerometer;
String Dateiname_audio = "";
String Dateiname_accelerometer = "";
//https://forum.arduino.cc/t/debouncing-an-interrupt-trigger/45110/2
unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = 0;
unsigned long interrupt_delay = 200;
//Accelerometer
int adxl357 = 0x1D;
uint8_t DEVID_AD;
uint8_t REVID;
uint8_t Status;
uint8_t Range;
uint8_t POWER_CTL;
uint8_t XDATA3 = 0;
uint8_t XDATA2 = 0;
uint8_t XDATA1 = 0;
uint8_t YDATA3 = 0;
uint8_t YDATA2 = 0;
uint8_t YDATA1 = 0;
uint8_t ZDATA3 = 0;
uint8_t ZDATA2 = 0;
uint8_t ZDATA1 = 0;
long int XDATA = 0;
long int DATA = 0;
long int ZDATA = 0;
void Interrupt_Start_Stop()
{
//allow new Intinterrupt only after a delay (debounce)
AudioNoInterrupts();
noInterrupts();
interrupt_time = millis();
if (interrupt_time - last_interrupt_time > interrupt_delay)
{
if(active == false) //Wenn keine Aufzeichnung aktiv -> Aufzeichnung Starten
{
Dateiname_audio = String(counter) + ".raw";
Dateiname_accelerometer = String(counter) + ".csv";
while (SD.exists(Dateiname_audio.c_str()) || SD.exists(Dateiname_accelerometer.c_str()))
{
Dateiname_audio = Dateiname_audio + "new";
Dateiname_accelerometer = Dateiname_accelerometer + "new";
Serial.println("Datei mit gleichen Namen schon vorhanden, Namen abwandeln");
counter ++;
Dateiname_audio = String(counter) + ".raw";
Dateiname_accelerometer = String(counter) + ".csv";
Serial.print("Neuer Dateinamen: ");
Serial.print(Dateiname_accelerometer);
Serial.print(" ; ");
Serial.println(Dateiname_audio);
}
File_audio = SD.open(Dateiname_audio.c_str(), FILE_WRITE);
if (File_audio)
{
queue1.begin();
active = true;
Serial.print("Start: ");
Serial.println(Dateiname_audio);
counter++;
}
else
{
Serial.print("Error while starting audio");
}
File_accelerometer = SD.open(Dateiname_accelerometer.c_str(), FILE_WRITE);
if (File_accelerometer)
{
Serial.print("Start: ");
Serial.println(Dateiname_accelerometer);
}
else
{
Serial.print("Error while starting accelerometer");
}
}
else//Aufzeichung Stoppen
{
active = false;
Serial.print("Stopping");
//Audio Stop
queue1.end();
while (queue1.available() > 0)
{
File_audio.write((byte*)queue1.readBuffer(), 256);
queue1.freeBuffer();
}
File_audio.close();
//Accelerometer Stop
File_accelerometer.close();
Serial.println("Stoped");
}
}
last_interrupt_time = interrupt_time;
AudioInterrupts();
interrupts();
}
void continueRecording()
{
if (queue1.available() >= 2) {
byte buffer[512];
memcpy(buffer, queue1.readBuffer(), 256);
queue1.freeBuffer();
memcpy(buffer+256, queue1.readBuffer(), 256);
queue1.freeBuffer();
File_audio.write(buffer, 512);
}
}
void convert(long int* output, uint8_t* Data3, uint8_t* Data2, uint8_t* Data1)
{
//-524288 bis 524287
//Umrechnen in Dezimal (Zweierkomplement)
*output = 0;
*output = *Data3;
*output <<= 8;
*output |= *Data2;
*output <<= 8;
*output |= *Data1;
*output >>= 4;
if(bitRead(*Data3, 7) == 1) //negative Zahel
{
*output = *output - (2*524288);
}
}
void Interrupt_Data()
{
Wire2.beginTransmission(adxl357);
Wire2.write(0x0E); //0x08 für start bei x // 0x0E für Start bei z
Wire2.endTransmission();
Wire2.requestFrom(adxl357, 3);
ZDATA3 = Wire2.read();
ZDATA2 = Wire2.read();
ZDATA1 = Wire2.read();
convert(&ZDATA, &ZDATA3, &ZDATA2, &ZDATA1);
File_accelerometer.print(micros()); //oder micros()
File_accelerometer.print(";");
File_accelerometer.println(ZDATA);
ZDATA = 0;
ZDATA3 = 0;
ZDATA2 = 0;
ZDATA1 = 0;
}
void setup()
{
//https://forum.pjrc.com/threads/57444-How-to-change-clock-speed-on-Teensy-4-0
//https://www.youtube.com/watch?v=i_pGZm4jqBc
set_arm_clock(816000000);
Serial.begin(115200);
while ( !Serial && millis() < 4000 ) ;
Serial.print("F_CPU_ACTUAL: ");
Serial.println(F_CPU_ACTUAL);
Serial.println("setup");
// ---- Set up Audio ----
AudioMemory(60);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(myInput);
sgtl5000_1.volume(0.5);
sgtl5000_1.micGain(40);
// ---- Initialize the SD card ----
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
while (1) {
Serial.println("Unable to access the SD card");
delay(1000);
}
}
// ---- Set up Accelerometer ----
Wire2.begin();
Wire2.setClock(400000); //400000
delay(500);
//Read and set Range
Wire2.beginTransmission(adxl357);
Wire2.write(0x2C);
Wire2.write(1); // 1 für Fast mode +-10g // 129 für High speed mode +110g // 2 für Fast mode +-20g
Wire2.endTransmission();
delay(100);
Wire2.requestFrom(adxl357, 1);
Range = Wire2.read();
Serial.print("Range: ");
Serial.println(Range);
//Read DEVID_AD
Wire2.beginTransmission(adxl357);
Wire2.write(0x00);
Wire2.endTransmission();
delay(100);
Wire2.requestFrom(adxl357, 1);
DEVID_AD = Wire2.read();
Serial.print("DEVID_AD: ");
Serial.println(DEVID_AD);
//Read REVID
Wire2.beginTransmission(adxl357);
Wire2.write(0x03);
Wire2.endTransmission();
delay(100);
Wire2.requestFrom(adxl357, 1);
REVID = Wire2.read();
Serial.print("REVID: ");
Serial.println(REVID);
//Read and set POWER_CTL
Wire2.beginTransmission(adxl357);
Wire2.write(0x2D);
Wire2.write(0); //enable measurement mode
Wire2.endTransmission();
delay(100);
Wire2.requestFrom(adxl357, 1);
POWER_CTL = Wire2.read();
Serial.print("POWER_CTL: ");
Serial.println(POWER_CTL);
// ---- Set Interrupt for Data ready (Accelerometer) ----
pinMode(Data_pin, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(Data_pin), Interrupt_Data, RISING);
// ---- Set Interrupt for Start/Stop Recording ----
pinMode(Switch_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Switch_pin), Interrupt_Start_Stop, CHANGE);
}
void loop()
{
if (active == true)
{
continueRecording();
}
}
I have also tired using the Bounce(2) libary without luck
Edit: when I add Serial.println(digitalRead(Switch_pin)); to the loop.
From the moment the recording is started, a change at the input is only detected with an extreme delay. It is even so that nothing more or is output. It seems as if he would no longer run through the loop.
Last edited: