Zum Hauptinhalt springen

Bei Interrupt lesen

Was dieses Beispiel zeigt​

Der Sensor teilt Ihrem Controller selbst mit, wann gelesen werden soll. Der BMV080 meldet sich über seinen active-low-Ausgang IRQ. Dieses Beispiel erkennt die fallende Flanke mit einem Interrupt und liest dann PM2.5, solange IRQ auf Low bleibt. Der Sensor läuft im kontinuierlichen Modus: Sein Interrupt kann im Duty-Cycling-Modus nicht als Trigger verwendet werden.

Verbinden Sie zusätzlich zum Qwiic-Kabel oder zur I2C-Verdrahtung aus dem Quick Start noch eine weitere Leitung:

ControllerSoldered BMV080 Particulate Matter Sensor
GPIO 13 (IRQ_PIN im Sketch)IRQ

Das Beispiel verwendet Pin 13. Wenn Ihr Board an diesem Pin keinen Interrupt unterstützt, gibt der Sketch Not a valid interrupt pin! aus: Verbinden Sie IRQ mit einem Pin, der einen Interrupt unterstützt, und passen Sie IRQ_PIN entsprechend an.

Der Beispielcode​

Dies ist InterruptTrigger.ino aus der festgelegten Bibliothek, ohne den Kopfkommentar. Der Sketch selbst ist unverändert, so wie er ausgeliefert wird. Er verwendet die Standardadresse des Boards, 0x57.

Dieses Beispiel verwendet außerdem attachInterrupt(), detachInterrupt(), digitalPinToInterrupt(), pinMode() und digitalRead() (Arduino-Referenz), die zum Arduino-Core gehören und nicht Teil der Soldered-BMV080-Bibliothek sind.

Select Board
InterruptTrigger.ino
#include "BMV080-SOLDERED.h"

BMV080 bmv080; // Create an instance of the BMV080 class
#define BMV080_ADDR 0x57 // BMV080 default I2C address

#define IRQ_PIN 13 // Declare interrupt pin

bool triggered = false; // Interrupt flag

void setup()
{
Serial.begin(115200);

while (!Serial) delay(10); // Wait for Serial to become available

Wire.begin();

// Attempt to initialize the sensor via I2C
if (bmv080.begin(BMV080_ADDR, Wire) == false)
{
Serial.println("BMV080 not detected");
while (1)
;
}
Serial.println("BMV080 found!");


// Initialize the sensor
if (bmv080.init())
{
Serial.println("BMV sensor initialized");
}
else
{
Serial.println("BMV initialization failed");
while (1)
;
}

// Set the sensor mode to continuous mode
// The hardware interrupt of the BMV080 sensor unit cannot be used as trigger
// in duty cycling mode.
if(bmv080.setMode(BMV080_MODE_CONTINUOUS) == true)
{
Serial.println("BMV080 set to continuous mode");
}
else
{
Serial.println("Error setting BMV080 mode");
}

enable_external_interrupt(true); // Enable external interrupt handling for the IRQ pin
}

void loop()
{
// Check if interrupt flag was set
if (triggered == true)
{
Serial.println("Interrupt triggered");
triggered = false; // Reset the interrupt flag

// Keep reading sensor data
do
{
Serial.print("Reading BMV080: ");
if (bmv080.readSensor())
{
float pm25 = bmv080.PM25();
Serial.print(pm25);

if (bmv080.isObstructed() == true)
{
Serial.print("\tObstructed");
}
Serial.println();
}
} while (digitalRead(IRQ_PIN) == LOW);
}
delay(150);
Serial.print(".");
}

void enable_external_interrupt(bool enable)
{
int checkPin = digitalPinToInterrupt(IRQ_PIN);

if (checkPin == -1)
{
Serial.println("Not a valid interrupt pin!");
}
else
{
Serial.println("Valid interrupt pin.");
}

pinMode(IRQ_PIN, INPUT_PULLUP); // Configure IRQ pin as input with internal pull-up resistor

if (enable)
{ // Enabel external interrupt
attachInterrupt(digitalPinToInterrupt(IRQ_PIN), ISR_handler, FALLING );
}
else
{ // Disable external interrupt
detachInterrupt(digitalPinToInterrupt(IRQ_PIN) );
}
}

void ISR_handler(void)
{
// Set interrupt flag
triggered = true;
}

