ESP-32 SPI sendet falsche bits

OP #7472875
Lesenswert?

Hallo,

ich versuche zurzeit die GPIO-Pins eines ESP32-Slaves mit einem ESP32-Master über SPI fernzusteuern. Konkret soll der Master die digitalRead- und digitalWrite-Methode fernsteuern. Für die SPI-Kommunikation nutze ich diese Library hier: https://github.com/hideakitai/ESP32DMASPI/

Nun zu meinem Problem. Es passiert recht häufig, dass Bits, die über den Bus geschickt werden, nicht korrekt übertragen werden. Das Interessante ist, dass bei einer Übertragungsfrequenz von 1 MHz nur selten ein Fehler passiert. Ist die Übertragungsrate kleiner oder größer, schleichen sich Fehler oft in fast jede Nachricht ein. Ich habe leider überhaupt keine Idee mehr, woran das liegen könnte.

Warum die Übertragungsqualität so sehr davon abhängt, dass ich mit 1 MHz übertrage, verstehe ich nicht. 100 kHz oder 2 MHz funktionieren kaum. Kann man das irgendwie beheben?

Hier ist mein Protokoll:
Ich kodiere jeden Befehl und die Nachricht dazu in einem Byte. Das Befehls-Byte vom Master zum Slave sieht so aus:

  • Bit 1: Der Identifier des Befehls. 0 bedeutet schreiben, 1 bedeutet lesen.
  • Bit 2: Falls der Befehl ein Schreibbefehl ist, ist das hier der Wert, der geschrieben werden soll.
  • Bit 3 - 8: Die Pin-Nummer.

Der Slave sendet dann mit der nächsten Nachricht die Antwort. Diese sieht dann so aus:

  • Bit 1: Die Gültigkeit der Antwort.
  • Bit 2: Der gelesene Wert.
  • Bit 3 - 8: Die Pin-Nummer.

Wenn der Befehl 'Lesen' ist, wird der Befehl vom Master so lange wiederholt, bis der Slave eine gültige Antwort gesendet hat.

Momentan übertrage ich trotzdem immer 4 Bytes. Das liegt daran, dass die Library das so vorschreibt. Das werde ich aber später noch ändern. Im Moment möchte ich erstmal die Daten zuverlässig übertragen bekommen.

Vielen Dank für eure Hilfe. Mein Aufbau/Schaltplan ist im Anhang.

Master-Code:

1
#include <ESP32DMASPIMaster.h>
2

3
ESP32DMASPI::Master master;
4

5
static const uint32_t BUFFER_SIZE = 4;
6

7
/*
8
Tx byte:
9
 bit 1: 1 == cmd
10
 bit 2: 1 == pin is high
11
 bit 3 - 8: pin_nr
12
*/
13
uint8_t* spi_master_tx_buf;
14
/*
15
Rx byte:
16
 bit 1: 1 == valid message
17
 bit 2: 1 == pin is high
18
 bit 3 - 8: pin_nr
19
*/
20
uint8_t* spi_master_rx_buf;
21

22
void setup() {
23
  Serial.begin(115200);
24
  Serial.println("Master program!");
25
  delay(2000);
26

27
  spi_master_tx_buf = master.allocDMABuffer(BUFFER_SIZE);
28
  spi_master_rx_buf = master.allocDMABuffer(BUFFER_SIZE);
29
  memset(spi_master_tx_buf, 0, BUFFER_SIZE);
30
  memset(spi_master_rx_buf, 0, BUFFER_SIZE);
31

32
  master.setDataMode(SPI_MODE0);
33
  master.setFrequency(1000000);
34
  master.setMaxTransferSize(BUFFER_SIZE);
35
  master.setDutyCyclePos(96);
36

37
  master.begin(HSPI); 
38
}
39

