Forum: Mikrocontroller und Digitale Elektronik CH32V003 und Arduino


von Ralph S. (jjflash)


Lesenswert?

Okay, Ihr könnt meine folgende Frage gleich mit "Ja, du bist zu dämlich" 
beantworten.

Frage: Bin ich zu dämlich mit Arduino und CH32V003 irgendetwas anderes 
zu bewerkstelligen als bloß Logikpegel auf einem Pin wackeln zu lassen?

Hintergrund:
Ich möchte mein serielles Bootloader-Board, welches ich jetzt 
überarbeitet habe und dessen Vorgängerschaltung und Firmware ich hier 
gepostet habe, tatsächlich Arduinotauglich machen (ich arbeite im 
Normalfall nicht mit Arduino).

Grundsätzlich kann Arduino Codes compilieren und auch ein Upload in mein 
Board durch patchen von platform.txt und boards.txt funktioniert 
einwandfrei.

Aber jede etwas erweiterte Funktion scheint nicht zu funktionieren. Ist 
der Core von hier:

 https://github.com/openwch/arduino_core_ch32

wirklich so fehlerhaft und unvollständig wie es sich mir darstellt oder 
mache ich grundlegend etwas falsch.

Für mich stellt es sich so dar:

- class Serial kann nur schreiben, lesen funktioniert nicht
- Interrupthandler funktioniert nicht
- Wire.h bedient i2c nicht korrekt
- SPI.h ebensowenig

Gerade versuche ich so etwas einfaches wie analogRead und das 
funktioniert natürlich genausowenig wie analogWrite.

Für die obigen "Probleme" habe ich jetzt eigenständigen Ersatz 
geschrieben, der Funktionen bereitstellt, der die Funktionaltät der 
Hardware herstellt, aber es ist eben etwas ausserhalb der 
Standardklassen und ich weiß nicht ob das Sinn und Zweck der Übung ist, 
denn: für jedes SPI-Device, für jedes I2C-Device muß dann eine eigene 
"Library" geschrieben werden, weil alle Beispiele aus dem Netz dann 
darauf aufbauen (und eben nicht funktionieren).

Momentan habe ich für CH32V003 dann geschrieben SPI-TFT Display, 
OLED-Display, TM16xx 7-Segmenttreiber, DS18B20, DHT11, LM75 ... etc.

Irgendwie fühlt sich das an, als ob ich das gesamte Ökosystem neu 
aufsetze.

Bin ich zu dämlich?

:-) natürlich dürft ihr das mit "ja" beantworten

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Gerade versuche ich so etwas einfaches wie analogRead und das
> funktioniert natürlich genausowenig wie analogWrite.

analogRead scheint zumindest implementiert zu sein:

https://github.com/openwch/arduino_core_ch32/blob/main/cores/arduino/ch32/analog.cpp

Vielleicht geht es ja trotzdem nicht, weil es auf einem anderen 
Prozessor probiert wurde.

Ich werfe jetzt einfach mal eine Vermutung den Raum: Wahrscheinlich ist 
eines der #defines nicht aktiv
1
#if (defined(CH32V20x) || defined(CH32V30x) || defined(CH32V30x_C) || defined(CH32V10x) || defined(CH32L10x) || defined(CH32VM00X) )

: Bearbeitet durch User
von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Christoph M. schrieb:
> Vielleicht geht es ja trotzdem nicht, weil es auf einem anderen
> Prozessor probiert wurde.
>
> Ich werfe jetzt einfach mal eine Vermutung den Raum: Wahrscheinlich ist
> eines der #defines nicht aktiv
> #if (defined(CH32V20x) || defined(CH32V30x) || defined(CH32V30x_C) ||
> defined(CH32V10x) || defined(CH32L10x) || defined(CH32VM00X) )

... sagen wir es einmal so: Der Core ist grundsätzlich irgendwie höchst 
unvollständig und höchst buggy. Aus diesem Grund, allerdings erst am 
Entstehen: siehe Anhang.

Daraus werde ich dann am We eine weitere, rein spezielle Library für den 
CH32V003 machen!

von Christoph M. (mchris)


Lesenswert?

Mittlerweile nutzt man für neue Kontrollerimplementierungen die 
Arduino-API:

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

Im Repository gibt es auch eine Kurzanleitung dazu.
Um das Ganze in Griff zu kriegen, muss man aber vermutlich Informatiker 
sein.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn ich mir den Header anschaue 
https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V00x/PinAF_CH32V00x.h 
stimmt etwas mit dem Include Guard nicht. Vermutlich copy paste und 
nicht zu Ende abgeändert oder nur erstmal kopiert und dann stehen 
gelassen. Ich habe noch keinen Core geschrieben, ich würde bei anderen 
schauen jedoch für den eigenen Core bei Null anfangen. Man wird bei dem 
Umfang sonst nicht fertig mit debuggen. Vielleicht hilft dir das weiter. 
https://www.elektronik-labor.de/Projekte/CH32V2.html

von Harald K. (kirnbichler)


Lesenswert?

Veit D. schrieb:
> stimmt etwas mit dem Include Guard nicht.

Was soll daran nicht stimmen?
1
#ifndef _PINAF_CH32V20X_H
2
#define _PINAF_CH32V20X_H
3
4
... diverser Pofel
5
6
#endif /* _PINAF_CH32V20X_H */

Das ist vollkommen korrekt.

von Christoph M. (mchris)


Lesenswert?

Harald K. schrieb:
> Was soll daran nicht stimmen?
> #ifndef _PINAF_CH32V20X_H

Vielleicht liegt es an der Überschrift diese Threads?
1
CH32V003

von Veit D. (devil-elec)


Lesenswert?

Harald K. schrieb:
> Veit D. schrieb:
>> stimmt etwas mit dem Include Guard nicht.
>
> Was soll daran nicht stimmen?
>
>
1
> #ifndef _PINAF_CH32V20X_H
2
> #define _PINAF_CH32V20X_H
3
> 
4
> ... diverser Pofel
5
> 
6
> #endif /* _PINAF_CH32V20X_H */
7
>
>
> Das ist vollkommen korrekt.

Bitte genau hinschauen. Ein CH32V003 ist kein CH32V20X. Der Ordnername 
steht für CH32V003 und drin der Header für CH32V20X. Das kann nicht 
richtig sein. Passt für mich nicht. Den Ordner für CH32V20X gibt es ja 
extra noch.

von Harald K. (kirnbichler)


Lesenswert?

Das praktische ist ja, daß vor lauter Platz, den die enthaltene Lizenz 
wegnimmt, keinerlei Kommentar in so einer Datei drinstehen darf, wofür 
sie genau da ist und welche Einschränkungen sie hat.

Und niemand wundert sich, daß da "Copyright (c) 2017, 
STMicroelectronics" drinsteht, obwohl die Datei doch für einen µC von 
WCH ist  ...

Es ist jedenfalls nicht komplett auszuschließen, daß derjenige, der sie 
geschrieben hat, sie aus einer Portierung für CH32V20x kopiert und 
einfach vergessen hat, sie nach dem umbenennen anzupassen.

Ob das, was da in den beiden Funktionen pinV32_DisconnectDebug und 
pin_SetV32AFPin geschieht, irgendwas macht, was spezifisch für CH32V20x, 
aber nicht für CH32V00x ist, müsste sich jemand ansehen, der die 
Reference Manuals vorliegen hat und weiß, was der ganze Kram überhaupt 
soll.

Ich hab' mit Arduino und dem zugehörigen Schichtkuchen weniger zu tun, 
aber ich beschäftige mich unter anderem schon mehrere Jahrzehnte damit, 
C-Code von verschiedenen Leuten anzugucken. Es gibt wirkklich viele 
Schlampen. Nach der Phase "zurechtgedengelt, bis es fehlerfrei 
compiliert und bei einfachen Tests funktionier" entfällt meistens die 
Phase "aufräumen", denn das ist ja mühsam ...

von Christoph M. (mchris)


Lesenswert?

Harald K. schrieb:
> Ich hab' mit Arduino und dem zugehörigen Schichtkuchen weniger zu tun,
> aber ich beschäftige mich unter anderem schon mehrere Jahrzehnte damit,
> C-Code von verschiedenen Leuten anzugucken. Es gibt wirkklich viele
> Schlampen. Nach der Phase "zurechtgedengelt, bis es fehlerfrei
> compiliert und bei einfachen Tests funktionier" entfällt meistens die
> Phase "aufräumen", denn das ist ja mühsam ...

Ja, das passiert öfters. Im obigen Fall
Beitrag "Re: CH32V003 und Arduino"
wäre es vielleicht eine gute Übung, die gezeigte ADC-Funktion einfach 
mal unterhalb des Komaptibilitätslayers anzuhängen.

Noch eine kleine Randbemerkung: In den ursprünglichen Arduino-API 
Funktionen ist analogRead nicht in einer Klasse implementiert.

: Bearbeitet durch User
von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Christoph M. schrieb:
> Noch eine kleine Randbemerkung: In den ursprünglichen Arduino-API
> Funktionen ist analogRead nicht in einer Klasse implementiert.

tja, dann habe ich das jetzt anderst gemacht und das analoge Einlesen in 
eine Klasse verpackt. Das ganze schön in Arduino-Häppchen, für jeden xyz 
eine eigene "Lib".

Hier dann meine im Anhang.

Klasse ADC, aus der für jeden analogen Eingang ein Objekt instanziiert 
wird. Es gibt dann nur 2 öffentliche Methoden: read() und 
calc_spg(advalue, refwert).

Ich sollte irgendwann mal "in die Pötte" kommen und alle Dinge die für 
Arduino und CH32V003 von mir gemacht worden sind, in einer Doku 
zusammenschreiben. Hier also "meine Methode", analoges in Arduino mit 
CH32V003 einzulesen.

Nächstes wird sein, "analog zu schreiben" (um das in Arduino-Sprech) zu 
formulieren,  in Wirklichkeit ist das ja eine PWM.

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> tja, dann habe ich das jetzt anderst gemacht und das analoge Einlesen in
> eine Klasse verpackt. Das ganze schön in Arduino-Häppchen, für jeden xyz
> eine eigene "Lib".

Wo wäre es laut Standard-API:
https://docs.arduino.cc/language-reference/en/functions/analog-io/analogRead/

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

gehe bitte mit einem besseren Beispiel voran. Zeiger zerfallen als 
Parameter, die Länge ist weg. Hier klappt das zufällig, weil print() bis 
zum Nullpointer liest. Ansonsten ist sowas gefährlich. Lieber Referenzen 
statt Zeiger.

