Forum: Mikrocontroller und Digitale Elektronik Arduino und CH32V003


von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Vorneweg: ich programmiere nicht (normalerweise) mit Arduino, aber da im 
Forum hier und auch ausserhalb des Forums angemerkt wurde, dass es doch 
"fein" wäre man könnte mein Bootloaderboard auch mit Arduino 
programmieren habe ich mich doch tatsächlich hingesetzt und einige 
Funktionen für Arduino in ihre sogenannten "Libraries" umgesetzt, was da 
heißt, ich habe da tatsächlich etwas im Arduino-Style umgesetzt.

Um jetzt diese Libraries zu demonstrieren bietet es sich normalerweise 
an, diese über UART (in Arduino Serial.print, Serial.read etc.) 
anzusprechen.

Das funktioniert aber (zumindest bei mir) nicht und befürchte, dass 
dieses am Core liegt (ich verwende 1.0.3).

Allerdings könnte es auch sein, dass ich da grobe Fehler mache.

Beholfen habe ich mir, dass ich Lesefunktionen dann über 
Registerzugriffe mache, um Funktionen demonstrieren zu können.

Erste Frage: ist so etwas legitim in Arduino?

Zweite Frage: kann das jemand in dem typischen Arduino-Style und mag 
seine Lösung hier mitteilen (damit ich nicht den Core durchkämmen muß)?

Codes meiner Lösung zum Lesen von der UART Schnittstelle innerhalb eines 
Beispielprogramms für einen DS3231 RTC-Chip (damit ich dort eben die 
Uhrzeit stellen kann)

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Habe deinen µC nicht!

Aber die Funktion würde bei mir so, oder so ähnlich, aussehen:
1
char uart_getchar()
2
{
3
  int c;
4
  do
5
  {
6
    c = Serial.read()
7
  }
8
  while (c < 0);
9
  return c;
10
}

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

... und genau das funktioniert mit  CH32V003 nicht. So, oder so ähnlich 
war der erste Ansatz. Jetzt bin ich am ünerlegen, ob ich eine Klasse 
'UART' anlegen soll, aber dann komm ich immer weiter weg von der 
typischen 'Arduino Optik' und ob das für andere dann zielführend ist?

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ralph S. schrieb:
> ... und genau das funktioniert mit  CH32V003 nicht.
Das ist schade!

Ralph S. schrieb:
> befürchte, dass
> dieses am Core liegt (ich verwende 1.0.3).
Es gibt verschiedene cores für den µC.

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Arduino F. schrieb:
> Ralph S. schrieb:
>> befürchte, dass
>> dieses am Core liegt (ich verwende 1.0.3).
> Es gibt verschiedene cores für den µC.

Ich finde im Netz nur 2 verschiedene Cores:

https://github.com/AlexanderMandera/arduino-wch32v003

https://github.com/openwch/arduino_core_ch32

Ich verwende den von openwch, weil der von Alexander Mandera deutlich 
unausgereifter ist und einige Funktionen schlicht nicht implementiert 
hat.

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt das im Anhang (auf die Schnelle) gemacht.

Wie sehen diejenigen die 'uart_test2.ino' Datei, die mit Arduino 
hantieren?

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Hmm...

Arduino User würden erwarten, dass eine UART Klasse von Stream und damit 
auch von Print erbt.

von Ralph S. (jjflash)


Lesenswert?

Arduino F. schrieb:
> Arduino User würden erwarten, dass eine UART Klasse von Stream und damit
> auch von Print erbt.

okay, dann schau ich mal, ob ich das print (welches ich so überhaupt gar 
nicht mag: Serial.print) ererben kann.

Also noch ein bischen mehr in die Tiefe von Arduino gehen.

Grundsätzlich finde ich ja printf um Längen flexibler... aber jetzt habe 
ich angefangen, jetzt will ich auch wissen wie das geht und was genehm 
ist.

von Ralph S. (jjflash)


Lesenswert?

Lustig: Beim Durchforsten von HardwareSerial.cpp des Cores für den 
CH32V003 stelle ich fest, dass keinerlei Read-Funktion implementiert ist 
und dann brauche ich mich auch nicht zu wundern, dass lesen nicht 
funktioniert.