40
void loop() {
41
  Serial.println("Start write HIGH!");
42
  write_spi_pin(4, true);
43

44
  Serial.println("Start read (should) HIGH!");
45
  Serial.print("Response ");
46
  Serial.println(read_spi_pin(4));
47
  delay(1000);
48

49
  Serial.println("Start write LOW!");
50
  write_spi_pin(4, false);
51

52
  Serial.println("Start read (should) LOW!");
53
  Serial.print("Response ");
54
  Serial.println(read_spi_pin(4));
55
  delay(1000);
56
}
57

58
bool read_spi_pin(uint8_t pin_nr) {
59
  spi_master_tx_buf[0] = pin_nr & 0b00111111;
60
  spi_master_tx_buf[0] = spi_master_tx_buf[0] | 0b10000000;
61
  master.transfer(spi_master_tx_buf, spi_master_rx_buf, BUFFER_SIZE);
62

63
  bool response_valid = false;
64
  bool response_high = false;
65
  uint8_t response_pin = 0;
66
  while (!response_valid || response_pin != pin_nr) {
67
    master.transfer(spi_master_tx_buf, spi_master_rx_buf, BUFFER_SIZE);
68
    uint8_t response = spi_master_rx_buf[0];
69

70
    Serial.print("Full intermediate response: ");
71
    for (int i = 7; i >= 0; i--)
72
    {
73
        bool b = bitRead(response, i);
74
        Serial.print(b);
75
    }
76
    Serial.println();
77

78
    response_valid = (response & 0b10000000) >> 7;
79
    response_high = (response & 0b01000000) >> 6;
80
    response_pin = response & 0b00111111;
81

82
    Serial.print("Read intermediate response: ");
83
    Serial.print("pin_nr ");
84
    Serial.print(pin_nr);
85
    Serial.print(", response_valid ");
86
    Serial.print(response_valid);
87
    Serial.print(", response_pin ");
88
    Serial.print(response_pin);
89
    Serial.print(", response_high ");
90
    Serial.println(response_high);
91

92
  }
93
  return response_high;
94
}
95

96
void write_spi_pin(uint8_t pin_nr, bool write_high) {
97
  spi_master_tx_buf[0] = pin_nr & 0b00011111;
98
  if (write_high) {
99
    spi_master_tx_buf[0] = spi_master_tx_buf[0] | 0b01000000;
100
  }
101
  master.transfer(spi_master_tx_buf, spi_master_rx_buf, BUFFER_SIZE);
102
}

Slave-Code:

1
#include <ESP32DMASPISlave.h>
2

3
ESP32DMASPI::Slave slave;
4

5
static const uint32_t BUFFER_SIZE = 4;
6
/*
7
Tx byte:
8
 bit 1: 1 == valid message
9
 bit 2: 1 == pin is high
10
 bit 3 - 8: pin_nr
11
*/
12
uint8_t* spi_slave_tx_buf;
13
/*
14
Rx byte:
15
 bit 1: cmd
16
 bit 2: 1 == pin is high
17
 bit 3 - 8: pin_nr
18
*/
19
uint8_t* spi_slave_rx_buf;
20

21

22
#define LED 2
23

24
void setup() {
25
  Serial.begin(115200);
26
  Serial.println("Slave program!");
27
  delay(2000);
28

29
  spi_slave_tx_buf = slave.allocDMABuffer(BUFFER_SIZE);
30
  spi_slave_rx_buf = slave.allocDMABuffer(BUFFER_SIZE);
31

32
  slave.setDataMode(SPI_MODE0);
33
  slave.setMaxTransferSize(BUFFER_SIZE);
34

35
  slave.begin(HSPI);
36
  // clear buffers
37
  memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
38
  memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
39
  pinMode(4, OUTPUT);
40
}
41

42
void loop() {
43
  Serial.print("Response:");
44
  for (int i = 7; i >= 0; i--) {
45
    bool b = bitRead(spi_slave_tx_buf[0], i);
46
    Serial.print(b);
47
  }
48
  Serial.println();
49

50
  slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);
51

52
  uint8_t cmd;
53
  uint8_t data;
54
  uint8_t pin_nr;
