ESP32S3 USB auf PL2303

OP #7498060
Lesenswert?

Hallo zusammen,

für ein Hobbyprojekt versuche ich seit einigen Tagen, eine ESP32S3-DevkitC-1 Plattine über ihre Native-USB mit einem Navspark NS-RAW GPS Empfänger zu verbinden.

ESP32S3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1-v1.0.html

NS-RAW: https://navspark.mybigcommerce.com/ns-raw-carrier-phase-raw-measurement-output-gps-receiver/

Mit dem uC der GPS-Platine kann man theoretisch über einen seriellen Port kommunizieren, leider ist nur TX und nicht RX über die Pins de Platine erreichbar. Will man dem GPS (z.B. Konfigurations-) Befehle schicken, muss man dies über den micro-USB Stecker und einen PL2303 der Platine tun.

Die GPS-Platine kann man per USB mit einem PC verbinden und mit einer SW des Herstellers steuern. Alles, was mir der Hersteller sagen konnte, ist, dass ich mit einem ESP32 die Funktion des PCs nachbilden musste, um ihre GPS-Platine mit dem ESP32 bedienen zu können.

Soweit ich zu verstehen glaube, muss man dafür mit den ESP32 über seinen nativen USB als Host arbeiten lassen, womit ich bisher noch keine Erfahrung gemacht hatte.

Für Testzwecken habe ich (unten anderen) den Setup im Bild benutzt. OTG Kabel zwischen dem USB des ESP32 und dem der GPS-Platine. Dazu 5v und GND (graues und gelbes Kabel, die Platine akzeptiert 3,6-10v) und eine serielle Verbindung mit TX des GPS (der RX, wie gesagt, ist nicht über die Pins zu erreichen.) Dieses Signal kann ich alternativ mit einem Oszilloskop überprüfen.

Die ESP32 verbinde ich über den UART Port mit einem PC. Ich weiß nicht, ob diese Darstellung alles besser schildert oder das Ganze noch komplizierter macht :)

[PC] <- Kabel -> [(CP2102)<->(ESP32S3 native USB)] <- Kabel -> [(PL2303) <-> (GPS-uC)]

Im ESP32 lasse ich dieses Program laufen (mit der Arduino IDE kompiliert, mit der Konfiguration die auf dem dritten Bild im Anhang zu sehen ist):

1
#if ARDUINO_USB_MODE
2
#warning This sketch should be used when USB is in OTG mode
3
void setup(){}
4
void loop(){}
5
#else
6
#include "USB.h"
7

8
#if ARDUINO_USB_CDC_ON_BOOT
9
#define HWSerial Serial0
10
#define USBSerial Serial
11
#else
12
#define HWSerial Serial
13
USBCDC USBSerial;
14
#endif
15

16
static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
17
  if(event_base == ARDUINO_USB_EVENTS){
18
    arduino_usb_event_data_t * data = (arduino_usb_event_data_t*)event_data;
19
    switch (event_id){
20
      case ARDUINO_USB_STARTED_EVENT:
21
        HWSerial.println("USB PLUGGED");
22
        break;
23
      case ARDUINO_USB_STOPPED_EVENT:
24
        HWSerial.println("USB UNPLUGGED");
25
        break;
26
      case ARDUINO_USB_SUSPEND_EVENT:
27
        HWSerial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en);
28
        break;
29
      case ARDUINO_USB_RESUME_EVENT:
30
        HWSerial.println("USB RESUMED");
31
        break;
32
      
33
      default:
34
        break;
35
    }
36
  } else if(event_base == ARDUINO_USB_CDC_EVENTS){
37
    arduino_usb_cdc_event_data_t * data = (arduino_usb_cdc_event_data_t*)event_data;
38
    switch (event_id){
39
      case ARDUINO_USB_CDC_CONNECTED_EVENT:
40
        HWSerial.println("CDC CONNECTED");
41
        break;
42
      case ARDUINO_USB_CDC_DISCONNECTED_EVENT:
43
        HWSerial.println("CDC DISCONNECTED");
44
        break;
45
      case ARDUINO_USB_CDC_LINE_STATE_EVENT:
46
        HWSerial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts);
47
        break;
48
      case ARDUINO_USB_CDC_LINE_CODING_EVENT:
49
        HWSerial.printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity);