So wäre das besser.
1
Stream &cout {Serial};
2
3
void textnvalue(Stream &out, const char (&s1)[], const int16_t value, const char (&s2)[], const bool mode)
4
{
5
  out.print(s1);
6
  out.print(' ');
7
8
  if (mode)
9
  {
10
    out.print(value / 100);
11
    out.print(".");
12
    out.print(value % 100);
13
  }
14
  else
15
  {
16
    out.print(value);
17
  }
18
19
  out.print(' ');
20
  out.println(s2);
21
}
22
23
textnvalue(cout, 
oder
1
void textnvalue(Stream &out, const char (&s1)[], const int16_t value, const char (&s2)[], const bool mode)
2
{
3
   char buffer[32];  // anpassen
4
5
  if (mode) {
6
    snprintf(buffer, sizeof(buffer), "%s %d.%02d %s", s1, (value/100), (value%100), s2);
7
  }
8
  else {
9
    snprintf(buffer, sizeof(buffer), "%s %d %s", s1, value, s2);
10
  }
11
12
  out.println(buffer);
13
}

von Veit D. (devil-elec)


Lesenswert?

Christoph M. schrieb:
> Ralph S. schrieb:
>> tja, dann habe ich das jetzt anderst gemacht und das analoge Einlesen in
>> eine Klasse verpackt. Das ganze schön in Arduino-Häppchen, für jeden xyz
>> eine eigene "Lib".
>
> Wo wäre es laut Standard-API:
> https://docs.arduino.cc/language-reference/en/functions/analog-io/analogRead/

Ist hier zu finden oder 1:1 auf dem Rechner.
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_analog.c

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Christoph M. schrieb:
> Ralph S. schrieb:
>> tja, dann habe ich das jetzt anderst gemacht und das analoge Einlesen in
>> eine Klasse verpackt. Das ganze schön in Arduino-Häppchen, für jeden xyz
>> eine eigene "Lib".
>
> Wo wäre es laut Standard-API:
> https://docs.arduino.cc/language-reference/en/functions/analog-io/analogRead/

Nur mal so am Rande:
Ich mache zwar im Normalfall so gar nichts mit Arduino und vor ein paar 
Monaten hatte ich mich genau wegen DIR damit einmal auseinandergesetzt, 
meinen Bootloader und mein passendes Board dazu, unter Arduino gangbar 
zu machen.

Allerdings muß man mir, und so dämlich und blöd bin ich dann doch nicht, 
nicht aufzeigen, wie ein analogRead in Arduino definiert ist.

Man muß nicht 1000 Klimmzüge machen, um ums Verrecken genau den gleichen 
Mist zu haben, dann Arduino standardmäßig vorgibt. Man muß / sollte hier 
nicht am Core herumfrickeln, wenn da 1000 Köche den Brei verderben.

Hier setze ich lieber auf das, was garantiert funktioniert und 
garantieren funktioniert erst mal nur eines wirklich: Linkerscript, 
Compiler und Linker (und so wie es aussieht digitalRead / write und 
Serial (hier aber nur schreibend).

Also alles andere was man haben will selbst aufsetzen (was so gar nicht 
wirklich Arduino-Style ist, weil: dann kann man es gleich anderst 
machen).

Von daher schreibe ich jetzt erstmal alles auf was ich so habe und werde 
dann alles "veröffentlichen": Allerdings wird dann zwar die Handhabung 
Arduino-Style sein, aber mit vorhandenen Programmen nicht kompatibel 
sein.

Vorhanden sind:

- adc (eigene Klasse, hier im Anhang)

- serial als eigene Klasse v003_serial (schreibend und lesend, erbt 
Stream von daher funktioniert print und println)

- i2c (eigene Klasse als Ersatz für wire)

- my_printf (abgespecktes sehr kleines, printf, keine klasse)

- colpos farbige Textausgaben und Cursorpositionierung bei 
Terminalausgaben

- v003_oled (Klasse für i2c-OLED mit SSD1306 / SSD1315 Controller)

- hx1838 (Infrarotempfänger, keine eigene Klasse, weil Benutzung Timer2 
- und auch Timerinterruptbehandlung ist im Core unvollständig)
usgaben und textcursorpositionierung

- ds18b20 (Klasse fürs auslesen eines einzelnen Temperatursensors, evtl. 
werd ich das für mehrere Sensoren erweitern)

- BMP280 (eigene Klasse, ein bereits initialisierter i2c wird 
vorrausgesetzt)

- charlie20 (Library für 20 charliegeplexte LED's, keine eigene Klasse, 
weil wieder Timerinterrupt)

- dht11 (eigene Klasse für diesen -schlechten- Sensor)

- Schieberegister 74HC595 (eigene Klasse)

- HD44780 (unglaublich: nicht einmal das originale Demo funktioniert, 
weil das Timing scheinbar komlett daneben ist. Deshalb auch hier eigene 
Library mit eigener Klasse. Erbt Stream und von daher funktioniert auch 
print und println)

- rtc (für ds3231 / ds1305, eigene Klasse, ein bereits initialisierter 
I2C Bus wird vorrausgesetzt).

- SPI-tftdisplay mit st7735 oder st7789 grafikcontroller, Displays von 
160x80 bis 320x240 Pixel (eigene Klasse)

- tm16xx (7-Segment Anzeigetreiber, eigene Klasse)

- ws2812 (eigene Klasse)

Demos für LM75 I2C-Temperatursensor, I2C-EEprom, interruptgesteuertem 
Blinken, Timernutzung generell.

------------------------

Das nächste ist PWM und Servos.

------------------------

Für den Fall, dass irgendjemand vorab von dem oben genannten "Zeugs" 
etwas brauchen kann, sagt bescheid, ich werde das hier posten.

Aber bitte verschont mich damit, welche Syntax Arduino im Originalen 
macht. Es nutzt hier nix, etwas kompatibel zu machen, das eher schlecht 
als recht funktioniert, nur damit auf jeder Plattform einheitlich die 
selbe Syntax herscht, nur um dann festzustellen: Funktioniert nur auf 
einer Plattform fehlerfrei: Arduino Uno / Nano mit ATmega328.... bei 
allen anderen Dingen zickt es immer irgendwo rum.

Egal was man ausprobiert, sogar mit originalen Uno r4 Platinen.

Aus diesem Grunde gleich eigene Klassen, Methoden und Funktionen... 
allerdings dokumentieren muß man es auch (und damit tu ich mich dann 
schwer).

----------------------------

Wie gesagt, wenn jemand etwas von obiger Liste benötigt: schreiben, ich 
poste das hier dann.

Wochenendlicher Gruß,
Ralph

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Allerdings muß man mir, und so dämlich und blöd bin ich dann doch nicht,
> nicht aufzeigen, wie ein analogRead in Arduino definiert ist.

Ich finde es ja gut, dass du etwas arduinoartiges machst. Vor langer 
Zeit habe ich einmal ähnlich angefangen, eine vereinfachte API 
arduinoähnlich für eine MCU zu machen. Mit der Zeit habe ich aber 
gemerkt, dass der Sinn eines "Kompatibilitätslayers" die Kompatibilität 
ist. Bei analogRead ist das noch relativ überschaubar, aber sobald man 
die I2C Funktionen implementiert, wird das schon schwieriger.

von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> So wäre das besser.
>
> Stream &cout {Serial};
> void textnvalue(Stream &out, const char (&s1)[], const int16_t value,
> const char (&s2)[], const bool mode)
> {
>   out.print(s1);
>   out.print(' ');
>   if (mode)
>   {
>     out.print(value / 100);
>     out.print(".");
>     out.print(value % 100);
>   }
>   else
>   {
>     out.print(value);
>   }
>   out.print(' ');
>   out.println(s2);
> }
> textnvalue(cout, …
> odervoid textnvalue(Stream &out, const char (&s1)[], const int16_t
> value, const char (&s2)[], const bool mode)
> {
>    char buffer[32];  // anpassen
>   if (mode) {
>     snprintf(buffer, sizeof(buffer), "%s %d.%02d %s", s1, (value/100),
> (value%100), s2);
>   }
>   else {
>     snprintf(buffer, sizeof(buffer), "%s %d %s", s1, value, s2);
>   }
>   out.println(buffer);
> }

Okay, die erste Variante kann ich einsehen (und finde ich auch recht 
"elegant"), die zweite Variante ist genau das, was ich auf einem 
ch32v003 vermeiden möchte: snprintf schluckt für die Verhältnisse eines 
ch32v003 (nur 16384 Byte Flash insgesamt) ungehörige Mengen Flash. Zu 
diesem Zweck habe ich ja auch extra ein abgespecktes printf, in den 
Demos vollte ich mein eigenes printf vermeiden und deshalb die Krücke 
mit textnvalue.

Die Frage ist, ob ein "üblicher" Arduino Nerd das hier:
1
Stream &cout {Serial};

versteht.

Aber im Grunde gehts ja um den ADC .... und nicht um die Ausgabe!

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


Lesenswert?

Ralph S. schrieb:
> Die Frage ist, ob ein "üblicher" Arduino Nerd das hier:
> Stream &cout  {Serial};
>
> versteht.

Nicht am ersten Tag...
Aber das Streaming ist schon recht verbreitet.

Wichtiger ist eigentlich, dass Serial von (über Stream) Print erbt.

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Die Frage ist, ob ein "üblicher" Arduino Nerd das hier:Stream &cout
> {Serial};

Das Ziel des Arduino-Frameworks ist maximale Verständlichkeit und 
einfachste Benutzbarkeit. Der gezeigte Code erfüllt diese Bedingungen 
nicht und ist deshalb ungeeignet.

von Andreas S. (bastelmax)


Lesenswert?

Hier hat sich auch jemand mit der Arduino Lösung rumgeärgert und
es doch noch irgendwie zum "laufen" gebracht.
Nur mal so und nebenbei für die mitlesenden Arduino Nerds:
https://www.elektronik-labor.de/Projekte/CH32V2.html

von Veit D. (devil-elec)


Lesenswert?

Christoph M. schrieb:
> Ralph S. schrieb:
>> Die Frage ist, ob ein "üblicher" Arduino Nerd das hier:Stream &cout
>> {Serial};
>
> Das Ziel des Arduino-Frameworks ist maximale Verständlichkeit und
> einfachste Benutzbarkeit. Der gezeigte Code erfüllt diese Bedingungen
> nicht und ist deshalb ungeeignet.

Was ist das denn für eine schwachsinnige Aussage? Sowas bringt mich von 
0 auf 100 auf die Palme. Überlege einmal was du da schreibst. Das passt 
vorn und hinten nicht zusammen. Frage dich einmal was der normale 
Arduino User davon sieht. Der guckt nicht einmal den Header an. Und das 
soll dann laut deiner Meinung Grund genug sein schlechten bzw. 
problematischen Code von einem selbst zu schreiben? Ich bitte dich. Das 
kann nur Unsinn werden. Ich hoffe du regst dich nie über Arduino im 
allgemeinen auf, sonst schmiere ich dir das jeden Tag aufs Brot.

Im Gegenteil, man könnte noch ein Funktion-Template daraus machen um die 
Länge für irgendwas verarbeiten zu können. Zum Bsp. falls man snprintf 
verwendet die optimale lokale Buffergröße anzulegen. Auch das würde der 
normale Arduino User der diese Funktion einfach nur verwendet nicht 
bemerken, aber dem Programmierer der Funktion schreibt, gibt es alle 
Möglichkeiten in die Hand. Letzteres hat immer Vorrang. Immer!

Und wenn es dann interessierte Arduino User gibt, die mehr machen wollen 
wie nur das Framework benutzen, die sehen dann wie es andere richtig 
bzw. richtiger (bin auch nicht perfekt) geschrieben haben und können 
dann selbst nachforschen oder Bücher lesen oder was auch immer um in die 
Programmierung einzusteigen.

Es jedenfalls kein einziger Grund dabei diesen Leuten guten Code 
vorzuenthalten bzw. umgekehrt schlechten Code zu servieren. Kein 
Einziger!

Falls du der Christian bist mit dem ich schon im Biergarten saß, dann 
müssten wir dieses Jahr darüber reden. :-)

Das war mein Sonntag-Plädoyer.

von Veit D. (devil-elec)


Lesenswert?

Ralph S. schrieb:
> ... die zweite Variante ist genau das, was ich auf einem
> ch32v003 vermeiden möchte: snprintf schluckt für die Verhältnisse eines
> ch32v003 (nur 16384 Byte Flash insgesamt) ungehörige Mengen Flash.

Kann ich nachvollziehen. Das Problem kenne ich mit dem ATtiny412. Für 
das Programm ist Platz genug. Zum bequemen Debuggen ist alles zu wenig.

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> Ralph S. schrieb:
>> ... die zweite Variante ist genau das, was ich auf einem
>> ch32v003 vermeiden möchte: snprintf schluckt für die Verhältnisse eines
>> ch32v003 (nur 16384 Byte Flash insgesamt) ungehörige Mengen Flash.
>
> Kann ich nachvollziehen. Das Problem kenne ich mit dem ATtiny412. Für
> das Programm ist Platz genug. Zum bequemen Debuggen ist alles zu wenig.

:-) jetzt bin ich etwas "abgelenkt" von den eigentlichen Dingen, die ich 
machen möchte.

Dein Vorschlag mittels stream etwas auszugeben ist natürlich absolut 
berechtigt, andererseits liest print nun halt wirklich bis zum Zerobyte.

Mir war/ist die Ausgabe mittels print / println viel zu "dämlich" und zu 
"Zeilenintensiv", vor allem geht da Übersicht verloren von dem, was man 
eigentlich zeigen möchte.

Abgesehen davon dass ich Arduino immer nur für andere verwende, habe ich 
deshalb ma mein eigenes, sehr abgepecktes printf, innerhalb Arduino 
(sehr sehr kleiner Flashbedarf).

Da ich das nun aber in einem Demo zu bspw. ADC nicht verwenden möchte - 
es erfordert dann eben das Einbinden meiner printf-Library (ich tu mich 
immer noch schwer mit dem Begriff "Library" hinsichtlich den 
Arduino-Libraries), was ich vermeiden möchte.

Hm, jetzt bin ich am überlegen, ob man so etwas wie textnvalues dann, um 
das instanziieren eines Streams zu vermeiden, vllt. besser in ein Makro 
packt (und den originalen Aufruf von mir dan beibehält) ?!?

Aber.... :-) ich werde mir das mit dem Stream zu Herzen nehmen und für 
meine zu erstellende Dokumentation zu dem ganzen Sermon (den ich 
hoffentlich wirklich mache) mit aufnehmen. Zumindest ist das mal auf 
meiner ToDo Liste

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

die Funktion mit Deklaration
1
void textnvalue(Stream &out, const String &s1, const int16_t value, const String &s2, const bool mode)
belegt bei mir 30kB weniger Flash bei gleichen RAM im Vergleich zu
1
void textnvalue(const String &s1, const int16_t value, const String &s2, const bool mode)
ich hätte vermutet es bleibt gleich, weil der Parameter out nur 
durchgereicht wird. Stream ist hierbei der Datentyp.

Die vielen print Zeilen nerven manchmal nicht nur dich. Deswegen gibt es 
eine gern verwendete Streaming Klasse.
https://github.com/janelia-arduino/Streaming

Wegen deiner Print Klasse. Du kannst gern deine Printklasse verwenden, 
ist kein Problem, du solltest nur, ich nenne es einmal 
"Funktionskompatibel" bleiben mit dem Interface. Wenn es nicht alles 
"drucken" kann was möglich wäre, geht das laut meiner Meinung nach auch, 
muss dann eben in der Doku erwähnt werden, dass auf Grund von zu wenig 
Flash nicht alles möglich ist. Wenn du eine Möglichkeit siehst Flash 
einzusparen und musst deswegen die "Funktionskompatibilität" verlassen, 
dann ist das eben so.

Thema Makros. Die sparen bestimmt durch Präprozessor Ersetzung Flash 
ein. Nur wird man an einen Punkt kommen ab dem man nicht mehr 
durchblickt und Fehler nicht mehr sieht. Man hat auch in C++ viele 
Möglichkeiten allein schon mit constexpr. Für eine Funktion verwendet 
kann alles zur Compile-Time ausgewertet werden, muss es jedoch nicht. 
Man muss zusehen das alle Parameter Compile Time konstant sind. Ähnlich 
wie mit Makros, nur das bei Makros weniger Prüfungen durchlaufen werden.

Das sind alles so viele Grundsatzentscheidungen, da sollte man sich Zeit 
nehmen. :-)

Nochwas, weil ich das gerade sehen.
1
void loop()
2
{
3
  uint16_t count = 0;
4
  uint16_t temp;
5
  while(1)
6
  {
7
    temp= ntc_gettemp(ntc1.read());
8
    textnvalue("\rCounter: ", count, "  |  ", 0);
9
    textnvalue("Temp.: ", temp, " oC", 1);
10
    count++;
11
    delay(1000);
12
  }
13
}
loop() ist in Arduino die while() Schleife.
setup() ist das in der main() bis zur while().

count und temp entweder lokal static machen oder noch besser global.
temp ist in deinem Fall in der loop lokal und nicht initialisiert. 
Vermutlich nur vergessen. ;-)

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

ich möchte dir nicht auf den Keks gehen oder klugsch. oder so. Habe 
nochmal genauer hingeschaut und mir gehts wirklich darum mit besseren 
Bsp. voranzugehen, weil in den Arduino IDE Bsp. schlummern mir nicht 
gefallende zu viele #defines etc. rum und wir sagen das auch im Arduino 
Forum fast wöchentlich jeden Neuling der zu uns findet. :-)

Nochmal zu deinem Bsp.
count global machen (ohne = 0;)
uint16_t count;
und dann
1
void loop()
2
{
3
    const uint16_t temp = ntc_gettemp(ntc1.read());
4
    textnvalue("\rCounter: ", count, "  |  ", 0);
5
    textnvalue("Temp.: ", temp, " oC", 1);
6
    count++;
7
    delay(1000);
8
}

und wenn man so richtig gut sein möchte, schreibt man die erste Zeile
1
const uint16_t temp {ntc_gettemp(ntc1.read())};
Dann finden noch Datentyp- und Bereichsüberlaufprüfungen statt.
Ist wirklich nur gut gemeint. Ist dein Code, kannst schreiben wie du 
möchtest. Falls temp noch weiter Verwendung finden soll, dann natürlich 
global.

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Grüß dich Veit,

nein, du gehst mir nicht auf den Keks. Grundsätzlich bin ich dankbar für 
die Arduino-Sichtweise (und ich überdenke meine Ansätze, auch wenn ich 
deine Meinung oder Sichtweise nur teilweise teile).

Man merkt mir auch an, dass ich bisweilen sehr "oldschool" unterwegs bin 
und mich manchen Dingen (leider) hartnäckig verschließe, auch wenn sie 
ihre Gründe haben und bisweilen besser sind.

Globale Variable lassen sich nicht immer vermeiden, aber dennoch 
versuche ich sie so wenig wie möglich zu verwenden.

Was ich im Moment mit Arduino mache, mache ich für mich (sorry, wenn ich 
das so sage, aber ich würde für mich oder auch dienstlich Arduino nicht 
einsetzen). Auch wenn viele jetzt die Nase rümpfen werden, bei Arduino 
(mit ATmega8, später ATmega328) hat mir vor allem der Bootloader und die 
günstige Hardware gefallen, die aber auch nativ mit AVR-GCC, AVRDUDE und 
Makefiles zu bedienen war / ist. Mehr aber ehrlich gesagt nicht.

Also habe ich für den CH32V003 eben auch einen seriellen Bootloader 
geschrieben. Die Hardware siehst du im Bild im Anhang. Das ganze ist 
vorrangig für meine Lehrlinge gedacht, die in der Schule mit Arduino 
(und ganz schlimm mit Blockly) umgehen müssen und dafür zu je 5 Personen 
sich eine SenseBox teilen müssen. Als Ausbildungsprojekt lernen sie hier 
dann auch das SMD löten und "basteln" sich ein Nano-Board mit CH32V003 
zusammen, für die ich jetzt die Libraries schreibe.

Natürlich verstehe ich das Anlegen lokaler Variable innerhalb des Codes, 
bspw.
1
for (int i = 0; i< 10; i++)
Weil hier der Compiler selbst entscheiden kann, ob er die Variable im 
Ram anlegt oder ob ein Register frei ist, die er als Laufvariable nutzen 
kann.

Dennoch mag ich das nicht (warum auch immer) und habe in einer Funktion 
/ Methode lieber ein für die gesamte Funktion gültige Variable i.

Im Falle von Arduino finde ich (sorry) void loop() fürchterlich, wird 
diese doch in einer function main eben in der Schleife aufgerufen. 
Inhalte lokaler Variablen gehen hier logischerweise verloren und sie 
müssen alle static gemacht werden oder sind global.

Aus diesem Grund, wenn du dir das erste Demo genau ansiehst, mache in in 
void loop genau das, was ich mit .c oder .cpp Sourcen auch mache, meine 
"loop" ist in eine Endlosschleife while(1) { code } eingebunden so dass 
die void loop niemals verlassen wird. Genau so, wie ich das im 
Embedded-Bereich eben mache, wenn ich das ausserhalb von Arduino mache.

