Calliope stürzt immer wieder ab

Seit einiger Zeit habe ich meine CO2-Ampel auf dem Calliope V1 und V2 am Laufen.
Jetzt habe ich mein Programm erweitert, so dass der Calliope auch auf Tastendruck direkt die Werte auf dem Display ausgibt.

Allerdings stürzt er immer wieder ab (komisches Muster auf dem Display und dann Reset). Dies passiert vor allem, wenn nach einem Tastendruck Text angezeigt wird. Allerdings an unterschiedlichen Stellen der Textanzeige.

Hat jemand einen Tipp, was zu dieser Instabilität führen könnte?
Die Stromversorgung schliesse ich aus, da ich die Calliope immer am USB-Port oder einer geladenen Powerbank betreibe.

Kann es sein, dass ich dem Calliope zu viel zumute?

Hallo Ralf,

kurz Vorweg: mein Sohn hat kürzlich zum Geburtstag einen Calliope Mini geschenkt bekommen. Wir haben dann direkt einen Grove-SDC30-Sensor bestellt und Deine CO2-Ampel ausprobiert. Cooles Projekt! Das mit den Abstürzen ist mir allerdings auch direkt aufgefallen, deshalb hatte ich mich bisher auch noch nicht getraut, eine Kalibrierung vorzunehmen. Außerdem hat die RGB-LED zwischenzeitlich immer mal wieder eine falsche Farbe angezeigt!

Da ich mich noch nicht wirklich gut mit dem Calliope System auskenne, hat es mich erst einmal ein wenig Mühe gekostet herauszufinden, welche Bibliothek Du für den SDC30 verwendest! In Deinen Repositories auf github existieren ja die Projekte pxt-SCD30, scd30-lib sowie scd30. Das die Erweiterung pxt-SCD30 verwendet wird, könntest Du ja vielleicht in dem Readme zu deiner CO2-Ampel erwähnen!

Die genauen Ursachen für die Abstürze kann ich Dir auch noch nicht nennen, ich habe aber ein paar Spekulationen angestellt und bei mir scheint jetzt zumindest alles stabil zu laufen!

Um den Code besser verstehen zu können, habe ich mir folgenden Artikel durchgelesen: https://makecode.microbit.org/device/reactive

In der Bibliothek wird ja eine eigene Endlosschleife gestartet
github: rdmueller/pxt-SCD30/blob/master/main.ts : control.inBackground()
in welcher im Hintergrund ununterbrochen alle zwei Sekunden über den I2C-Bus Messdaten beim Sensor abgeholt werden.

Dazu kommt die Endlosschleife Deiner Ampelanwendung
github: rdmueller/co2-ampel/blob/master/main.ts : basic.forever()

Wenn man jetzt eine Taste drückt, muss der Scheduler also die Rechenzeit an drei „gleichzeitig laufende“ Unterprogramme verteilen. Bei jedem Aufruf von basic.pause() wird nach meinem Verständnis zum nächsten Unterprogramm gewechselt. Wie schnell aber z.B. Funktionen wie basic.showString() wieder Rechenzeit abgeben, konnte ich in der Dokumentation erst einmal nicht finden!

In der Bibliothek wird in der Endlosschleife über die Funktion
readMeasurement() aber z.B. zwischen dem Schreiben und Lesen auf dem
I2C-Bus die Rechenzeit wieder an die anderen Unterprogramme
abgegeben:

pins.i2cWriteNumber(0x61, 0x0300, NumberFormat.UInt16BE, false) basic.pause(10) buf = pins.i2cReadBuffer(0x61, 18, false)

Was passiert, wenn die Pause zu lange dauert? Ist es nicht denkbar, das
der Sensor dann vielleicht keine gültigen Daten mehr zurückliefert?
Im weiteren Verlauf werden die gelesenen Daten ja nicht mehr auf
Plausibilität geprüft sondern einfach weiterverarbeitet! Das könnte ja möglicherweise ein Grund für den Absturz darstellen? Bei
Bedarf ließe sich das ja noch einmal genauer untersuchen, aber
vielleicht kann ja auch ein Calliope-Experte hier im Forum etwas dazu
sagen?