50
        break;
51
      case ARDUINO_USB_CDC_RX_EVENT:
52
        HWSerial.printf("CDC RX [%u]:", data->rx.len);
53
        {
54
            uint8_t buf[data->rx.len];
55
            size_t len = USBSerial.read(buf, data->rx.len);
56
            HWSerial.write(buf, len);
57
        }
58
        HWSerial.println();
59
        break;
60
       case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT:
61
        HWSerial.printf("CDC RX Overflow of %d bytes", data->rx_overflow.dropped_bytes);
62
        break;
63
     
64
      default:
65
        break;
66
    }
67
  }
68
}
69

70
void setup() {
71
  HWSerial.begin(115200);
72
  HWSerial.setDebugOutput(true);
73
  
74
  USB.onEvent(usbEventCallback);
75
  USBSerial.onEvent(usbEventCallback);
76
  
77
  USBSerial.begin();
78
  USB.begin();
79
}
80

81
void loop() {
82
  while(HWSerial.available()){
83
    size_t l = HWSerial.available();
84
    uint8_t b[l];
85
    l = HWSerial.read(b, l);
86
    USBSerial.write(b, l);
87
  }
88
}
89
#endif /* ARDUINO_USB_MODE */

Dieses Program sollte seitens des ESP32, alles was über den UART kommt, auf den nativen USB weiterleiten. Damit kann ich am PC z.B. mit Realterm Konfigurationsbefehle an die ESP32 schicken, die dann die GPS Platine auch empfangen sollte - tut sie aber nicht, denn sie reagiert nicht auf sie. Die Befehle sollten nicht das Problem sein: Mit dem Protokol habe ich schon mit einem anderen GPS Empfänger desselben Herstellers ziemlich viel rumgespielt, und die NS-RAW reagiert auf diese Befehle, wenn ich die Platine direkt am PC per USB anschließe.

Als weiterer Hinweis: Von den mehreren Meldungen, die das Program zeigen kann, sehe ich nur "USB Unplugged" wenn ich die GPS-Platine trenne. Ich sehe keine, wenn ich die wieder anschließe, doch auch gar nichts zu einer CDC Verbindung.

Also die Frage, wenn das Problem halbwegs zu verstehen ist: Kann jemand sehen, warum die GPS-Platine angeblich nichts vom nativen USB des ESP32 empfängt? Habe ich einfach ein grunsätzliches Verständnisproblem über die Funktionsweise des ESP32 als USB Host? Jeder Vorschlag ist willkommen!

Vielen Dank im Voraus

#7498117
Lesenswert?

Guille schrieb:

Ich sehe keine, wenn ich die wieder anschließe, doch auch gar nichts zu einer CDC Verbindung.

Kein Wunder, die USB-Seriell-Bridges von Prolific sind keine CDC-Devices. Wie sehr viele andere USB-Seriell-Bridges auch nicht.

Stattdessen verwenden diese Bausteine ihre eigene, nicht standardisierte Art der Ansteuerung. Wie man mit ihnen redet, kann man den Sourcen der USB-Seriell-Treiber für Linux entnehmen, das aber auf Deinen ESP32 umzusetzen, erfordert schon etwas Arbeit.

OP #7498598
Lesenswert?

Harald K. schrieb:

Kein Wunder, die USB-Seriell-Bridges von Prolific sind keine CDC-Devices. Wie sehr viele andere USB-Seriell-Bridges auch nicht

Ok, nicht die Antwort, die ich hätte lessen wollen, aber auf jeden Fall hilfreich.

Einen Treiber für den PL2303 zu schreiben, ist außerhalb meiner Fähigkeiten. Die Lösung war, einen AWG30 Draht nah auf den TX Pin des PL2303 (entspricht RX im GPS-uC) anzulöten. Mit diesem Draht und dem schon vorhandenen TX kann ich jetzt direkt mit dem GPS seriell kommunizieren.

Vielen Dank für deinen Hinweis!

Angehängte Dateien:
Beitrag #7498615 wurde von einem Moderator gelöscht.

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