Forum: Mikrocontroller und Digitale Elektronik ESP32S3 USB auf PL2303


von Guille (guille)



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

von Harald K. (kirnbichler)


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.

von Guille (guille)


Angehängte Dateien:

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!

Beitrag #7498615 wurde vom Autor gelöscht.
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.