55
  while (slave.available()) {
56
    // show received data
57
    Serial.print("Command Received: ");
58

59
    cmd = (spi_slave_rx_buf[0] & 0b10000000) >> 7;
60
    data = (spi_slave_rx_buf[0] & 0b01000000) >> 6;
61
    pin_nr = (spi_slave_rx_buf[0] & 0b00111111);
62

63
    Serial.print("cmd ");
64
    Serial.print(cmd);
65
    Serial.print(", data ");
66
    Serial.print(data);
67
    Serial.print(", pin_nr ");
68
    Serial.println(pin_nr);
69
    slave.pop();
70

71
    if (cmd == 0) {
72
      spi_slave_tx_buf[0] = 0;
73
      if (data == 0) {
74
        digitalWrite(pin_nr, LOW);
75
      } else {
76
        digitalWrite(pin_nr, HIGH);
77
      }
78
    } else {
79
      if (digitalRead(pin_nr) == HIGH) {
80
        Serial.println("Sending HIGH!");
81
        spi_slave_tx_buf[0] = 0b11000000 | pin_nr;
82
      } else {
83
        Serial.println("Sending LOW!");
84
        spi_slave_tx_buf[0] = 0b10000000 | pin_nr;
85
      }
86
    }
87
  }
88
}
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #7472882
Lesenswert?

Alexander L. schrieb:

Ich habe leider überhaupt keine Idee mehr, woran das liegen könnte.

Allererster Schritt bei der Inbetriebnahme serieller Schnittstellen: man nimmt das Oszilloskop und kontrolliert Spannungsverlauf und Timing.

Hast du das gemacht? Ist da alles im grünen Bereich? Siehst du auf dem Oszi den richtigen SPI-Mode? Passt der zu dem, was der Empfänger erwartet?

Kann man das irgendwie beheben?

Dazu muss man erst mal wissen, was man beheben muss. Wenn man Überschwinger oder Unstetigkeiten in den Flanken sieht, dann muss man die Terminierung anpassen. Wenn die Pegel nicht passen, dann gibts evtl. irgendwo eine Buskollision.

OP #7472927
Lesenswert?

Das kann ich leider nicht tun. Ich bin eigentlich eher weniger im Hardware-Bereich tätig und habe kein Oszilloskop. Eventuell kann ich mal an der Uni schauen, ob ich dort irgendwo eines finde, womit ich kurz testen kann.

Gibt es vielleicht häufige Fehler, die bei so etwas auftreten, die man mal probieren könnte?

Moderator (Firma: Titel) Persönliche Seite #7472955
Lesenswert?

Alexander L. schrieb:

Eventuell kann ich mal an der Uni schauen, ob ich dort irgendwo eines finde

Tu das. Wenn da alles unfraglich passt, dann suche auf der SW-Seite weiter.

Gibt es vielleicht häufige Fehler

Fehlerhafte Terminierung und falscher SPI-Mode sind die häufigsten Fehler. Aber das ist blindes Stochern im Trüben, solange die Datenintegrität auf der Hardwareseite nicht sichergestellt ist.

Alexander L. schrieb:

nur selten ein Fehler passiert.

Meine SPI-Schnitten müssen im Labor und im Klimaschrank über mehrere Tage absolut ohne jeglichen Übertragungsfehler laufen. Dann bin ich zufrieden und traue mich damit raus ins Feld.

Moderator (Firma: Titel) Persönliche Seite #7472988
Lesenswert?

Alexander L. schrieb:

Gibt es vielleicht häufige Fehler

Wenn deine Schaltung so aussieht, wie du sie oben gezeichnet hast, dann wundert mich, dass die überhaupt was tut.

Denn da fehlt ja jegliche Masseverbindung zwischen den µc und auch die Versorgung der µC.

Oder der Schaltplan ist falsch. Und mit falschen Schaltplänen Fehler suchen ist ein spannendes Unterfangen.

OP #7473037
Lesenswert?