Hmm, vielleicht ist es einfacher, die fehlenden Readfunktionen dort zu 
implementieren?

von Christoph M. (mchris)


Lesenswert?

https://docs.arduino.cc/language-reference/en/functions/communication/serial/available/

Ralph S. schrieb:
> Zweite Frage: kann das jemand in dem typischen Arduino-Style und mag
> seine Lösung hier mitteilen (damit ich nicht den Core durchkämmen muß)?

Die serielle Schnittstelle im Arduino hat einen kleinen Buffer.
Um festzustellen, ob Bytes verfügbar sind wird normalerweise 
"Serial.available" verwendet:
https://docs.arduino.cc/language-reference/en/functions/communication/serial/available/

Die Implementierung sieht im Arduino-Core so aus:
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.cpp

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

na ja Christoph, das hier

Christoph M. schrieb:
> Die Implementierung sieht im Arduino-Core so aus:
> 
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.cpp

ist das HardwareSerial für AVR Controller und da funktioniert das auch. 
Im HardwareSerial für CH32V003 sind genau die Readfunktionen (inkl. 
available) schlicht nicht implementiert.

Das ist u.a. ja auch ein Grund mit dafür, dass bestimmte/manche 
Programme unter Arduino schlicht nicht laufen, wenn es kein AVR 
Controller ist.

Das ist auch der Grund, warum ich mich jetzt doch tatsächlich mit 
Arduino beschäftige, damit man mit einem CH32V003 auch unter Arduino so 
einigermaßen etwas anfangen kann.

Der Hinweis von Arduino F. , dass ein User wohl erwarten würde, den 
Stream in einer eigenen Klasse zu erben werde ich nach Durchsicht eher 
weiter verfolgen, als die HardwareSerial zu patchen, weil das dann nur 
auf meiner Installation funktionieren würde und jeder User denselben 
Patch durchführen müßte.

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Das ist u.a. ja auch ein Grund mit dafür, dass bestimmte/manche
> Programme unter Arduino schlicht nicht laufen, wenn es kein AVR
> Controller ist.

Falls du dich auf Hardwareserial beziehst, habe ich da noch keine 
Problem auf den verschiedenen Controllerfamilien festgestllt. Ich habe 
da schon einige Familien durch: AVR,Atmel-ARM, STM,PiPico,ESP32 ..
Es gibt aber vermutlich schon einige schnell hingehackte Frameworks, die 
in der Tiefe wohl nicht richtig implementiert sind .. wahrscheinlich ist 
die CH32xx Implementierung eine davon. Vielleicht könntest du noch mal 
einen Link auf das Repo schicken, auf das du dich genau beziehst.
An deiner Stelle würde ich vermutlich das ganze clonen und dann am Clone 
die Änderungen durchführen.

von Christoph M. (mchris)


Lesenswert?

Übrigens .. EarlyHillPower hat die gesamte API als extra Modul 
ausgelagert:

https://github.com/earlephilhower/arduino-pico

Aber dann wird es vermutlich immer informatikerlastig und geht weg vom 
schönen, einfach programmierten Framework.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ralph S. schrieb:
> Ich finde im Netz nur 2 verschiedene Cores:

Habe noch mal nachgeschaut!
Hier: 
https://github.com/maxint-rd/arduino_core_ch32/tree/Interrupt-driven-Serial

Vielleicht kannst du ja damit was anfangen....

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

im Grunde musst du dir nur die HardwareSerial Klasse bspw. vom Arduino 
Uno nehmen, für dich kopieren und alles was darin Hardware spezifisch 
ist, Registernamen etc., für deinen CH32x anpassen. Und wenn du ganz gut 
bist, ersetzt du noch alle defines durch constexpr. Wenn dir die 
bisherigen Cores noch nicht gut genug sind oder andere Probleme habe, 
mach einen Fork und ändere/ergänze es nach deinen Wünschen ab. Das wäre 
meine Herangehensweise.

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Veit D. schrieb:
> im Grunde musst du dir nur die HardwareSerial Klasse bspw. vom Arduino
> Uno nehmen, für dich kopieren und alles was darin Hardware spezifisch
> ist, Registernamen etc., für deinen CH32x anpassen. Und wenn du ganz gut
> bist, ersetzt du noch alle defines durch constexpr. Wenn dir die
> bisherigen Cores noch nicht gut genug sind oder andere Probleme habe,
> mach einen Fork und ändere/ergänze es nach deinen Wünschen ab. Das wäre
> meine Herangehensweise.

