Hallo Forum,
Ich habe Anfang November begonnen eine Modellbahnanlage zu bauen. Die Gleise sind bereits verlegt. Ich habe mir vorgenommen die Sensoren (Reedkontakte), Signale und Weichen über zwei Microcontroller zu steuern. Diese arbeiten über den I2C Bus zusammen. Der Master ist ein Atmega 32 und der Slave ein Atmega 16. Ich habe allerdings dabei mehrere Probleme und ich hoffe ihr könnt mir dabei helfen.
1. Ich hab das Problem, dass wenn ich Weichen schalte, diese manchmal eine Störung auf das komplette System geben. Die Weichenantriebe laufen mit 16VAC und werden mittels eines Relais und einem ULN2004 vom Microcontroller aus gesteuert. Das heißt, es gibt eine galvanische Trennung zwischen µC und dem Antrieb und zum anderen laufen diese beiden über verschiedene Trafos, d.h. auch hier ist eine galvanische Trennung vorhanden. Die Frage ist nur, ob man was machen kann, damit nicht das ganze System zusammenbricht/gestört wird?
(Ich würde auch gern eine Zeichnung davon mit hochladen, ich hab nur kein geeignetes Zeichenprogramm. Könnt ihr mir ein kostenloses empfehlen?)
2. Ich verwende den I2C code vom RP6. Der funktioniert einwandfrei. Ich kann vom Master Befehle senden und diese werden vom Slave auch erfolgreich angenommen und verarbeitet. Meine Frage ist nur, ich habe die Reedkontakte am Slave angeschlossen. Jetzt möchte ich aber deren Zustände am Master auslesen. Leider funktioniert das nicht.
Auszug aus dem Slave, je nachdem ob der Sensor 1 oder 0 hat wird ja das entsprechende Bit in diesem Sensoren1.byte auf 1 oder 0 gesetzt.
Code:
union {
uint8_t byte;
struct {
uint8_t S1S4:1;
uint8_t S2S3:1;
uint8_t S5S8:1;
uint8_t S6S7:1;
uint8_t S9S0S12:1;
uint8_t S10S11:1;
uint8_t S20:1;
uint8_t S21:1;
};
} Sensoren1;
----
#define I2C_REG_STATUS1 0
#define I2C_REG_STATUS2 1
----
void task_updateRegisters(void)
{
if(!I2CTWI_readBusy)
{
I2CTWI_readRegisters[I2C_REG_STATUS1] = (uint8_t)(Sensoren1.byte);
I2CTWI_readRegisters[I2C_REG_STATUS2] = (uint8_t)(Sensoren2.byte);
}
}
----
void Gleissensor(void)
{
if(adc7 < 10)
{
Sensoren1.S2S3 = 1;
}
else if(adc7 > 300 && adc7 < 700)
{
Sensoren1.S1S4 = 1;
}
----
while(true)
{
Gleissensor();
task_ADC();
//task_Zugbremsung();
task_commandProcessor();
task_updateRegisters();
}
und über diesen will ich es bei Master abrufen und in eine Testausgabe umwandeln
Code:
#define Weichencontroller 10 // Adresse des Slave Microcontrollers
----
uint8_t messageBuf[2]; // Buffer for I2C Data
void test(void) //test() wird in der while-Schleife immer wieder abgerufen
{
I2CTWI_transmitByte(Weichencontroller, 0); // Start with register 0...
I2CTWI_readBytes(Weichencontroller,messageBuf, 2); //Sensoren1.byte und Sensoren2.byte auslesen
if(messageBuf[0] == 128) // 128 wäre, wenn Sensoren1.S1S4 betätigt wäre
{
Gleis2links.byte = 255; //steht dafür, dass 8 LEDs der Signale vom Gleis 2 leuchten sollen
}
}
Ich dachte, dass ich damit die Zustände auslesen konnte. Gibt es eine andere / bessere Lösung dafür, oder was mache ich falsch? Ich bin leider ziemlich ratlos. Könnte man die Abfrage auch so machen, dass sie nur durchgeführt wird, wenn es eine Änderung gab?
3. Wäre es sinnvoll, wenn ich den Watchdog aktiviere?
Ich hoffe ihr könnt mir helfen. Ich bin für jede Antwort dankbar. Wenn ihr noch Informationen benötigt, dann sagt es mir bitte. Ein Zeichenprogramm (freeware) wäre auch sehr schön.
Vielen Dank.
Frohe Weihnachten
MfG
Daniel
Lesezeichen