Ich habe mich in den vergangenen Tagen ein wenig mit grafischen Programmierumgebungen beschäftigt. Ich bin ja eigentlich kein großer Fan von grafischer Programmierumgebung (im Zusammenhang mit C++), aber demnächst sind kurze Workshops geplant für Leute zwischen 9 und 13 Jahren und aus vorigen Veranstaltungen ist bekannt, dass das Tippen (von Programmcode) in dieser Altersgruppe für die meisten eine ziemliche Qual ist.
So wollen wir (ich mache das gemeinsam mit einem Kollegen) es diesmal mit einer grafischen Programmierumgebung versuchen. Wir haben uns für mBlock entschieden. https://ide.mblock.cc/
Die Basis von mBlock ist wohl Scratch und man kann verschiedene Hardware programmieren (auch in unterschiedlichen Sprachen).
Man kann zum Beispiel Arduino Uno als "Gerät" wählen und verschiedene Libraries hinzufügen. Da wir mit Neopixel/WS2812 arbeiten wollen, habe ich eine passende Library gesucht und es ausprobiert.
Nachdem man ein Tool zum Upload heruntergeladen und installiert hat, funktioniert es recht gut. Der "grafische Code" wird zuerst in C++ "umgewandelt", das Kompilieren erfolgt am Server von mBlock, der entstandene Maschinencode wird dann mit dem Upload-Tool auf den Uno geladen. Das läuft prinzipiell einigermaßen glatt.
Ich persönlich finde dieses "grafische Zeug" ja nicht sooo prickelnd, aber ich bin ja auch nicht die Zielgruppe (und habe mit Tippen überhaupt kein Problem).
Für einfache Projekte und zum ersten Einstieg kann das schon passen (wir werden es merken).
Den generierten C++ Code kann man sich anschauen, aber er ist nicht direkt veränderbar. Und hier komme ich endlich zu meiner eigentlichen Frage...
Als Beispiel habe ich einfach mal den berühmten Blink-Sketch in mBlock erstellt.
Hier zusammen mit dem generierten C++ Code:
Und hier nochmal der C++ Code:
// generated by mBlock5 for <your product>
// codes make you happy
#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>
void _delay(float seconds) {
long endTime = millis() + seconds * 1000;
while(millis() < endTime) _loop();
}
void setup() {
pinMode(9,OUTPUT);
while(1) {
digitalWrite(9,1);
_delay(1);
digitalWrite(9,0);
_delay(1);
_loop();
}
}
void _loop() {
}
void loop() {
_loop();
}
Wenn ich mir den generierten C++ Code anschaue, dann zieht es mir bei Funktion _delay die Schuhe aus, bei dieser Zeile:
long endTime = millis() + seconds * 1000;
Da gibt es also endTime (vorzeichenbehaftet) und millis (vorzeichenlos) und seconds (float) und es wird addiert...
Ich bin ja kein Profi-Programmierer, aber so viele unterschiedliche Datentypen in einer Berechnung, würde ich bei Code den ich selbst schreibe eher vermeiden. Vor allem bei den vorzeichenlosen und vorzeichenbehafteten Datentypen in einer Berechnung laufen mir Schauer über den Rücken.
Aber vielleicht ist das auch nur meine Paranoia.
Ich frage mich, was passiert beim Überlauf von "endTime". Der Überlauf wird wohl nach etwa 24,8 Tagen stattfinden, da wird "endTime" dann negativ.
Und dann wird wahrscheinlich endlos (bzw. 24,8 Tage) gewartet, denn ... (ich setze hier mal konkrete Zahlen ein, wie sie nach 24,8 Tagen ungefähr sein könnten):
while (2147483649 < -2147483000) _loop();
Oder sind meine Überlegungen falsch?