Der Schaltplan ist genau das was ich auch in echt gebaut habe. Den habe ich selbst gezeichnet. Eine Masseverbindung bzgl. der SPI Kommunikation existiert wirklich nicht. Ich bin eigentlich Informatiker und meine Hardware-Kenntnisse kommen aus genau einem Vertiefungsmodul, wo wir das am Rande mal angesprochen haben. Deshalb bin ich bei so etwas vermutlich etwas unbeholfen.

Das Grafik aus der ich diesen Aufbau abgeleitet habe ich diese hier: https://puu.sh/JNejs/a0800d4add.png (Steht so bei uns im Skript.)

Da sehe ich jetzt keine Masserverbindung. Wo genau müsste die dann sein? Ich finde auch online keine Pläne, wo eine Masseverbindung dabei ist. Ich nehme auch mal an, dass da dann noch ein Widerstand zur Masseverbindung gehört, damit das nicht zum Kurzschluss wird.

Die Länge der Verbindung ist nicht weit. Das dürften etwa 15cm sein.

(Firma: Schweigstill IT) Persönliche Seite #7473053
Lesenswert?

Alexander L. schrieb:

Der Schaltplan ist genau das was ich auch in echt gebaut habe. Den habe ich selbst gezeichnet. Eine Masseverbindung bzgl. der SPI Kommunikation existiert wirklich nicht. Ich bin eigentlich Informatiker

Aha, mal wieder die typische Einstellung vieler Informatiker, die sich einbilden, dass für sie die physikalischen Gesetze nicht gelten.

Das Grafik aus der ich diesen Aufbau abgeleitet habe ich diese hier: https://puu.sh/JNejs/a0800d4add.png (Steht so bei uns im Skript.)

Das ist nur eine Vereinfachung, die die reinen Nutzsignale darstellt.

Da sehe ich jetzt keine Masserverbindung. Wo genau müsste die dann sein?

Dann musst Du Dich wohl mal mit den elektrotechnischen Grundlagen befassen. Hierfür gibt es unzählige Lehrbücher.

Ich finde auch online keine Pläne, wo eine Masseverbindung dabei ist.

Dann benötigt man wohl auch keine, und tausende professioneller Elektronikentwickler haben einfach keine Ahnung.

Ich nehme auch mal an, dass da dann noch ein Widerstand zur Masseverbindung gehört, damit das nicht zum Kurzschluss wird.

Aha. Gewagte Behauptung für jemanden, der schon mit seiner tatsächlichen Unwesenheit so kokettiert. Offenbar scheinen die Autoren unzählige Fachpublikationen über das Thema Masseführung, Signalintegrität und Elektromagnetische Verträglichkeit keine Ahnung zu haben. Deren Berechnungen, Simulationen und Messungen scheinen auch alle fehlerhaft zu sein.

Die Länge der Verbindung ist nicht weit. Das dürften etwa 15cm sein.

Aha. Gewagte Behauptung für jemanden, der jegliche physikalischen bzw. elektrotechnischen Grundlagen konsequent ignoriert. Aber Du musst es ja wissen.

#7473055
Lesenswert?

Alexander L. schrieb:

Der Slave sendet dann mit der nächsten Nachricht die Antwort.

Das kann er schon rein zeitlich nicht. Der Master schickt immer den Takt. Nach dem ersten Byte kriegt der Slave einen Interrupt und kann das Byte auswerten. Dazu nutzt er die Zeitdauer des 2. Bytes, d.h. der Master kriegt im 1. und 2. Byte Müll zurück. Erst im 3. Byte kann der Slave was zurück senden.

Einen Oszi braucht man nicht fürs SPI. Nur etwas Lesen des Datenblattes und logisches Denken. Terminiert wird beim SPI auch nichts.

Ich würde aber erstmal nur dumme Slaves ansprechen (74HC595, 74HC165) und zum Laufen bringen.

Moderator Persönliche Seite #7473061
Lesenswert?

Alexander L. schrieb:

Da sehe ich jetzt keine Masserverbindung. Wo genau müsste die dann sein?