Erwartetes Ergebnis, hier von einem ESP32-Entwicklungsboard (ESP32-WROOM-32), bei dem IRQ mit GPIO 13 verbunden ist und IRQ_PIN unverändert bleibt:

Serial MonitorAutoscrollShow timestampNewline115200 baud
Message (Enter to send message to the board)
BMV080 found!
BMV sensor initialized
BMV080 set to continuous mode
Valid interrupt pin.
......Interrupt triggered
Reading BMV080: 7.18
......Interrupt triggered
Reading BMV080: 7.26
......Interrupt triggered
Reading BMV080: 7.09

Solange der Sketch wartet, erscheint alle 150 ms ein Punkt. Jedes Mal, wenn der Sensor ein Signal gibt, gibt der Sketch Interrupt triggered aus, dann Reading BMV080: mit dem PM2.5-Wert in µg/m³, gefolgt von Obstructed, wenn die Sicht des Sensors blockiert ist. Ihre Werte hängen von der Luft um den Sensor ab.

Verwendete Funktionen​

BMV080()returns None

Erstellt das Sensorobjekt. Es nimmt keine Argumente entgegen: Die Adresse und der Wire-Port werden an begin() übergeben.

ReturnsKonstruktor; kein Rückgabewert.

begin(const uint8_t address = BMV080_DEFAULT_ADDRESS, TwoWire &wirePort = Wire)returns bool

Legt die I2C-Adresse und den Wire-Port fest, die die Bibliothek verwendet, und prüft, ob der Sensor unter dieser Adresse antwortet. Der I2C-Bus wird dabei nicht gestartet, rufen Sie daher zuerst Wire.begin() auf, wie im Beispiel.

Returnstrue, wenn der Sensor unter der Adresse geantwortet hat, sonst false.

Parameter

NameTypBeschreibung
addressuint8_tDie I2C-Adresse des Sensors. Standardmäßig BMV080_DEFAULT_ADDRESS, also 0x57, die Standardadresse des Boards.
wirePortTwoWire &Der zu verwendende I2C-Port. Standardmäßig Wire.
init()returns bool

Bereitet den Sensor über den Bosch-Driver vor: liest die Driver-Version, öffnet den Sensor, führt einen Soft-Reset durch und liest die ID des Sensors. Rufen Sie sie nach begin() und vor allem anderen auf.

Returnstrue, wenn jeder Schritt erfolgreich war, false, wenn einer fehlgeschlagen ist.

setMode(uint8_t mode)returns bool

Startet die Messung im gewählten Modus. Verwenden Sie den kontinuierlichen Modus zusammen mit dem Interrupt.

Returnstrue, wenn der Bosch-Driver die Messung gestartet hat, sonst false.

Parameter

NameTypBeschreibung
modeuint8_tBMV080_MODE_CONTINUOUS für kontinuierliche Messung, wie hier, oder BMV080_MODE_DUTY_CYCLE für Duty Cycling.
readSensor(bmv080_output_t *bmv080_output = nullptr)returns bool

Lässt den Bosch-Driver einmal Daten vom Sensor abrufen und verarbeiten. Wenn ein neuer Messwert eintrifft, speichert ihn die Bibliothek für PM25() und isObstructed().

Returnstrue, wenn während dieses Aufrufs ein neuer Messwert eingetroffen ist, sonst false.

Parameter

NameTypBeschreibung
bmv080_outputbmv080_output_t *Optional. Eine Bosch-Ausgabestruktur, in die der neue Messwert kopiert wird. Das Beispiel lässt sie weg.
PM25()returns float

Gibt den PM2.5-Wert der letzten Messung zurück: Partikel mit einem Durchmesser von 2,5 µm oder kleiner.

ReturnsPM2.5-Massenkonzentration in µg/m³.

isObstructed()returns bool

Gibt das Obstruction-Flag der letzten Messung zurück. Der Sensor setzt es, wenn sich ein feststehendes Objekt in seinem optischen Pfad befindet.

Returnstrue, wenn die letzte Messung blockiert war, sonst false.

Zusammenfassung​

Die Interrupt-Routine setzt nur ein Flag, und loop() übernimmt das Lesen. IRQ ist active low, daher löst das Beispiel bei der fallenden Flanke aus und setzt den Pin als Eingang mit Pull-up.