:-) :-) vielen Dank für euer Interesse, aber für mich jetzt irgendwie 
"zu spät gekommen". Ich bin ja nicht Arduino-Hero (und auch überhaupt 
nicht der Arduino-User), hier ging es mir nur darum, den CH32V003 mit 
Arduino "umgänglicher" zu machen. Die Anmerkungen von Arduino F. habe 
ich jetzt mal sacken lassen und habe mich ans Werk gesetzt. 
(HardwareSerial wollte ich nicht patchen).

Also habe ich eine neue UART-Klasse namentlich V003serial geschrieben. 
Die, wie Arduino F. angemerkt hat, den Stream (und somit auch print) 
erbt. Außerdem hab ich dieser Klasse meine Eingabefunktionen noch dazu 
beigestellt, sodass die Klasse eigentlich wie Serial verwendbar ist, nur 
dass man eben eine Objektinstanz erstellen muß: V003serial myserial;

Danach sollte dann alles so sein wie bei Serial, nur dass man dann eben 
myserial.begin schreibt.

Im Anhang sind die 3 Dateien. Zusätzlich gibt es die Eingabefunktionen:

- lineinput
- readint
- readhex

Usage kann man den Kommentaren entnehmen und ich muß das alles noch in 
einer Dokz zusammen fassen. An sich war das jetzt schon ein kleines 
Mini-Projekt für sich und ich bin am überlegen ob ich die Demos für 
bereits erstellte "Libraries" mit dieser eigenen V003serial Klasse 
verwenden soll.

Vielen Dank an alle, die hier gepostet haben.

von Ralph S. (jjflash)


Lesenswert?

Arduino F. schrieb:
> Habe noch mal nachgeschaut!
> Hier:
> https://github.com/maxint-rd/arduino_core_ch32/tree/Interrupt-driven-Serial
>
> Vielleicht kannst du ja damit was anfangen....

der von dir angegebene Link hätte einen read in HardwareSerial, aber 
jetzt ist es für mich dann irgendwie zu spät gewesen, außerdem habe ich 
jetzt die Dinge für den "offziellen Core" gemacht. Eigentlich wollte ich 
nur demonstrieren, dass mein Bootloaderboard gut mit Arduino kann.

Sorry @Arduino F. : ich habe nicht wirklich vor, mit Arduino zu werkeln 
(und irgendwie erst Recht nicht auf einem CH32V003. Arduino ist hier 
einfach ein zu großer Resourcenfresser wenn dein Chip nur 16kbyte hat), 
Für kleine Dinge sollte es allerdings reichen.

Aber ich muß zugeben, dass das jetzt relativ interessant für mich war, 
etwas knapp unter der Oberfläche von Arduino zu kratzen. Hier bin ich 
dann verwundert, wie extrem effektiv (aus meiner Sicht der Dinge) 
Arduino mit einem AVR-Controller hier umgeht.

Allerdings: ohne Arduino habe ich deutlich mehr Controlle über mein 
Programm und C++ nutze ich eigentlich - wenn überhaupt - erst ab STM32F4 
(und natürlich auf dem PC mit bspw. SDL2)

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ralph S. schrieb:
> ich habe nicht wirklich vor, mit Arduino zu werkeln
Das ist mit recht egal.
Du must machen, was du für richtig hältst.

Wo ich kann, möchte ich dich gerne unterstützen.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> :-) :-) vielen Dank für euer Interesse, aber für mich jetzt irgendwie
> "zu spät gekommen". Ich bin ja nicht Arduino-Hero (und auch überhaupt
> nicht der Arduino-User), hier ging es mir nur darum, den CH32V003 mit
> Arduino "umgänglicher" zu machen.

Danke für deinen interessanten Beitrag.