Verbinde GND ("Ground" = "Masse") des linken ESP-32 mit GND des rechten ESP-32, falls das nicht sowieso über ein gemeinsam genutztes Netzteil bereits der Fall ist.

Immerhin hast Du GND des rechten ESP-32 (obere rechte Ecke) ja mit dem FE_Srly-Modul verbunden. So muss das auch sein.

Du brauchst Masseverbindungen, damit Pegel (Low, High) ein gemeinsames Grundniveau haben. Spannungspegel sind Potentialdifferenzen. Diese können nur existieren bzw. eine gemeinsame Grundlage haben, wenn beide dasselbe Bezugspotential haben. Das ist eben GND.

(Firma: Schweigstill IT) Persönliche Seite #7473089
Lesenswert?

Peter D. schrieb:

Terminiert wird beim SPI auch nichts.

Bei langen Verbindungen, insbesondere wenn dann auch noch externe Leitungen enthalten sind, wirken sich kleine Serienwiderstände (z.B. 33 Ohm) sehr vorteilhaft auf die Signalintegrität aus. Gerade die SPI-Taktleitung ist diesbezüglich sehr empfindlich und kann ggf. schon leichtes "Klingeln" als weitere Impulse ansehen. Daher kann es je nach Aufbau sogar ratsam sein, am Takteingang zusätzlich einen Tiefpass vorzusehen, d.h. mit wenigen Picofarad und ebenfalls kleinem Serienwiderstand. Natürlich darf man dabei den Takt nicht so stark verzögern, dass die Empfangsrichtung aus dem Tritt gerät.

Ich würde aber erstmal nur dumme Slaves ansprechen (74HC595, 74HC165) und zum Laufen bringen.

Genau. Und sinnvollerweise verbindet man diese Bausteine nicht nur mit den SPI-Leitungen, sondern auch den parallelen Ein- und Ausgängen, so dass man munter Bitmuster generieren und zurücklesen kann. Das ermöglicht dann auch quantitative Aussagen über die Signalintegrität. Vorzugsweise sind natürlich die Parallelverbindungen gespiegelt, um sicherzustellen, dass man nicht durch Softwarefehler versehentlich die zu schreibenden Daten statt der ausgelesenen Daten miteinander vergleicht.

OP #7473110
Lesenswert?

Der ESP hat natürlich Strom. Der hängt bis das funktioniert per USB am PC, der auch die Programme flasht.

@schweigstill Genau so motiviert man Leute, die einer neuen Community beitreten. /s

@peda. Das wird soweit ich weiß von der Library gehandelt. Die allermeisten Befehle kommen auch durch und die allermeisten Antworten auch.

@ukw Ich habe das Schaltbild mal geupdated. So sieht es jetzt aus. (Anhang) Der Fehlerverhalten ist allerdings geblieben.

Angehängte Dateien:
#7473140
Lesenswert?

Hört doch mal auf zu mobben. Natürlich hat er eine Masseverbindung und auch VCC. Mir wurde gesagt die Dupont-Leitungen seien nicht so gut geeignet, und ich solle lieber Kieselsteine sammeln. Am besten wäre mal ein Foto wenn Du Dich traust, da kann der ein oder andere vielleicht was erkennen was stört.

Moderator (Firma: Titel) Persönliche Seite #7473146
Lesenswert?

Alexander L. schrieb:

Ich habe das Schaltbild mal geupdated. So sieht es jetzt aus.

Auch im upgedateten Schaltplan fehlt was ganz Elementares: die Verbindung zum und die Versorgung über USB.

Der ESP hat natürlich Strom. Der hängt bis das funktioniert per USB am PC, der auch die Programme flasht.

Und auch der zweite ESP wird über USB versorgt? Und auch die Masseverbindung zwischen den beiden ESP läuft über diese beiden USB?

OP #7473152
Lesenswert?

Das ist die aktuelle Verkabelung nochmal als Foto. Nicht wundern, dass das nicht mehr zu der Pinbelegung aus dem Code passt. Ich habe den HSPI mit dem VSPI-Bus getauscht.