Deine Einwände habe ich "in mich aufgenommen" und werde das so 
überdenken. Ein
1
const uint16_t temp = ntc_gettemp(ntc1.read());
funktioniert in deiner void loop() nur deshalb, weil diese Funktion vom 
Arduino-Framework permanent neu aufgerufen wird und in die loop immer 
wieder neu eingetreten wird.
Ich werde das so, den Auszubildenden auch mitteilen. Dieses Vorgehen ist 
aber AUCH eines der Gründe, weshalb mir Arduino nicht soooo sonderlich 
gut gefällt und ich verwende dann Dinge, wie ich sie auch in reinem C 
oder C++ verwende.

Im Falle des textnvalues habe ich mich entschlossen das ganz fallen zu 
lassen und in den Beispielprogrammen zu den Libraries, an denen Ausgaben 
gemacht werden, egal ob auf Displays oder auf UART, mein abgespecktes 
printf .... namentlich my_printf einzusetzen. Die Demos müssen demnach 
einen Zugriff auf diese Library my_printf haben (auch wenn ich weiß, 
dass man unter C++ - Arduino ist ja nichts anderes - eigentlich cout 
verwendet).

Grundsätzlich bin ich der Meinung, dass C++ auf Leistungsschwachen 
Mikrocontrollern wie bspw. AVR oder in meinem Falle jetzt CH32V003 ein 
C++ zu viel Overhead hat und deshalb diese Chips doch besser mit C 
bedient sind. C++ setze ich auf PC (in Verbindung mit QT5 ein) oder auf 
leistungsstarken Mikrocontrollern ab STM32F4 oder auch H7.... ein- 
zweimal auch auf einem STM32F030CCt (hat aber wenig RAM) und einem 
STM32F103CCT (schon eher, aber alt). Die haben dann wenigstens 256 kByte 
Flash und der Overhead von C++ ist hier zu verkraften.

Wahrscheinlich treffe ich Deine Meinung nicht, aber ich denke, man darf 
auch unterschiedlicher Meinung sein. 2 hochinteressierten Lehrlingen 
(aber noch nicht weit fortgeschritten) habe ich die unterschiedlichen 
Realisierungsweisen gezeigt und deine - zugegeben sehr profesionellen - 
Äußerungen haben sie nicht auf Anhieb verstanden.

Zur Schaltung, weil hier auch manche (nicht in diesem Forum) angemerkt 
haben, dass die Resetschaltung hierfür "befremdlich" aussieht:

Der CH32V003 hat eine eigene Bootloader-Section, die NICHT in den 
Firmwareflashbereich hereinragt. Somit sind die vollen 16384 Byte Flash 
für die Firmware verfügbar. Die Bootloader-Section ist 1920 Byte groß 
und wird, wenn die Optionbytes gesetzt sind, bei einem PowerOn 
angesprungen. Und nur bei einem PowerOn. Für meine Schaltung ist das 
"dämlich", weil ein Resetimpuls an nrst zwar das Userprogramm neu 
startet, aber NICHT in den Bootloader springt. Aus diesem Grund habe ich 
ein einfaches PushPull-Register gebaut, das dem V003 kurzfristig die 
Spannung wegnimmt und somit den gesamten Chip neu startet und in den 
Bootloader springt (wenn ein Impuls auf rts des CH340 Chips kommt).

Ursprünglich hatte ich hierfür einen einzelnen PNP vorgesehen gehabt. 
Dieses hatte den Nachteil, sollte die Betriebsspannung hierüber 
abgeschaltet werdeb, aber eine Peripherieelektronik an den Chip 
angeschlossen sein, es vorkommen kann, dass der V003 über einen GPIO mit 
Spannung fremdversorgt wird und der gesamte Chip nicht neu gestartet 
wird.

Im Anhang auch mein (sehr) abgespecktes printf, das ich hier auch mit 
dem Arduino verwende und mir die (unsägliche) Sache mit langen Reihen 
von Serial.print erspart

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

sehr schön das du sowas mit Lehrlingen machst. :-)
Eine kurze Nachfrage bevor ich darauf antworten möchte.
> 2 hochinteressierten Lehrlingen (aber noch nicht weit fortgeschritten)
> habe ich die unterschiedlichen Realisierungsweisen gezeigt und deine -
> zugegeben sehr professionellen - Äußerungen haben sie nicht auf Anhieb
> verstanden.
Ging es dabei um die Funktionsparameter oder wegen der loop() / 
while(1)?

von Ralph S. (jjflash)


Lesenswert?

die Funktionsparameter haben sie nicht verstanden, die loop nach 
Erklärung, dass diese Funktion in einer nicht sichtbaren funktion main 
in einer endlosschleife aufgerufen wird:
1
int main(void)
2
{
3
  loop();
4
}

und dass hier loop nur eine normale Funktion aus Sicht von C++ ist, die 
eben lokale Variable wieder "vergißt" wenn sie nicht static sind.

:-) hier war dann "Erklärungsbedarf", dass es außerhalb von Arduino ohne 
eigenes zutun keine Funktion loop gibt und dass die Funktion, die in 
einem Programm beim Start des Programms "main" heißt.

Auch wenn dich das vielleicht ärgert, einer meinte in der Art: "wozu 
braucht man dann noch Arduino" (ich habe meine Toolchain gezeigt).

Meine Antwort war, dass es für Arduino eine Unmenge an fertigen 
Beispielen gibt und der Einstieg sehr schnell ist und ein installieren 
einer Toolchain nicht notwendig ist. Einstecken und geht!

Für Funktionsparameter:
Ich bin erst einmal froh, dass, zumindest einige, den Unterschied 
zwischen call by reference und call by value verstehen!

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

aus lauter Jux und Dollerei habe ich jetzt mein my_printf und v003colpos 
auf avr losgelassen und prompt funktioniert es nicht, weil ich type int 
verwende (und die auch als 32-bit behandle), die aber auf avr nur 16 bit 
lang sind. eine explizite angabe von int32_t für alle bisher int angaben 
macht my_printf und v003colpos auch mit avr kompatibel.

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Grundsätzlich bin ich dankbar für
> die Arduino-Sichtweise (und ich überdenke meine Ansätze, auch wenn ich
> deine Meinung oder Sichtweise nur teilweise teile).
>
> Man merkt mir auch an, dass ich bisweilen sehr "oldschool" unterwegs bin
> und mich manchen Dingen (leider) hartnäckig verschließe, auch wenn sie
> ihre Gründe haben und bisweilen besser sind.
>
> Globale Variable lassen sich nicht immer vermeiden, aber dennoch
> versuche ich sie so wenig wie möglich zu verwenden.

Übrigens: Ein paar der syntaktischen Eigenheiten der Arduino-API sind 
der Kompatibilität mit Processing geschuldet. Mit Processing kann man 
z.B. Daten vom Arduino Visuallisieren oder eine einfache GUI erzeugen, 
mit der man die Arduinos steuern kann.
Processing ist eigentlich Java und nur bedingt kompatibel mit der C++ 
Seite von Arduino. Aber man hat eine gewisse Kompatibilität wie z.B.
1
 boolean

eingeführt, obwohl es in C++ eigentlich
1
 bool

ist

https://www.arduino.cc/education/visualization-with-arduino-and-processing/

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

Lokale vs. globale Variablen. Ja man sollte wenn immer möglich lokale 
vorziehen. Nur in der Mainloop macht das für mich keinen Sinn, wenn sie 
static sein müssen. Dann kann man sie auch gleich global machen.

> Natürlich verstehe ich das Anlegen lokaler Variable innerhalb des Codes, bspw.
>
1
> for (int i = 0; i< 10; i++)
2
>
> Weil hier der Compiler selbst entscheiden kann, ob er die Variable im
> Ram anlegt oder ob ein Register frei ist, die er als Laufvariable nutzen
> kann.

Hier verstehe ich dann wiederum nicht, warum du i nicht immer lokal für 
for() machst. Das ist sehr fehlerträchtig.
Gut, die Marotte wirst du wohl nicht mehr rausbekommen. :-)  :-)

Kommen wir zur Arduino loop. Ich denke hier liegt ein großes 
Missverständnis vor.

Die Bedeutung von setup() und loop() ist eigentlich, für mich, mehr 
eindeutig wie der klassische Aufbau mit main und while. Aber gut, ist 
Ansichtssache. Geschenkt. Kommen wir zum Kern.

In deiner demo.ino gehört alles zwischen
loop() {
und
while(1)
in setup().
Dann ist die überflüssige while(1) in der loop weg. Ansonsten ist deine 
loop-while Programmierweise kurz gesagt wirklich etwas eigenartig und 
würde ich Lehrlingen auch so nicht zeigen, weil es nirgends so steht und 
ehrlich gesagt auch keinen Sinn macht.

Lehrlinge:
> und dass hier loop nur eine normale Funktion aus Sicht von C++ ist, die
> eben lokale Variable wieder "vergißt" wenn sie nicht static sind.

Eine non static lokale Variable in while(1) wird von der Wirkungsweise 
genauso vergessen wie in loop. Entweder wird sie immer neu initialisiert 
oder bekommt einen Zufallswert zugewiesen. Das heißt auch in while(1) 
muss man static verwenden, wenn der Wert erhalten bleiben soll.

Wenn sie call by reference vs. call by value verstanden haben, dann sind 
sie doch schon einen großen Schritt weiter.

Wenn dich setup() und loop() stören, dann musst du diese nicht 
verwenden. Du kannst in der Arduino IDE genauso gut
1
int main() {
2
  ...
3
  while(1) 
4
  {
5
   ...
6
  }
7
}
verwenden. Und wenn du sowieso eigene Libs schreibst, dann fällt damit 
auch der gesamte Basis Overhead vom Framework weg. Du bist damit auf 
dich mit allen allein gestellt und nutzt die IDE nur noch zum 
einfacheren flashen des Controllers.

> Auch wenn dich das vielleicht ärgert, einer meinte in der Art: "wozu
> braucht man dann noch Arduino" (ich habe meine Toolchain gezeigt).

Keine Sorge, dass ärgert mich nicht. Ich kann mit und ohne Arduino IDE 
programmieren.

Genau das meinte ich mit #defines
1
// Farbzuordnungen der EGA-Farben zu den Farbnummern
2
  #define black           0
3
  #define blue            1
4
  #define green           2
5
  #define cyan            3
Das ist in C++ alles Datentyp sicher zur Compile Time mit
constexpr uint8_t farbe {1};
Oder du hast dich noch nicht entschieden ob du C oder C++ programmierst. 
:-)

Deine #define Konstanten cnt_speed bis yofs wären bei mir auch constexpr 
… Compile Time Konstanten mit Datentyp.
Irgendwo hatte ich noch gesehen das du bool selbst definierst. Muss du 
nicht, bringt die Toolchain schon mit.

Damit höre ich auch auf an der Stelle. Sonst schreiben wir Ellenlange 
Seiten über jedes Detail und hilft niemanden weiter. Ich wünsche dir auf 
jeden Fall jederzeit interessierte Lehrlinge, weil das ist etwas schönes 
wenn jemand zuhören möchte und auch mit Fragen bohrt wo man erstmal 
überlegen muss. In diesem Sinne, bleib so nett.

von Ralph S. (jjflash)


Lesenswert?

Grüß Dich Veit,

erstmal Danke für den Kommentar. Nur um evtl. Mißverständnisse 
auszuräumen, ich mache mit Arduino eigentlich (und nicht nur eigentlich) 
nichts.

Ich bin - gebe ich zu - schon ein Verfechter von klassisch C oder C++. 
Mit Arduino bin ich derzeit nur deshalb beschäftigt, um zum einen 
aufzuzeigen, dass mit meinem Bootloaderboard Arduino genauso gut umgehen 
kann, wie mir "normalem" C oder auch C++.

Von daher bin ich "nur" damit beschäftigt, die Dinge, die in meiner 
Toolchain funktionieren nach Arduino zu portieren, weil der Core für den 
V003 aus meiner Hinsicht unzureichend ist.

Hier ist es dann etwas mühselig, die hardwarenahen Dinge mittels Arduino 
zu realisieren. Was "state of the art" in und unter Arduino ist, weiß 
ich zugegebenermaßen nicht.

Ich weiß nicht mehr wer es war (könntest sogar Du gewesen sein), müßte 
ich nachlesen im Thread, der anmerkte, dass bei einer eigenen seriellen 
Klasse ein Arduinoanwender erwarten würde, dass diese Klasse den Stream 
von Arduino erbt (und somit auch print, println, write etc.).

Also habe ich den Stream in dieser Klasse geerbt. Mache ich dann auch 
mit den Displays dann so.

Deine Anmerkungen zu setup und loop ... und wie das in Arduino gewollt 
ist werde ich dann tatsächlich so auch dann in den Demos übernehmen:

Veit D. schrieb:
> In deiner demo.ino gehört alles zwischen
> loop() {
> und
> while(1)
> in setup().
> Dann ist die überflüssige while(1) in der loop weg. Ansonsten ist deine
> loop-while Programmierweise kurz gesagt wirklich etwas eigenartig und
> würde ich Lehrlingen auch so nicht zeigen, weil es nirgends so steht und
> ehrlich gesagt auch keinen Sinn macht.

Die loop also für das verwenden, für das sie gedacht ist, alles vor 
"meiner" while ins setup setzen und ein while in der loop nicht 
verwenden. Variable dann eben static oder tatsächlich global.

Das reißt mir kein Arm (und auch kein Bein aus).

Veit D. schrieb:
> Und wenn du sowieso eigene Libs schreibst, dann fällt damit
> auch der gesamte Basis Overhead vom Framework weg.

dass die eigenen Libs geschrieben werden ist leider eine Notwendigkeit, 
weil ansonsten bestimmt Dinge mit V003 und Arduino sonst nicht 
funktionieren, leider!

Hier dann einfach mal die Frage: Hast du mit V003 unter Arduino schon 
gewerkelt? Wenn ja :-) hätte ich ja glatt einen Ansprechpartner, wie man 
etwas zum Laufen bekommt OHNE etwas neu schreiben zu müssen, das Rad muß 
ja nicht immer wieder neue erfunden werden.

Veit D. schrieb:
> Genau das meinte ich mit #defines// Farbzuordnungen der EGA-Farben zu
> den Farbnummern
>   #define black           0
>   #define blue            1
>   #define green           2
>   #define cyan            3
> Das ist in C++ alles Datentyp sicher zur Compile Time mit
> constexpr uint8_t farbe {1};

Das hier ist natürlich eine gute Anmerkung. Im Sinne der Farbzuordnung 
hatte ich mir tatsächlich ein constexpr überlegt, auch wegen der wie du 
absolut richtig anmerkst, der Datentypsicherheit wegen. Hier sieht man 
auch sehr deutlich an, dass das Original tatächlich ein C-code (und kein 
C++) ist. Ich habe noch nicht evaluiert, ob ein constexpr uint8_t farbe 
zusätzlichen Speicherplatz wegnimmt oder nicht und werde das einfach 
einmal testen. Für den Fall dieser Farbzuordnungen schätze ich jedoch 
die Gefahr eines falschen Datentyps eher als gering ein, testen werde 
ich des dennoch.

Veit D. schrieb:
> Oder du hast dich noch nicht entschieden ob du C oder C++ programmierst.
> :-)

Veit D. schrieb:
> Oder du hast dich noch nicht entschieden ob du C oder C++ programmierst.
> :-)

Veit D. schrieb:
> Oder du hast dich noch nicht entschieden ob du C oder C++ programmierst.
> :-)

Na ja, ich habe mich schon entschieden und die Antwort ist: beides. Ich 
mache das vom Target abhängig, normalerweise würde ich jedoch für einen 
so kleinen Controller wie den V003 eben C bevorzugt nehmen (genauso wie 
für AVR) und für die größeren dann eben C++ oder vorzugsweise für 
PC-Anwendungsprogramme.

Ich tu mich immer noch schwer damit, das die vor Jahrzehnten schmerzhaft 
gelernten C++ (damals unter Borland C++) Dinge auch auf Mikrocontroller 
anzuwenden (mit meinem ersten Controller MCS-48 wäre das undenkbar 
gewesen), einfach des größeren Resourcenbedarfs wegen.

