Forum: Mikrocontroller und Digitale Elektronik Spannungsteiler funktioniert nicht, was mache ich falsch?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von zip (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich versuche gerade eine "Wetterstation" mit Hilfe eines Arduino Nano 
(5V) zu realisieren. Neben Temperatur, usw. möchte ich auch 
Feinstaubdaten sammeln. Dafür habe ich den SDS011 Feinstaub Sensor im 
Einsatz. Dieser wird mit 5V betrieben, die PINs RX, bzw. TX sind aber 
über 3,3V anzusteuern.

Hier im Forum wird als eine mögliche Lösung ein Spannungsteiler 
beschrieben:
3,3V (SDS011) zu 5V Eingang Arduino sollte kein Problem sein, und sauber 
erkannt werden.
5V (Arduino) zu 3,3V (SDS011) müsste "gewandelt" werden.

Die 3,3V kann ich über einen Spannungsteiler relativ einfach dritteln:
1/3 * 5V => ~1,7V
2/3 * 5V => ~3,333V

Daraus habe ich dann R1 = 4,7k Ohm und R2 = 10k Ohm gewählt, da dies die 
einzigen zwei Widerstände sind, die ich zur Verfügung habe (-:

Anbei ein Schaltplan.
Die PINs vom SDS011 sind dabei wie folgt:
PIN 1: +5V
PIN 2: TX @3,3V
PIN 3: RX @3,3V
PIN 4: GND

Leider funktioniert das Ganze nicht.

Meine Frage ist nun, ob R1 und R2 zu groß sind, oder ob ich generell 
etwas falsch verstanden habe, oder vll. sogar beides.

Vielen Dank und einen schönen Sonntag

- zip

von Piffpaffpuff (Gast)


Bewertung
-8 lesenswert
nicht lesenswert
Spannungsreicher funktionieren immer! Geht nämlich nicht anders.


Suche den Fehler.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
> Leider funktioniert das Ganze nicht.

Was genau funktioniert denn nicht? Stimmen die Spannungspegel nicht oder 
die Signalflanken?

Oder genügt die Ausgangsspannung in Rückrichtung dem Mikrocontroller 
nicht?

> Meine Frage ist nun, ob R1 und R2 zu groß sind

Vielleicht, vielleicht auch nicht. Du solltest das mit einem Oszilloskop 
überprüfen.

von Pz (Gast)


Bewertung
-4 lesenswert
nicht lesenswert
5v------4k7-----10k-------uC
                    |
                  GND

von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
>
> Was genau funktioniert denn nicht? Stimmen die Spannungspegel nicht oder
> die Signalflanken?
>

Jetzt wo ich eure Antworten lese, war mein Betreff etwas ungeschickt 
gewählt. Der Spannungsteiler funktioniert. Wie eingangs beschrieben sind 
die Spannung ca 3,3V von R2 zu GND und 1,7V von R1 zu R2. Allerdings 
funktioniert die Kommunikation 5V -> 3,3V nicht.

Das Bauteil ist auch nicht beschädigt, da es mit einem NodeMCU, welcher 
direkt mit 3,3V funktioniert. Deshalb muss der Fehler irgendwo bei mir 
liegen.

> Oder genügt die Ausgangsspannung in Rückrichtung dem Mikrocontroller
> nicht?

Die Rückrichtung funktioniert, denn Daten können vom Bauteil gelesen, 
aber nicht geschrieben werden. Deshalb mein etwas ungeschickt 
formulierter Titel "Spannungsteiler funktioniert nicht".

>
>> Meine Frage ist nun, ob R1 und R2 zu groß sind
>
> Vielleicht, vielleicht auch nicht. Du solltest das mit einem Oszilloskop
> überprüfen.

Ich habe leider kein Oszilloskop.

Piffpaffpuff schrieb:
> Spannungsreicher funktionieren immer! Geht nämlich nicht anders.
>

Ja, da hast du natürlich Recht.
Mein Titel war etwas ungeschickt gewählt.

Pz schrieb:
> 5v------4k7-----10k-------uC
>                     |
>                   GND

Ich verstehe nicht, was du mir damit sagen möchtest :-/

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
zip schrieb:
> Leider funktioniert das Ganze nicht.

Geht es auch etwas genauer?

Mit deiner Anschlussbelegung bist du dir sicher?
Datenblatt?

Für den SDS011 V1.3 ist ein 7-poliger Stecker angegeben.

von Michael B. (laberkopp)


Bewertung
-1 lesenswert
nicht lesenswert
zip schrieb:
> SDS011

Nach der Beschreibung
https://www.watterott.com/media/files_public/jikujowxn/SDS011.pdf
arbeitet der mit 5V, Spannungsteiler entfallen.

von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Mit deiner Anschlussbelegung bist du dir sicher?
> Datenblatt?
>
> Für den SDS011 V1.3 ist ein 7-poliger Stecker angegeben.

Ja, der Sensor hat 7 Pins. Vgl. 
https://www.watterott.com/media/files_public/jikujowxn/SDS011.pdf
Ich habe im Schaltplan aber nur 4 Pins eingezeichnet.
Das hätte ich vll. auch mal erwähnen sollen.


Michael B. schrieb:
> Nach der Beschreibung
> https://www.watterott.com/media/files_public/jikujowxn/SDS011.pdf
> arbeitet der mit 5V, Spannungsteiler entfallen.

Das stimmt m.M.n nicht, denn der Sensor wird zwar mit 5V betrieben, aber 
die Kommunikation erfolgt über 3,3V. Seite 5, ganz oben:

6 R RX of UART(TTL)@3.3V
7 T TX of UART(TTL)@3.3V

von Aber Aber (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Michael B. schrieb:
> arbeitet der mit 5V, Spannungsteiler entfallen.

Das mag schon sein, wer aber die Schnittstellenbeschreibung
liest und berücksichtig ist klar im Vorteil.

Ich entnehme daraus dass das Teil mit 5V von aussen versorgt
wird aber daraus intern eine Versorgung von 3.3V erzeugt wird.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
zip schrieb:
> Das hätte ich vll. auch mal erwähnen sollen.

Ja, du hättest sogar direkt das Datenblatt verlinken können.
Was kommt denn aus den beiden PWM-Ausgängen raus - funktionieren die?

von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
@Wolfang, ich werde die Schaltung nochmal überprüfen bzw. so gut es für 
mich möglich ist durchmessen und mich dann noch einmal melden. Danke 
schon einmal für die Hilfe.

von Michael B. (laberkopp)


Bewertung
-1 lesenswert
nicht lesenswert
Aber Aber schrieb:
> Das mag schon sein, wer aber die Schnittstellenbeschreibung
> liest und berücksichtig ist klar im Vorteil.

Den Vorteil gönn ich mir

"Serial Port: 5V TTL, 9600bps with 8 data bit, no parity, one stop bit"

https://www.watterott.com/media/files_public/kluucwpsc/SDS011_Control_Protocol.pdf

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wie viel Baud sind denn eingestellt?
Bei den relativ großen R, könnte das Signal schon recht matschig sein.

Wenn du nur 10k und 4k7 hast, schalte mal jeweils 3 davon parallel.
Dann sind die Signale etwas "steiler".

Beitrag #5535863 wurde vom Autor gelöscht.
von Aber Aber (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Michael B. schrieb:
> Den Vorteil gönn ich mir

Das finde ich sehr nett von dir.

von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe noch einmal alles angeschlossen und zuvor scheinbar mehrmals 
einen Fehler gemacht, denn dieses mal hat es funktioniert. Und wieder 
einmal saß das Problem vor dem Computer :)

Bzgl. der Versorgungsspannung von 5V und der Spannung an Rx/Tx, ist die 
Spezifikation leider widersprüchlich. Eingangs wird von 5V, bei 9600 
Bauds geredet. Später allerdings wird Rx @3,3V bzw. Tx @3,3V festgelegt.

Wie Michael B bereits geschrieben hat, wird 9600 bauds in der 
Spezifikation definiert: "Serial Port: 5V TTL, 9600bps with 8 data bit, 
no parity, one stop bit" und so kommuniziere ich mit den Sensor auch.

@pegel, das mit dem parallel schalten von Widerständen ist eine gute 
Idee, daran habe ich gar nicht gedacht.

Welche Größe von R1 bzw. R2 würdet ihr denn in diesem Fall empfehlen?

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
> Welche Größe von R1 bzw. R2 würdet ihr denn in diesem Fall empfehlen?

Einstellige kΩ Werte. Ich verwende immer 1kΩ und 2,2kΩ.

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
zip schrieb:
> Welche Größe von R1 bzw. R2 würdet ihr denn in diesem Fall empfehlen?

Bei 3 parallel sind das dann ca. 1,5k und 3,3k.

von Wolfgang (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Michael B. schrieb:
> Den Vorteil gönn ich mir
>
> "Serial Port: 5V TTL, 9600bps with 8 data bit, no parity, one stop bit"
>
> 
https://www.watterott.com/media/files_public/kluucwpsc/SDS011_Control_Protocol.pdf
Du vertraust einer Softwarespezifikation bezüglich elektrischer Daten?

Was spricht dagegen, erstmal mit dem worst Case zu rechnen und der 
Interface Spezifikation im Datenblatt zu vertrauen?
http://www.komputer.de/wordpress/wp-content/uploads/2018/01/SDS011laserPM2.5sensorspecification-V1.3.pdf

Bei einem Widerstand von 1.5kΩ (3x 4.7kΩ parallel) zwischen Ausgang vom 
µC und RX vom SDS011 wird der Strom, falls der SDS011 wirklich nur 
maximal 3.3V verträgt, durch dessen vermutlich vorhandene Schutzdioden 
(nachmessen) auf einen ungefährlichen Wert von um 1mA begrenzt. Bei 
9k6Bd sollte das die Flanken noch nicht unzulässig verschleifen.
Dann kann man sich mit dem Oszi mal angucken, was passiert und 
insbesondere auch, welcher Pegel am TX oder an den PWM-Ausgängen vom 
SDS011 raus kommt.

Vielleicht liegt es auch einfach an der Software, dass das Ganze nicht 
funktioniert.

von zip (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Ich bin kompletter Anfänger und bin relativ naiv an die Sache 
rangegangen. Nach dem Motto "learning by doing".

Deshalb habe ich anfangs auch gar nicht gemerkt, dass der Sensor nur 
mittels 3,3V über RX/TX angeschlossen werden sollte. Das ist mir erst 
aufgefallen, als nur das Lesen, aber nicht das Schreiben (set 
query/sleep mode, etc. des Sensors) geklappt hat. Erst danach habe ich 
im Detail gesehen, dass eingangs zwar 5V, weiter unten aber 3,3V steht. 
Die meisten Tutorials im Internet benutzen in Verbindung mit dem SDS011 
Sensor auch ein NodeMCU, welcher mit 3,3V betrieben wird und somit das 
Problem nicht hat.

Da ich leider kein Oszilloskop habe, kann ich es auch nicht 
nachmessen/anschauen.

Ich muss das Ganze noch mal mit kleineren Widerständen ausprobieren, da 
das Lesen/Schreiben manchmal, aber nicht zuverlässig funktioniert.

Die anliegende Spannung an Rx (SDS011) liegt bei ~3,0V anstatt den 
empfohlen 3,3V.

von Herr Klamm (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Könnte das Problem sein dass mit dem Spannungsteiler zwar 5V vom µC 
zum IC korrekt funktioniert, da die Spannung reduziert werden muss.

Wenn allerdings vom_ Sensor _zum µC gesendet werden soll, dann werden 
die 3.3V Pegel durch den Spannungsteiler nicht "hochtransformiert".

Google mal nach Levelshifter.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Herr Klamm schrieb:
> Wenn allerdings vom_ Sensor _zum µC gesendet werden soll, dann werden
> die 3.3V Pegel durch den Spannungsteiler nicht "hochtransformiert".

Der TX vom SDS011 hängt lt. Schaltplan direkt am D10 vom Arduino. Was 
soll da "transformiert" werden.

zip schrieb:
> Ich muss das Ganze noch mal mit kleineren Widerständen ausprobieren, da
> das Lesen/Schreiben manchmal, aber nicht zuverlässig funktioniert.

Nimm doch einfach mal 1.5kΩ (3x 4.7kΩ parallel) zwischen D9 und RX vom 
SDS011 (R1), lasse deinen R2 komplett weg und dann gib einen High-Pegel 
auf D9 aus. Welche Spannung misst du dann am Eingagn vom SDS011?

von Frank E. (ffje)


Bewertung
0 lesenswert
nicht lesenswert
In der Probephase verwende ich <1kΩ. Vor dem endgültigen Zusammenbau 
ermittele ich die Kapazität des Einganges und kompensiere mit einem 
Kondensator. Bei MOS-Eingängen kann der Wert der Widerstände im Bereich 
um 50kΩ liegen.
mfG ffje

von Christian S. (roehrenvorheizer)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

zu Weihnachten könntest Du Dir ein Oszilloskop mit Tastköpfen und eine 
Galerie mit den gängigen Widerstandswerten in 100er Packs wünschen, 
damit Du umfassend ausgestattet bist. Und zu Ostern dann die gängigen 
Kondensator-Werte in 10er bis 100er Mengen.

Somit hätten die Institutionen ihre Aufgaben und würden nicht obsolet 
werden.

MfG

: Bearbeitet durch User
von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Nimm doch einfach mal 1.5kΩ (3x 4.7kΩ parallel) zwischen D9 und RX vom
> SDS011 (R1), lasse deinen R2 komplett weg und dann gib einen High-Pegel
> auf D9 aus. Welche Spannung misst du dann am Eingagn vom SDS011?

Das sind dann ca. 4,2V

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
Versorge deinen Arduino mal über den 5V Pin statt über VIN (da sitzt 
noch ein LDO dazwischen).
Das würde auch die 4.2V erklären, und hinter deinem Spannungsregler 
hättest du dann nur noch 2.8V.

von 2 Cent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
zip schrieb:
> Das sind dann ca. 4,2V
Ist die Kommunikation damit stabil? Problem gelöst?

von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich kann gerade nicht mehr ganz folgen.

Mein erster Lösungsversuch war ein klassischer Spannungsteiler mit R1 
1/3 und R2 2/3. "Vor" R2 -> Rx (SDS011) habe ich dann ca. 3,3V. 
Ursprünglich habe ich die Werte von R1 mit 4,7kOhm und R2 mit 10kOhm 
recht hoch gewählt und konnte damit nur manchmal Werte auslesen.

Wolfang's Vorschlag war - sofern ich das richtig verstanden habe - 
keinen Spannungsteiler, aber einen Vorwiderstand zu verwenden. Richtig 
dimensioniert würde dort dann die Spannung entsprechend abfallen und 
eine Spannung von ~3,3V an Rx (SDS011) anliegen. Sein Vorschlag von 
1,5kOhm (4,7kOhm 3x parallel) als Vorwiderstand (kein R2), hat für einen 
Spannungsabfall gesorgt, so dass noch 4,2V an Rx (SDS011) anliegen.

Ich habe weiterhin versucht R1 und R2 kleiner zu dimensionieren.
R1 ~1,5kOhm (3x 4,7kOhm parallel) und R2 ~3,3kOhm (3x 10kOhm parallel).
Entsprechend verkabelt liegen jetzt ca. 3,2V bei High an Rx (SDS011) an.
Allerdings ist hier das selbe Verhalten zu beobachten.

Bisher konnte ich beobachten, dass die Kommunikation mit dem Sensor im 
"Continous-Modus" funktioniert, aber sobald der Sensor 1x schlafen war, 
nicht mehr. Deshalb würde ich sagen, dass die Verkabelung soweit stimmt, 
die Implementierung des Protokolls aber wahrscheinlich fehlerhaft ist, 
sprich es sich um einen Software-Fehler handelt.

von HildeK (Gast)


Bewertung
0 lesenswert
nicht lesenswert
zip schrieb:
> Deshalb würde ich sagen, dass die Verkabelung soweit stimmt,
> die Implementierung des Protokolls aber wahrscheinlich fehlerhaft ist,
> sprich es sich um einen Software-Fehler handelt.

Bei UART ist der Ruhepegel HIGH. Wenn ein Teilnehmer schlafen geht und 
dabei der Pin hochohmig wird, dann zieht der Teiler den Pegel auf LOW, 
sendet damit also das Startbit. Könnte es sowas sein?

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
Miss doch mal bitte die Spannung zwischen "5V" und GND an deinem 
Arduino, denn

siehe
Beitrag "Re: Spannungsteiler funktioniert nicht, was mache ich falsch?"

(LDO zwischen VIN und "5V")

: Bearbeitet durch User
von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
zip schrieb:
> Ich habe leider kein Oszilloskop.

Wenn du Teile bestellen willst, aber für dieses nützliche Werkzeug kein 
Geld ausgeben willst, wie wäre es damit?

https://makezine.com/projects/sound-card-oscilloscope/

von zip (Gast)


Bewertung
0 lesenswert
nicht lesenswert
HildeK schrieb:
> Bei UART ist der Ruhepegel HIGH. Wenn ein Teilnehmer schlafen geht und
> dabei der Pin hochohmig wird, dann zieht der Teiler den Pegel auf LOW,
> sendet damit also das Startbit. Könnte es sowas sein?

Es scheint eher am "Aufwachen" zu liegen.
Ein sehr einfaches und zusammengehacktes Programm, was das Protokoll des 
Sensors (teilweise) implementiert, ist nachfolgend beschrieben

setup():
- Query Firmware und Version
- Setze Report Mode auf "Query"
- Lege Sensor schlafen

Anschließend wird im loop() gelesen was über die serielle Schnittstelle 
verfügbar ist. Alle 5 Sekunden wird:
 - der Sensor aufgeweckt
 - etwas gewartet
 - Daten angefragt
 - Sensor wieder schlafen gelegt

Das ist das Ergebnis aus dem Serial Monitor, ergänzt um erklärende 
Kommentare
1
// Query Firmware und Version
2
// Jedes Byte der Antwort einzeln gelesen
3
0: aa
4
1: c5
5
2: 7
6
3: 12
7
4: 1
8
5: 12
9
6: ec
10
7: e1
11
8: f9
12
9: ab
13
// Erwartetes Ergebnis:
14
// AA C5 7 <jahr> <monat> <tag> <device Id byte 1> <device ID byte 2> <checksum> AB 
15
// => stimmt
16
Message received: AA C5 7 12 1 12 EC E1 F9 AB 
17
18
// Set Report Mode to "query"
19
0: aa
20
1: c5
21
2: 2
22
3: 1
23
4: 1
24
5: 0
25
6: ec
26
7: e1
27
8: d1
28
9: ab
29
// Erwartetes Ergebnis
30
// AA C5 2 1 1 0 <Device ID Byte 1> <Device ID Byte 2> <Checksum> AB
31
// => Stimmt
32
Message received: AA C5 2 1 1 0 EC E1 D1 AB 
33
34
// Lege Sensor schlafen
35
// Einzelne Antwort Bytes
36
0: aa
37
1: c5
38
2: 6
39
3: 1
40
4: 0
41
5: 0
42
6: ec
43
7: e1
44
8: d4
45
9: ab
46
// Erwartetes Ergebnis:
47
// AA C5 6 1 0 0 <Device ID Byte 1> <Device ID Byte 2> <Checksum> AB
48
// => stimmt
49
Message received: AA C5 6 1 0 0 EC E1 D4 AB 
50
51
// Sensor schläft
52
1: still sleeping ...
53
2: still sleeping ...
54
3: still sleeping ...
55
4: still sleeping ...
56
5: still sleeping ...
57
58
// Triggere Wake up and warm up
59
Waking up..
60
Warming up...
61
// Query data
62
Data is beeing queried
63
// Lege Sensor wieder schlafen
64
Going back to sleep now
65
66
// Jetzt wird es interessant
67
// Die ersten Bytes, welche eingelesen werden, nach dem "Wake up" sind die folgenden: 
68
0: ad
69
0: 50
70
0: 10
71
0: 5e
72
0: dd
73
74
// Ab hier beginnt die Nachricht erst
75
0: aa
76
1: c0
77
2: 1a
78
3: 0
79
4: 29
80
5: 0
81
6: ec
82
7: e1
83
8: 10
84
9: ab
85
// Erwartetes Ergebnis: 
86
// AA C0 <PM2.5 low byte> <PM2.5 high byte> <PM10 low byte> <PM10 high byte> <Device ID Byte 1> <Device ID Byte 2> <Checksum> AB
87
// Mal abgesehen von den 5 bytes nach dem aufwachen, scheint die Nachricht auch zu stimmen. 
88
Message received: AA C0 1A 0 29 0 EC E1 10 AB 
89
90
// Wieder schlafen legen
91
0: aa
92
1: c5
93
2: 6
94
3: 1
95
4: 0
96
5: 0
97
6: ec
98
7: e1
99
8: d4
100
9: ab
101
// Erwartetes Ergebnis
102
// AA C5 6 1 0 0 <Device ID Byte 1> <Device ID Byte 2> <Checksum> AB
103
Message received: AA C5 6 1 0 0 EC E1 D4 AB 
104
105
// und das Ganze von vorne

Der Code ist hier:
1
include <Arduino.h>
2
#include <SoftwareSerial.h>
3
4
// SDS011 commands
5
const uint8_t set_SDS_report_query_mode_cmd[] = {0xAA, 0xB4, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0xAB};
6
const uint8_t set_SDS_report_active_mode_cmd[] = {0xAA, 0xB4, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xAB};
7
const uint8_t start_SDS_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0xAB};
8
const uint8_t stop_SDS_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0xAB};
9
const uint8_t continuous_mode_SDS_cmd[] = {0xAA, 0xB4, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0xAB};
10
const uint8_t check_firmware_version_SDS_cmd[] = {0xAA, 0xB4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0xAB};
11
const uint8_t query_data_SDS_cmd[] = {0xAA, 0xB4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02 , 0xAB};
12
const uint8_t SDS_cmd_len = 19;
13
14
int rxPin = 9;
15
int txPin = 10;
16
SoftwareSerial sdsSerial(rxPin, txPin, false);
17
18
int sleepTime = 1000; // ms
19
int steps = 5;
20
int threshold = 0;
21
22
void setup() {
23
  Serial.begin(9600);
24
  sdsSerial.begin(9600); 
25
  delay(1000); // let's wait before actually reading
26
27
  SDS_queryFirmwareAndVersion();
28
  SDS_setQueryReportingMode();
29
  SDS_sleep();
30
}
31
32
void loop() {
33
  byte buffer;   // Current read byte
34
  byte message[10]; // each message is 10 bytes long, so we save it here
35
  int index = 0;
36
  int value = 0;
37
  int checksum_received = 0;
38
  int checksum_expected = 0;
39
  bool checksum_ok = false;
40
  bool messageStarted = false;
41
  
42
  // Read data
43
  if (sdsSerial.available() > 0) {
44
    Serial.println();
45
    while (sdsSerial.available() > 0) {
46
      buffer = sdsSerial.read();
47
      value = int(buffer);
48
49
      // Debug output for now just the current read byte at the index
50
      Serial.println(String(index) + ": " + String(buffer, HEX));
51
52
      // beginning of new message
53
      if (buffer == 0xAA && index == 0) {
54
        //        Serial.println(F("Start new message"));
55
56
        // reset previous received message
57
        for (byte i = 0; i < sizeof(message); i++) {
58
          message[i] = 0;
59
        }
60
        index++;
61
      } else if (index > 0) {
62
        // Read next index but only if we already started a message
63
        index++;
64
      }
65
66
      // Assign value if in bounds
67
      if (index >= 0 && index <= sizeof(message)) {
68
        message[index - 1] = buffer;
69
      } else {
70
        // TODO for now just complain
71
        Serial.print(F("Index is out of bounds: "));
72
        Serial.println(index - 1);
73
      }
74
75
      // Message fully read, now print
76
      if (buffer == 0xAB && index - 1 == sizeof(message) - 1) {
77
        // Message length may either be 10 or 19, depending on the message
78
        int messageLength = index;
79
        
80
        Serial.print(F("Message received: "));
81
        for (byte i = 0; i < messageLength; i++) {
82
          Serial.print(message[i], HEX);
83
          Serial.print(" ");
84
        }
85
        Serial.println();
86
87
        // reset index to prepare reading of next message
88
        index = 0;
89
      }
90
    }
91
  }
92
93
  // if we reached the threshold, wakeup, and trigger reading of data
94
  if (threshold >= steps) {
95
    Serial.println("Waking up..");
96
    SDS_start();
97
    Serial.println("Warming up...");
98
    delay(5000); // wait before we are ready
99
    Serial.println("Data is beeing queried");
100
    SDS_queryData();
101
    Serial.println("Going back to sleep now");
102
    SDS_sleep();
103
    xxxx = 0;
104
  } else {
105
    Serial.print(threshold + 1);
106
    Serial.println(": still sleeping ...");
107
    delay(sleepTime);
108
    threshold ++;
109
  }
110
}
111
112
void SDS_queryFirmwareAndVersion() {
113
 sdsSerial.write(check_firmware_version_SDS_cmd, SDS_cmd_len);
114
 delay(100);
115
}
116
117
void SDS_setQueryReportingMode() {
118
  sdsSerial.write(set_SDS_report_query_mode_cmd, SDS_cmd_len);
119
  delay(100);
120
}
121
122
void SDS_setActiveReportingMode() {
123
  sdsSerial.write(set_SDS_report_active_mode_cmd, SDS_cmd_len);
124
  delay(100);
125
}
126
127
void SDS_setContinousMode() {
128
  sdsSerial.write(continuous_mode_SDS_cmd, SDS_cmd_len);
129
  delay(100);
130
}
131
132
void SDS_start() {
133
  sdsSerial.write(start_SDS_cmd, SDS_cmd_len);
134
  delay(100);
135
}
136
137
void SDS_sleep() {
138
  sdsSerial.write(stop_SDS_cmd, SDS_cmd_len);
139
  delay(100);
140
}
141
142
void SDS_queryData() {
143
  sdsSerial.write(query_data_SDS_cmd, SDS_cmd_len);
144
  delay(100); 
145
}

Joe F. schrieb:

> Miss doch mal bitte die Spannung zwischen "5V" und GND an deinem
> Arduino, denn
>
> siehe
> Beitrag "Re: Spannungsteiler funktioniert nicht, was mache ich falsch?"
>
> (LDO zwischen VIN und "5V")

Also Spannung zwischen 5V und GND liegt bei 4,6 - 4,7V.
Spannung zwischen VIN und GND liegt bei 4,2 bis 4,3V.

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
Vielleicht muss das delay zwischen wakeup und query etwas länger werden.

zip schrieb:
> Also Spannung zwischen 5V und GND liegt bei 4,6 - 4,7V.
> Spannung zwischen VIN und GND liegt bei 4,2 bis 4,3V.

Das klingt seltsam, wenn du die 5V an VIN anlegst, müsste "5V" eine 
geringere Spannung haben (da der LDO einen Spannungs-Drop erzeugt). Ich 
denke da hast du dich einfach nur vertippt.
Wie gesagt, wenn du direkt mit 5V versorgst, sollte dies über den 5V Pin 
geschehen und nicht über VIN.

Und wie gesagt, wenn deine Versorgungsspannung so gering ist (4.2V?), 
dann teilt dein Spannungsteiler 4.7K/10K das Signal auf 2.85V runter.
Müsste für einen 3.3V Eingang reichen, aber ob dein Arduino bei 4.2V 
noch 100%ig funktioniert weiss ich nicht.

: Bearbeitet durch User
von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
> ob dein Arduino bei 4.2V noch 100%ig funktioniert weiss ich nicht.

Tut er. Bei meinem Test kam es erst bei weniger als 3V zu 
Fehlfunktionen.

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Tut er. Bei meinem Test kam es erst bei weniger als 3V zu
> Fehlfunktionen.

Gut zu wissen.
Man muss beim ATMega328 also nichts umkonfigurieren, wenn man ihn mit 
3.3V statt 5V betreiben möchte?

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Joe F. schrieb:
> Man muss beim ATMega328 also nichts umkonfigurieren, wenn man ihn mit
> 3.3V statt 5V betreiben möchte?

Dann guck mal im Datenblatt auf die maximal zulässige Taktfrequenz. Für 
alles, was darüber hinaus geht, übernimmt Microchip keine Garantie.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt sind 3,3V für 16MHz zu wenig, schau Dir mal das 
entsprechende Diagramm an. 4,2V sind für 16MHz noch OK.

Du kannst in deinem Programm den Clock Prescaler ändern, um eine 
passende Taktfrequenz einzustellen.

Wie dem auch sei, einen kurzen Test hat mein Arduino Nano Clone mit 
erheblicher Unterspannung bestanden. Man sollte aber sein Glück nicht 
allzu sehr herausfordern - vor allem wenn es um mehr geht als ein 
flüchtiges Experiment.

von Markus Q. (zip)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anbei noch einmal der aktuelle Schaltplan mit den aktuell verwendeten 
Widerständen und Anschlüssen. Der Arduino wird dabei mit der Spannung 
vom USB-Port des Notebooks versorgt. Obwohl sich die Leitungen in der 
Zeichnung überschneiden, sind diese NICHT verbunden. Ich weiß nicht, wie 
man in Fritzing Brücken malt :-/

R1 ist dabei durch 3 x 4,7kOhm Widerstände parallel und R2 mit 3x 10kOhm 
Widerstände parallel realisiert.

Der SDS011 Sensor wird mit +5V betrieben.
Im Betrieb liegen folgende Spannungen an:
- R1 -> R2 => ~1.6V
- R2 -> GND => ~3.4V

Auch die Spannungen am Arduino ergeben für mich Sinn:
+5V -> GND => 4,6 (SDS011 aktiv) bzw. 4,7V (SDS011 schlafend)
VIN -> GND => 4,2 (SDS011 aktiv) bzw. 4,3V (SDS011 schlafend)

Für mich Newbie sieht das alles soweit richtig aus.
Einziges Problem was ich noch habe ist, dass nach dem Aufwachen des 
Sensors SDS011 dieser 5 Bytes sendet, welche keine gültige Nachricht 
ergeben. Woher kommt das bzw. wie kann ich das lösen?

Der Vollständigkeit halber, hier nochmal die Sensor-Daten:
http://www.komputer.de/wordpress/wp-content/uploads/2018/01/SDS011laserPM2.5sensorspecification-V1.3.pdf

Das Protokoll:
https://www.watterott.com/media/files_public/kluucwpsc/SDS011_Control_Protocol.pdf

Den Beitrag mit dem Oszilloskop selbst bauen habe ich gesehen, werde das 
ggf. in Erwägung ziehen. Danke für den Tipp.

Edit: Kann jemand das doppelte Bild entfernen? Ich kann es leider nicht 
löschen :-/

: Bearbeitet durch User
von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
> Kann jemand das doppelte Bild entfernen?

Für's nächste mal: Du kannst den ganzen Beitrag löschen und neu 
erstellen. Jetzt aber nicht mehr, weil ich ihn beantwortet habe.

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
Joe F. schrieb:
> Vielleicht muss das delay zwischen wakeup und query etwas länger werden.

von Markus Q. (zip)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe das Ganze noch etwas genauer analysiert und die 5 random Bytes 
sind die Antwort des Sensors auf das "Aufwachen". Also scheint er irgend 
ein Problem zu haben, wenn er vom sleep nach active wechselt. 
Dementsprechend hilft ein längeres warten bevor Daten ausgelesen werden 
nicht. Als "Workaround" könnte man das wakeup einfach 2x senden und 
erhält zumindest eine korrekte Antwort, aber das empfinde ich als 
unschön, da noch nicht geklärt ist, was das Problem eigentlich ist :-/

Hat hier vll. jemand den SDS011-Sensor und könnte diesen mal 
ausprobieren bzw. sagen ob dieser ein ähnliches Verhalten aufweist?

: Bearbeitet durch User
von Markus Q. (zip)


Bewertung
0 lesenswert
nicht lesenswert
Es scheint ein bekanntes Problem zu sein. Ich habe auf github mal einen 
issue angelegt bei einer der vielen Bibliotheken und der Autor konnte 
das Problem nachvollziehen: 
https://github.com/lewapek/sds-dust-sensors-arduino-library/issues/6

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.