Der ESP bei dem man den Chip sieht ist der Slave. Der andere ist der Master.

OP #7473162
Lesenswert?

@kirnbichler Die sind richtig verlötet. Die sind nur deshalb einmal auf der Unterseite, weil ich erst dachte, dass ich den kompletten ESP auf mein Breadboard stecken kann. Dafür war der dann allerdings zu breit. Beim 2. ESP habe ich das dann gewusst und ihn andersrum verlötet, damit ich die Kabel anschließen kann und gleichzeitig einfacher an den Reset-Knopf komme.

Moderator (Firma: Titel) Persönliche Seite #7473168
Lesenswert?

Alexander L. schrieb:

Das ist die aktuelle Verkabelung nochmal als Foto

Du verbindest da die internen 3V3 vom Einen mit den 3V3 vom Anderen? Spannend...

Hast du mal die Versorungsspanungen mal gemessen?

Was passiert, wenn du die beiden ESP programmierst, sinnvoll mit den nötigen 5V aus 1 Netzteil versorgst und dann die USB-Kabel aussteckst?

#7473171
Lesenswert?

Lothar M. schrieb:

Du verbindest da die internen 3V3 vom Einen mit den 3V3 vom Anderen? Spannend...

Das habt ihr doch so vorgeschlagen!?

Ich denke nicht dass es am Aufbau liegt. Wird wohl eher so ein Software Ding sein. Die Frequenz wird ja letztendlich in Takte herunter geteilt, und da gibt es naturgemäß nur Näherungswerte. Kenne mich absolut nicht aus, aber könnte doch an der Library liegen? Mal die Warnings auf github gelesen?

Moderator (Firma: Titel) Persönliche Seite #7473177
Lesenswert?

Alexander schrieb:

Das habt ihr doch so vorgeschlagen!?

Nein, es wurde vorgeschlagen, beide aus der selben einzigen Versorgung zu versorgen. Denn zu diesem Zeitpunkt war ja nicht klar, das an beiden ein USB-Kabel steckt...

Die Frequenz wird ja letztendlich in Takte herunter geteilt, und da gibt es naturgemäß nur Näherungswerte.

Bei SPI völlig uninteressant, weil da der Takt mitübertragen wird. Du musst dich über die Bussysteme und ihre Funktion schlau machen, wenn du sie einsetzen willst.

Alexander schrieb:

Mal die Warnings auf github gelesen?

1
There is also a known issue that received data is bit shifted depending on the SPI mode
2
Please try SPI mode 0 for this issue
3
But SPI mode 1 or 3 is required based on the official doc
4
Please use this library and SPI modes for your own risk

Sagte ich ja: falscher SPI-Mode. Das betrifft dann alle empfangenen Datenbits eines der beiden Teilnehmer. Nicht nur einzelne Bits.

Allerdings ist diese Anmerkung ein Indiz dafür, dass der Programmierer da auch nicht so richtig wusste, was er tat...

OP #7473195
Lesenswert?

@wangnick Das sollte eigentlich passen. Das kann nur auftreten, wenn zwei Read-Requests hintereinander kommen. Dabei gibt es zwei verschiedene Fälle:

  1. Der Read-Request ist für denselben Pin: In diesem Fall stammt der Buffer zwar von der letzten Request, aber da zwischendrin keine Write-Request stattgefunden hat, ist das Ergebnis trotzdem aktuell.

  2. Der Read-Request ist für einen anderen Pin: Hier ist zwar das Valid-Bit gesetzt, aber da es auch die Pin-Nummer in der Antwort mitschickt, erkennt der Master, dass sich die Antwort auf einen anderen Pin bezieht, und verwirft das Ergebnis.

Wenn die vorherige Request eine Write-Request war, antwortet der Slave mit einem 0-Byte. Dabei ist dann auch das Valid-Bit 0.

Was die zusammengeschalteten VCC-Pins der ESPs angeht: Ich hatte die Antwort vorhin so interpretiert, dass ich das machen soll. Der einzige Effekt, den das hat, ist dass ich jetzt einen ESP vom USB trennen kann und er trotzdem weiterläuft. Funktional macht es allerdings keinen Unterschied.