Bei größeren Controllern, STM32F4 aufwärts habe ich dann dieses Problem 
nicht mehr, weil da dann genug von allem da ist.

Man möge mir meine Ansichten verzeihen.

Aber dennoch ein großes Dankeschön für die Anmerkungen - und wie du 
hoffentlich gelesen hast - werde ich dann eben ein paar Dinge doch so 
machen wie du da gesagt hast, einfach weil ich in der "Arduino-Welt" 
nicht wirklich zu Hause bin (die Demos zu den Hardware-Libraries werden 
es dir danken).

Veit D. schrieb:
> In diesem Sinne, bleib so nett.

Schmunzeln muß, du weißt doch: "Nett ist die kleine Schwester von 
sch****" , nein ich gehe mal davon aus, das das so gemeint war, wie du 
das geschrieben hast.

Einen Gruß an Dich,
Ralph

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

alles gut und schön das es keine Missverständnisse gibt.  :-)

Wegen deiner Frage ob ich einen CH32V003 habe, da muss ich leider 
passen. Bestimmt ein interessantes Teil, würde dann aber zu viel für 
mich mit allen anderen Dingen. Ich bewundere daran, an so einem völlig 
anderen fremden Controller, dein Durchhaltevermögen. Ehrlich. Bei allen 
anderen bspw. neuen AVRs gibt es immer hier und da jemanden der helfen 
könnte. Mit kleinen STM32 wollte ich einmal anfangen, dazu kam es aber 
nie.

Eine constexpr Variable wird auf jeden Fall zur Compile Time "ersetzt" 
und belegt keine zusätzlichen Ressourcen. Kann auch ein Rückgabewert 
einer constexpr Funktion sein, allerdings nur, wenn dabei auch alles zur 
Compile Time konstant ist und nicht nur "gefühlt" konstant. Zur Laufzeit 
berechnet und mit const deklariert zählt nicht dazu. Die constexpr 
Funktion funktioniert dennoch, man spart damit jedoch keine Ressourcen, 
wenn nicht alles richtig konstant ist. Das findet man durch testen 
heraus. Ich möchte dich jedoch nicht in die C++ Ecke drängen. Das 
entscheidest du. Es sollte einem nur bewusst sein, dass Arduino C++ ist. 
Ob man das alles nutzt steht auf einem anderen Blatt. Mach das worin du 
dich wohl fühlst, dann profitieren auch deine Lehrlinge davon.

Auf eines kannste dich bei mir verlassen. Ich meine alles so wie 
schreibe. Auch wenn manchmal hier und da meine Leidenschaft der 
Überzeugungsarbeit mit mir durch gehen sollte. :-) Gute nachvollziehbare 
begründete Gegenargumente können mich allerdings stoppen.

In diesem Sinne Grüße zurück,
Veit

von Alexander (alecxs)


Lesenswert?

Veit D. schrieb:
> Kommen wir zur Arduino loop. Ich denke hier liegt ein großes
> Missverständnis vor.

Kann mir auch vorstellen dass es mit dem Multitasking im FreeRTOS nicht 
mehr hinhaut (wenn es sowas beim CH32V003 gibt)

Senf

https://copilot.microsoft.com/shares/m3DxodnxxTu8k9eSLDAcL

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

> https://copilot.microsoft.com/shares/m3DxodnxxTu8k9eSLDAcL

Da hat die Microsoft KI was unterschlagen. "serialEventRun" in der loop 
kann schon wichtig sein.

Auf meiner Platte findet sich in 
.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino
1
#include <Arduino.h>
2
3
// Declared weak in Arduino.h to allow user redefinitions.
4
int atexit(void (* /*func*/ )()) { return 0; }
5
6
// Weak empty variant initialization function.
7
// May be redefined by variant files.
8
void initVariant() __attribute__((weak));
9
void initVariant() { }
10
11
void setupUSB() __attribute__((weak));
12
void setupUSB() { }
13
14
int main(void)
15
{
16
  init();
17
18
  initVariant();
19
20
#if defined(USBCON)
21
  USBDevice.attach();
22
#endif
23
  
24
  setup();
25
    
26
  for (;;) {
27
    loop();
28
    if (serialEventRun) serialEventRun();
29
  }
30
        
31
  return 0;
32
}

Bei den "Cören" für den ESP32 oder dem RP2040 wird das dann noch 
aufwändiger. Dort ist oft noch die Funktion "yield" eingebaut, die von 
manchen Treibern als zyklischer Aufruf benötigt wird.

von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> Eine constexpr Variable wird auf jeden Fall zur Compile Time "ersetzt"
> und belegt keine zusätzlichen Ressourcen. Kann auch ein Rückgabewert
> einer constexpr Funktion sein, allerdings nur, wenn dabei auch alles zur
> Compile Time konstant ist und nicht nur "gefühlt" konstant. Zur Laufzeit
> berechnet und mit const deklariert zählt nicht dazu. Die constexpr
> Funktion funktioniert dennoch, man spart damit jedoch keine Ressourcen,
> wenn nicht alles richtig konstant ist. Das findet man durch testen
> heraus. Ich möchte dich jedoch nicht in die C++ Ecke drängen.

:-) du drängst mich nicht in die Ecke... da bin ich schon (zumindest 
immer wieder). Allerdings lernt man nie aus, dass gcc constexpr 
"wegoptiomiert" wenn alles tatsächlich konstant ist, wußte ich, dass das 
unter Arduino mit avr-g++ auch so ist wußte ich nicht zu 100% ... Ich 
habe es ausprobiert und es ist tatsächlich wie du sagst (unter riscv-gcc 
auch), ergo, werde ich versuchen, bei Portierungen von C nach C++ etwas 
"sorgfältiger" zu sein, was solche Dinge angeht.

Veit D. schrieb:
> Auch wenn manchmal hier und da meine Leidenschaft der
> Überzeugungsarbeit mit mir durch gehen sollte. :-)

lachen muß (sorry), dann überzeuge mich einmal, anstelle von C oder C++ 
bei Microcontrollern Arduino zu verwenden anstelle einer Toolchain (wie 
bspw. eine eigen eingerichtete oder auch einfach nur avr-gcc, libopencm3 
bei stm32 oder das ch32fun framework).

Mein Gegenargument für bspw. ch32v003 (weil ich das hier gerade belegen 
kann) ist, dass ein Programm, welches im Code identisch ist (einfach 
C-Code ins Arduino Sketch kopiert) mit dem Framework 3192 Byte belegt, 
mit Arduino 9178 Byte!

Die Codegröße schreckt mich häufig ab (Verarbeitungsgeschwindigkeit 
manchmal auch).

Okay, ich habe mittlerweile - auch durch Azubis - gelernt, dass die 
Einstiegshürde niedrig ist, dass es etwas braucht, was schnell 
funktioniert. Es kein Setup benötigt. Spricht dafür.

Aber wenn man auch anderst kann?

von Alexander (alecxs)


Lesenswert?

Christoph M. schrieb:
> Da hat die Microsoft KI was unterschlagen.

Hab's gelöscht.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

yield() gibt es nicht nur in fremden Cores, yield() gibt es schon immer 
und wird in delay() aufgerufen.

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

ich denke ich muss nochmal darauf eingehen. Auch auf die Gefahr das du 
es doch schon weißt. :-) Oder für andere Mitleser. "Arduino" ist keine 
eigene Sprache oder sowas wie man mancher Ortens traurigerweise lesen 
muss. Das Framework ist ganz normales C/C++ und stellt viele Funktionen 
bereit, damit die Nutzbarkeit und damit die Einstiegshürde niedrig wird. 
Das haben deine Lehrlinge schon richtig erkannt. Arduino nutzt auch 
keine eigens geschriebene Toolchain, sie nutzen einen ganz normalen 
avr-gcc 7.3.0 mit eingestellten Sprachstandard C++11. Den kann man 
locker auf C++14 und auch auf C++17 einstellen. Man darf nur keine 
komplette C++17 Unterstützung erwarten. Den 'auto' Datentyp in 
Range-based for loop verwenden zu können ist nett. Mit C++11 ist das 
noch nicht möglich. 
https://www.gnu.org/software/gcc/projects/cxx-status.html
Worin sich die Gimmicks eines avr-gcc von anderen xyz-gcc unterscheiden 
ist die avr-LibC. Da hat man Dinge wie Range für switch-case, was man in 
anderen Toolchains nicht hat. Das sind dann allgemeine Unterschiede der 
Toolchains, die nichts mit Arduino zu tun haben, was auch gut so ist. 
;-)

> lachen muß (sorry), dann überzeuge mich einmal, anstelle von C oder C++
> bei Microcontrollern Arduino zu verwenden anstelle einer Toolchain (wie
> bspw. eine eigen eingerichtete oder auch einfach nur avr-gcc, libopencm3
> bei stm32 oder das ch32fun framework).

:-) Ich muss und möchte dich nicht überzeugen. Mir ging es vorwiegend 
darum, wenn man Arduino verwendet, dass man es richtig verwendet. Also 
nicht die loop() verschandelt und setup() ungenutzt lässt. :-)

> Mein Gegenargument für bspw. ch32v003 (weil ich das hier gerade belegen
> kann) ist, dass ein Programm, welches im Code identisch ist (einfach
> C-Code ins Arduino Sketch kopiert) mit dem Framework 3192 Byte belegt,
> mit Arduino 9178 Byte!

Das ist ein berechtigtes Argument. Das ist vermutlich dem Framework 
geschuldet. Also der Anpassung an alle Cores ohne Code Kompatibilität zu 
verlieren. Was ja auch der Sinn von Arduino ist. Ein nacktes setup + 
loop belegt schon Speicher, kommt noch Serial dazu, steigt es schon 
stark an. Das rührt daher das unter der Haube schon viel Code ausgeführt 
wird um Grundeinstellungen der Hardware vorzunehmen. Bsp. werden Timer 
voreingestellt für millis, delay und analogWrite, damit dann zur 
Laufzeit nichts/wenig umkonfiguriert werden muss. Der Komfort kostet 
dann Speicher. Jetzt kann man das speziell für seine Hardware natürlich 
auf ein Minimum reduzieren. Muss dann aber bspw. zusätzliche init/begin 
Funktionen zur Verfügung stellen. Bei Serial kommt noch die Vererbung 
dazu, die da scheinbar nicht so optimal ist. Allerdings hat wohl damals 
von Arduino.cc niemand geahnt, dass Arduino für 
Controller-Speicher-Miniaturen verwendet wird. :-) Arduino fing zwar 
laut meines Wissens mit einem ATmega168P an, der Durchbruch begann 
jedoch mit dem ATmega328P auf dem bekannten UNO R3.

> Aber wenn man auch anders kann?
Wenn man anders kann, dann kann man es anders machen. Ich sage einmal 
so. Was du unter Haube wie in deinem Core programmierst ist deine Sache. 
Für den Arduino User ist nur wichtig, wenn man den Anspruch hat 
kompatibel zu bleiben, dass das Interface deiner Funktionen/Methoden dem 
entspricht, was in der Arduino Doku steht. Was anderes interessiert den 
gemeinen Arduino User nicht. :-) Alle anderen schauen ggf. unter die 
Haube die mehr wissen wollen.

Betrachten wir es einmal anders. Auf der Welt schreiben bestimmt 
Millionen Programmierer immer wieder fast den gleichen Code für USART 
zum Bsp.. Ist das nicht vergeudete Zeit? Jetzt kann man bestimmt Arduino 
in einem anderen Licht betrachten, die es geschafft haben vieles, trotz 
unterschiedlichster Hardware, auf einen gemeinsamen Nenner 
zusammenzuführen, damit eben nicht jeder bei Null anfangen muss. Dabei 
bleiben fast unweigerlich Ressourcen liegen. Tja, ist eben so. Ich 
meine, wenn man die Entwicklung von Arduino sieht, wieviele Leute ihren 
eigenen Core beitragen usw., dann ist das schon eine Nummer. Wenn man 
aus heutiger Sicht das Framework programmieren würde, würde es bestimmt 
anders aussehen, weil paar Aspekte anders einfließen würden, wie zum 
Bsp. Speicher sparen. Ich muss Arduino.cc nicht schön reden, da läuft 
auch nicht alles rund, möchte jedoch einen Grund erkennen warum das so 
ist wie es ist.

Was du noch machen könntest, SpenceKonde 
(https://github.com/SpenceKonde) unterstützt mit seinen Cores ATtinys 
die wenig Speicher haben. Hier könntest du einmal reinschauen wie er das 
gemacht hat um Ressourcen zu sparen. Er arbeitet viel mit Makros und C 
und Assembler und lehnt C++ regelrecht ab, was Schade ist.

Habe ich schon wieder zu viel getippt. ;-)

Ruhiges Wochenende wünsche ich …

von Christoph M. (mchris)


Lesenswert?

Veit D. schrieb:
> Controller-Speicher-Miniaturen verwendet wird. :-) Arduino fing zwar
> laut meines Wissens mit einem ATmega168P an

Atmega8
1
 In 2005, Massimo Banzi, along with David Mellis (an IDII student at the time) and David Cuartielles, added support for the cheaper ATmega8 microcontroller to Wiring. Then they forked (or copied) the Wiring source code and started running it as a separate project, called Arduino.

https://arduinohistory.github.io/#the-formation-of-arduino

von Veit D. (devil-elec)


Lesenswert?

Geschenkt. :-)

von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> ch denke ich muss nochmal darauf eingehen. Auch auf die Gefahr das du
> es doch schon weißt. :-) Oder für andere Mitleser. "Arduino" ist keine
> eigene Sprache oder sowas wie man mancher Ortens traurigerweise lesen
> muss. Das Framework ist ganz normales C/C++

Das wußte ich natürlich schon, wie in vergangenen Threads bereits 
geschrieben, bin ich ja gerade dabei, Arduino-Libraries für CH32V003 zu 
schreiben und dann sieht man in den .c und .cpp Dateien schon deutlich, 
was das ist ( :-) und ganz Blinde könnten das schon ander Dateiextension 
.cpp erkennen). In den Libraries dich speziell für den V003 mache bin 
ich permanent am überlegen, ob ich daraus eine Klasse mache oder nicht 
und ob das eine eigenständige Library wird oder nicht.

Bsp. Auszubildende sollen / müssen Textdisplay in Betrieb nehmen 
(HD44780) und stellen fest: Originaldemo funktioniert leider (wegen 
Timingsachen am Clock) nicht. Also schreibe ich eine extra Library mit 
denen die auch sofort umgehen konnten.

Gehen wir einen Schritt weiter, weil in einem anderen Thread scheinbar 
schon der Unterschied zwischen einem OLED (Grafik) Display und einem 
Textdisplay nicht sofort klar war, dass es Displayadapter für HD44780 
mit I2C Anschluß gibt. Also bin ich momentan dabei, einen I2C 
Displayadapter für Arduino CH32V003 zu machen. Ehrlichkeitshalber muß 
ich sagen, dass ich die Funktionalität erst einmal in reinem C gemacht 
habe und jetzt portiere ich das nach C++ / Arduino. Hier stellt sich 
dann schon die triviale Frage: Packe ich das in eine kompakte Library 
mit evtl. unterschiedlichen Klassen, die zum einen ein Display parallel 
anfährt und die andere Klasse das mit I2C macht. Packe ich das in eine 
Klasse, bei der über den Konstruktor entschieden wird, welche 
Schnittstelle das Display hat? Prinzipiel: Nutze ich meine bereits 
erstellte I2C auf Hardware-Basis (weil der Core von V003 fehlerhaft ist) 
oder verwende ich lieber ein Software - Bitbanging um das an anderen 
Pins als den I2C Hardwarepins zu legen ... oder mache ich beides und 
untescheide wieder mit dem Konstruktor? Ganz "schräg" könnte ich noch 
sagen: Hey, ich mache das als Demo für den I2C-Bus.

