Projekt Modellfeuerwehrauto: Blinken without delay, Lauflicht, später Ton

// Zwei mit unterschiedlicher Frequenz blinkende LEDs
#define Blinker  13
#define delayBlinker  500  // Verzoegerungszeit in Millisekunden
#define BL1  1
#define delayBL1  100  
#define BL2  2
#define delayBL2  100
#define BL3  3
#define delayBL3  100  
#define BL4  4
#define delayBL4  100
#define BL5  5
#define delayBL5  100

unsigned long millisBlinker = millis();
unsigned long millisBL1 = millis();
unsigned long millisBL2 = millis();
unsigned long millisBL3 = millis();
unsigned long millisBL4 = millis();
unsigned long millisBL5 = millis();

void setup() {
  pinMode(Blinker, OUTPUT);
  pinMode(BL1, OUTPUT);
  pinMode(BL2, OUTPUT);
  pinMode(BL3, OUTPUT);
  pinMode(BL4, OUTPUT);
  pinMode(BL5, OUTPUT);
}

void loop() {
  if (millis() > millisBlinker + delayBlinker) {                  // Verzoegerungszeit abgelaufen?
    digitalWrite(Blinker, !digitalRead(Blinker));   // invertiert den Ausgang von LED1
    millisBlinker = millis();                                  // neue Zeit merken
  }
  if (millis() > millisBL1 + delayBL1) {
    digitalWrite(BL1, !digitalRead(BL1));   
    millisBL2 = millis();
  }
  if (millis() > millisBL2 + delayBL1 + delayBL2) {
    digitalWrite(BL2, !digitalRead(BL2));   
    millisBL2 = millis();
  }
  if (millis() > millisBL3 + delayBL1 + delayBL2 + delayBL3) {
    digitalWrite(BL3, !digitalRead(BL3));   
    millisBL3 = millis();
  }
  if (millis() > millisBL4  + delayBL1 + delayBL2 + delayBL3 + delayBL4) {
    digitalWrite(BL4, !digitalRead(BL4));   
    millisBL4 = millis();
  }
  if (millis() > millisBL5 + delayBL1 + delayBL2 + delayBL3 + delayBL4 + delayBL5) {
    digitalWrite(BL5, !digitalRead(BL5));   
    millisBL5 = millis();
  }
}

Schön wieder von Dir zu lesen!

Gestatte mir etwas Kritik:

#define BL1  1

I/O 0 und 1 werden beim UNO für USB benötigt, da würde ich keine LED anschließen!

