Forum: Mikrocontroller und Digitale Elektronik Probleme bei der SoftwareSerial-Kommunikation zwischen Wemos D1 (ESP8266) und Arduino


von Johannes S. (johannes_sch)


Angehängte Dateien:

Lesenswert?

Nach einiger Zeit des stillen Mitlesens trete ich aus dem Schatten 
hervor und traue mich mal an meinen ersten Forumspost.

Im Rahmen eines betrieblichen Projekts möchte ich mit 2 Arduinos 
Messdaten erfassen und diese Seriell an einen Wemos D1 senden um sie 
anschließend auf einem Webserver darzustellen.
Dazu verwende ich die SoftwareSerial um mir den Seriellen Port zum 
debuggen freizuhalten.

Da es mit dem Wemos D1 Lieferprobleme aus China gab habe ich mein 
Serielles "Kommunikationsprotokoll" zunächst mit 3 Arduinos aufgebaut. 
Da ich erst im Laufe des Projektes meine erste Programmierer Erfahrung 
gesammelt habe war ich überrascht wie gut die Kommunikation funktioniert 
hat.
Die beiden Slaves senden auf Anfrage nacheinander ihre Daten und der 
Master gibt diese am Ende am Seriellen Monitor aus.

Das böse Erwachen kam als ich den Master-Arduino gegen den Wemos D1 
ausgetauscht habe der in der Zwischenzeit geliefert wurde.
Der Wemos stürzt sofort ab sobald ich versuche über den SoftwareSerial 
Port Daten zu senden oder zu empfangen.
Gibt es eine (möglichste einfache) Lösung mein Problem zu lösen?

Bitte seid gnädig mit mir ich bin leider noch ein blutiger Anfänger auf 
dem Gebiet allerdings mit großer Lernbereitschaft.

Die Sketche für Master und Slave, die Fehlermeldung des Wemos D1 und 
eine Skizze der Verschaltung häng ich an.

Vielen Dank im voraus!
Gruß Johannes



Master:
1
 
2
#include <SoftwareSerial.h>                      //Füge die SoftwareSerial Bibliothek hinzu
3
4
SoftwareSerial softserial(10,11);                //Starte eine Sofware Serielle Schnitstelle mit Tx = 11 und Rx = 10
5
6
byte addr1 = 'A';                                //Adresse Slave 1
7
byte addr2 = 'B';                                //Adresse Slave 2
8
9
10
byte Messwert1[16];                              //Array um die 16-Byte Messwerte von Slave 1 zu speichern 
11
byte Messwert2[16];                              //Array um die 16-Byte Messwerte von Slave 2 zu speichern
12
int16_t adc1_0, adc1_1, adc1_2, adc1_3;          //Variablen um die aufbereiteten Werte von Slave 1 zu speichern 
13
int16_t adc1_4, adc1_5, adc1_6, adc1_7;          //Variablen um die aufbereiteten Werte von Slave 1 zu speichern
14
int16_t adc2_0, adc2_1, adc2_2, adc2_3;          //Variablen um die aufbereiteten Werte von Slave 2 zu speichern
15
int16_t adc2_4, adc2_5, adc2_6, adc2_7;          //Variablen um die aufbereiteten Werte von Slave 2 zu speichern
16
17
int counter = 0;                                 //Zähler initialisieren
18
19
void setup() {
20
Serial.begin(9600);                              //Starte die Serielle Kommunikatuion mit einer Baudrate von 9600
21
softserial.begin(9600);                          //Starte die Software Serielle Kommunikation mit einer Baudrate von 9600
22
delay(1000);                                     //Warte 1 Sekunde
23
}
24
25
void loop() {
26
  counter ++;                                    //Zähler hochzählen
27
  Serial.println(counter);                       //Zählerstand am Seriellen Monitor ausgeben
28
//Slave 1 ansprechen
29
do{
30
  softserial.write(addr1);                       //Adresse an Slave 1 senden
31
} while(softserial.read() != addr1);             //solange bis Slave 1 geantwortet hat
32
Serial.println("Slave 1 OK");                    //Nach erfolgreichem Kommunikationsaufbau mit Slave 1 kurzer Statusbericht am Seriellen Monitor
33
softserial.begin(9600);                          //Neustart der Software Seriellen Kommunikation um evtl. vorhandene Datenreste im Seriellen Puffer zu löschen (Theorie)
34
delay(10);                                       //10ms Delay
35
36
while(softserial.available() < 16){              //Warte Solange bis mindestens 16 Werte im Seriellen Puffer vorhanden sind
37
  delay(1);                                      //1ms Delay 
38
}
39
40
//Messwerte von Slave 1 empfangen
41
softserial.readBytes(Messwert1, 16);             //16 Werte aus dem Seriellen Puffer in das Array "Messwert1" schreiben
42
43
//Messwerte von Slave 1 "zusammensetzten"
44
adc1_0 = Messwert1[0] << 8 | Messwert1[1];       //Der Messwert adc1_0 vom ADS1115, A0 am Slave 1 setzt sich aus den ersten beiden Einträgen im Array Messwert1
45
adc1_1 = Messwert1[2] << 8 | Messwert1[3];       //Dazu wird mit Hilfe der Bitmath Operationen der 1. Wert (Messwert1[0]) um 8 Bits nach hinten verschoben
46
adc1_2 = Messwert1[4] << 8 | Messwert1[5];       //Anschließend wird der 2. Wert mit der Bitwise Or funktion hinten angefügt. Es ensteht ein 16-Bit Integer.
47
adc1_3 = Messwert1[6] << 8 | Messwert1[7];       //Die Operation wird für alle Messwerte wiederholt
48
adc1_4 = Messwert1[8] << 8 | Messwert1[9];
49
adc1_5 = Messwert1[10] << 8 | Messwert1[11];
50
adc1_6 = Messwert1[12] << 8 | Messwert1[13];
51
adc1_7 = Messwert1[14] << 8 | Messwert1[15];
52
delay(10);
53
54
55
//Slave 2 ansprechen
56
do{
57
  softserial.write(addr2);                       //Adresse an Slave 1 senden
58
} while(softserial.read() != addr2);             //solange bis Slave 1 geantwortet hat
59
Serial.println("Slave 2 OK");                    //Nach erfolgreichem Kommunikationsaufbau mit Slave 2 kurzer Statusbericht am Seriellen Monitor
60
softserial.begin(9600);                          //Neustart der Software Seriellen Kommunikation um evtl. vorhandene Datenreste im Seriellen Puffer zu löschen (Theorie)
61
delay(10);                                       //10ms Delay
62
63
while(softserial.available() < 16){              //Warte Solange bis mindestens 16 Werte im Seriellen Puffer vorhanden sind                                  
64
  delay(1);                                      //1ms Delay
65
}
66
67
//Messwerte von Slave 1 empfangen
68
softserial.readBytes(Messwert2, 16);             //16 Werte aus dem Seriellen Puffer in das Array "Messwert1" schreiben
69
70
//Messwerte von Slave 2 "zusammensetzten"
71
adc2_0 = Messwert2[0] << 8 | Messwert2[1];       //Der Messwert adc1_0 vom ADS1115, A0 am Slave 1 setzt sich aus den ersten beiden Einträgen im Array Messwert1
72
adc2_1 = Messwert2[2] << 8 | Messwert2[3];       //Dazu wird mit Hilfe der Bitmath Operationen der 1. Wert (Messwert1[0]) um 8 Bits nach hinten verschoben
73
adc2_2 = Messwert2[4] << 8 | Messwert2[5];       //Anschließend wird der 2. Wert mit der Bitwise Or funktion hinten angefügt. Es ensteht ein 16-Bit Integer.
74
adc2_3 = Messwert2[6] << 8 | Messwert2[7];       //Die Operation wird für alle Messwerte wiederholt
75
adc2_4 = Messwert2[8] << 8 | Messwert2[9];
76
adc2_5 = Messwert2[10] << 8 | Messwert2[11];
77
adc2_6 = Messwert2[12] << 8 | Messwert2[13];
78
adc2_7 = Messwert2[14] << 8 | Messwert2[15];
79
80
81
//Datenausgabe
82
//Serielle Ausgabe der Messwerte mit anschließendem Tab
83
Serial.println("Daten von Slave 1");
84
Serial.print(adc1_0); Serial.print("\t");         
85
Serial.print(adc1_1); Serial.print("\t");
86
Serial.print(adc1_2); Serial.print("\t");
87
Serial.print(adc1_3); Serial.print("\t");
88
Serial.print(adc1_4); Serial.print("\t");
89
Serial.print(adc1_5); Serial.print("\t");
90
Serial.print(adc1_6); Serial.print("\t");
91
Serial.println(adc1_7);
92
Serial.println("Daten von Slave 2");
93
Serial.print(adc2_0); Serial.print("\t");
94
Serial.print(adc2_1); Serial.print("\t");
95
Serial.print(adc2_2); Serial.print("\t");
96
Serial.print(adc2_3); Serial.print("\t");
97
Serial.print(adc2_4); Serial.print("\t");
98
Serial.print(adc2_5); Serial.print("\t");
99
Serial.print(adc2_6); Serial.print("\t");
100
Serial.println(adc2_7);
101
delay(25);
102
}

Slave:
(die Sketche für Slave 1 und Slave 2 unterscheiden sich nur in der 
Adresse)
1
#include <SoftwareSerial.h>                 //Füge die SoftwareSerial Bibliothek hinzu
2
#include <Adafruit_ADS1015.h>               //Füge die ADS1115 Bibliothek hinzu
3
#include <Wire.h>                           //Füge die I2C Bibliothek hinzu
4
5
SoftwareSerial softserial(10,11);           //Starte eine Software Serielle Schnittstelle mit Tx = 11 und Rx = 10
6
7
byte addr = 'B';                            //Adresse Slave 2 
8
9
byte Messwert[16];                          //Array um die 16-Byte Messwerte zu speichern
10
int16_t adc0, adc1, adc2, adc3;             //Variablen um die Messwerte des 1. ADS1115 zu speichern
11
int16_t adc4, adc5, adc6, adc7;             //Variablen um die Messwerte des 2. ADS1115 zu speichern
12
13
Adafruit_ADS1115 ads1115_0;                 //1. ADS1115 mit default Adresse (=0x48) am I2C Bus
14
Adafruit_ADS1115 ads1115_1(0x49);           //2. ADS1115 mit Adresse 0x49 am I2C Bus
15
16
void setup() {
17
  
18
softserial.begin(9600);                     //Starte die Software Serielle Kommunikation mit einer Baudrate von 9600
19
20
ads1115_0.begin();                          //Starte die I2C Kommunikation vom 1. ADS1115
21
ads1115_1.begin();                          //Starte die I2C Kommunikation vom 2. ADS1115
22
}
23
24
void loop() {
25
do{                                         //Lese am Software Seriellen Port  
26
  softserial.read();
27
} while(softserial.read() != addr);         //solange du NICHT die Adresse empfangen hast  => Lese solange bis die Adresse kommt
28
softserial.write(addr);                     //Antworte mit der Adresse
29
30
adc0 = ads1115_0.readADC_SingleEnded(0);    //Speichern der Analogen Eingangswerte der beiden ADS1115 in die Variablen adc0 bis adc7
31
adc1 = ads1115_0.readADC_SingleEnded(1);
32
adc2 = ads1115_0.readADC_SingleEnded(2);
33
adc3 = ads1115_0.readADC_SingleEnded(3);
34
adc4 = ads1115_1.readADC_SingleEnded(0);
35
adc5 = ads1115_1.readADC_SingleEnded(1);
36
adc6 = ads1115_1.readADC_SingleEnded(2);
37
adc7 = ads1115_1.readADC_SingleEnded(3);
38
39
Messwert[0] = adc0 >> 8;                    //Mit Hilfe der Bitmath Operationen wird das Array "Messwert[]" gefüllt 
40
Messwert[1] = adc0;                         //Jeder Analogwert ist 16-Bit groß und muss daher auf 2 Plätze im Array aufgeteilt werden
41
Messwert[2] = adc1 >> 8;
42
Messwert[3] = adc1;
43
Messwert[4] = adc2 >> 8;
44
Messwert[5] = adc2;
45
Messwert[6] = adc3 >> 8;
46
Messwert[7] = adc3;
47
Messwert[8] = adc4 >> 8;
48
Messwert[9] = adc4;
49
Messwert[10]= adc5 >> 8;
50
Messwert[11]= adc5;
51
Messwert[12]= adc6 >> 8;
52
Messwert[13]= adc6;
53
Messwert[14]= adc7 >> 8;
54
Messwert[15]= adc7;
55
56
57
softserial.write(Messwert, 16);             //Sende das Array mit den Messwerten an den Master
58
delay(25);                                  //25ms Delay
59
}

Serielle Ausgabe des Wemos D1:
1
H!°Ô…äÿDHû1
2
3
Soft WDT reset
4
5
ctx: cont 
6
sp: 3ffef540 end: 3ffef740 offset: 01b0
7
8
>>>stack>>>
9
3ffef6f0:  3fffdad0 00000000 3ffee654 3ffe834d  
10
3ffef700:  3ffee4f4 3ffee4f4 3ffee654 40201cf2  
11
3ffef710:  3fffdad0 00000000 00002580 3ffee710  
12
3ffef720:  3fffdad0 00000000 3ffee708 40202b5c  
13
3ffef730:  feefeffe feefeffe 3ffee720 40100718  
14
<<<stack<<<

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> Soft WDT reset

Das dürfte der entscheidende Hinweis sein.

von Johannes S. (johannes_sch)


Lesenswert?

1
do{
2
  softserial.write(addr1);                       //Adresse an Slave 1 senden
3
  counter++;
4
  Serial.println(counter);
5
  delay(25);
6
} while(softserial.read() != addr1);             //solange bis Slave 1 geantwortet hat

durch den delay(25) konnte ich immerhin den Absturz des Wemos 
verhindern..
Allerdings kommt noch keine Kommunikation zu stande.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.