Hier habe ich so überhaupt keine Ahnung davon, was ein Arduino User 
gerne hätte. Meine eigene "Strategie" ist, für jedes "Problem" seine 
eigene Source zu haben (zumindest mal im Embeddedbereich). Auf PC oder 
großen System packt man das in eine Datei, vllt. sogar in eine sehr 
mächtige Klasse, weil man eh genügend Resourcen hat.

Veit D. schrieb:
> was in der Arduino Doku steht.

Es ist nicht nur wichtig was in der Arduino Doku steht, sondern 
grundsätzlich (und da muß ich mich daran machen) muß man seine 
Funktionen dokumentieren, damit andere und man selbst später damit 
umgehen kann.

Veit D. schrieb:
> Jetzt kann man bestimmt Arduino
> in einem anderen Licht betrachten, die es geschafft haben vieles, trotz
> unterschiedlichster Hardware, auf einen gemeinsamen Nenner
> zusammenzuführen, damit eben nicht jeder bei Null anfangen muss.

Das größere Problem ist doch eher, dass man versucht, alles irgendwie 
"Arduino-kompatibel" zu machen, auf biegen und brechen. Für jede neue 
Plattform oder für jede neue Controllerfamilie wird ein neuer Core 
erstellt.... und dieser ist erst einmal unvollständig und häufig auch 
noch buggy (leider). Aber das Produkt muß ja schnell auf den Markt.

Im Falle von AVR ist das im Laufe der Jahre gewachsen, aber man sieht 
diesem Teil deutlich an, dass es ursprünglich eben für ATmega gemacht 
war.

Für mich als Elektroniker sieht Arduino in manchen Dingen "befremdlich" 
aus, ein "digitalWrite" ... herjeh... und dann auch noch eine Angabe von 
"HIGH" und "LOW"... anstelle von 1 und 0 (ich weiß, dass ich auch 1 und 
0 angeben kann).

Aber das ist eben der Lauf der Dinge, wie heute Sachen verstanden werden 
(das ist jetzt keine Wertung von positiv oder negativ). Tatsache ist 
aber auch, dass mit Arduino grundsätzlich fast kein Hardwareverständnis 
gefördert wird (leider)

Herjeh, :-) ich wollte mich nicht darüber auslassen über ein für und 
wider von Arduino... (und hab hier schon zu viel geschrieben).

Veit D. schrieb:
> Arduino fing zwar
> laut meines Wissens mit einem ATmega168P an, der Durchbruch begann
> jedoch mit dem ATmega328P auf dem bekannten UNO R3.

Arduino fing mit einem Board namens "Arduino Board Serial" an, das noch 
mit einer RS232 (anstelle von USB) ausgestattet war und einen ATmega8 
als Controller hatte (das war im Jahr 2005). Diesem folgen Diecimila 
2007 mit ATmega168 und USB... und dann gab es einige Platinen im r3 
Format.

Veit D. schrieb:
> Was du noch machen könntest, SpenceKonde
> (https://github.com/SpenceKonde) unterstützt mit seinen Cores ATtinys
> die wenig Speicher haben. Hier könntest du einmal reinschauen wie er das
> gemacht hat um Ressourcen zu sparen.

Da habe ich vor Jahren schon reingesehen gehabt. Ehrlich erschließt es 
sich mir nicht, auf solch kleinen Controllern Arduino machen zu wollen. 
Für die neueren ATtiny 0/1/2 series gilt das nicht, die sind ja oft min. 
so leistungsstark wie ein Mega... :-) den ATtiny1612 finde ich bspw. gar 
nicht so schlecht.

Veit D. schrieb:
> Habe ich schon wieder zu viel getippt. ;-)

Ich habe auch zu viel geschrieben... und wünsche dir ebenfalls ein 
schönes Wocheende


PS: und ich ... bastel jetzt an einer anderen Baustelle die mir am 
Herzen liegt und die lange brach lag: meine Webseite ... und damit ich 
es nicht ganz verlerne, Seite mit JavaScript: NTC - LookUp Table 
Generator entsteht ... ähnlich wie es vor einiger Zeit sebulli gemacht 
hat ... er online und ich als konsolenprogramm ... :-) beim generierten 
Code der Tabelle kommen wir zur gleichen Tabelle, was nicht wundert, 
weil die benutzten Mechanismen sind dieselben. Bei der Interpolation 
habe ich dort etwas "gespickelt", gebe ich zu ... und habe diese 
Interpolation übernommen, weil sie effizienter ist als meine. Jetzt... 
habe ich mich entschlossen, meine Webseite um eben auch einen 
NTC-LookUp-Table Generator zu erweitern, die erste Version siehst man 
hier ... und wenn man sich den JavaScript Code anschaut, sieht man bei 
mir dann sehr deutlich, dass das einmal C war : 
https://www.jjflash.de/ntc_table_v2.html

von Nemopuk (nemopuk)


Lesenswert?

Veit D. schrieb:
> Du kannst in der Arduino IDE genauso gut ... verwenden.

Nein, kann er nicht. Weil damit die unsichtbare Initialisierung des 
Frameworks verloren geht.

Dir ist das klar, aber anderen womöglich nicht. Außeredem wir sind ja 
gerade dabei, den ordentlichen Weg zu lehren. Wenn schon Arduino, dann 
richtig.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Veit D. schrieb:
> Geschenkt. :-)

Übrigens, die Arduino-API hieß ursprünglich "Wiring".
Es lohnt sich, hier mal die ersten zwei Seiten zu lesen.
1
Have you ever wondered where those commands come from?
2
3
Probably one of the most distinctive things, that is widely known and used today by Arduino users in their sketches, is the set of commands I created as the language definition for Wiring.
4
5
    pinMode()
6
    digitalRead()
7
    digitalWrite()
8
    analogRead()
9
    analogWrite()
10
    delay()
11
    millis()
12
    etc

https://arduinohistory.github.io

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Arduino Nutzer wollen nichts, Arduino Nutzer nehmen (was immer man 
ihnen vorsetzt)

Ein
Arduino Nutzer

von Veit D. (devil-elec)


Lesenswert?

Christoph M. schrieb:
> Veit D. schrieb:
>> Geschenkt. :-)
>
> Übrigens, die Arduino-API hieß ursprünglich "Wiring".
> Es lohnt sich, hier mal die ersten zwei Seiten zu lesen.

Mir fiel dann ein, ich hatte das vor Jahren schon gelesen, die 
Geschichte um Wiring und den Streit darum.

von Veit D. (devil-elec)


Lesenswert?

Alexander schrieb:
> Arduino Nutzer wollen nichts, Arduino Nutzer nehmen (was immer man
> ihnen vorsetzt)
>
> Ein
> Arduino Nutzer

Du sprichst ganz klar für dich. Nicht alle sind wie du.

von Nemopuk (nemopuk)


Lesenswert?

Alternativ würde die STM32C031 ab ca. 50 Cent empfehlen. Deren Software 
ist wahrscheinlich ausgereift.

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Veit D. schrieb:
> Du sprichst ganz klar für dich. Nicht alle sind wie du.

Dito. Du bist bist extrem drin. Und ich kann ruhigen Gewissens behaupten 
ich bin schon überdurchschnittlich tief ins Framework eingetaucht, 
verglichen mit dem gemeinen Arduino Nutzer.

von Veit D. (devil-elec)


Lesenswert?

Nemopuk schrieb:
> Veit D. schrieb:
>> Du kannst in der Arduino IDE genauso gut ... verwenden.

Kannst du ordentlich zitieren? Wir sind schon viele Antworten weiter.
Worauf beziehst du dich?

von Veit D. (devil-elec)


Lesenswert?

Alexander schrieb:
> Veit D. schrieb:
>> Du sprichst ganz klar für dich. Nicht alle sind wie du.
>
> Dito. Du bist bist extrem drin. Und ich kann ruhigen Gewissens behaupten
> ich bin schon überdurchschnittlich tief ins Framework eingetaucht,
> verglichen mit dem gemeinen Arduino Nutzer.

Dann schreib nicht laufend solchen Unsinn, welche absolut unnötige 
Gegenreaktion hervorrufen. Mir macht das keinen Spass.

von Nemopuk (nemopuk)


Lesenswert?

Veit D. schrieb:
> Worauf beziehst du dich?

Auf den verlinkten Beitrag. Quelltexte zitieren funktioniert nicht, 
daher die Auslassungspunkte.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Nemopuk schrieb:
> Veit D. schrieb:
>> Du kannst in der Arduino IDE genauso gut ... verwenden.
>
> Nein, kann er nicht. Weil damit die unsichtbare Initialisierung des
> Frameworks verloren geht.
>
> Dir ist das klar, aber anderen womöglich nicht. Außeredem wir sind ja
> gerade dabei, den ordentlichen Weg zu lehren. Wenn schon Arduino, dann
> richtig.

Ich habe es rausgesucht. Du meinst

> Du kannst in der Arduino IDE genauso gut
1
int main() {
2
  ...
3
  while(1) 
4
  {
5
   ...
6
  }
7
}

Dazu musst du den gesamten Kontext der Unterhaltung zwischen Ralph und 
mir betrachten.

von Alexander (alecxs)


Lesenswert?

Ralph hat sich gefragt was der gemeine Arduino Nutzer will. Hier bin ich 
und antworte.

Sorry: Ralph

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo Nemupuk,

kleine Ergänzung. Das alleine für sich aus dem gesamten Kontext zu 
ziehen macht wirklich keinen Sinn. In der Unterhaltung ging es an dem 
Punkt darum, ob man sich generell entscheidet konform für Arduino zu 
programmieren oder die IDE nur als Programmierwerkzeug verwendet und 
ohne Framework sein eigenes Ding macht.

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

wegen Display Lib. Ja so eine Grundsatzentscheidung ist schwierig. 
Meistens wird das mittels Konstruktor Überladung gelöst. Dafür muss man 
die Parameterreihenfolge gut überlegt wählen und man kann mit 
Defaultwerten arbeiten. Die Vorliebe muss man gedanklich durchspielen.

Eine beliebte Lib für grafische Displays ist die von Oli Kraus.
https://github.com/olikraus/u8g2
https://github.com/olikraus/u8g2/wiki
Dich wird es erschlagen wenn du die anschaust. Er erschlägt alles mit 
Konstruktor überladen.
Ist bestimmt einen Blick wert. Nur ein Bsp. wegen Konstruktor.

Man kann auch eine gemeinsame Basisklasse schreiben die dann an die 
verwendete spezifische Interface Klasse vererbt wird. Dann hätte man 
unterschiedliche Konstruktoren und mehr Parameterfreiheiten. Da gibt es 
keine Vorgabe. Beim Standard HD44780 Display vielleicht nur, dass wie 
erwähnt, sowas wie lcd.print() nutzbar ist.

Wenn man zwischendurch die "Baustelle" wechselt, deine Webseite, wird 
das helfen aus dem Gedankenwald herauszukommen. Danach kommen meistens 
bessere Ideen. Glaub mir.  :-)

von Kilo S. (kilo_s)


Lesenswert?

Bisher,bin ja ebenfalls Arduino nutzer, kam ich nach kurzer Einarbeitung 
auch mit fremden "Codeschnipseln" ganz gut zurecht und habe diese 
entsprechend "Arduino gerecht" für meine PY32 zurechtgebastelt.

Drehgeber zb. 
https://www.mikrocontroller.net/articles/Drehgeber#Solide_L%C3%B6sung:_Beispielcode_in_C

War am Ende nicht wirklich schwer das umzustricken, weil Arduino eben 
für die Interrupts/Timer ect. definierte Funktionen hat.
Es ist leichter als die Einstellungen in die entsprechenden Register zu 
Schreiben, was das verstehen das Code angeht.
Was fehlt ist der Bezug zum Hintergrund, das kommt aber mit den ersten 
Problemen die sich nicht mit Hilfe eines Tutorial lösen lassen. Wenn der 
core beim Einstellen des Takt fehlerhaft ist, bleibt das schnellste 
workaround es selbst zu lernen und was eigenes dafür zu schreiben. Man 
bleibt halt leichter am Ball wenn wenigstens zwischendurch mal was ohne 
basteln läuft.

Codegröße ist echt ein Faktor, schon die Optimierungsoptionen ergeben 
teils einige KB Unterschied.

von Ralph S. (jjflash)


Lesenswert?

Moin Veit,

die u8g2 Library und auch die Displaytreiber von Adafruit (egal ob 
monochrome oder farbig) habe ich mir natürlich schon vor längerer Zeit 
angesehen und genau diese Librarys schrecken mich ab.

Der größte Vorteil dieser Treiber ist aus meiner Sicht der Dinge auch 
ihr größter Nachteil. Sie sind derart umfangreich, dass dich die 
Libraries schier erschlagen und ohne das Wiki kann man intuitiv zum 
Einstieg erst einmal gar nichts machen leider.

Natürlich ist es sehr super, wenn man ultra viele Displays unterstützt, 
aber das Inbetriebnehmen wird dadurch nicht so wirklich leichter.

Beispielsweise habe ich versucht, allerdings in C, mehrere Displays 
(farbige TFT's) in einer Source unterzubringen, was ich auch getan habe. 
Die Source ist in ihrern Einstellmöglichkeiten mittlerweile hart an der 
Grenze, was ich mir antun möchte (und ich habe das selbst geschrieben). 
Unterschiede in Farbreihenfolgen, Adressräumen (sogar bei Displays mit 
dem gleichen Displaycontroller, Serien, die eine Verdrahtung wie ein 
160x128 haben, aber ein nur ein Glas 128x128 montiert haben), 
Initialisierungssequenzen und dann möchte man das ganze ja universell 
haben in den Anschlussmöglichkeiten. Zu guter letzt dann noch SPI oder 
paralleles Interface war / ist nicht so richtig übersichtlich und zu 
guter letzt (im Falle von STM32) das ganze noch mittels DMA betreibbar 
bewegt mich dann, das ganze (auch eine meiner Baustellen) auf C++ 
umzustellen und ich erhoffe mir davon eine einfachere Handhabung.

Aber wie gesagt ist das auch eine weitere Baustelle, :-) mit dem 
CH32V003 dachte ich eigentlich, ich mache etwas mit einem schönen Anfang 
und einem schönen Ende und bin da dran kleben geblieben (egal ob Arduino 
oder Plain-C) und werkel daran schon länger als ich es mir so gedacht 
hatte.

Im Falle eines Textdisplays mit I2C Adapter denke ich, ich mache eine 
extra Lib dafür.

Veit D. schrieb:
> Wenn man zwischendurch die "Baustelle" wechselt, deine Webseite, wird
> das helfen aus dem Gedankenwald herauszukommen. Danach kommen meistens
> bessere Ideen. Glaub mir.  :-)

:-), ich weiß !

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Aber wie gesagt ist das auch eine weitere Baustelle, :-) mit dem
> CH32V003 dachte ich eigentlich, ich mache etwas mit einem schönen Anfang
> und einem schönen Ende und bin da dran kleben geblieben (egal ob Arduino
> oder Plain-C) und werkel daran schon länger als ich es mir so gedacht
> hatte.

Das dürfte jedem bei jedem Projekt so gehen. Selbst in Firmen mit Geld 
und viel Druck ist das so.

von Nemopuk (nemopuk)


Lesenswert?

Behalte immer im Hinterkopf, daß die Chinesen erheblich weniger 
Hemmungen haben, unausgereifte Sachen in den Massenmarkt zu bringen. Da 
könnte man erwägen, für ordentliche Doku und vollständige Software aus 
Europa 30 Cent mehr aus zu geben. Der CH32V003 war mal ein extremes 
Schnäppchen, aber andere haben inzwischen nach gezogen.

: Bearbeitet durch User
von Georg M. (g_m)



Lesenswert?

> Arduino
> Arduino
> Arduino
> Arduino