if (millis() > millisBlinker + delayBlinker) {

Das stammt möglicherweise von mir. Inzwischen habe ich aber gelernt, daß dies beim Überlauf von millis() nicht funktioniert. Besser

if (millis() - millisBlinker >= delayBlinker) {

Mir ist nicht ganz klar, welches Muster Du erzeugen möchtest. Alle LEDs bis auf eine aus, dann die eine aus und die NachbarLED an, also das klassische Lauflicht? Dafür hätte ich einen Vorschlag:

byte ein = LOW;
byte aus = HIGH;

const int BLINKER = 13;   //Warnblinker
const int BL1 = 2;  //BL = Blaulicht Lauflicht
const int BL2 = 3;
const int BL3 = 4;
const int BL4 = 5;
const int BL5 = 6;


const int BLAULICHTDELAY = 75;
const int BLINKERDELAY = 750;

void setup() {
  pinMode (BLINKER, OUTPUT);
  pinMode (BL1, OUTPUT);
  pinMode (BL2, OUTPUT);
  pinMode (BL3, OUTPUT);
  pinMode (BL4, OUTPUT);
  pinMode (BL5, OUTPUT);
}

void loop() {
  digitalWrite (BL1, !((millis() / BLAULICHTDELAY) % 5 == 0)); // '%' nennt sich "modulo" und ist der Restwert der Ganzzahldivision
  digitalWrite (BL2, !((millis() / BLAULICHTDELAY) % 5 == 1));
  digitalWrite (BL3, !((millis() / BLAULICHTDELAY) % 5 == 2));
  digitalWrite (BL4, !((millis() / BLAULICHTDELAY) % 5 == 3));
  digitalWrite (BL5, !((millis() / BLAULICHTDELAY) % 5 == 4));

  digitalWrite (BLINKER, (millis() / BLINKERDELAY) % 2 == 0);
}

Dann noch die Deinem Vorschlag näher liegende Variante:

const int BLINKER = 8;   //Warnblinker
const byte BlaulichtLEDs[] = {2, 3, 4, 5, 6};
const byte AnzahlBlaulichtLEDs = (sizeof(BlaulichtLEDs) / sizeof(BlaulichtLEDs[0]));
const int BLINKERDELAY = 500;
const int BLAULICHTDELAY = 100;

unsigned long millisBlinker = millis();
unsigned long millisBlaulicht = millis();
byte indexBlaulicht;

void setup() {
  pinMode(BLINKER, OUTPUT);
  for (indexBlaulicht = 0; indexBlaulicht < AnzahlBlaulichtLEDs; indexBlaulicht++) {
    pinMode(BlaulichtLEDs[indexBlaulicht], OUTPUT);
  }
  indexBlaulicht = 0;
  digitalWrite(BlaulichtLEDs[indexBlaulicht], !digitalRead(BlaulichtLEDs[indexBlaulicht]));
}

void loop() {
  if (millis() - millisBlinker >= BLINKERDELAY) {    // Verzoegerungszeit abgelaufen?
    millisBlinker = millis();                        // neue Zeit merken
    digitalWrite(BLINKER, !digitalRead(BLINKER));    // invertiert den Ausgang von LED1
  }
  if (millis() - millisBlaulicht >= BLAULICHTDELAY) {
    millisBlaulicht = millis();
    digitalWrite(BlaulichtLEDs[indexBlaulicht], !digitalRead(BlaulichtLEDs[indexBlaulicht]));
    indexBlaulicht++;
    indexBlaulicht= indexBlaulicht % AnzahlBlaulichtLEDs;
    digitalWrite(BlaulichtLEDs[indexBlaulicht], !digitalRead(BlaulichtLEDs[indexBlaulicht]));
  }
}

Kann mir hier jemand nochmals helfen? Das Aussetzten zeigt sich dadurch, dass alle LEDs ausgehen und Pin 13 zwei-drei mal kurz aufblinkt, dann geht alles wieder weiter.

Das sieht wie ein Reset aus.
Der Bootloader blinkt mit der LED an 13.

Hallo,
klar darf kritisiert werden, ich bin ja froh darum, nur so lernt man es.

Danke für deine Antwort.

Ich habe deine Vorschläge mal hochgeladen und die 2. Variante trifft meine Vorstellungen. Ich verstehe allerdings immer noch nicht genau warum die Unterbrechung drin ist, und wie ich die rausbekomme?

Combie hat ja geschrieben, dass es eventuell ein Reset sein könnte.

Läuft da intern eine Zähler ab, der nach einer gewissen Zeit resetet werden muss?

Mögliche Ursachen für spontane Resets:

  1. irgendwelche Störungen (auf der Reset Leitung)
  2. WDT aktiviert, aber nicht richtig abgehandelt
  3. Spannungseinbrüche BOD
  4. Speicherüberlauf(Rekursionen,dynamische Anforderungen)
  5. Aktivierte Interrupts und fehlende/defekte Abhandlung
  6. Zeiger, welche in die Wiese zeigen

Die Möglichkeiten sind vielfältig.
Aber in deinem Code ist nichts davon zu sehen!
Von daher kommen eher 1 bis 3 in Betracht.

Ich ergänze noch:

  1. Leitender Untergrund oder Gerätefüßchen. Ich kenne da jemanden, den ich morgens im Spiegel sehe, der es mit Gerätefüßchen geschaft hat, zwei UNOs lahm zu legen, glücklicherweise nur vorübergehend. Metallspäne vom Sägen sind auch geeignet.

Beide Sketche von mir (#21) sind längere Zeit ohne Störung auf einem MEGA 2560 durchgelaufen.

Okay, ich habe soeben einen sehr alten Sketch durchlaufen lassen und dort war das Problem auch. Shit! Kann man das irgendwie beheben? Mit dem Reset Button funktioniert es leider nicht.

Danke Euch :slight_smile:

Mit dem Reset Button funktioniert es leider nicht.

Was soll damit funktionieren?

Kann man das irgendwie beheben?

Klar ist das Problem zu beheben!
Sobald die Ursache geklärt ist.......

Ich wiederhole mich einfach mal: "Von daher kommen eher 1 bis 3 in Betracht."

In welchen zeitlichen Abständen passiert der Reset?
Exakt regelmäßig? Alle 2,x Sekunden?
Dann hast du irgendwann mal den WDT aktiviert.

Unregelmäßig?
Stromversorgung.
Spitzen von anderen Geräten... usw ...

Hallo,

Ich dachte der Reset Button setzt das Board in die Werkseinstellungen zurück, was ich jetzt weiß nicht stimmt. :slight_smile:

Der Reset kommt regelmäßig und exakt alle 30,5 sec.

Dann wird es höchstwahrscheinlich der WDT sein. Wie kann ich diesen wieder entfernen?

Danke für die Antwort und Hilfe.

Du kannst mit irgendeinem ISP Programmer die Fuses ändern.

Alternativ:
Innerhalb der 30,5 Sekunden den Watchdog anstoßen.
(wobei die 30,5s eine mir unbekannte Größe ist)

#include <avr/wdt.h>

void loop()
{
  wdt_reset(); 
}

Hi Danke für deine Antwort. :slight_smile: ISP Programmer sagt mir leider gar nichts. Ich bin blutiger Anfänger. Die Alternative habe ich ausgeführt, leider jedoch hat es nicht funktioniert. :o Ich habe folgenden Sketch verwendet, da er gemeckert hat, dass was fehlt:

void setup(){
}

#include <avr/wdt.h>


void loop()
{
  wdt_reset();
}

Kann ich auch einfach den Atmega 328P ersetzen?

Fire_Minion:
Hi Danke für deine Antwort. :slight_smile: ISP Programmer sagt mir leider gar nichts. Ich bin blutiger Anfänger. Die Alternative habe ich ausgeführt, leider jedoch hat es nicht funktioniert. :o Ich habe folgenden Sketch verwendet, da er gemeckert hat, dass was fehlt:

void setup(){

}

#include <avr/wdt.h>

void loop()
{
  wdt_reset();
}




Kann ich auch einfach den Atmega 328P ersetzen?

Macht er denn mit dem Script immer noch alle 30,5s Resets?

Klar kannst du den ersetzen.
(wenn dich nix daran hindert)
Nimm einen mit aufgespieltem Bootloader.

Aber ich kann mir nicht vorstellen, dass dein Prozessor einen solchen Defekt hat.
Ich vermute ganz stark, dass das Problem woanders liegt.
Verborgen.
Manchmal reicht es den Blickwinkel zu ändern.....

Nachtrag:
Ich wette, wenn du den PC(das USB Kabel) abziehst, und mit einer externen Stromversorgung arbeitest, tuts das wie gewünscht.
Denn meine Glaskugel sagt:
Irgendeine Software auf deinem PC reitet auf den Seriellen Schnittstellen rum und verursacht den Reset.

Ich werde verrückt

Hab es gerade getestet und an einen anderen PC angeschlossen und in der Tat, da läuft es so wie ich es will ohne Unterbrechung. Wieder umstöpseln an meinen PC Unterbrechung wieder da.

DANKE!!!!!

PS: Schau bitte nochmal in deine Glaskugel ob sie 7 Zahlen von 1-49 anzeigt für diesen Samstag.... das wäre mega super!!!! :slight_smile:

Nee...
Das tue ich nicht!
Es sei denn, du gibst mir 70% ab...

DANKE!!!!!

Gern geschehen!

Tipp:
Ein Serieller Monitor, wie dieser FREE Serial Port Monitor RS232 Communication Software Data Sniffer Analyzer kann dir den Verursacher zeigen.