Feinstaubsensor schlafenlegen

Um den Stromverbrauch des Box zu senken, möchte ich den Feinstaubsensor für mehrere Minuten schlafen legen. Aus dem Protokolldatenblatt entnehme ich dazu eine Sequenz von 19 Bytes, die man an den Sensor senden kann. Aus dem Listing des Mustersketches entnehme ich, dass dafür die Library “SDS011-select-serial.h” zuständig ist.
Weiter entnehme ich dem Listing dass ein Kommando SDS.read(&pm25,&pm10) gibt.
Gibt es auch ein Kommando SDS.write oder wie kann ich die Bytefolge an den Sensor schicken und wie kann ich die Antwort entgegen nehmen?

2 Likes

Die Library für den SDS besitzt die Funktion SDS.sleep() über die der Sensor schlafen gelegt werden kann und über SDS.wakeup()kann der Sensor wieder aufgewacht werden.

1 Like

Danke @mario.
Zusatzfrage wie komme ich an die Doku für solch eine Library?

1 Like

Die Library findest du hier. In der .h finden sich alle Funktionen, die verfügbar sind. Die Dokumentation für die Library muss allerdings noch um die sleep()und wakeup Funktionen erweitert werden

1 Like

Es funktioniert mit sleep() und wakeup(). Nur das Ergebnis hat mich etwas enttäuscht:
Mit aktivem SDS 170mA
Mit SDS im Ruhezustand 110 mA

Zur Teststation senseBox:edu mit HDC1080, BMP280 sowie TSL45315 & VENL6070 und natürlich SDS011.
@OllyS mit sleep() und wakeup() funktioniert es prächtig.

2 Likes

hallo Zusammen,
leider hat die Library “SDS011-select-serial.h” bei mir nicht ganz perfekt funktioniert. Das wakeup() hat bei mir nicht funktioniert. In der SDS-serial-serial.cpp steht in der Funktion wakeup():

void SDS011::wakeup() {
sds_data.write(0x01);
sds_data.flush();
}

