cboden
21.12.2013, 17:11
Hallo,
ich habe eine modulare Steuerung für die Beleuchtung einer Häuser-Szenerie auf einer Modell-Eisenbahn-Anlage gebaut. Das ganze ist - finde zumindest ich ;) - so gut geworden, dass ich es Euch gerne vorstellen würde. Vielleicht bringt es ja den ein oder anderen auf eine Idee.
Herzstück des ganzen ist ein ATtiny Controller auf einem Digispark. Um an die I/O-Pins zu kommen, habe ich ihn auf eine kleine Platine gesetzt, die 4 I/O Pins und einen I2C-Bus über einzelne Stiftleisten heraus führt. Eine weitere Stiftleiste ist für den Anschluss der Versorgungsspannung. Damit man nicht immer erst überlegen muss, wo denn nun Plus und wo Minus hinkommt, habe ich dem ganzen auch gleich noch einen Gleichrichter als Schutz gegen Verpolung spendiert. Ein Spannungsregler ist ja auf dem Digispark-Board schon drauf:
26981
Über den I2C-Bus können dann weitere Platinen mit einem PCF8574 Portexpander angeschlossen werden. Um die Adresse einfach zu konfigurieren, haben die einen 3fach DIP-Schalter. Damit lassen sich also bis zu 8 dieser Platinen an den Bus hängen. Da jede Platine wiederum 8 Kanäle zur Verfügung stellt, können so bis zu 64 Ausgänge geschalten werden. Um kleinere Lasten direkt anschließen zu können, haben diese Platinen dann noch einen ULN2803 (mit entsprechenden Invertern davor, damit er im Ruhe-Zustand sperrt). Zusätzlich hat jede dieser Platinen eine eigenen Spannungsregeler um die max. 500 mA des Treiber Bausteins zur Verfügung stellen zu können.
26982
Die 5 Volt, die mit Hilfe des ULN geschaltet werden sind natürlich zu viel für eine LED. Deshalb habe ich eine kleine Adapter-Platine gebaut, die direkt auf die Pfostenleisten der Treiber-Platine gesteckt werden kann. Hierauf finden sich 8 Vorwiderstände und die entsprechenden Anschlüsse für die LED's.
26983
Zusammen mit der Treiber-Platine sieht das dann so aus:
26984
Durch die stapelbaren Leiterplattenverbinder lassen sich theoretisch auch mehrere dieser Adapter-Platinen übereinander stecken um unterschiedliche LED's anzuschließen.
Alternativ habe ich mir überlegt, dass man ja vielleicht auch mal was anderes als LED's schalten will und habe eine 8fach Relais-Platine gebaut, die direkt vom ULN getrieben werden kann und mit der man bis zu 6 Ampere bei 30 Volt AC/DC schalten kann. Diese wird einfach an Stelle der LED-Adapter-Platine auf das Treiber-Modul gesteckt und fertig.
26985
Hier noch ein einfacher Code, um die max. 64 Kanäle der bis zu 8 Treiber-Platinen per Zufalls-Steuerung ein und aus zu schalten:
// --------------------------------
// Benötigte Bibliotheken einbinden
// --------------------------------
#include <TinyWireM.h> // I2C
// ---------------------
// Konstanten definieren
// ---------------------
#define adrModul1 0x20 // I2C-Adresse für erstes Treiber-Modul
// ----------------------------
// globale Variablen definieren
// ----------------------------
boolean channelBit [64]; // speichert den Schaltzustand der einzelnen Kanäle
unsigned long channelMils [64]; // speichert den nächsten Umschaltzeitpunkt je Kanal
// --------------------------------------------------------
// Setup-Routine (wird automatisch beim Starten ausgeführt)
// --------------------------------------------------------
void setup(){
int i;
// I2C Schnittstelle initialisieren
TinyWireM.begin();
// Zufallszahlen initialisieren
for (i=0;i<64;i++){
channelMils[i] = millis() + random(40000);
channelBit[i] = HIGH;
}
}
// ------------------------------------------------------------
// Haupt-Routine (wird kontinuierlich als Schleife durchlaufen)
// ------------------------------------------------------------
void loop(){
int i;
int j;
int out;
// Zeiten auswerten
for (i=0;i<64;i++){
if (channelMils[i] < millis()){
if (channelBit[i] == LOW){
channelBit[i] = HIGH;
channelMils[i] = millis() + random(60000);
} else {
channelBit[i] = LOW;
channelMils[i] = millis() + random(40000);
}
}
}
// einzelne Module durchgehen
for (j=0; j<8; j++){
// einzelne Bits durchgehen
for (i=0; i<8; i++){
bitWrite(out, i, channelBit[i+j*8]);
}
// Byte an Modul übertragen
writePort(adrModul1+j, out);
}
}
// -----------
// I2C Routine
// -----------
void writePort(int address, byte data) {
TinyWireM.beginTransmission(address);
TinyWireM.send(data);
TinyWireM.endTransmission();
delay(5);
}
ich habe eine modulare Steuerung für die Beleuchtung einer Häuser-Szenerie auf einer Modell-Eisenbahn-Anlage gebaut. Das ganze ist - finde zumindest ich ;) - so gut geworden, dass ich es Euch gerne vorstellen würde. Vielleicht bringt es ja den ein oder anderen auf eine Idee.
Herzstück des ganzen ist ein ATtiny Controller auf einem Digispark. Um an die I/O-Pins zu kommen, habe ich ihn auf eine kleine Platine gesetzt, die 4 I/O Pins und einen I2C-Bus über einzelne Stiftleisten heraus führt. Eine weitere Stiftleiste ist für den Anschluss der Versorgungsspannung. Damit man nicht immer erst überlegen muss, wo denn nun Plus und wo Minus hinkommt, habe ich dem ganzen auch gleich noch einen Gleichrichter als Schutz gegen Verpolung spendiert. Ein Spannungsregler ist ja auf dem Digispark-Board schon drauf:
26981
Über den I2C-Bus können dann weitere Platinen mit einem PCF8574 Portexpander angeschlossen werden. Um die Adresse einfach zu konfigurieren, haben die einen 3fach DIP-Schalter. Damit lassen sich also bis zu 8 dieser Platinen an den Bus hängen. Da jede Platine wiederum 8 Kanäle zur Verfügung stellt, können so bis zu 64 Ausgänge geschalten werden. Um kleinere Lasten direkt anschließen zu können, haben diese Platinen dann noch einen ULN2803 (mit entsprechenden Invertern davor, damit er im Ruhe-Zustand sperrt). Zusätzlich hat jede dieser Platinen eine eigenen Spannungsregeler um die max. 500 mA des Treiber Bausteins zur Verfügung stellen zu können.
26982
Die 5 Volt, die mit Hilfe des ULN geschaltet werden sind natürlich zu viel für eine LED. Deshalb habe ich eine kleine Adapter-Platine gebaut, die direkt auf die Pfostenleisten der Treiber-Platine gesteckt werden kann. Hierauf finden sich 8 Vorwiderstände und die entsprechenden Anschlüsse für die LED's.
26983
Zusammen mit der Treiber-Platine sieht das dann so aus:
26984
Durch die stapelbaren Leiterplattenverbinder lassen sich theoretisch auch mehrere dieser Adapter-Platinen übereinander stecken um unterschiedliche LED's anzuschließen.
Alternativ habe ich mir überlegt, dass man ja vielleicht auch mal was anderes als LED's schalten will und habe eine 8fach Relais-Platine gebaut, die direkt vom ULN getrieben werden kann und mit der man bis zu 6 Ampere bei 30 Volt AC/DC schalten kann. Diese wird einfach an Stelle der LED-Adapter-Platine auf das Treiber-Modul gesteckt und fertig.
26985
Hier noch ein einfacher Code, um die max. 64 Kanäle der bis zu 8 Treiber-Platinen per Zufalls-Steuerung ein und aus zu schalten:
// --------------------------------
// Benötigte Bibliotheken einbinden
// --------------------------------
#include <TinyWireM.h> // I2C
// ---------------------
// Konstanten definieren
// ---------------------
#define adrModul1 0x20 // I2C-Adresse für erstes Treiber-Modul
// ----------------------------
// globale Variablen definieren
// ----------------------------
boolean channelBit [64]; // speichert den Schaltzustand der einzelnen Kanäle
unsigned long channelMils [64]; // speichert den nächsten Umschaltzeitpunkt je Kanal
// --------------------------------------------------------
// Setup-Routine (wird automatisch beim Starten ausgeführt)
// --------------------------------------------------------
void setup(){
int i;
// I2C Schnittstelle initialisieren
TinyWireM.begin();
// Zufallszahlen initialisieren
for (i=0;i<64;i++){
channelMils[i] = millis() + random(40000);
channelBit[i] = HIGH;
}
}
// ------------------------------------------------------------
// Haupt-Routine (wird kontinuierlich als Schleife durchlaufen)
// ------------------------------------------------------------
void loop(){
int i;
int j;
int out;
// Zeiten auswerten
for (i=0;i<64;i++){
if (channelMils[i] < millis()){
if (channelBit[i] == LOW){
channelBit[i] = HIGH;
channelMils[i] = millis() + random(60000);
} else {
channelBit[i] = LOW;
channelMils[i] = millis() + random(40000);
}
}
}
// einzelne Module durchgehen
for (j=0; j<8; j++){
// einzelne Bits durchgehen
for (i=0; i<8; i++){
bitWrite(out, i, channelBit[i+j*8]);
}
// Byte an Modul übertragen
writePort(adrModul1+j, out);
}
}
// -----------
// I2C Routine
// -----------
void writePort(int address, byte data) {
TinyWireM.beginTransmission(address);
TinyWireM.send(data);
TinyWireM.endTransmission();
delay(5);
}