Fehlermeldung kopf

Arduino Tipps und Pinouts

ATTiny Pinouts Porterweiterung Direkte Portmanipulation ESP32
Modelleisenbahn und Arduino, Anwendungen der Arduinos in der Modellbahn, ATtiny
Es gibt sehr viele Einsatzmöglichkeiten für einen Arduino auf einer Modelleisenbahn. Nicht immer muss es ein "ganzer" Arduino sein, der μC mit einigen peripheren Bauteilen genügt und häufig genügt auch ein kleinerer μC z.B. ein ATtiny.

Folgende Tipps finden Sie mehrmals im Netz:

Um einen ATtiny einsetzen zu können, muss die Programmierumgebung des Arduino erweitert werden. Laden Sie dazu das File attiny.zip herunter und entpacken Sie es.
Den Unterordner "attiny" kopieren Sie in den Ordner "hardware" der Arduinoumgebung. (Falls dieser Unterordner noch nicht existiert, erstellen Sie ihn unter dem Programmordner "arduino".) Die Ordnerstruktur sollte sein: ..>arduino>hardware>attiny und der Ordner "attiny" sollte ein File "boards.txt" und einen Ordner "variants" enthalten.
Starten Sie die Arduinoumgebung neu und unter "Tools/Board" sollten die ATtiny-Einträge auftauchen.

Unter der Arduino-IDE 1.6 muss die Ordnerstruktur ..>arduino>hardware>attiny>avr sein.

Da die Arduino-IDE jetzt schon bei Version 1.8 angekommen ist, sind obige Tipps evtl. nicht mehr aktuell. Aktuelle Tipps finden Sie z.B. hier

Eine gute aktuelle Anleitung für den ATtiny und Arduino liefert dieser Link.

Damit in den ATtiny ein Programm geladen werden kann, muss ein Arduino als Programmer ausgerüstet werden. Schließen Sie dazu einen Arduino an und laden in ihn das ISP-Programm, das Sie unter "Datei/Beispiele/ArduinoISP" finden. Dann wählen Sie "Tools/Programmer/Arduino as ISP". Der Arduino ist jetzt als Programmer für ATtiny bereit. Fast: Sie müssen natürlich noch ATtiny und Arduino verbinden: siehe dazu folgende Bilder:

Die braunen Portnummern beziehen sich auf den Arduino. Und noch etwas: Bei einem Duemillanove müssen Sie nichts weiter tun, aber bei einem UNO muss noch ein Kondensator von ca. 10 μF zwischen Reset (des Arduino) und GND geschaltet werden.

Ein neuer ATtiny läuft mit 1MHz, für viele Anwendungen sollte er jedoch mit 8MHz getaktet werden. Wählen Sie dazu den entsprechenden ATtiny unter "Tools/Board" und danach "Tools/Bootloader installieren". Hier wird kein Bootloader installiert sondern die Fuses des ATtiny werden entsprechend gesetzt. (Dies muss nur einmal für jeden ATtiny gemacht werden.)

Jetzt können Sie unter "Tools/Board" den passenden ATtiny auswählen und Ihren Sketch wie gewohnt "uploaden". Dass danach zwei Zeilen Fehlermeldungen erscheinen, ist unbedenklich.
Vorher haben Sie sicher bedacht, dass die Portnummern der ATtiny sich von denen des Arduino unterscheiden und dass die Portnummern nicht gleich den Pinnummern sind. Folgende Bilder können Ihnen dabei helfen:




Pinout des Arduino Nano:


Pinout des Arduino Uno:


Pinout des Arduino Mega:




Manchmal genügen die 20 Ports eines UNO nicht. Bevor man jetzt daran denkt, einen MEGA zu benutzen (Aber vielleicht hat der MEGA immer noch zuwenig Ports.), kann man erwägen, mit Schieberegistern zusätzliche Ports zu simulieren.
Braucht man zusätzliche Ausgänge, dann setzt man das IC 74HC595 ein, sind zusätzliche Eingänge nötig, verwendet man das IC 74HC165. Für beide Fälle gilt, daß man drei Ports benötigt, um 8 simulierte Ports zu erhalten. Mit einem solchen Schieberegister gewinnt man also 5 Ports. Diese Schieberegister lassen sich jedoch kaskadieren, verwendet man zwei hintereinander, gewinnt man mit drei Steuerports 13 zusätzliche simulierte Ports, jedes weitere Schieberegister fügt 8 weitere Ports hinzu.
Beide Schieberegister folgen in der Pinbezeichnung der Logik "MSB first", d.h. beim 595 steht das zuerst geschobene Bit in Q7 und beim 165 wird D7 als erstes eingelesen.
Es empfiehlt sich, auf der Platine jedes einzelne Schieberegister-IC mit einem 100nF Kondensator abzublocken.

Für zusätzlich Ausgänge ist das IC 74HC595 geeignet.

An Pin 10 und 16 werden +5V angeschlossen und die Pins 8 und 13 werden mit GND verbunden. Einen 100nF Kondensator zwischen +5V und GND in der Nähe der Pins nicht vergessen! Die Steuersignale an den Pins 11, 12 und 14 kommen vom Arduino. An den Pins 15, 1, 2, 3, 4, 5, 6 und 7 stehen die zusätzlichen Ausgänge zur Verfügung. Dabei ist ein Unterschied zu "echten" Ports wichtig: Jeder Ausgang kann ca. 20mA liefern (HIGH) oder aufnehmen (LOW), dabei darf die gesamte Strombelastung des ICs jedoch 70mA nicht übersteigen. Das per Programm zuerst geschobene Bit steht an Ausgang Q7 (Pin 7).

Nun zum Programm:
// Die Portnummern sind beliebig
byte dataPort=17; // geht an Pin 14
byte clockPort=18; // geht an Pin 11
byte strobePort=19; // geht an Pin 12
// weitere Definitionen von Variablen
// ....

void setup(){
pinMode(dataPort,OUTPUT);
pinMode(clockPort,OUTPUT);
pinMode(strobePort,OUTPUT);
// weitere Ports
// ....
}

void loop(){
// Daten und Variable bereitstellen
// ....
seriellOut();
}

void seriellOut(){
// Die Variablennamen bit# sind nur ein Beispiel
// Sie könnten auch ein Array sein und in einer for-next-Schleife ausgelesen werden
digitalWrite(dataPort,bit7);
clockOut();
digitalWrite(dataPort,bit6);
clockOut();
digitalWrite(dataPort,bit5);
clockOut();
digitalWrite(dataPort,bit4);
clockOut();
digitalWrite(dataPort,bit3);
clockOut();
digitalWrite(dataPort,bit2);
clockOut();
digitalWrite(dataPort,bit1);
clockOut();
digitalWrite(dataPort,bit0);
clockOut();

digitalWrite(strobePort,HIGH);
delay(1);
digitalWrite(strobePort,LOW);
}

void clockOut(){
digitalWrite(clockPort,HIGH);
delay(1);
digitalWrite(clockPort,LOW);
}

Wird innerhalb "loop()" eine Variable geändert, so erscheint diese Änderung natürlich erst dann am Schieberegister, wenn "seriellOut()" aufgerufen wurde. In "seriellOut()" werden die Bits nacheinander auf dataPort gesetzt und mit "clockOut()" ins Schieberegister geschrieben - sie erscheinen jedoch noch nicht an den Ausgängen des Schieberegisters. Erst wenn alle Bits geschoben sind, wird über den strobePort die Information an die Ausgänge des ICs geschaltet.

Sollen mehrere 74HC595 angeschlossen werden, dann werden die Pins 11 und 12 an allen Schieberegistern parallel an den Arduino angeschlossen. Der Pin 14 des folgenden ICs ist mit dem Pin 9 des vorhergehenden ICs zu verbinden. Das Programm wird bei "seriellOut()" um die weiteren Ausgabezeilen ergänzt - dabei sollte man immer jeweils 8 Ausgaben pro IC machen auch wenn man evtl. weniger Ausgänge braucht. Dann steht das zuerst geschobene Bit an Q7 des letzten ICs.

