Hallo Community,
für die Modellbahnsteuerung verwende ich einen MEGA 2560 mit drei Portextender MCP23017 über IIC für die Ansteuerung und Rückmeldung von Weichenantrieben.
Jeweils Port A0..A7 als Ausgänge/Ansteuerung und Port B0..B7 als Rückmeldung.
Gleichzeitig benötige ich die Modellzeit für diverse Steuerungen und für einen Watchdog.
Bei dem abgespeckten Code anbei (alles hab ich nicht rausgeschmissen) begibt es sich, dass jeweils nach ca. 30s der Wert für "Modellzeit = millis()" auf 0 zurückgesetzt wird!
(Hierfür lasse ich mir den Wert Probehalber auf den Seriellen Monitor anzeigen..)
Nach einigen Minuten (ca. 10 .. 15min) hängt sich das Progamm dann auf.
Ich verstehe nicht, wieso der millis()-Wert zurückgesetzt wird!?
Über den delay-Wert kann man die Sekunden, bis die Rücksetzung erfolgt, steuern... ![]()
Ich hoffe, ich habe alle wesentlichen Kriterien zum Problem reingeschrieben.
Vielleicht kann mir jemand helfen....
Grüße, Torsten.
// Test der Weichenansteuerung und -Rückmeldung über IIC für das Modul Bahnhof-West
// 3 Portextender und hex20 bis 22
// jeweils 2 WA5 angesteuert,
// Ports A0..A7 Ansteuerung Rotlage/Grünlage einzeln
// Ports B0..A7 Rückmedlung Rotlage/Grünlage einzeln
#include "Wire.h"
#include "Adafruit_MCP23X17.h"
Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;
Adafruit_MCP23X17 mcp3;
const int ledPin = LED_BUILTIN; // the number of the LED pin
// Variable für Stellungsmeldung der Weichen, initialisiert mit false = 0
bool W1_RL = false; // Abfrage Weiche 1, Weiche 4 läuft immer mit
bool W1_GL = false; //
bool W3_RL = false; // Abfrage Weiche 3, Weiche 2 läuft immer mit
bool W3_GL = false; //
bool W5_RL = false; // Abfrage Weiche 5
bool W5_GL = false; // Abfrage Weiche 5
bool W6_RL = false; // Abfrage Weiche 6
bool W6_GL = false; //
bool W7_RL = false; // Abfrage Weiche 7
bool W7_GL = false; //
bool W8_RL = false; // Abfrage Weiche 5
bool W8_GL = false; // Abfrage Weiche 5
bool W9_RL = false; // Abfrage Weiche 5
bool W9_GL = false; // Abfrage Weiche 5
bool W10_RL = false; // Abfrage Weiche 1, Weiche 4 läuft immer mit
bool W10_GL = false; //
bool W11_RL = false; // Abfrage Weiche 5
bool W11_GL = false; // Abfrage Weiche 5
bool W12_RL = false; // Abfrage Weiche 3, Weiche 2 läuft immer mit
bool W12_GL = false; //
bool W13_RL = false; // Abfrage Weiche 6
bool W13_GL = false; //
bool W14_RL = false; // Abfrage Weiche 14
bool W14_GL = false; //
byte WA1_2 = 0b01010101; // Variable zum Senden an portexpander 0x20, WA1/2 sind Weichen 5, 8, 9 und 11, 1 bedeutet kein Ausgnagssignal
byte WA3_4 = 0b01010101; // Variable zum Senden an portexpander 0x21, WA3/4 sind Weichen 1-4, 7 und 7, 1 bedeutet kein Ausgnagssignal
byte WA5_6 = 0b01010101; // Variable zum Senden an portexpander 0x22, WA5/6 sind Weichen 10, 12, 13 und 14, 1 bedeutet kein Ausgnagssignal
byte RM_WA1_2; // Variable zur Rückmeldung der Weichenstellung
byte RM_WA3_4;
byte RM_WA5_6;
// sonstige Variable
int ledState = LOW; // ledState used to set the LED for watchdog
unsigned long previousMillis = 0; // will store last time LED was updated
int interval = 1000; // interval at which to blink (milliseconds) the watchdog
unsigned long Modellzeit;
int gesendeterWert = 0;
void setup() {
pinMode(ledPin, OUTPUT);
// I2C-Bus aktivieren und Ports definieren
mcp1.begin_I2C(0x20); // definiere bei Portexpander mit Adresse hex20 Ports A0 bis A7 als Ausgänge und B0 bis B7 als Eingänge
for (int i=0;i<8;i++)
mcp1.pinMode(i, OUTPUT);
mcp1.writeGPIOA(WA1_2); // Vorbelegung für die Ausgänge, 1 bedeutet Ausgang nicht gesetzt
WA1_2 = 0b11111111;
for (int i=8;i<16;i++)
mcp1.pinMode(i, INPUT_PULLUP);
mcp2.begin_I2C(0x21); // definiere bei Portexpander mit Adresse hex20 Ports A0 bis A7 als Ausgänge und B0 bis B7 als Eingänge
for (int i=0;i<8;i++)
mcp2.pinMode(i, OUTPUT);
mcp2.writeGPIOA(WA3_4);
WA3_4 = 0b11111111;
for (int i=8;i<16;i++)
mcp2.pinMode(i, INPUT_PULLUP);
mcp3.begin_I2C(0x22); // definiere bei Portexpander mit Adresse hex20 Ports A0 bis A7 als Ausgänge und B0 bis B7 als Eingänge
for (int i=0;i<8;i++)
mcp3.pinMode(i, OUTPUT);
mcp3.writeGPIOA(WA5_6);
WA5_6 = 0b11111111;
for (int i=8;i<16;i++)
mcp3.pinMode(i, INPUT_PULLUP);
Serial.begin(9600);
}
// Ansteuerung Weichen erster Portexpander, Beispiel
void set_W5_RL(){
bitClear(WA1_2, 0); // ursprünglich auf 1 --> kein Ausgangssignal
mcp1.begin_I2C(0x20); // Kommunikation mit hex20
mcp1.writeGPIOA(WA1_2); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA1_2, 0); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp1.writeGPIOA(WA1_2); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
void set_W5_GL(){
bitClear(WA1_2, 1); // ursprünglich auf 1 --> kein Ausgangssignal
mcp1.begin_I2C(0x20); // Kommunikation mit hex20
mcp1.writeGPIOA(WA1_2); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA1_2, 1); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp1.writeGPIOA(WA1_2); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
// Ansteuerung Weichen zweiter Portexpander, Beispiel
void set_W1_RL(){
bitClear(WA3_4, 0); // ursprünglich auf 1 --> kein Ausgangssignal
mcp2.begin_I2C(0x21); // Kommunikation mit hex21
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA3_4, 0); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
void set_W1_GL(){
bitClear(WA3_4, 1); // ursprünglich auf 1 --> kein Ausgangssignal
mcp2.begin_I2C(0x21); // Kommunikation mit hex21
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA3_4, 1); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
void set_W3_RL(){
bitClear(WA3_4, 2); // ursprünglich auf 1 --> kein Ausgangssignal
mcp2.begin_I2C(0x21); // Kommunikation mit hex21
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA3_4, 2); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
void set_W3_GL(){
bitClear(WA3_4, 3); // ursprünglich auf 1 --> kein Ausgangssignal
mcp2.begin_I2C(0x21); // Kommunikation mit hex21
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA3_4, 3); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp2.writeGPIOA(WA3_4); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
// Ansteuerung Weichen dritter Portexpander, Beispiel
void set_W10_RL(){
bitClear(WA5_6, 0); // ursprünglich auf 1 --> kein Ausgangssignal
mcp3.begin_I2C(0x22); // Kommunikation mit hex22
mcp3.writeGPIOA(WA5_6); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA5_6, 0); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp3.writeGPIOA(WA5_6); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
void set_W10_GL(){
bitClear(WA5_6, 1); // ursprünglich auf 1 --> kein Ausgangssignal
mcp3.begin_I2C(0x22); // Kommunikation mit hex22
mcp3.writeGPIOA(WA5_6); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
delay(200);
bitSet(WA5_6, 1); // wieder auf 1 setzen --> kein Ausgnagssignal
mcp3.writeGPIOA(WA5_6); // Schreibe die aktuelle Belegung für die Ausgänge Bank A, O bedeutet Ausgang gesetzt
}
// Stellen der Weichenstraßen, Beispiel
void set_G1_NS(){
if (W1_RL){
set_W1_GL();
delay(500); // kurzen Zeitversatz bis zur nächsten Weiche
}
if (W3_RL){
set_W3_GL();
delay(500);
}
}
void loop() {
//Watchdog
Modellzeit = millis();
if (Modellzeit - previousMillis >= interval) {
previousMillis = Modellzeit;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
Serial.print("aktuelle Zeit: ");
Serial.println(Modellzeit);
}
delay(100);
//Rücklesen der Weichenstellung
mcp1.begin_I2C(0x20); // Kommunikation mit hex20
RM_WA1_2 = mcp1.readGPIOB(); // lies die Belegung der Eingänge der Bank B
W5_GL = !bitRead(RM_WA1_2, 0); // bitweise Zuordnung
W5_RL = !bitRead(RM_WA1_2, 1);
W8_GL = !bitRead(RM_WA1_2, 2);
W8_RL = !bitRead(RM_WA1_2, 3);
W9_GL = !bitRead(RM_WA1_2, 4);
W9_RL = !bitRead(RM_WA1_2, 5);
W11_GL = !bitRead(RM_WA1_2, 6);
W11_RL = !bitRead(RM_WA1_2, 7);
mcp2.begin_I2C(0x21); // Kommunikation mit hex21
RM_WA3_4 = mcp2.readGPIOB(); // lies die Belegung der Eingänge der Bank B
W1_GL = !bitRead(RM_WA3_4, 0); // bitweiese Zuordnung
W1_RL = !bitRead(RM_WA3_4, 1);
W3_GL = !bitRead(RM_WA3_4, 2);
W3_RL = !bitRead(RM_WA3_4, 3);
W6_GL = !bitRead(RM_WA3_4, 4);
W6_RL = !bitRead(RM_WA3_4, 5);
W7_GL = !bitRead(RM_WA3_4, 6);
W7_RL = !bitRead(RM_WA3_4, 7);
mcp3.begin_I2C(0x22); // Kommunikation mit hex22
RM_WA5_6 = mcp3.readGPIOB(); // lies die Belegung der Eingänge der Bank B
W10_GL = !bitRead(RM_WA5_6, 0); // bitweiese Zuordnung
W10_RL = !bitRead(RM_WA5_6, 1);
W12_GL = !bitRead(RM_WA5_6, 2);
W12_RL = !bitRead(RM_WA5_6, 3);
W13_GL = !bitRead(RM_WA5_6, 4);
W13_RL = !bitRead(RM_WA5_6, 5);
W14_GL = !bitRead(RM_WA5_6, 6);
W14_RL = !bitRead(RM_WA5_6, 7);
}