Erstens, es gibt dedizierte Arduino-Foren.
Zweitens, Mikrocontroller sind sehr unterschiedlich, weil ihre 
Komponenten sehr unterschiedlich sind. Und weder C, noch C++, noch C+++, 
noch Python, noch Kobra, noch Anakonda beschreiben die konkreten 
Komponenten konkreter Mikrocontroller. Und auch Arduino hilft nicht.
Z.B., der kleine ATtiny412 enthält
• 16-bit Timer/Counter type A (TCA)
• 16-bit Timer/Counter type B (TCB)
• 12-bit Timer/Counter type D (TCD)
• 16-bit Real-Time Counter (RTC)
Alle Zähler sind für unterschiedliche Aufgaben konzipiert, nicht für 
Arduino.

von Veit D. (devil-elec)


Lesenswert?

Hallo Georg,

hast du dich im Thread vertan?
Hat irgendjemand etwas anderes behauptet?
Deine Antwort, weil als Gegenargument formuliert, passt irgendwie nicht 
zu den geschriebenen Antworten. Ich weiß nicht worauf deine Antwort eine 
Antwort ist. Manual Screenshots ohne Bezug. Ich finde das komisch.

von Alexander (alecxs)


Lesenswert?

Georg M. schrieb:
> Erstens, es gibt dedizierte Arduino-Foren.

Es steht doch schon Arduino im Betreff, also warum klickst Du da 
überhaupt drauf?

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

... jetzt muß ich schmunzeln zwecks des Posts von Georg M. der mich doch 
am Anfang verwirrt hat, ob ich hier richtig bin.

Okay.... ich war zwar auf einer anderen Baustelle unterwegs (meine 
Webseite), aber da funktioniert etwas zumindest funktional und ich muß 
"nur" noch einen Beschreibungstext da einstellen. Dann läßt mich das 
Thema hier nicht so wirklich los und das, obwohl ich ja "eigentlich" 
kein Arduino mache (aber wie es jetzt ausschaut eben doch ein bisschen).

Zudem ist da (negative Charaktereigenschaft) mein Ego (aber nur ein 
kleines bisschen) angekratzt, weil es dann irgendwie so ausschaut, als 
ob ich ein blutiger Anfänger bin (hmm, unter Arduino stimmt das vllt. 
sogar, Arduino ist unter der Motorhaube dann doch so ziemlich 
vielschichtig).

Also habe ich mich noch einmal hingesetzt und mich der "Problematik" 
gewidmet, wie man diesem für mich unsäglichen "Serial.print" Herr werden 
kann und - zu Veit schiel - das dann mal so überlegt, wie denn das unter 
C++ aussehen sollte / würde und für mich erst einmal etwas "hingebogen".

Und ich bin wirklich sehr gespannt, was Veit und andere dazu sagen (und 
Veit, du siehst, ich habe die loop nicht kastriert und die counter 
variable brav static gemacht).

Die nächste Frage hier ist dann, ob ein typischer Arduino-User oder auch 
Anfänger damit etwas anfangen kann.... und ob das legitim ist, das für 
Demonstration anderer Arduino-Libraries zu verwenden (bspw. Auswertung 
NTC-Sensor).

Weil es so kurz ist, der Demo-Sketch ausnahmsweise auch hier zu lesen:
1
/* --------------------------------------------------------
2
                         cout_demo.cpp
3
4
     demonstriert die Verwendung eines abgepeckten cout
5
     mit Arduino
6
     
7
     07.03.2026 R. Seelig
8
   -------------------------------------------------------- */
9
10
#include <Arduino.h>
11
#include "cout_light.h"
12
13
// Objektinstanz fuer cout_light
14
15
cout_light<HardwareSerial> cout_serial(Serial);
16
17
// und Umleiten auf den Namen "cout" ... :-) nicht ganz die feine Art
18
#define cout  cout_serial
19
20
/* --------------------------------------------------------
21
                         setup
22
   -------------------------------------------------------- */
23
void setup() 
24
{
25
  Serial.begin(115200);
26
27
  cout << F("\n\r Hallo Welt,\n\r ein cout-Demo mit Arduino,hier Zaehlerausgabe auf Serial\n\n\r");
28
}
29
30
/* --------------------------------------------------------
31
                         loop
32
   -------------------------------------------------------- */
33
void loop() 
34
{
35
  static int counter = 0;
36
  
37
  cout << F("\r Counter: ") << Dec << counter;
38
  delay(1000);
39
  counter++;
40
}

von Nemopuk (nemopuk)


Lesenswert?

Ich fand schon vor 30 Jahren, dass dieses
> cout << irgendwas
syntaktisch nicht zum Rest der Sprache passt. Da hat man meiner Meinung 
nach gleich zu Anfang demonstriert, wie man die Sprache nicht 
missbrauchen sollte.

Seit dem habe ich viele andere Programmiersprachen gelernt. Trotz der 
damit einhergehenden Toleranz für Vielfalt ist das Unbehagen gegen cout 
bis heute geblieben. Cout fügt sich wie ein Krebsgeschwür ins Projekt 
ein.

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nemopuk schrieb:
> ....

Du hast mein volles Mitgefühl.

von Kilo S. (kilo_s)


Lesenswert?

Also so als Anfänger, ja, anfangen könnte man was damit.

Allerdings cout gibt's unter Arduino eigentlich nicht standardmäßig, der 
gemeine Arduino nutzer wird damit erst mal nicht viel anfangen können, 
verbreiteter ist Streaming.

Das muss zwar auch erst hinzugefügt werden, ist aber scheinbar beliebter 
als CinCout.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich sage einmal so für mich redend. Sobald der gemeine Arduino 
Nutzer/Programmierer :-) irgendwann ein C/C++ Buch aufschlägt, kommt er 
mit cin und cout in Berührung. Von daher finde ich es legitim. Wer eine 
Streaming Lib nutzt muss sowieso umdenken und ohne print klar kommen. 
Und das geht. ;-) Ansonsten, irgendwas ist doch immer. ;-)

Zum Ralph seinen Code. Ja ja, dass #define sticht mir ins Auge. :-)
using funktioniert leider nicht. Dafür kann man C++ like eine Referenz 
verwenden.
Entweder:
1
constexpr auto &cout {cout_serial};
oder
1
constinit auto &cout {cout_serial};
oder
1
cout_light<HardwareSerial> &cout {cout_serial};

Man kann das auch weglassen und gleich die Objektinstanz so benennen.
1
cout_light<HardwareSerial> cout (Serial);

Hier bitte kein '\r' sondern ein '\n'.
1
cout << F("\n Counter: ") << Dec << counter;

Ansonsten sieht das doch gut aus.  :-)

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Lach, Hallo Veit,

irgendwie finde ich das grundsätzlich witzig, dieses "hin und her" der 
Postings.

Und immerhin, die "Anmerkungen" von dir werden kleiner, grundsätzlich 
wußte ich, dass du das #define monieren würdest, aber die cout - 
Umsetzung ist doch schon mal so halbwegs C++, oder etwa nicht (und das 
cout auch).

Allerdings muß ich Nemopuk rechtgeben, so wirklich warm geworden bin ich 
mit dem cout und cin nicht wirklich und für den Output "liebe" ich das 
printf, das so viele hassen. Für mich ist der Aufbau von printf alles in 
allem eher logisch und auch relativ schnell zu sehen, was ausgegeben 
werden soll und es ist weniger Schreibarbeit (empfinde ich zumindest). 
Aber, es ging hier um C++ und deshalb auch dieses cout hier.

Grundsätzlich gefällt mir das immer noch besser, als die einzelnen 
Streamfunktionen print, println, write etc. im Sketch aufzurufen.

Und:

Veit D. schrieb:
> Hier bitte kein '\r' sondern ein '\n'.cout << F("\n Counter: ") << Dec
> << counter;

By the way: Sollte dich - wider erwarten - der CH32V003 interessieren, 
klebe (okay löte) ich dir gerne einen kleinen Programmer hierfür 
zusammen und einen Controller auf eine Adapterplatine und schick dir 
das. Allerdings funktioniert der Programmer zumindest von mir getestet 
nur unter Linux (würde ich doch sogar glatt unentgeldlich machen, 
einfach so just for fun). Beim Core des Arduino muß man dann boards.txt 
plattform.txt und system_ch32v00x.c patchen (aber wem erzähl ich das, 
das weißt du alles selbst)

Natürlich soll das ein '\r' sein: Mein Terminalprogramm ist so 
eingestellt, dass \r  und \n eben als Carriage return und Newline 
getrennt interpretiert werden. Damit erreiche ich, dass meine Ausgabe 
immer in derselben Zeile erfolgt (ohne Zeilensprung) und das ist auch 
gewollt so.

von Veit D. (devil-elec)


Lesenswert?

Hallo Ralph,

kein Problem, ich habe gegen cout nichts einzuwenden.
Wenn \r Absicht ist, wusste ich nicht, dann ist das okay,
Danke für das Angebot, freut mich, ggf. kommen wir darauf zurück. ;-)
Das ist auch lustig, hatte vor kurzem im Arduino Forum jemanden auch ein 
kleines Geschenk machen wollen. :-)

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Zudem ist da (negative Charaktereigenschaft) mein Ego (aber nur ein
> kleines bisschen) angekratzt, weil es dann irgendwie so ausschaut, als
> ob ich ein blutiger Anfänger bin (hmm, unter Arduino stimmt das vllt.
> sogar, Arduino ist unter der Motorhaube dann doch so ziemlich
> vielschichtig).

So ist es:
Arduino nutzen ist nicht schwer,
Arduino machen hingegen sehr.

Ich erwähne es noch mal: Es gibt da gewisse Coding-Guidlines, die man 
natürlich einfach brechen kann, wenn es einem Spaß macht. Nur sollte man 
es dann vielleicht nicht mehr "Arduino" nennen.

von Alexander (alecxs)


Lesenswert?

Ralph S. schrieb:
> Mein Terminalprogramm ist so eingestellt, dass \r  und \n eben als
> Carriage return und Newline getrennt interpretiert werden.

Und warum schreibst Du es dann nicht konsequent durchgängig auch so da 
wo neue Zeilen gewünscht sind F("\r\nHallo Welt,\r\n"); das muss doch 
auch am Ego kratzen?

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Alexander schrieb:
> Und warum schreibst Du es dann nicht konsequent durchgängig auch so da
> wo neue Zeilen gewünscht sind F("\r\nHallo Welt,\r\n"); das muss doch
> auch am Ego kratzen?

??????

Irgendwie verstehst du wohl das einfachste nicht, um das es geht, oder ?
Wenn ich nach "Hallo Welt" eine neue Zeile haben möchte (und die möche 
ich haben), dann folgt dem eben ein "\n\r".

Und ob ich jetzt (wie von dir vorgeschlagen) \r\n schreibe, oder \n\r 
ist Jacke wie Hose. Ob ich erst einen Carriage return mache und dann 
einen Zeilensprung oder umgekehrt macht auf der Ausgabe keinen 
Unterschied.

