Hello everyone,
I have the Adafruit MPRLS Ported Pressure Sensor. It uses I^2C for communication. For my project, these pressure values need to be stored in a buffer continuously. Unfortunately, the code interrupts after the sensor has been calibrated. The interrupt time has already been increased, but this did not solve the problem. (The reason for the communication interruption is due to I^2C, which also uses interrupts).
Can someone please help me figure out how to read the values in the ISR anyway?
Thank you very much for any help!
Here is my code:
#include <Wire.h>
#include "Adafruit_MPRLS.h"
#include <Adafruit_NeoPixel.h>
const int PIN = 6;
const int NUM_PIXELS = 11;
Adafruit_NeoPixel pixels(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
int fuellstand = 0;
const int RESET_PIN = -1;
const int EOC_PIN = -1;
const int Engine = 2;
const int button = 8;
int value = 0;
Adafruit_MPRLS mpr = Adafruit_MPRLS(RESET_PIN, EOC_PIN);
// ---- Konstanten ----
const float rho = 1000.0; // Dichte Wasser (kg/m³)
const float g_acc = 9.81; // Erdbeschleunigung (m/s²)
const float A = 0.01; // 10 cm × 10 cm = 0.01 m²
// ---------------------
float p0_hPa = 0; // Umgebungsdruck (wird beim Start gemessen)
const int BUILED = 13;
const int BUFFERSIZE = 100;
int Buffer[BUFFERSIZE] = { 0 };
void setup() {
pinMode(BUILED, OUTPUT);
pinMode(button, INPUT_PULLUP);
pinMode(Engine, OUTPUT);
pixels.begin();
Serial.begin(9600);
while (!Serial) { delay(10); }
Serial.println("MPRLS - Diagnose startet...");
Serial.println("Initialisiere MPRLS Sensor...");
if (!mpr.begin()) {
Serial.println("FEHLER: MPRLS Sensor nicht gefunden!");
}
Serial.println("MPRLS Sensor gefunden!");
Serial.println("Kalibriere...");
const int samples = 10;
float sum = 0;
for (int i = 0; i < samples; i++) {
float pressure = mpr.readPressure();
Serial.print("Messung ");
Serial.print(i);
Serial.print(": ");
Serial.println(pressure);
sum += pressure;
delay(200);
}
p0_hPa = sum / samples;
Serial.print("Referenzdruck: ");
Serial.print(p0_hPa);
Serial.println(" hPa");
Serial.println("Kalibrierung abgeschlossen!");
Timer1_init_us(1000);
}
void NeoPixel_strip(int fuellstand) {
if (fuellstand > 1500) {
pixels.fill(pixels.Color(0, 150, 0), 0, 11);
pixels.show();
}
if (fuellstand <= 1500 && fuellstand > 1250) {
pixels.fill(pixels.Color(0, 150, 0), 0, 4);
pixels.fill(pixels.Color(255, 120, 0), 4, 8);
pixels.fill(pixels.Color(150, 0, 0), 8, 11);
pixels.show();
}
if (fuellstand <= 1250 && fuellstand > 1000) {
pixels.fill(pixels.Color(255, 120, 0), 4, 8);
pixels.fill(pixels.Color(150, 0, 0), 8, 11);
pixels.show();
}
if (fuellstand <= 1000 && fuellstand > 750) {
pixels.fill(pixels.Color(255, 120, 0), 6, 8);
pixels.fill(pixels.Color(150, 0, 0), 8, 11);
pixels.show();
}
if (fuellstand <= 750 && fuellstand > 500) {
pixels.fill(pixels.Color(255, 120, 0), 7, 8);
pixels.fill(pixels.Color(150, 0, 0), 8, 11);
pixels.show();
}
if (fuellstand <= 500 && fuellstand > 200) {
pixels.fill(pixels.Color(150, 0, 0), 8, 11);
pixels.show();
}
if (fuellstand <= 200) {
pixels.fill(pixels.Color(250, 0, 0), 0, 3);
pixels.show();
}
}
void loop() {
//Mittelwert Buffer
float mlAV = 0.0;
for (int i = 0; i < BUFFERSIZE; i++) {
mlAV += Buffer[i];
}
mlAV = mlAV / BUFFERSIZE;
Serial.print("MW:");
Serial.println(mlAV);
NeoPixel_strip(mlAV);
value = digitalRead(button);
if (value == LOW) {
digitalWrite(Engine, HIGH);
} else {
digitalWrite(Engine, LOW);
}
delay(500);
}
ISR(TIMER1_COMPA_vect) // ISR Timer1
{
static int timer = 0;
static bool state = 0;
static int BufferCounter = 0;
//fa=1kHz
float pressure_hPa = mpr.readPressure();
float diff_hPa = pressure_hPa - p0_hPa;
float diff_Pa = diff_hPa * 100.0; // 1 hPa = 100 Pa
// Höhe der Wassersäule in Metern
float h = diff_Pa / (rho * g_acc);
// Volumen in ml
float volumen_ml = (A * h) * 1e6;
Buffer[BufferCounter] = volumen_ml;
BufferCounter++;
if (BufferCounter >= BUFFERSIZE) {
BufferCounter = 0;
}
//Test
//1Hz Blinker
timer++;
if (timer >= 500) {
timer = 0;
state = !state;
digitalWrite(BUILED, state);
}
}
//inspired by Google Code project http://code.google.com/p/arduino-timerone/
//Value in microseconds
//ISR(TIMER1_ISR(TIMERx_vect)){} is necessary
void Timer1_init_us(long microseconds) {
unsigned char clockSelectBits;
long RESOLUTION = 65536;
TCCR1A = 0;
TCCR1B = _BV(WGM13);
long cycles = (F_CPU / 2000000) * microseconds;
if (cycles < RESOLUTION) clockSelectBits = _BV(CS10);
else if ((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11);
else if ((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10);
else if ((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12);
else if ((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10);
else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10);
char SREG_bak = SREG;
cli(); // Disable interrupts for 16 bit register access
ICR1 = cycles; // ICR1 is TOP in phase & frequency correct PWM mode
SREG = SREG_bak;
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
TCCR1B |= clockSelectBits;
TIMSK1 = _BV(TOIE1);
TCCR1B |= clockSelectBits;
}
//______________________________________________________________________________________________________________________________________________