Außerdem ist mir aufgefallen, dass zum Kalibrieren nach drücken der beiden Tasten „AB“ ein Befehl über den I2C-Bus gesendet wird, während offensichtlich im Hintergrund in der Bibliothek weiter Messdaten über I2C abgefragt werden! Hier
herrscht also auch ein großes Konfliktpotential:
Read Measurement Anfrage, in der „Pause“ wird vor dem Lesebefehl in den AB-Tastenhandler gewechselt, wo dann der FRC-Befehl zum Kalibrieren abgesetzt wird…

Und bei der RGB-LED wird ja in jedem Messzyklus die Farbe über den Befehl basic.setLedColor() neu gesetzt, auch wenn sie sich nicht geändert hat! Offensichtlich führt das häufige Neusetzten der Farbe dann zu der falschen Farbanzeige, wobei ich den Fehler hier irgendwo in den Calliope Firmware vermuten würde?!

Um die Ampel zu verbessern, wollte ich deshalb die Endlosschleife in der Bibliothek eliminieren und die Kalibrierfunktion erst dann starten, wenn die letzte readMesurement()-Funktion erfolgreich beendet und gegenüber der Kalibrierfunktion „verriegelt“ wurde. Außerdem wollte ich basic.setLedColor() nur
aufrufen, wenn ein Farbwechsel ansteht!

Um das zu realisieren war es für mich am einfachsten, die pxt-SCD30 Bibliothek
aus dem Projekt zu werfen und die benötigten Funktionen direkt in dem Ampelcode zu integrieren. Immerhin sind das insgesamt noch weniger als 200 Zeilen Code. Trotzdem ist es nach meiner jetzigen Erfahrung leider keine gute Idee, von der JavaScript-Ansicht in die Blockansicht zu wechseln! Beim zurückwechseln wurden bei mir dann manche Kommentare entfernt, andere wurden verdoppelt, hexadezimal angegebene Werte wurden in dezimale Schreibweise umgewandelt, etc. Kurz gesagt: der Code funktioniert zwar weiterhin, wird aber recht unlesbar! Hier nun der geänderte Code:

EDIT: ich habe noch keine Rechte, einen Anhang hinzuzufügen und wenn ich den Code hier einfach einfüge, geht die Formatierung verloren! Soll ich Ihn Dir via Email schicken?

Viele Grüße,
Frank

1 „Gefällt mir“

Hallo Frank,
Danke für die ausführliche Antwort. Das habe ich auch schon vermutet, dass dem Prozessor da vielleicht zu viel nebenbei läuft - aber dass er dann gleich abschmiert?
Den Code kannst Du mir gerne per Mail schicken: ralf.d.mueller@gmail.com
Noch besser wäre es aber, wenn Du einen PR auf Github stellen könntest :slight_smile:

Viele Grüße,
Ralf

Es könnte das gleiche Problem wie hier Fehler beim Bluetooth UART Dienst sein

1 „Gefällt mir“

ja, daran hatte ich auch schon gedacht :grimacing:

so, wie Frank schon vermutet hat, läuft es jetzt besser, wenn die CPU nicht ständig alles gleichzeitig machen soll… :slight_smile:
Danke!

1 „Gefällt mir“

@rdmueller kannst du das Programm hier posten?
Ich habe einen RGB-LED-Ring und den SCD30 Sensor hier am Laufen und zeige parallel nach Tastendruck die Co2 Werte an. Anfangs hatte ich den Effekt auch, da hatte ich den SCD30 aber noch nicht dran, sondern Probleme mit dem NeoPixel Ring, jetzt läuft das aber völlig ohne Aussetzer.

1 „Gefällt mir“

@joern.alraun gerne. Es war diese Version hier: rdmueller/co2-ampel at 8278c190d56a8340ca6223c6bdd08d1cdd706bd4 (github.com)
mit dieser Version der library: rdmueller/pxt-SCD30: SCD30 CO2 Sensor (github.com)

Die Parallelität habe ich jetzt rausgenommen - die Software funktioniert jetzt prima.
Morgen gehen die CO2-Ampeln an die Schule :slight_smile:

1 „Gefällt mir“

Vorsichtshalber könntest Du in der library noch die
basic.pause(10) Aufrufe zwischen den I2C-Schreib- und
Lesekommandos (pins.i2cWriteNumber() und pins.i2cReadBuffer())
durch control.waitMicros(10000) ersetzen! Dann wäre sichergestellt,
dass nicht mitten in der Kommunikation mit dem Sensor der Scheduler
beginnt, andere Unterprogramme abzuarbeiten!

3 „Gefällt mir“