Hallo zusammen!
Ich habe für eine Ausstellung ein interaktives Exponat gebaut was mit einem Arduino Uno gesteuert wird.
Ein Teil des Exponats ist eine 7-Segment Anzeige, welche sekundenweise von 1 bis 9 hochzählt, so lange eine Lichtschranke unterbrochen wird (licht3==LOW).
Das funktioniert auch eine Weile.
Irgendwann aber zeigt die Anzeige nur noch 0 und der Counter zählt nicht mehr. Die Lichtschranke funktioniert, der Rest des Programms auch, nur der Counter nicht.
Komischerweise hilft Neustarten des Arduino nicht um den Fehler zu beheben, nur wenn ich das Programm neu aufspiele funktioniert es wieder (eine Weile, wie lange genau konnte ich noch nicht reproduzieren).
Der dazugehörige Programmteil ist die letzte große If-Abfrage "if (countdown){...}" ganz am Ende:
#include "SevSeg.h" //7-Segment-Anzeig Bib
#include <Servo.h> //Servo Bib
Servo ESC; // Servo Objekt zur ESC-Steuerung initialisieren
SevSeg sevseg; //Ein sieben Segment Objekt initialisieren
int potipin= A1;
int potiwert = 0;
int zahl = 10;
int gruen=11;
int gelb=12;
int rot=13;
int licht1;
int licht2;
int licht3;
int drehzahl;
int ESCwert;
bool countdown=false;
bool gewonnen=false;
int pos;
unsigned long previousMillis = 0; // speichert den Zeitpunkt an dem zuletzt geschalten wurde
const long interval = 1000; // Länge der Pause in ms
int potimin=260; // Poitwert in Ruheposition (auslesen per skript)
int potimax=612; // Poitwert in Maximalposition (auslesen per skript)
void setup() {
ESC.attach(0,1000,2000); //Motorsteuerung (pin, min pulse width, max pulse width in microseconds)
pinMode(1, OUTPUT); //Segment b
pinMode(2, OUTPUT); //Segment a
pinMode(3, OUTPUT); //Segment f
pinMode(4, OUTPUT); //Segment g
pinMode(5, OUTPUT); //Segment e
pinMode(6, OUTPUT); //Segment d
pinMode(7, OUTPUT); //Segment c
pinMode(11, OUTPUT); //LED grün
pinMode(12, OUTPUT); //LED orange
pinMode(13, OUTPUT); //LED rot
pinMode(8, INPUT_PULLUP); //Lichtschranke 3
pinMode(9, INPUT_PULLUP); //Lichtschranke 2
pinMode(10, INPUT_PULLUP); //Lichtschranke 1
pinMode(A0, OUTPUT); //Drehzahlmesser
//Einstellungen 7-Segment-Anzeige:
byte numDigits = 1; //Hier wird die Anzahl der Ziffern angegeben
byte digitPins[] = {}; //Die Pins zu den Ziffern werden festgelegt
byte segmentPins[] = {2, 1, 7, 6, 5, 3, 4}; //Die Pins zu den Segmenten a-f werden festgelegt
bool resistorsOnSegments = true;
byte hardwareConfig = N_TRANSISTORS;
bool updateWithDelays = false; // Default 'false' is Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected. Then, you only need to specify 7 segmentPins[]
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
digitalWrite(gruen, HIGH); //Grüne LED ein
sevseg.setBrightness(1);
}
void loop() {
licht1 = digitalRead(10); //Lichtschranken auslesen
licht2 = digitalRead(9);
licht3 = digitalRead(8);
potiwert =analogRead(potipin); // liest den Poti aus
drehzahl = map(potiwert,potimin+40,potimax,31,4300); // Wert skalieren: 31...4300Hz für Drehzahlmesser
if(potiwert<potimin+10){ // Nullstellung des Drehzahlmessers bei kleinem Potiwert erzwingen
noTone(A0); // Frequenzgenerator für Drehzahlmesser aus
digitalWrite(A0, LOW); // Ausgang für Drehzahlmesser LOW
}
else{
tone(A0,drehzahl); // Rechtecksignal an Drehzahlmesser ausgeben
}
ESCwert = map(potiwert,potimin,potimax, 0, 180); // Wert skalieren (value between 0 and 180)
ESC.write(ESCwert); // Signal an ESC senden
if(licht1==LOW){ //Startposition erkennen
pos=1;
digitalWrite(rot, LOW);
digitalWrite(gruen, HIGH);
sevseg.blank();
sevseg.refreshDisplay();
zahl = 10;
}
if(licht2==LOW && pos==1) // von unten in Lichtschranke 2 fahren
{
digitalWrite(gruen, LOW);
digitalWrite(gelb, HIGH);
countdown=true;
pos=2;
}
if (countdown){
if (millis() - previousMillis >= interval) { // Falls mehr als 1000 ms vergangen sind
previousMillis = millis(); // Zeitpunkt der letzten Schaltung wird festgehalten
zahl--;
sevseg.setNumber(10-zahl); // Zahl für Segmentanzeige setzten: hochzählen: (10-zahl) , runterzählen: (zahl)
sevseg.refreshDisplay(); // Anzeige aktualisieren
if(zahl==0){ //Countdown abgelaufen
digitalWrite(gruen, HIGH);
digitalWrite(gelb, LOW);
//sevseg.blank(); // Segmentanzeige zurücksetzen
sevseg.setNumber(9-zahl); //Letzte Zahl anzeigen
sevseg.refreshDisplay();
countdown=false;
gewonnen=true;
zahl=10;
}
}
if (licht3==LOW){ //Linie wird überfahren
countdown=false;
//sevseg.blank(); // Zahl für Segmentanzeige zurücksetzen
//sevseg.refreshDisplay();
zahl=10;
gewonnen=false;
pos=3;
digitalWrite(gelb, LOW);
digitalWrite(rot, HIGH);
ESC.write(40); //Motor langsamer werden lassen
delay(500);
ESC.write(0); // Motor aus
noTone(A0); // Rechecksignal aus
digitalWrite(A0, LOW); // Ausgang auf LOW
delay(2000);
while(potiwert>potimin+10){ // Warten bis hebel in Nullstellung zurückgebracht wurde
potiwert =analogRead(potipin); // Poti wieder aktiveren
delay(100);
}
}
if (licht2==HIGH){ //Countdown bereich wird nach unten verlassen
countdown=false;
sevseg.blank(); // Zahl für Segmentanzeige setzten
sevseg.refreshDisplay();
zahl=10;
gewonnen=false;
pos=1;
digitalWrite(gelb, LOW);
digitalWrite(gruen, HIGH);
}
}
}