Für zusätzlich Eingänge ist das IC 74HC165 geeignet.

An Pin 16 werden +5V angeschlossen und die Pins 8 und 15 werden mit GND verbunden. Einen 100nF Kondensator zwischen +5V und GND in der Nähe der Pins nicht vergessen! Die Steuersignale an den Pins 1, 2 und 9 kommen vom Arduino. An den Pins 11, 12, 13, 14, 3, 4, 5 und 6 stehen die zusätzlichen Eingänge zur Verfügung.

Nun zum Programm:
// Die Portnummern sind beliebig
byte dataInPort=0; // geht an Pin 9
byte clockInPort=1; // geht an Pin 2
byte strobeInPort=2; // geht an Pin 1
// weitere Definitionen von Variablen
// ....

void setup(){
pinMode(dataInPort,INPUT);
pinMode(clockInPort,OUTPUT);
pinMode(strobeInPort,OUTPUT);
// weitere Ports
// ....
}

void loop(){
seriellIn();
// Daten und Variable bearbeiten
// ....
}

void seriellIn(){
// Die Variablennamen bit# sind nur ein Beispiel
// Sie könnten auch ein Array sein und in einer for-next-Schleife eingelesen werden
digitalWrite(strobeInPin,LOW);
delay(1);
digitalWrite(strobeInPin,HIGH);

bit7=digitalRead(dataInPin);
clockIn();
bit6=digitalRead(dataInPin);
clockIn();
bit5=digitalRead(dataInPin);
clockIn();
bit4=digitalRead(dataInPin);
clockIn();
bit3=digitalRead(dataInPin);
clockIn();
bit2=digitalRead(dataInPin);
clockIn();
bit1=digitalRead(dataInPin);
clockIn();
bit0=digitalRead(dataInPin);
//clockIn();
}

void clockIn(){
digitalWrite(clockInPort,HIGH);
delay(1);
digitalWrite(clockInPort,LOW);
}


Eine Änderung an den Eingängen des ICs wird erst dann in "loop()" registriert, wenn "seriellIn()" aufgerufen worden ist, dann werden über den strobeInPort die Eingangswerte in das Schieberegister übernommen und danach mit digitalRead einzeln eingelesen.

Sollen mehrere 74HC165 angeschlossen werden, dann werden die Pins 1 und 2 an allen Schieberegistern parallel an den Arduino angeschlossen. Der Pin 9 des folgenden ICs ist mit dem Pin 10 des vorhergehenden ICs zu verbinden. Das Programm wird bei "seriellIn()" um die weiteren Einlesezeilen ergänzt - dabei sollte man immer jeweils 8 digitalRead pro IC machen auch wenn man evtl. weniger Eingänge braucht. (Dann liest man eben in einen "dummy" ein.) Das zuerst eingelesene Bit ist der Eingang D7 (Pin 6) des ersten ICs.


Natürlich kann man in einem Programm auch beide Porterweiterungen nutzen.
Und noch etwas:
Wenn hier von Arduino die Rede ist, so kann man einen Arduino UNO nehmen oder sehr viel preiswerter sich aus einem ATMega328 einen Arduino-Clone basteln.

Eine andere Lösung wäre die Verwendung von Portexpander-ICs wie z.B. dem PCA9554, welches über I2C angesteuert wird. Hier erhält man mit zwei Steuerleitungen (SDA und SCL) 8 zusätzliche Ports, die wahlweise einzeln als INPUT oder OUTPUT geschaltet werden können. Die Ansteuerung ist jedoch etwas komplizierter, für das PCA9554 sind jedoch Libraries verfügbar. (In der verlinkten Library muss die I2C-Adresse in der cpp-Datei angepasst werden.)