Ralph S. schrieb:
> cout << F("\n\r Hallo Welt,\n\r ein cout-Demo mit Arduino,hier
> Zaehlerausgabe auf Serial\n\n\r");

Natürlich hätte ich auch schreiben können:
1
cout << F("\n\r Hallo Welt,");
2
cout << F("\n\r ein cout-Demo mit Arduino, hier Zaehlerausgabe auf Serial");
3
cout << F("\n\n\r);

Hrmpf, ich hätte ja noch als Kommentar hinzufügen können, dass ich hier 
"Hallo Welt" ausgebe (das.... würde dann wirklich am Ego kratzen)

von Alexander (alecxs)


Lesenswert?

Ralph S. schrieb:
> dann folgt dem eben ein "\n\r".

aber nur bei Dir, sonst nirgends auf der Welt

von Nemopuk (nemopuk)


Lesenswert?

Alexander schrieb:
>> dann folgt dem eben ein "\n\r".
> aber nur bei Dir, sonst nirgends auf der Welt

Das ist halt ein altes Relikt aus der Zeit, als man Schreibmaschinen zur 
Ausgabe nutzte. Heute bringt fast jedes Terminal den Cursor automatisch 
an den Anfang der neuen Zeile - außer bei Microsoft.

Üblicherweise ist die Reihenfolge \r\n.

von Alexander (alecxs)


Lesenswert?

Wenn man wie eine Schreibmaschine denkt passieren eben solche Fehler. 
LFCR ist nicht nur unüblich sondern falsch. Mag auf der 
"Schreibmaschine" nicht stören, aber spätestens bei utils wie dos2unix 
wird das spannend (wer's braucht)

Ich wusste übrigens bis gestern nicht dass Arduino gar kein 
Serial.printf() hat. Auf dem ESP32 funktioniert das. Würde IMHO Sinn 
machen das aus arduino-esp32/cores/esp32/Print.h zu klauen.

https://forum.arduino.cc/t/serial-print-and-printf/146256

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Alexander schrieb:
> Ich wusste übrigens bis gestern nicht dass Arduino gar kein
> Serial.printf() hat.

Hat es nicht!
printf selber kann man nachrüsten.
printf ist allerdings auch arg fett für kleine µC

streaming.h bietet einiges an Formartiermöglichkeiten welche ungewohnt 
aber meist ausreichend sind.

von Ralph S. (jjflash)


Lesenswert?

Alexander schrieb:
> aber nur bei Dir, sonst nirgends auf der Welt

wie schräg bist du denn drauf? Erstens, auch wenn ich das nicht wirklich 
mag, macht das Microsoft so... zweitens darf man seine Console so 
einstellen wie es funktional ist. Wenn man also wie ich, es gerne hat, 
dass die Ausgabe in ein und derselben Zeile erfolgen soll, stellt man 
das Terminal für getrennte \n \r ein. Einzig mittels ESC-Sequenzen kann 
man das auch bewerkstelligen, allerdings aufwändiger. Grundsätzlich: was 
machst du für ein Fass auf, für so etwas triviales wie Steuerzeichen in 
einem AsciiZ String???

Ich finde dich ganz toll, echt.

Aber immerhin, das meine ich ernst, könnte ich meiner HardwareSerial 
mein abgespecktes printf vermachen. Grundsätzlich werd ich hier dieses 
abgespeckte printf mit den entstehenden Bibliotheken hier einstellen. 
Das kann dann zwar kein float und auch keine Längenangaben, dafür trägt 
es im Falle von AVR nur mit 350 Byte auf, bei CH32V003 419 Byte... aber 
du darfst dann gerne auch wegsehen, weil in den Demos dann wieder \n\r 
zu sehen ist.

Auch würde ich gerne von dir lernen, zeig mal, was du da an 
Arduino-Klassen schon produziert hast (anstelle dich über den Stil 
anderer zu echaufieren)

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


Lesenswert?

Ralph S. schrieb:
> könnte ich meiner HardwareSerial
> mein abgespecktes printf vermachen.

Es ist üblich solche Erweiterungen in Print.h unter zu bringen.

von Christoph M. (mchris)


Lesenswert?

Alexander schrieb:
> Auf dem ESP32 funktioniert das. Würde IMHO Sinn
> machen das aus arduino-esp32/cores/esp32/Print.h zu klauen.

printf braucht aber auf einem kleine Prozessor sehr viel Speicher. Das 
könnte auch der Grund für das Fehlen von printf in der Atmega328 Version 
gewesen sein.

von Christoph M. (mchris)


Lesenswert?

In der Arduinowelt kann man vieles mit der Stringklasse machen:
1
void setup() {
2
  Serial.begin(115200);
3
}
4
5
int Counter=0;
6
7
void loop() {
8
  String msg="Counter is: ";  
9
  Serial.println(msg+String(Counter));
10
  Counter++;
11
  delay(1000);
12
}

Getestet hier:
https://wokwi.com/projects/new/arduino-nano

von Veit D. (devil-elec)


Lesenswert?

Hallo,

> In der Arduinowelt kann man vieles mit der Stringklasse machen:

Kann man, man sollte jedoch auch die Probleme damit kennen. Gerade eben 
mit dem + Operator.

von Alexander (alecxs)


Lesenswert?

Ralph S. schrieb:
> Und ob ich jetzt (wie von dir vorgeschlagen) \r\n schreibe, oder \n\r
> ist Jacke wie Hose.

Ist es nicht. Wenn ich meine Jacke als Hose anziehe fällt da was raus.

Ralph S. schrieb:
> Erstens, auch wenn ich das nicht wirklich mag, macht das Microsoft so...

Nein macht es nicht. Du meinst:

Nemopuk schrieb:
> Üblicherweise ist die Reihenfolge \r\n.

Ralph S. schrieb:
> Grundsätzlich: was machst du für ein Fass auf

Mach ich nicht. Ich hab Dich nur auf den (trivialen) Typo hingewiesen, 
der sich bei Dir durchzog (und zu solchen Mißverständnissen wie mit Veit 
führen kann). Sieht halt schlampig aus so, wäre schade wenn das so ins 
Repo wandert.

Ralph S. schrieb:
> zeig mal, was du da an Arduino-Klassen schon produziert hast

Da gibt es nichts. Ich nutze was da ist und erfinde nicht das Rad neu. 
Das ist ja das schöne an Arduino. Ich muss gar nichts können.

: Bearbeitet durch User
von Gerhard O. (gerhard_)


Lesenswert?

Moin,

Ich bin eigentlich der Meinung, wenn etwas mehr Komfort gewünscht ist, 
daß man dann besser eine etwas üppiger ausgestatteten uC wählen sollte. 
Beim ATMEGA1284 mit 16K z.B., spielt die Unterstützung von printf eine 
geringere Rolle als beim 328P oder noch kleiner. Beim STM32L496 denke 
ich überhaupt nicht daran. Ausser Sportlichkeit lohnt es sich nicht mehr 
frugal den uC zu wählen. 32-bit uC kosten heutzutage weniger als die 
älteren 8-Bitter und braucht nicht abgespeckte Bibliotheken. Beim STM 
habe ich auch noch einen schnell und gut funktionierenden Debugger. Da 
ist das Arduino Konzept klar im Nachteil. Andrerseits kann man bei 
Erfahrung auch gut ohne Debugger auskommen und mit cleverer Ausnützung 
von printf und Oszi Unterstützung Probleme verfolgen. Aber manchmal hat 
natürlich der Debugger schon den Tag gerettet.

Trotzdem arbeite ich noch gerne mit den kleineren Exemplaren, weil es 
einfach erzieherisch ist, mit geringen uC Ressourcen Probleme effizient 
in funktionierende HW umzusetzen und diszipliniert zu planen and 
programmieren. Viele Realwelt Steuer Anwendungen agieren mit ihrer 
Umwelt in ms oder s Skala. Und wenn es wirklich nicht langt, skaliert 
man aufwärts. Für "moderne" kommunizierenden Anwendungen nimmt man 
ohnehin oft ESP32 oder Vergleichbares.


Gerhard

von Harald K. (kirnbichler)


Lesenswert?

Gerhard O. schrieb:
> 32-bit uC kosten heutzutage weniger als die
> älteren 8-Bitter und braucht nicht abgespeckte Bibliotheken.

Der CH32V003 ist ein 32-Bit-µC, nur halt einer am unteren Ende der 
Ausstattung.

Ihm hat sich übrigens ein etwas besser ausgestatteter Nachfolger 
hinzugesellt, der CH32V002 mit doppelt so viel RAM.

Und wenn man damit leben kann, daß es kein SO-8 bzw. SO-16 als Gehäuse 
gibt, ist der CH32V006 ein nochmal deutlich besser ausgetatteter 
Kandidat -  8 kiB RAM und in den meisten Fällen* 62 kiB Flash-ROM. Geben 
tuts ihn ab TSSOP20/QFN20 bis zu QFN32 (mit dann den meisten I/Os).

Dennoch ist der auch für 5V-Betrieb geeignet, was für viele Bastler den 
einen oder anderen Pegelkonverterkrampf vermeiden hilft.



*) der CH32V006F4U6 hat aus irgendwelchen Gründen nur 16 kiB Flash und 
auch nur 4 kiB RAM,

von Nemopuk (nemopuk)


Lesenswert?

Harald K. schrieb:
> Dennoch ist der auch für 5V-Betrieb geeignet, was für viele Bastler den
> einen oder anderen Pegelkonverterkrampf vermeiden hilft.

Was läuft denn heute noch mit 5V, außer uralter Arduino Kram?

von Christoph M. (mchris)


Lesenswert?

Gerhard O. schrieb:
> Beim STM
> habe ich auch noch einen schnell und gut funktionierenden Debugger. Da
> ist das Arduino Konzept klar im Nachteil.

Wie das?

https://github.com/stm32duino

von Harald K. (kirnbichler)


Lesenswert?

Anscheinend genug, daß es manchen "Makern" oder Bastlern Probleme 
bereitet und sie mit Pegelwandlern herummachen müssen, weil sie mit 
5V-Peripherie zu tun bekommen.

Die verschiedenen CH32V00x-Modelle laufen aber auch mit weniger als 3 V, 
die neueren bereits ab 2 V (2.4, wenn ein ADC genutzt werden soll). 
Beschränkungen bei der Taktfrequenz gibt es wohl nicht.

Insofern ist der 5-V-Betrieb ein Kann, kein Muss.

von Veit D. (devil-elec)


Lesenswert?

Alexander schrieb:
> Da gibt es nichts. Ich nutze was da ist und erfinde nicht das Rad neu.
> Das ist ja das schöne an Arduino. Ich muss gar nichts können.

Ich würde an deiner Stelle den Ball flacher halten. Dir muss bewusst 
sein, wenn du nichts kannst, dann müssen andere etwas können, damit du 
vorhandenes Nutzen darfst. Das heißt, du bist abhängig von Entwicklern 
wie Ralph die einen Core schreiben, den du später nutzen kannst. In der 
Sache hast du Recht, nur kann man es auch netter formulieren.

Es gibt zwischen den Betriebssystemen paar kleine Unterschiede in der 
Interpretation der Steuerzeichen.
Das betrifft jedoch weniger Serial -> Terminalausgabe, sondern Programme 
welche in eine Textdatei schreiben.
Jetzt weiß ich nicht was Ralph für ein Terminal verwendet.
Ich hatte es mit dem Seriellen Monitor der Arduino IDE 1.8.19 und 2.3.8 
probiert.
Eine Einstellung auf CR hilft da nicht. Es wird fortlaufend die Zeile 
weitergeschrieben, bis es aus den Sichtfeld ist bzw. man den 
Scrollbalken bewegen muss.
hterm kommt mit CR allein zurecht und macht einen Zeilenumbruch. hterm 
weiß offenbar, dass am COM Port (USB) im Jahre 2026 keine 
Schreibmaschine angeschlossen ist. :-)
Der Serielle Monitor weiß das nicht bzw. gibt es da ein Problem was man 
adressieren sollte oder es verhält sich Windows konform, was auch nicht 
sein kann, denn ein Wagenrücklauf erfolgt auch nicht. Könnte man separat 
besprechen.
Ausreichend für einen Zeilenumbruch im Terminal im Jahre 2026 wäre '\n', 
macht das was die Beschreibung dazu sagt.
Mit welchen Terminal '\r' sauber funktioniert weiß ich nicht. Ich kenne 
keines was an den Anfang der Zeile springt und alles überschreibt.

Unter Windows mit Dateioperationen ist dagegen '\r\n' Standard für EOL.
Hiermit gibt es dann wohl die bekannten Problem mit Textdateien bei 
Austausch zwischen Betriebssystemen.

Jedes Detail habe ich nun nicht studiert, es gibt jedoch 
Interpretationsunterschiede im OS.
https://www.loginradius.com/blog/engineering/eol-end-of-line-or-newline-characters

Nemopuk schrieb:
> Was läuft denn heute noch mit 5V, außer uralter Arduino Kram?
Entwicklungen verpasst?

Hier geht es übrigens immer noch um CH32V003. Kein STM oder sonstwas.

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Veit D. schrieb:
> Das heißt, du bist abhängig von Entwicklern
> wie Ralph die einen Core schreiben, den du später nutzen kannst. In der
> Sache hast du Recht, nur kann man es auch netter formulieren.

Den Satz ich lasse programmieren habe ich mir verkniffen.

von Norbert (der_norbert)


Lesenswert?

Veit D. schrieb:
> Ausreichend für einen Zeilenumbruch im Terminal im Jahre 2026 wäre '\n',
> macht das was die Beschreibung dazu sagt.
> Mit welchen Terminal '\r' sauber funktioniert weiß ich nicht. Ich kenne
> keines was an den Anfang der Zeile springt und alles überschreibt.

Alles was sich VT52,VT100,VT220, … nennt.
Und wahrscheinlich ein ganzer Sack voller korrekt implementierter 
Terminal Emulationen. Selbst minicom, rudimentär in Python programmiert, 
macht das.

Als newline/neue Zeile:
0x0d CR wird/wurde vom alten Apple genutzt.
0x0d,0x0a CRLF wird von Windows genutzt.
0x0a LF wird von allem Unixodiden genutzt.
0x15 NL wird/wurde von IBM im EBCDIC genutzt.

: Bearbeitet durch User
von Gerhard O. (gerhard_)


Lesenswert?

Christoph M. schrieb:
> Gerhard O. schrieb:
>> Beim STM
>> habe ich auch noch einen schnell und gut funktionierenden Debugger. Da
>> ist das Arduino Konzept klar im Nachteil.
>
> Wie das?
>
> https://github.com/stm32duino

Danke für den Hinweis. Habe ich bisher ignoriert, weil ich beim STM32 
lieber mit ST Werkzeugen und Debugger arbeite. Und bei den 8-bittern 
stimmt es ja, dass Debugging in der Regel nicht vorgesehen ist.

Wer effizienten Debug mit minimal IO Verlust möchte, ist wahrscheinlich 
z.B. bei MSP430 und Z!Encore besser aufgehoben. Der MSP430 ist da im 
Umgang mit CubeMX IDE ohnehin sehr ähnlich. Auch Siliconlabs 8051 
Derivate haben ähnlichen Komfort. Über die CH32 Familie kann ich nicht 
kommentieren, weil ich noch keinen Grund hatte, mich damit zu befassen - 
stehe da eher neutral dazu. Vermutlich sind die Dokumentationen unserer 
Hersteller zugänglicher, aber das ist Geschmacksache.

Die einzige chinesische uC Famile die mich peripherell interessiert, 
sind STCs 8051 uC Flash programmierbare Derivate, die sich über UART 
Flashen lassen. Und auch nur, weil mir einige zugelaufen sind und der 
Keil MC51 kompatibel ist. Ob es sich lohnt viel Zeit zu investieren - da 
bin ich eher skeptisch. Aber es wäre eine Gelegenheit die Tochter einer 
anderen Mutter näher kennenzulernen.

Seid froh, dass es für die uC eures Herzen, vielfach freie mächtige 
Entwicklungswerkzeuge gibt, die den Einstieg leicht machen. Arduino ist 
für viele Sachen auch sehr zweckmässig, wobei dort, wenn man nicht uC 
übergreifend arbeiten muß, auch dort wie sonst gewohnt, bare Metal 
Zugang hat. Keiner ist gezwungen immer nur mit Libraries arbeiten zu 
müssen. Arduino, dank GCC, wo kompatible, lässt da keine Wünsche offen. 
Übergreifende uC Kompatibilität im Quellcode für Portabilität ist nicht 
immer unbedingt für alle notwendig noch wichtig.

Gerhard

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Gerhard O. schrieb:
> Und bei den 8-bittern
> stimmt es ja, dass Debugging in der Regel nicht vorgesehen ist.

Hätten sie bestimmt gerne implementiert, wenn der Hersteller (Atmel) das 
nicht als geheimes Premium Feature für seine eigenen schweineteuren 
Debugger reserviert hätte. Die Hardware ist inzwischen bezahlbar 
geworden, aber das Protokoll immer noch geheim.

Gerhard O. schrieb:
> Vermutlich sind die Dokumentationen unserer
> Hersteller zugänglicher, aber das ist Geschmacksache.

Finde ich nicht. Ordentliche Dokumentation ist Grundvoraussetzung für 
vernünftiges Arbeiten.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Norbert schrieb:

> Alles was sich VT52,VT100,VT220, … nennt.
> Und wahrscheinlich ein ganzer Sack voller korrekt implementierter
> Terminal Emulationen. Selbst minicom, rudimentär in Python programmiert,
> macht das.
>
> Als newline/neue Zeile:
> 0x0d CR wird/wurde vom alten Apple genutzt.
> 0x0d,0x0a CRLF wird von Windows genutzt.
> 0x0a LF wird von allem Unixodiden genutzt.
> 0x15 NL wird/wurde von IBM im EBCDIC genutzt.

Hallo Norbert,

Danke für den Hinweis. Von VT100 hatte ich schon gehört, da nie benötigt 
fiel das immer hinten runter.  ;-)

von Veit D. (devil-elec)


Lesenswert?

Gerhard O. schrieb:

Hallo Gerhard, muss das jetzt hier wirklich sein?

von Harald K. (kirnbichler)


Lesenswert?

Norbert schrieb:
> Alles was sich VT52,VT100,VT220, … nennt.

Nö. Die interpretieren CR als "springe an den Anfang der aktuellen 
Zeile".
Erst in Kombination mit LF gibt es eine neue Zeile.

LF alleine positioniert den Cursor eine Zeile unter seiner bisherigen 
Position, ändert aber nichts an seiner horizontalen Ausrichtung.

Allerdings nutzen die meisten Terminalemulatoren eine Einstellung, daß 
sie auch einzelne CR bzw. LF wie eine Kombination aus CR+LF 
interpretieren.

von Norbert (der_norbert)


Lesenswert?

Harald K. schrieb:
> Norbert schrieb:
>> Alles was sich VT52,VT100,VT220, … nennt.
>
> Nö. Die interpretieren CR als "springe an den Anfang der aktuellen
> Zeile".
> Erst in Kombination mit LF gibt es eine neue Zeile.



Tja Harald, die korrekte Abfolge des Zitats lautet allerdings wie folgt:

Veit D. schrieb:
> Mit welchen Terminal '\r' sauber funktioniert weiß ich nicht. Ich kenne
> keines was an den Anfang der Zeile springt und alles überschreibt.

Worauf ich antwortete:

Norbert schrieb:
> Alles was sich VT52,VT100,VT220, … nennt.

von Veit D. (devil-elec)


Lesenswert?

Hallo Norbert,

richtig. Tera Term habe ich ausprobiert und es führt CR korrekt aus. Für 
einen Zählerwert den Ralph in seinem Demoprogramm zeigt, ist das okay. 
Funktioniert nur leider nicht mit dem Seriellen Monitor der Arduino IDE 
und auch nicht mit hterm, welches ich auch sehr gern verwende. Da kann 
man wie gesagt eine Anfrage stellen. Werde ich machen.

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Veit D. schrieb:
> Funktioniert nur leider nicht mit dem Seriellen Monitor der Arduino IDE
> und auch nicht mit hterm

Da stören die Zeitstempel / time logs.

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Veit D. schrieb:
> Jetzt weiß ich nicht was Ralph für ein Terminal verwendet.
> Ich hatte es mit dem Seriellen Monitor der Arduino IDE 1.8.19 und 2.3.8
> probiert.

Ich verwende 2 Terminals, zum einen PuTTY, das so ziemlich alles kann, 
was Datenübertragung angeht (auch SSH und Telnet), aber häufiger ein 
(nur optisch) modifiziertes picocom 
https://github.com/npat-efault/picocom in der Konsole!

Den seriellen Monitor der Arduino IDE verwende ich gerade wegen der 
vielen Einschränkungen überhaupt nicht.

Veit D. schrieb:
> Das heißt, du bist abhängig von Entwicklern
> wie Ralph die einen Core schreiben, den du später nutzen kannst.

:-) um Mißverständnissen vorzubeugen, ich entwickle keinen Core, dafür 
bin ich ein viel zu großer Arduino-Anfänger und werde das wohl auch 
bleiben. Ich weiß, wie schon erwähnt nicht, was ein typischer 
Arduino-User sich wünscht.