Ralph S. schrieb:
> Aber ich muß zugeben, dass das jetzt relativ interessant für mich war,
> etwas knapp unter der Oberfläche von Arduino zu kratzen. Hier bin ich
> dann verwundert, wie extrem effektiv (aus meiner Sicht der Dinge)
> Arduino mit einem AVR-Controller hier umgeht.

Ja, da waren echte C++ Profis am Werk. Auf einem so kleinen Controller 
das System so hin zu kriegen, dass es keine zusätzlichen Resourcen 
frisst, schafft nicht jeder.

Ralph S. schrieb:
> ist das HardwareSerial für AVR Controller und da funktioniert das auch.
> Im HardwareSerial für CH32V003 sind genau die Readfunktionen (inkl.
> available) schlicht nicht implementiert.
>
> Das ist u.a. ja auch ein Grund mit dafür, dass bestimmte/manche
> Programme unter Arduino schlicht nicht laufen, wenn es kein AVR
> Controller ist.

Das Arduino Projekt ist ja ein echtes Großprojekt dass seine Interfaces 
so abstrahieren muss, dass es auf allen möglichen Controllern läuft. 
Außerdem arbeiten sehr viele Leute daran.
Deshalb ist man wohl dazu übergegangen, die API-Spezifikation (bzw. die 
Interfaces) als ein separates Projekt zu behandeln:

https://github.com/arduino/ArduinoCore-API

Dieses Interface kann dann als ganzes von den entsprechenden 
Kontrollerimplementierungen eingebunden werden, so wie es EarlyHillPower 
für die PiPico-Kontroller gemacht hat:

https://github.com/earlephilhower/arduino-pico

(Er hat die API aber vorher ins eigene Repo gecloned um sicher vor 
etwaigen Änderungen zu sein:
https://github.com/earlephilhower/ArduinoCore-API/
)

In der Arduino-IDE findet sich im Drop-Down-Menue ganz links der Punkt 
"examples" wo man die grundlegenden Beispiele mit "basics" auswählen 
kann.

Diese grundlegenden Beispiele sollten eigentlich auf allen 
Prozessorspezifischen Implementierungen funktionieren.

Hie mal das "analogRead" Beispiel:
1
void setup() {
2
  Serial.begin(9600);
3
}
4
5
void loop() {
6
  int sensorValue = analogRead(A0);
7
  Serial.println(sensorValue);
8
  delay(1);       
9
}

Hier sieht man den typischen Syntax der seriellen Schnittstelle.
Die Default-UART-Klasse ist immer "Serial" (groß geschrieben) und 
default mäßig vorhanden und muss nicht extra instanziert werden.
(Ich finde 115200 Baud standardmäßig besser)

Der ESP32 hat mehr als eine serielle Schnittstelle. Die zweite serielle 
Schnittstelle wird dann gerne so verwendet:
1
#define RX1 18
2
#define TX1 19
3
void setup() {
4
  Serial.begin(9600);
5
  Serial1.begin(9600, SERIAL_8N1, RX1, TX1);
6
}
7
void loop() {
8
  if(Serial1.available()){
9
    String messageIn = Serial1.readString(); 
10
    Serial.print("I received: ");
11
    Serial.println(messageIn);
12
    Serial1.print("Hi Mega, thank you!");
13
  }
14
}

aus
https://wolles-elektronikkiste.de/en/serial-and-softwareserial

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Christoph M. schrieb:
> In der Arduino-IDE findet sich im Drop-Down-Menue ganz links der Punkt
> "examples" wo man die grundlegenden Beispiele mit "basics" auswählen
> kann.
>
> Diese grundlegenden Beispiele sollten eigentlich auf allen
> Prozessorspezifischen Implementierungen funktionieren.

"Sollten" heißt nicht, dass sie das tun. Im Falle von CH32V003 ist zum 
einen Wire.h nicht fehlerfrei und wie oben genannt waren / sind die 
Serial.read Methoden nicht implementiert.

Wie auch immer, ich habe hierfür eine Lösung gefunden. Sicherlich wird 
der Core (irgendwann) überarbeitet und dann implementieren die bestimmt 
auch die read-Funktionen.

Wer auf einem CH32V003 Arduino macht, wird sicherlich damit umgehen 
können.

