Čitanje na prekid
Što prikazuje ovaj primjer
Senzor sam javlja mikrokontroleru kada treba čitati. BMV080 signalizira na svom izlazu IRQ (aktivan u niskom stanju), a ovaj primjer hvata padajući brid prekidom, a zatim čita PM2.5 dok IRQ ostaje nisko. Senzor radi u kontinuiranom načinu rada: njegov prekid se ne može koristiti kao okidač u načinu rada s ciklusima (duty cycling).
Uz Qwiic kabel ili I2C ožičenje iz Brzog početka, spojite još jednu žicu:
| Kontroler | Soldered BMV080 Particulate Matter Sensor |
|---|---|
GPIO 13 (IRQ_PIN u skici) | IRQ |
Primjer koristi pin 13. Ako vaša pločica na tom pinu nema prekid, skica ispisuje Not a valid interrupt pin!: spojite IRQ na pin koji ga ima i promijenite IRQ_PIN u skladu s tim.
Kod primjera
Ovo je InterruptTrigger.ino iz fiksirane verzije biblioteke, bez uvodnog komentara. Sama skica je točno onakva kakva se isporučuje. Koristi zadanu adresu pločice, 0x57.
Ovaj primjer koristi i attachInterrupt(), detachInterrupt(),
digitalPinToInterrupt(), pinMode() i digitalRead()
(Arduino referenca),
koji dolaze s Arduino jezgrom i nisu dio biblioteke Soldered BMV080.
#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;
}
Očekivani rezultat, ovdje s ESP32 razvojne pločice (ESP32-WROOM-32) s
IRQ spojenim na GPIO 13 i nepromijenjenim IRQ_PIN:
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
Točka se pojavljuje svakih 150 ms dok skica čeka. Svaki put kada senzor signalizira, skica ispisuje Interrupt triggered, zatim Reading BMV080: s vrijednošću PM2.5 u µg/m³, a nakon toga Obstructed kada je pogled senzora blokiran. Vaši će se brojevi razlikovati ovisno o zraku oko senzora.
Korištene funkcije
BMV080()returns NoneStvara objekt senzora. Ne prima argumente: adresa i Wire port zadaju se u begin().
ReturnsKonstruktor; nema povratne vrijednosti.
begin(const uint8_t address = BMV080_DEFAULT_ADDRESS, TwoWire &wirePort = Wire)returns boolPostavlja I2C adresu i Wire port koje biblioteka koristi te provjerava odgovara li senzor na toj adresi. Ne pokreće I2C sabirnicu, zato prvo pozovite Wire.begin(), kao što to radi primjer.
Returnstrue kada je senzor odgovorio na adresi, inače false.
Parametri
| Naziv | Tip | Opis |
|---|---|---|
address | uint8_t | I2C adresa senzora. Zadano je BMV080_DEFAULT_ADDRESS, što je 0x57, zadana adresa pločice. |
wirePort | TwoWire & | I2C port koji se koristi. Zadano je Wire. |
init()returns boolPriprema senzor preko Bosch upravljačkog programa: čita verziju upravljačkog programa, otvara senzor, izvodi programski reset i čita ID senzora. Pozovite je nakon begin() i prije svega ostalog.
Returnstrue kada su svi koraci uspjeli, false kada je neki propao.
setMode(uint8_t mode)returns boolPokreće mjerenje u odabranom načinu rada. Uz prekid koristite kontinuirani način rada.
Returnstrue kada je Bosch upravljački program pokrenuo mjerenje, inače false.
Parametri
| Naziv | Tip | Opis |
|---|---|---|
mode | uint8_t | BMV080_MODE_CONTINUOUS za kontinuirano mjerenje, kao ovdje, ili BMV080_MODE_DUTY_CYCLE za rad s ciklusima. |
readSensor(bmv080_output_t *bmv080_output = nullptr)returns boolOmogućuje Bosch upravljačkom programu da jednom dohvati i obradi podatke sa senzora. Kada stigne novo očitanje, biblioteka ga sprema za PM25() i isObstructed().
Returnstrue kada je tijekom ovog poziva stiglo novo očitanje, inače false.
Parametri
| Naziv | Tip | Opis |
|---|---|---|
bmv080_output | bmv080_output_t * | Neobavezno. Bosch izlazna struktura u koju se kopira novo očitanje. Primjer je izostavlja. |
PM25()returns floatVraća vrijednost PM2.5 posljednjeg očitanja: čestice promjera 2,5 µm ili manje.
ReturnsMasena koncentracija PM2.5 u µg/m³.
isObstructed()returns boolVraća zastavicu zapriječenosti posljednjeg očitanja. Senzor je postavlja kada se nepomičan predmet nalazi na njegovom optičkom putu.
Returnstrue kada je posljednje očitanje bilo zapriječeno, inače false.
Sve zajedno
Rutina prekida samo postavlja zastavicu, a loop() obavlja čitanje. IRQ je aktivan u niskom stanju, pa primjer okida na padajući brid i postavlja pin kao ulaz s pull-up otpornikom.