Ich schreibe nur Funktionalitäten für einen meiner Ansicht nach 
unvollständigen Core, damit eben ein CH32V003 auch unter Arduino gut 
verwendbar ist. Hier vordergründig SPI, I2C, ADC und UART (uart 
funktioniert mit dem Core, allerdings nur schreibend, nicht lesend). Und 
ich schreibe Demosketche, wie bspw. Timer2 verwendet werden kann. Die 
Interruptbehandlung des CH32V003 Core ist ebenfalls unvollständig und 
hier muß ich ein ebenfalls ein Workaround machen, damit man dieses 
Nutzen kann. Ohne die Arduinofunktionen habe ich es bspw. noch nicht 
erreicht, einen Interruptvektor aus einer Klasse heraus anszuspringen.

Aber ich lasse mich von Nörglern wie alecxs nicht abschrecken: er muß ja 
einen CH32V003 nicht nutzen.

Meine "Versuchskanninchen" kommen mit den Funktionen die ich bereits 
habe sehr gut zurecht, allerdings - geb ich zu - muß ich die Verwendung 
erklären und es wartet eine Menge Doku auf mich.

Im Moment geht mir durch den Kopf, für den CH32V003 das Streaming um 
eine Methode printf zu erweitern.

PS:
wenn ich gerade so über Unzulänglichkeiten nachdenke, erinnere ich mich 
noch sehr genau, wie ich mich gewundert habe, wie ein einfaches 
Arduino-Programm, welches eine 7-Segmentanzeige über einen TM1650 
angesteuert hat, unverhältnismäßig groß geworden ist, und mich deshalb 
in die Tiefen des Cores hinabbegeben habe. Als Übeltäter habe ich dann 
delayMicroseconds() ausgemacht, welches soviele Dinge mit einbindet, 
dass der Speicherbedarf bei Verwendung dieser delayMicroseconds um mehr 
als 5600 Byte angestiegen ist (was bei einem gesamten Flashspeicher von 
16 kByte enorm ist).

Also gibt es bei mir, wenn es genauer sein soll, hier eine Verzögerung, 
die mittels Timer2 realisiert wird und wenn es ungenauer sein darf 
schlicht über eine for schleife, in der __asm volatile(" nop "); 
ausgeführt wird (und sicherlich schreien jetzt Arduino-User auf, weil 
(eine einzige) Assembleranweisung in Arduino auftaucht. Grundsätzlich 
glaube ich hier jedoch, dass die Speichereinsparung enorm ist und ein 
Kommentar reicht, was man der Funktion zu übergeben hat. Wie die 
Funktion dann die Mikrosekunden verzögert sollte dem Anwender dann egal 
sein.

von Kilo S. (kilo_s)


Lesenswert?

Ralph S. schrieb:
> und ein Kommentar reicht, was man der Funktion zu übergeben hat. Wie die
> Funktion dann die Mikrosekunden verzögert sollte dem Anwender dann egal
> sein.

Die interna jucken meistens null, jedenfalls dann nicht wenn die 
Funktion das macht was man braucht.

Erst wenn's nicht klappt, gehen die meisten erst mal library für library 
durch bis eine funktionierende gefunden ist, gibt's da nichts, geht's 
weiter:
KI, Foren, Aufgeben..

Ralph S. schrieb:
> Ich weiß, wie schon erwähnt nicht, was ein typischer Arduino-User sich
> wünscht.

Das muss im Prinzip wie PHP sein, der normale "Arduino Nutzer" 
instbesondere diese die sich an diesen comfort gewohnt haben, will ein 
analogWrite(Pin, Val) usw.
Hochsprache ohne mit Registern, Magic Numbers, bitoperation usw. 
konfrontiert zu werden.

Wenn du das Benennungsschema nach dem richtest was es bereits gibt, 
Funktionsnamen, übergabeparameter usw. fragt nicht mal jemand was im 
Hintergrund abgeht, ob da nun "nop" oder "sackreisumgefallen" in der 
Funktion steht, nach dem Motto analogWrite ist immer das gleiche 
analogWrite weil es heißt ja analogWrite.
Es guckt keiner genau hin, aber dafür wurde es ja auch so konstruiert, 
einstiegsfreundlich.

Das war auch mein Anfang. Ein Nano, LCD anstöpseln, library laden und 
Loslegen. Erst mit dem PY32 kam so richtig Interesse auch "besser" 
programmieren zu lernen. Gibt wenig librarys, wobei häufig die vom STM32 
kompatibel sind. Und wie beim CH32 ein paar unschöne Mankos im core für 
PY32, also sehr viel weniger, trotzdem doof. (Takt, GPIO usw..)

Das muss gestaltet sein das ein Kind das lernen kann, dann ist es 
Arduino Nutzer tauglich. ;-)

von Alexander (alecxs)


Lesenswert?

Ralph S. schrieb:
> Aber ich lasse mich von Nörglern wie alecxs nicht abschrecken

Sowas nennt man Übertragung. Ich habe kein Wort zu Deinem Core 
gewechselt. Den hab ich mir noch nicht mal angeschaut, das war Veit. Bin 
dann jetzt auch mal wieder still.

von Christoph M. (mchris)


Lesenswert?

Kilo S. schrieb:
> library laden und Loslegen.

Das ist genau das Entscheidende: Das Framework muss es ermöglichen, dass 
Libraries ohne Anpassung einfach laufen.

Außerdem sollten die grundsätzlichen, in der Arduino IDE vorhandenen 
Beispiel laufen:

blink ( setzt die Definition von LED_BUILTIN voraus )
analogReadSerial ( setzt voraus das analogRead und Serial funktioniert )

Serial.available muss unbedingt für die serielle Steuerung und 
Datenübertragung funktionieren:
https://docs.arduino.cc/language-reference/de/funktionen/communication/serial/available/

Der I2C-Scanner sollte funktionieren
https://wolles-elektronikkiste.de/en/i2c-scanner

von Ralph S. (jjflash)


Lesenswert?

Kilo S. schrieb:
> Das muss im Prinzip wie PHP sein, der normale "Arduino Nutzer"
> instbesondere diese die sich an diesen comfort gewohnt haben, will ein
> analogWrite(Pin, Val) usw.

Jetzt habe ich natürlich ein Problem: Ich weiß wie man den Core dazu 
bringt, dass bspw. analogWrite(Pin, Val); so funktioniert, wie das auch 
mit einem AVR-Board funktioniert und habe das auch schon gemacht. Es 
erfordert dann einen Patch des Cores.

Das Problem ist jetzt: Gibt es ein Update des Core's und installiert 
dieses, ist der Patch dann weg!

Am Beispiel des ADC (analogRead) die Frage, ist folgendes "noch in 
Ordnung" für einen Arduino-User (die Klasse hat 2 öffentliche Methoden, 
"read" und "calc_spg") oder sollte tatsächlich der Core gepatcht werden, 
so dass man nur die analogRead Funktion hat:
1
#include "v003_adc.h"
2
3
// Objekte erzeugen, Konstruktor erwartet GPIO-Pin, auf dem
4
// ein analoger Wert eingelesen wird. Erlaubte Pins sind:
5
6
//                PA2, PA1, PC4, PD2 .. PD6
7
ADC analog1(PD4);
8
ADC analog2(PA1);
9
10
// zum Einlesen einer Spannung (4990 ist die Betriebsspannung in mV als Referenz)dann:
11
  uint16_t val1, val2;
12
13
  val1= analog1.calc_spg(analog1.read(), 4990);
14
  delay(20);
15
  val2= analog1.calc_spg(analog2.read(), 4990);
16
  delay(20);

von Christoph M. (mchris)


Lesenswert?

Was man auch immer gerne hat sind die NeoPixels.
Da wird es bezüglich Arduino aber unscharf, weil es keine normierte 
Bibliothek gibt. Oft verwendet wird Adafruit verwendet:

https://github.com/adafruit/Adafruit_NeoPixel

Tim hat was für den CH32V003 gemacht, ist aber nicht kompatibel:
Beitrag "Automatischer WS2812 Tester mit CH32V003"

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Am Beispiel des ADC (analogRead) die Frage, ist folgendes "noch in
> Ordnung" für einen Arduino-User (die Klasse hat 2 öffentliche Methoden,
> "read" und "calc_spg") oder sollte tatsächlich der Core gepatcht werden,
> so dass man nur die analogRead Funktion hat:
1
// PA2, PA1, PC4, PD2 .. PD6
2
ADC analog1(PD4);
3
ADC analog2(PA1);

Hier liegt ein ganz grundlegendes Verständnisproblem vor. Hernando 
Barragán schreibt auf der zweiten Seite in
https://arduinohistory.github.io
1
 Abstracting the microcontroller pins as numbers was, without a doubt, a major decision, possible because the syntax was defined prior to implementation in any hardware platform. All the language command naming and syntax were the result of an exhaustive design process I conducted, which included user testing with students, observation, analysis, adjustment and iteration.

Die Abstrahierten analogen Eingänge heißen bei den Arduino-Boards A0, A1 
..

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Christoph M. schrieb:
> blink ( setzt die Definition von LED_BUILTIN voraus )
> analogReadSerial ( setzt voraus das analogRead und Serial funktioniert )
>
> Serial.available muss unbedingt für die serielle Steuerung und
> Datenübertragung funktionieren:
> 
https://docs.arduino.cc/language-reference/de/funktionen/communication/serial/available/
>
> Der I2C-Scanner sollte funktionieren
> https://wolles-elektronikkiste.de/en/i2c-scanner

Genau das alles macht der "offizielle Core" für den CH32V003 nicht, und 
für LED_BUILTIN muß man wissen, dass Arduino in diesem Core "2" 
verwendet und dieser als PC0 interpretiert wird. Noch nicht einmal ein 
Textdisplay unter Verwendung von #include <LiquidCrystal.h> funktioniert 
(Timingfehler)

von Ralph S. (jjflash)


Lesenswert?

Christoph M. schrieb:
> Die Abstrahierten analogen Eingänge heißen bei den Arduino-Boards A0, A1
> ..

ich glaube ich werde mich nie daran gewöhnen, bei Arduino die 
Boardbezeichnungen anstelle der wahren Bezeichnung des Chips zu 
verwenden. Will man wirklich so weit von der Hardware weg, dass das Teil 
ein absolut abstraktes Stück Elektronik ist?

Hm, überlege ich, ob meine Library ADC auch um die Arduino-Namen für die 
GPIO-Pins erweitert wird

von Kilo S. (kilo_s)


Lesenswert?

Ralph S. schrieb:
> Das Problem ist jetzt: Gibt es ein Update des Core's und installiert
> dieses, ist der Patch dann weg!

Übermittel die Patches doch per GitHub an WCH bzw. an einen der anderen 
auf GitHub die einen Core für CH32 bereitstellen.
Ich weiß nicht wie weit die den Code pflegen, ob die vorhaben selbst 
noch was zu machen, so unvollständig kann der aber eigentlich kaum 
bleiben.
Aber letzte Version von WCH direkt ist auch drei Jahre alt. (2023)

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Ralph S. schrieb:
> Will man wirklich so weit von der Hardware weg, dass das Teil
> ein absolut abstraktes Stück Elektronik ist?

Man will:
1
Abstracting the microcontroller pins as numbers was, without a doubt, a major decision, possible because the syntax was defined prior to implementation in any hardware platform.

Das mach sogar STM (wie man im Bild oben für eines der Nucleo-Boards 
sieht) und es ist auch der Grund warum analogRead(A0) sowohl auf dem 
Arduinos mit Atmega als auch den STM32 Varianten funktioniert.

Im STM32 Framework selbst gibt es für jede Variante einen eigenen 
Ordner, in dem die Pins definiert werden:

https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32C0xx/C031C(4-6)(T-U)/variant_NUCLEO_C031C6.cpp

von Alexander (alecxs)


Lesenswert?

Ralph S. schrieb:
> Das Problem ist jetzt: Gibt es ein Update des Core's und installiert
> dieses, ist der Patch dann weg!

Solange Du keinen Pullrequest erstellt und dieser nicht angenommen und 
gemerged wurde.

von Georg M. (g_m)


Lesenswert?

Christoph M. schrieb:
> Man will:

Man will weniger denken. Mikrocontroller sind sehr unterschiedlich 
(Warum?), und durchs Arduinieren werden sie alle gleich gemacht.

von Christoph M. (mchris)


Lesenswert?

Georg M. schrieb:
> Man will weniger denken.

Ja, wer schlau ist, will das.

von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Georg M. schrieb:
>> Man will weniger denken.
>
> Ja, wer schlau ist, will das.

Wer's macht wird's bald nicht mehr sein.

von Veit D. (devil-elec)


Lesenswert?

Alexander schrieb:
> Veit D. schrieb:
>> Funktioniert nur leider nicht mit dem Seriellen Monitor der Arduino IDE
>> und auch nicht mit hterm
>
> Da stören die Zeitstempel / time logs.

Das kann man in beiden einstellen.

von Kilo S. (kilo_s)


Lesenswert?

Christoph M. schrieb:
> Ja, wer schlau ist, will das.

Schade wenn es halt nicht so wirklich klappt.

Ich muss dank Arduino sogar "mehr denken". Das gleiche Problem 
(Benennung, Parameter, Rückgabewerte) hab ich auch wenn ich Code 
produzieren möchte der anderen helfen kann.

Beispiel Beitrag "Re: Fumot Tornado 25000 mit LCD -Teardown"

Setzte das dem blutigen Anfänger vor der die IDE vielleicht seit einem 
Monat benutzt, der wird erst mal Fragezeichen in den Augen haben.
Ohne Erklärung kommt der damit vermutlich nicht direkt weiter, schon der 
Unterschied zwischen der Schreibweise LCD_ (Uppercase!) Zu lcd. 
(Lowercase) der Standard library. (Hab's getestet! Mein Nachbar, 
wandelndes Klischee der Arduino Welt. Tutorial kopieren, scheitern, 
nächstes Tutorial. Das ist ein Loop bis irgendwann der Frust so groß ist 
das er hin wirft oder zufällig mal ein Versuch klappt.)
Das bringt Manche Leute völlig aus dem Konzept.

Lustigerweise, lcd.print, lcd.prinln usw.. kennt der alles!
Er war nicht in der Lage aus diesem "Quasistandard" auszubrechen.

Erst als ich ihm erklärt habe das LCD_DrawString theoretisch lcd.println 
entspricht hat er es halbwegs kapiert.

Klar, ist eines der extremen Beispiele, es gibt in der Arduino Fraktion 
so viele Facetten, auch Leute die (Guck ich mir ja auch zum Teil so ab) 
die IDE auch nur als IDE mit kompilerfunktion nutzen. Da wird dann bare 
Metal oder mit HAL gearbeitet, klappt erstaunlich gut.

Einerseits geiler scheiß, niedriger Einstieg, günstige Hardware, 
schneller Erfolg.

Andererseits Beihilfe zur aktiven Verdummung!

Alles hat halt gute und schlechte Seiten.

von Veit D. (devil-elec)


Lesenswert?

Veit D. schrieb:
> ... Da kann man wie gesagt eine Anfrage stellen. Werde ich machen.

Zum Thema Nachfrage wegen der CR Fehlinterpretation der Arduino IDE hat 
sich ganz schnell geklärt. Dazu gibt es schon "Hunderte" Anfragen, wird 
alles abgelehnt. Bsp. https://github.com/arduino/arduino-ide/issues/406
Da wird nichts passieren, man muss ein anderes Terminal verwenden.
Tera Term und putty funktionieren bspw..

von Alexander (alecxs)


Lesenswert?


von Veit D. (devil-elec)


Lesenswert?

Hallo Alex,

da gab es scheinbar ein Missverständnis.  ;-)
Offtopic: Wegen hterm. Wir teilen uns rein. Ich frage an und du 
spendest. Okay?

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

wenn er noch lebt

von Veit D. (devil-elec)


Lesenswert?

Hallo,

hterm Anfrage ist raus.

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.