Arduino F. schrieb:
> Ralph S. schrieb:
>> ich habe nicht wirklich vor, mit Arduino zu werkeln
> Das ist mit recht egal.
> Du must machen, was du für richtig hältst.
>
> Wo ich kann, möchte ich dich gerne unterstützen.

:-) du hast mir mit dem Hinweis, den Stream zu erben schon geholfen. Im 
Übrigen bin ich KEIN Arduino-Basher! Jeder soll mit dem hantieren, mit 
dem er glücklich ist und mit dem er zu Rande kommt. Für mich war jetzt 
das insofern (hoch)interessant um ma zu sehen, wie denn Arduino wirklich 
funktioniert.

Prinzipiell bleibt es aber eben C++ und von daher kann ich da eben 
einiges implementieren. Irgendwie hat es auch Spaß gemacht, die 
"Libraries" zu erstellen und ich sollte, sollte, sollte wirklich ans 
dokumentieren gehen, bevor ich weitere Teile mache (wahrscheinlich werde 
ich jedoch noch eine Weile damit spielen bevor ich mich an Doku und 
Webseitenerweiterung mache).

Momentan bin ich am Überlegen, ob ich ST7735 / ST7789 TFT-Display 
Libraries erstellen soll, aber ich weiß nicht, ob unter Arduino diese 
Displays wirklich Sinn machen, viel Flashspeicher bleibt dann nicht mehr 
übrig.

OLED mit Hardware I2C habe ich, sowie Libraries für HX1838, DS18B20, 
DS3231, LM75, 24LCxx EEProms, abgespecktem printf mit Library für 
farbige Konsolenausgabe und Demoprogramme für Verwendung von 
Timerinterrupt (weil attachinterrupt ebenfalls nicht funktioniert).

Hast Du Vorschläge, was in eine Sammlung für einen CH32V003 noch 
hineingehört? V-USB habe ich nicht hinbekommen, hierfür reichte dann der 
Flash-Speicher nicht aus.

von Ralph S. (jjflash)


Lesenswert?

Christoph M. schrieb:
> In der Arduino-IDE findet sich im Drop-Down-Menue ganz links der Punkt
> "examples" wo man die grundlegenden Beispiele mit "basics" auswählen
> kann.
>
> Diese grundlegenden Beispiele sollten eigentlich auf allen
> Prozessorspezifischen Implementierungen funktionieren.

:-) ich bin ja schon etwas "deppert", aber wo man die Beispiele findet 
habe ich dann doch herausgefunden, und sei es nur darum, damit ich im 
Ordner libraries eigene Beispiele hinterlegen kann.

Aber deswegen schreibe ich nicht, sondern der Aussage wegen, dass die 
grundlegenden Beispiele funktionieren sollten.

Das Beispiel für LiquidCrystal funktioniert ebenfalls nicht. Dort habe 
ich jetzt ein bisschen am Timing gespielt, aber daran hapert es auch 
nicht: Ergo, auch für das eine eigene Library erstellen. Und die sollte 
dann, wie zuvor von Arduino F. angemerkt", den Stream erben.

Herjeh, CH32V003 und Arduino nimmt für mich kein Ende

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Herjeh, CH32V003 und Arduino nimmt für mich kein Ende

Ja, das könnte ein wenig aufwändig sein.

Gerade habe ich einen MC-Netz Artikel entdeckt:

https://www.mikrocontroller.net/articles/Umstieg_von_Arduino_auf_AVR

Da fehlt jetzt ein Artikel "Unstieg von CH32V003 auf Arduino" :-)

von Kilo S. (kilo_s)


Lesenswert?

Ralph S. schrieb:
> Herjeh, CH32V003 und Arduino nimmt für mich kein Ende

Der core ist irgendwie noch unvollständiger als der für PY32?

Ohne Quatsch, ich hab da alles drin. Serial (R/W, Stelle meine RTC über 
die serielle Schnittstelle) I2C (EEPROM/RTC) und SPI (Display).

Genau zwei GPIO gehen nicht.

Dachte der core sei sogar von WCH selbst? (Bugreport an yy@wch(.)cn)

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.