Lt. SDS011-Manual (https://nettigo.pl/attachments/398) brauchts ein paar mehr Bytes für das Kommando WAKEUP.
Nach dem ich die Funktion wie folgt angepasst habe, läufts.

void SDS011::wakeup() {
// Sleepcmd Byte5 +1
// Sleepcmd Byte18 +1 (checksum)
for (uint8_t i = 0; i < 19; i++) {
if (i == 4 || i == 17) {
sds_data.write(SLEEPCMD[i] + 1);
} else {
sds_data.write(SLEEPCMD[i]);
}
}
sds_data.flush();
while (sds_data.available() > 0) {
sds_data.read();
}
}

Das Stromsparen ist damit aber auch bei mir nicht wirklich berauschend.(ca 180mA vs. ca.110mA) Es bringt mehr den Sensor über
senseBoxIO.powerUART(true); //bzw (false)
komplett auszuschalten und dann auch wieder einzuschalten.
Wirklich effektiv ist es den Prozessor und IO-Hardware in den Tiefschlaf zu versetzen. Das ist aber ein neues Thema.

Bernd

1 Like

Hallo zusammen,

das war eine ausführliche Antwort. Laut SDS Datenblatt muss wirklich eine ganze Bytefolge an den Sensor geschickt werden. Es scheint aber wirklich auch anders zu gehen wie beim HackairProjekt ( https://github.com/hackair-project/hackAir-Arduino/blob/master/src/hackair.cpp) zu sehen ist. Anscheinend reagiert in manchen Fällen der Sensor auch, wenn er einfach irgendetwas empfängt.
Das Abschalten des UART-Ports ist eine gute Idee, bringt aber laut Datenblatt nur 4 mA, die der Sensor im Ruhezustand verbraucht.
Die offiziellen Angaben von senseBox mit 100 mA Incl. Feinstaubsensor sind nur erklärlich, wenn nur der Feinstaubsensor alleine angeschlossen ist.
P.S: @Fuchsbau ist Deine Station in Mannheim?

1 Like

Hallo Altprog,
52,6951 13,173186 Fuchsbau-OHV (is aber noch ne Baustelle)

Bernd

1 Like

@Fuchsbau

Hallo,
janz weit weg. Velten bei Berlin?

1 Like

Danke dir für den Fix Bernd. Denkt aber daran, dass der Sensor sich erst “aufheizen” muss bevor ihr wieder mit den Messungen beginnt.

1 Like

Reichen 10 s zum “Aufheizen”?

1 Like

Lt. SDS011-Manual (https://nettigo.pl/attachments/398) soll man 30s warten.

1 Like

Hi altprog,
habe im Forum danach gesucht und folgende funktionierende Lösung gefunden:
Auszüge aus meinem Programm (geht sicher noch eleganter, es macht aber was es soll- SDS 1 Minute vor auslesen Messwert einschalten und Ser Schnittstelle initialisieren!Wichtig! – Messwert auslesen und SDS wieder ausschalten):
--------------begin teil 1 –
// PM2.5
const char PM25SENSOR_ID[] PROGMEM = “5xxxxxxxxxxx…”;

int SDSdelay = 0; //Zähler
int uber = 20; //Anzahl Minuten für Aktivierung Feinstaubsensor –>const… besser

WiFiSSLClient client;

--------------ende teill 1

--------------beginn-teil 2
//-----PM-----//
#ifdef SDS011_CONNECTED

uint8_t attempt = 0;
float pm10, pm25;
SDSdelay++;
Serial.print(SDSdelay);
Serial.print (" ");
//if (SDSdelay<uber-1) senseBoxIO.powerUART(true); //bzw (false)??
if (SDSdelay == uber - 1) {
Serial.println(“SDS SensornON”);
senseBoxIO.powerUART(true);
delay(3000);
SDS_UART_PORT.begin(9600);
}
else {
senseBoxIO.powerUART(false);
Serial.println(“SDS SensornOFF”);
}

if (SDSdelay >= uber) {
Serial.println(“SDS-Sensor read”);
while (attempt < 10) {

  bool error = SDS.read(&pm25, &pm10);
  if (!error) {
    addMeasurement(PM10SENSOR_ID, pm10);
    addMeasurement(PM25SENSOR_ID, pm25);
    break;
  }
  attempt++;
}
senseBoxIO.powerUART(false);
Serial.println("SDS SensornOFF");
SDSdelay = 0;

}
#endif

DEBUG(F(“Submit values”));
submitValues();
-----------ende teil 2—

…viel Erfolg!

2 Likes

@AlbertEb

Vielen Dank für die Lösung. Eine ähnliche Lösung habe ich auch gefunden.

uint8_t attempt = 0;
float pm10, pm25;
//prüfen ob Zeit für eine neue Feinstaubmessung
unsigned long jetzt=millis();
unsigned long vergangen=jetzt-startSDS_time;
//Serial.println(jetzt/1000);
//Serial.println(startSDS_time/1000);
//Serial.println(vergangen/1000);
if (vergangen>=feinstaubIntervall) {
SDS.wakeup();
zustand=true;
delay(10000); // Vorlauf damit nicht gleich nach dem Einschalten gemessen wird
}
while (attempt < 5) {
bool error = SDS.read(&pm25, &pm10);
if (!error) {
addMeasurement(PM10SENSOR_ID, pm10);
addMeasurement(PM25SENSOR_ID, pm25);
SDS.sleep();
zustand=false;
startSDS_time=millis();
break;
}
attempt++;
}

Die Vorlaufzeit ist im Moment etwas kurz gewählt, muss ev. verlängert werden

Gruß Altprog

1 Like

Beste Prog,

I am working on the similar project, My teacher sent me a part of sketch which has function that can be called when lora module sends TX.
*My project is to make the sensebox run on solar power. The part of sketch from my teacher is as follow:

const long time2sleep = 300000 // where does this function belong in the sketch?*

void send2Sleep(long mills){*

     senseBoxIO.powerUART(false);​*
     senseBoxIO.powerI2C(false);​*
     delay(mills);​*
     senseBoxIO.powerUART(true);​*
     delay(250);​*
     SDS_UART_PORT.begin(9600);​*
     senseBoxIO.powerI2C(true);​*
     delay(250);​*
}

*and this function is called when the lora module starts to do its TX:

case EV_TXCOMPLETE:*
DEBUG(F("EV_TXCOMPLETE (includes waiting for RX windows)"));​*
      if (LMIC.txrxFlags & TXRX_ACK)​*
        DEBUG(F("Received ack"));​*
      if (LMIC.dataLen) {​*
        DEBUG(F("Received "));​*
        DEBUG(LMIC.dataLen);​*
        DEBUG(F(" bytes of payload"));​*
      }
      // Schedule next transmission​*
      send2Sleep(time2sleep);​*
      os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);​*
      break;

*I have not tried your suggested solution yet. As this topic relates only with SDS011, I do get it only has sleep and wake function for it.
I would be happy to have your insights on it.
on which section of the sketch do i need to put the time2sleep function?
I am noob with arduino and have been looking through all the forums.
I did find someone mentinioning about the project where the sketch about putting sensors into deep sleep are to be found but probably it is in other forums.

thank you for your time,
Kind Regards,
john

1 Like

Hi Everyone,

I used @AlbertEb sketch and it has been working for me now. Looking forward to just power it with solar panel and Lipo battery :).

TY for the sketch.

Best Regards,
John