Tera Sensor nextPM auslesen

Hi Zusammen, ich habe hier zwei mal den Feinstaubsensor "nextPM" von Tera Sensor und würde diese gerne über den Arduino auslesen und die Werte auf einer SD-Karte speichern. Später evtl. sogar über ein GSM Modul mit Simkarte die Werte auf einen Webserver laden oder in eine Dropbox/Drive o.ä.. Ich bin kompletter Anfänger und habe den Code mal so gut es ging selber geschrieben bekomme aber momentan leider keine Werte aus dem Sensor. Ich bin über jede Hilfe dankbar.

Angefügt der Userguide des Sensors:

Userguide NextPM

Mein Code:

#include <SoftwareSerial.h>

// SoftwareSerial 1: RX = digital pin 2, TX = digital pin 3

SoftwareSerial portOne(2, 3);

// SoftwareSerial 2: RX = digital pin 4, TX = digital pin 5

SoftwareSerial portTwo(4, 5);

void setup() {

// Open serial communications and wait for port to open:

Serial.begin(9600);

//Start each software serial port

portOne.begin(9600);

portTwo.begin(9600);

}

void loop() {

Serial.write(0x11);

portOne.listen();

Serial.println("FeinstaubUmgebung:");

while (portOne.available() > 0){

char inByte = portOne.read();

Serial.println(inByte);

}

//blank line to seperate data from teh two ports:

Serial.println();

portTwo.listen();

Serial.print("FeinstaubFilter:");

while (portTwo.available() > 0) {

char inByte = portTwo.read();

Serial.write(inByte);
}

//blank line to seperate data from the two ports:

Serial.println();
}

habe versucht den code als Datei hochzuladen aber ich darf leider nicht.....

Hallo,
So einfach wie Du es dir vorstellst wird das nicht sein. Schau Dir mal die Doku an. Du must zuerst mal ein Komando senden und dann antwortete das Ding. Prüfsumme wird auch noch bennötigt.
Leider haben die anscheinend kein Beispiel in der Doku .

Frag noch mal beim Hersteller ob er nicht ein Beispiel hat.
Heinz

Hallo, danke für deine Antwort. Ich hab dem Hersteller nochmal geschrieben.

das Kommando zum Sensor für einen Wert schicken ich via: Serial.write(0x11)

Muss ich da noch etwas hinzufügen, dass der Befehlt auch über den Serial portOne gesendet wird? bzw. wird der Befehl so wie es da steht über alle Serials geschickt?

portOne.write(0x11);

aber ich denke da fehlt die Prüfsumme noch. Schau noch mal in die Doku ich hatte da ein Beispiel gesehen wenn ich mich richtig erinnere.
Heinz

Danke nochmal. Wegen der Prüfsumme habe ich den Hersteller angefragt, das versteh ich leider nicht ganz - leider noch keine Antwort.

Ich hätte noch eine andere Frage....

ich muss dem Sensor ein Command Frame senden aus Adresse, Kommando, Data und Checksumme. Also z.B.

portOne.write(0x81 0x11 0x6E + "Checksumme") aber leider bekomme ich eine Fehlermeldung also habe ich den Befehl als char formuliert

char PMaverage = (0x81, 0x11, 0x6E);
portOne.write(PMaverage);

ist das richtig mit dem char oder kommt da was komplett falsches bei raus?

Hallo,
wenn Du etwas an char definierst ist das zunächst mal nur ein byte. Du könntest ein char Array nehmen oder ein String Objekt. Oder in einer Schleife die char einzeln ausgeben. Ich würde ersteres nehmen. Lass dir doch zur Kontrolle die Ausgabe auch auf dem Monitor anzeigen.
Wenn ich mich richtig erinnere war in der Doku auch ein Beispiel zur Berechnung der Prüfsumme.
Heinz

Hallo, Danke nochmal. Ich habe inzwischen einen Code gefunden auf github:

Habe den Code etwas geändert, da im gefunden Code die Pins 0&1 für den Sensor verwendet wird und er in Verbindung mit einem MKR Wifi 1010 board geschrieben ist. Leider bekomme ich immer noch keine Werte. Serieller Bildschirm ist natürlich immer an.

Hat jemand eine Idee? auch checke ich nicht welcher Teil im Code für das Wifi board sein soll.
Mein Code sieht jetzt wie folgt aus:

#include <SoftwareSerial.h>
#include <Arduino.h>
#include "wiring_private.h"

// SoftwareSerial 1: RX = digital pin 2, TX = digital pin 3

SoftwareSerial portOne(2, 3);

// SoftwareSerial 2: RX = digital pin 4, TX = digital pin 5

SoftwareSerial portTwo(4, 5);

const uint8_t
msgLen = 3,
mean10sec[msgLen] = {0x81, 0x11, 0x6E}, // 10 sec mean, 1 sec update
mean1min[msgLen] = {0x81, 0x12, 0x6D}, // 1 min mean, 10 sec update
mean5min[msgLen] = {0x81, 0x12, 0x6D}, // 5 min mean, 1 min update
temp_rhum[msgLen] = {0x81, 0x14, 0x6B},// temperature and humidity
sleep_power[msgLen] = {0x81, 0x16, 0x69};// sleep or power on

// See datasheet section 2.1.3 for message description

const uint8_t bufferLen = 16;
uint8_t buffer[bufferLen]; //sure that no name conflict with "buffer"?
inline uint16_t buff2word(uint8_t n) {
return (buffer[n] << 8) | buffer[n + 1];

}

void setup() {

// Open serial communications and wait for port to open:

Serial.begin(9600); // Normale UART Schnittstelle Pin 0 und Pin 1

//Start each software serial port

portOne.begin(115200); // Feinstaubsensor 1 - Umgebung

portTwo.begin(115200); // Feinstaubsensor 2 - Nach Filter

}

void loop() {

// read the NextPM sensor
portOne.write(mean10sec, msgLen); // request PM data

delay(350);

while (portOne.available() > 0) { //my methode

unsigned int r = portOne.readBytes(buffer, 16); // read PM data

if (r == 16) {
String reader = "Read: ";
for (int i = 0; i < 16; i++){
reader += "0x";
if (buffer[i] < 0x10)
reader += "0";
reader += String(buffer[i], HEX);
if (i != 15) {
reader += ", ";
}
}

uint16_t pm01 = word(buffer[9],buffer[10]); //it is x10 here! //Does it work on MKR????
uint16_t pm25 = word(buffer[11],buffer[12]);
uint16_t pm10 = word(buffer[13],buffer[14]);

Serial.print(F("PM1.0 ")); Serial.print(pm01, 1); Serial.print(F(", "));
Serial.print(F("PM2.5 ")); Serial.print(pm25, 1); Serial.print(F(", "));
Serial.print(F("PM10 ")) ; Serial.print(pm10, 1); Serial.print(F(" [ug/m3], "));

}

}
// decode PM message, see datasheet section 2.1.3

portOne.write(temp_rhum, msgLen); // request T/RH data
while (portOne.available() > 0) { //just to wait but the rest out of the while loop...
portOne.readBytes(buffer, 8); // read T/RH data
}
// decode T/RH message, see datasheet section 2.1.3

float temp = buff2word(3);// * 0.9754 - 4.2488;
float rhum = buff2word(5);// * 1.1768 - 4.727;

// print the results

Serial.print(temp, 2); Serial.print(F("C, "));
Serial.print(rhum, 2); Serial.println(F("%rh"));

// wait for 1 second
delay(1000);
}

Im seriellen Monitor wir angezeigt:

0.00C, 0.00%rh
0.00C, 0.00%rh
.
.
.
.
.

Liebe Grüße
Tobias