Was die Warnung auf GitHub angeht: Ich hatte zuerst diese Library verwendet: https://github.com/hideakitai/ESP32SPISlave. Da ich mit dieser bereits Probleme hatte, dachte ich, ich probiere mal die andere aus (also die, die ich gerade nutze). Ich habe auch die known Issues gesehen und die entsprechenden Workarounds implementiert.

Moderator Persönliche Seite #7473200
Lesenswert?

Alexander schrieb:

Lothar M. schrieb:

Du verbindest da die internen 3V3 vom Einen mit den 3V3 vom Anderen? Spannend...

Das habt ihr doch so vorgeschlagen!?

Wenn das Modul über den 3V3-Pin versorgt wird, dann ja.

Du versorgst aber beide Module über USB (5V). Diese Info kam erst jetzt. In diesem Fall werden die 3V3-Pins zu Ausgängen durch den jeweiligen auf der Platine befindlichen Spannungswandler (5V -> 3V3). In diesem Falle solltest Du tunlichst die 3V3-Verbindung kappen, denn hier treiben dann 2 Ausgänge gegeneinander. Schon bei geringen Spannungsdifferenzen/Toleranzen fließt dann ein nicht unerheblicher Strom, welche die 3V3-Wandler unnötig belastet.

Also: Nimm die 3V3-Verbindung zwischen den ESP32 raus - zumindest solange Du die über USB versorgst. Wenn später die USB-Versorgung wegfällt, versorge die Module über den 5V-Pin mit 5V, denn ich kenne nicht den Schaltplan des Moduls. Unter Umständen lässt sich der 3V3-Pin lediglich als Output nutzen und nicht, um das komplette Modul mit 3V3 zu versorgen.

Die 3V3-Verbindung zum FE_SRly-Modul ist okay. Dieses wird hier über den 3V3-Output des rechten ESP32-Moduls mit Spannung versorgt.

Moderator (Firma: Titel) Persönliche Seite #7473202
Lesenswert?

Alexander L. schrieb:

Der einzige Effekt, den das hat, ist dass ich jetzt einen ESP vom USB trennen kann und er trotzdem weiterläuft. Funktional macht es allerdings keinen Unterschied.

Doch, ja, einen gewichtigen. Du musst dir einfach mal die interne Schaltung der Boards mit einzeichnen...

Du meinst vermutlich nur, dass sich die Funktion dadurch nicht verbessert/ändert. Das hat mit der Funktionalität aber nur am Rande zu tun.

Alexander L. schrieb:

Das werde ich ausprobieren.

Hatte ich den Trick mit dem Oszi schon mal erwähnt? Damit kannst du nämlich sehen, was auf dem Bus los ist. Und schauen ob es zu dem passt, was dein Programm macht.

Derzeit ist es, wie wenn du mit verbundenen Augen nach Gehör mit dem Auto fährst. Das kann eine Zeit lang gut gehen. Du siehst und erkennst dann allerdings nicht, warum es wieder mal nicht gut gegangen ist.

OP #7473265
Lesenswert?

Okay, ich habe die 3.3V Pins wieder getrennt.

Was allerdings ein Problem ist, ist dass diese ganze Geschichte nur eine Komponente von einem größerem Open-Source Projekt ist, welches ich entwickle. Besagtes Projekt läuft auf einem RaspberryPi und es wäre ganz nett gewesen eine Möglichkeit zu haben die GPIO-Pins des Pis erweitern zu können. Der Pi wäre dann der Master und der ESP würde als GPIO Erweiterung funktionieren. Die Master-Komponente müsste ich allerdings nochmal in Java neu schreiben. Der Aufbau hier war eigentlich nur für mich gedacht, damit ich mich mal etwas in das Thema SPI einfinden kann. Ich baue die Komponente jetzt mal lieber nochmal direkt mit Java auf der Master Seite. Bevor ich hier die Arbeit doppelt mache.

Wichtig ist vor allem, dass man das ganze am Ende auch als dritter reproduzierbar nachbauen kann.

#7473275
Lesenswert?

Alexander L. schrieb:

Besagtes Projekt läuft auf einem RaspberryPi und es wäre ganz nett gewesen eine Möglichkeit zu haben die GPIO-Pins des Pis erweitern zu können.

Der Raspberry Pi kann sicherlich auch I2C, und für I2C gibt es /fertige/ ICs, die man als Portexpander verwenden kann. Die müssen dafür nicht eigens programmiert werden und sind deutlich unkomplizierter zu handhaben als ausgerechnet ein ESP32.

Hier ein willkürlich ausgesuchtes "Tutorial" dazu:

https://tutorials-raspberrypi.de/raspberry-pi-gpios-erweitern-mittels-i2c-port-expander/

OP #7473288
Lesenswert?

@kirnbichler Das stimmt zwar, allerdings ist SPI wesentlich schneller als I2C. An diesen Erweiterungskarten hängen im Worst Case schnell laufende Schrittmotoren und der Pi unterstützt für I2C leider nur eine Bandbreite von 400kBit/s. Wobei man die Step-Pin auf auf den nativen Pi-Pins lassen könnte und nur Direction und Enable auf die Karte legt. Das würde vermutlich gehen. Aber es wäre schon irgendwie cooler, wenn auch die Step-Pin dort liegen könnte. Ist halt die Frage ob das den Aufwand wert ist.

Gast #7473307
Lesenswert?

Alexander L. schrieb:

Hab ich da was übersehen?

Dass das USB Kabel und ESP Modul wahrscheinlich nicht genug Strom für das Relais liefern. Die Stromaufnahme des ESP Moduls alleine ist schon für viele USB Kabel zu viel. Kurzzeitig brauchen die Module etwa 500 mA.

Mit einem Oszilloskop könntest du die Stabilität der Stromversorgung prüfen.

Deine GND Verbindungen über das Steckbrett und Dupont Kabel würde ich durch gelötete Kupferkabel ersetzen, welche erheblich besser leiten. Wie viel Spannung auf dieser GND Verbindung abfällt, könntest du auch wieder mit einem Oszilloskop prüfen. Ein Multimeter taugt dazu nicht, denn es geht um hohe Frequenzen die sich zum DC Anteil überlagern.

#7473310
Lesenswert?

Schrittmotor-Signale über einen per SPI angebundenen Port-Expander von einem Raspberry Pi auszugeben ist Unsinn, das wird nur umständlich (wenn überhaupt) irgendwie stabil und bleibt immer langsam. Vernünftiger funktioniert das so wie hier mit externem µC der sich um das Timing kümmert https://github.com/scottalford75/Remora oder gleich FPGA z.B. mesa 7i90, 7c80 oder 7c81.

(Firma: Schweigstill IT) Persönliche Seite #7473416
Lesenswert?

Robert M. schrieb:

Vernünftiger funktioniert das so wie hier mit externem µC der sich um das Timing kümmert https://github.com/scottalford75/Remora oder gleich FPGA z.B. mesa 7i90, 7c80 oder 7c81.

Oder mit einem speziell für solche Anwendungen entwickelten Schritt- und Rampengenerator, z.B. Trinamic TMC429, TMC4210 oder TMC4361:

https://www.trinamic.com/products/integrated-circuits/

#7473707
Lesenswert?

Andreas S. schrieb:

Oder mit einem speziell für solche Anwendungen entwickelten Schritt- und Rampengenerator, z.B. Trinamic TMC429, TMC4210 oder TMC4361:

https://www.trinamic.com/products/integrated-circuits/

oder gleich Arduino-kompatibel, Rampengenerator mit eingebauter Schrittmotor-Endstufe in Form eines Nucleo mit STM Powerstep01 (falls das wieder lieferbar ist). Damit kann man alles was mit Schrittmotoren von der Leistung her Sinn macht ansteuern.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren