Attiny85 OneWire-Verbindung zum Seriellen Monitor
Wegen des benötigten SRAM- und Flash-Speicherplatz nur bedingt für Attiny45 verwendbar!
Wer Attiny85 verwendet, kennt sicher folgendes Problem: Man liest z.B. Messwerte von einem Sensor ein und möchte diese Werte über Funk versenden, beim Empfänger kommt aber nichts "G'scheits" an. Liegt das am Sensor selbst oder am Programmteil, der Rohwerte oder Messwerte einliest und berechnet, oder funktioniert die Übertragung nicht? In solchen Fällen schicke ich dann die Messwerte oder andere Kontrollwerte zur Visualisierung über die ohnehin oft für die Auslesung des Sensors benötigte I2C-Schnittstelle zu einer Digitalanzeige und kann so meistens relativ schnell die Ursache herausfinden.
Wird aber die I2C-Schnittstelle nicht benötigt und sind die Pins trotzdem nicht frei, oder hat man gerade keine Digitalanzeige mit I2C-Schnittstelle zur Verfügung, so wird es oft mühselig, ohne Visualisierung die Ursache für einen Fehler zu finden. Häufig kommt es aber vor, dass man zwar nicht 2 frei Pins zur Verfügung hat, sondern gerade nur einen Pin, oder einen Pin vorübergehend für Testzwecke frei machen kann. Und genau für solche Fälle habe ich für den Attiny eine Library geschrieben, die leicht eingebunden werden kann und mit der ich die Informationen (Werte oder Texte) über nur eine Datenleitung zu einem Arduino (Uno oder Nano) sendet. Auf dem Arduino selbst läuft ein Empfangsprogramm, welches die übermittelten Daten dann weiter an den Seriellen Monitor leitet.
Testaufbau:
Der Vollständigkeit halber, habe ich den gesamten Testaufbau, einschließlich des Arduinos (hier ein Uno) zum Flashen des Attiny-Programms, dargestellt. Nachdem ich die Programmierung eines Attiny auf einer eigenen Seite beschrieben habe (Attiny programmieren), habe ich bei meinen anderen Attiny-Anwendungen auf die Darstellung verzichtet. Hier scheint es mir aber aus Gründen der Übersichtlichkeit doch wichtig beide Arduinos darzustellen.
Verwendete Bauteile:
- 1 Attiny85 mit 1 oder 8 MHz Taktfrequenz
- 1 Taster (Reset)
- 1 Programmierstecker 4-pol
- 1 Arduino (Uno oder Nano) zum Flashen des Attiny
- 1 Arduino (Uno oder Nano) zur Datenausgabe am Seriellen Monitor
- 1 Elko 10 µF
Optional:
- 1 I2C-Sensor-Breakout Board, z.B. BME280 (Verwendung für Testprogramm 2, nur mit Attiny85)
Library MyOneWire:
Meine Library kann also Zahlen, Zeichen und Texte von einem Attiny85 zu einem Arduino (z.B. Uno oder Nano) und benötigt dafür nur eine Datenleitung. Auf dem Arduino läuft ein Empfangsprogramm, welches die empfangenen Daten weiter zum Seriellen Monitor leitet.
Die Übertragung der einzelnen Bits eines Bytes erfolgt mittels unterschiedlicher Pulslänge, so wird bei 8 MHz Taktfrequenz des Attiny ein Low-Bit mit einer Pulslänge von 100 µs, ein High-Bit mit einer Länge von 200 µs gesendet. Bei einer Taktfrequenz von 1 MHz sind die Impulslängen viermal so lang.
Folgende Funktionen stehen zur Verfügung:
- Schreiben von Integer-Zahlen (einschließlich Long-Format) 1)
- Schreiben von Float-Zahlen
- Schreiben von Zeichen und Zeichenketten
1) Unsigned-Long-Zahlen können nur im Rahmen des positiven Zahlenbereichs von Long-Zahlen verwendet werden, also von 0 bis 2.147.483.647 (= 2^31)
Die Library kann hier heruntergeladen werden:
Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!
Version 1.3
Änderung gegenüber Version 1.0: Bessere Synchronisierung der Datenübertragung, wenn das Empfangsprogramm erst im Nachhinein gestartet wird, wenn vom Attiny bereits Daten gesendet werden.
Achtung: Beim Empfangsprogramm die Version 1.2 (oder höher) verwenden!!
Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Library das Suffix ".txt" aus diesen Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyOneWire" im Sketchbook-Ordner im Ordner "libraries" speichern.
Zur Auflistung der Funktionen der Libraries geht es hier: Funktionen
Programme:
Empfangsprogramm für Arduino:
Das nachfolgende Empfangsprogramm MyOneWireReceive ist auf den Arduino zu übertragen (im gezeigten Testaufbau auf den Nano). Das Empfangsprogramm empfängt die Daten, die über die OneWire-Verbindung vom Attiny übertragen werden und sendet diese weiter an den Seriellen Monitor. Achtung: Die Übertragung vom Nano zum Seriellen Monitor ist auf 115200 Baud eingestellt.
Nach Start des Programms muss die Taktfrequenz des verwendeten Attiny (1 MHz oder 8 MHz) vorgegeben werden. Weiters ist der Empfangs-Pin des Arduino anzugeben. Dazu können die Pins D2 bis D7 verwendet werden. Danach wartet das Programm auf Daten, die vom Attiny gesendet werden. Jedes empfangene Byte wird auf positive Parität überprüft, bei erkannten Fehler wird ein "†"-Zeichen ausgegeben.
Bild 1: Serieller Monitor nach dem Start und Eingabe von Taktfrequenz und Empfangs-Pin
Das Empfangsprogramm benötigt meine Library MySerialRead. Diese kann hier heruntergeladen werden: Serieller Monitor
Leider kann ich hier keine "ino"-Files hochladen, daher zum Verwenden des Programms ".txt" aus den Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyOneWireReceive" speichern.
Hier das Empfangsprogramm:
Version 1.2
Änderung gegenüber Version 1.0: Bessere Synchronisierung der Datenübertragung, wenn das Empfangsprogramm erst im Nachhinein gestartet wird, wenn vom Attiny bereits Daten gesendet werden.
Achtung: Bei der Library die Version 1.2 (oder höher) verwenden!!
MyOneWireReceive.ino.txt
Testprogramm 1 Attiny85:
Das Testprogramm1 auf Attiny überträgt alle 5 Sekunden Texte und Zahlen an den Arduino.
//Testprogramm für MyMOneWire-Library
//Code fuer Attiny85
//Author Retian
//Version 1.1
#include <MyOneWire.h>
MyOneWire MOneW;
char text[] = "**** Das ist ein Testprogramm fuer die MyOneWire-Library ****";
float zahl1 = -45.35645;
const float pi = 3.1415926;
long zahl2 = 2147483647;
void setup() {
MOneW.init(3); //OneWire-Datenleitung auf PB3
}
void loop() {
MOneW.writeln(); //Zeilenvorschub
MOneW.writeln(text);MOneW.write("Int-Zahl: ");
MOneW.writeln(125);
MOneW.write("Int-Zahl im HEX-Format: ");
MOneW.writeln(125, HEX);MOneW.write("Float-Zahl mit 3 Kommastellen: ");
MOneW.writeln(zahl1, 3);
MOneW.write("Float-Zahl mit 2 Kommastellen: ");
MOneW.writeln(2.56897E+4);
MOneW.write("Die Zahl Pi mit 5 Kommastellen: ");
MOneW.writeln(pi, 5);MOneW.write("Groesstmoegliche Long-Zahl: ");
MOneW.writeln(zahl2);
MOneW.write("Groesstmoegliche Long-Zahl im BIN-Format: ");
MOneW.writeln(2147483647, BIN);
delay(5000);
}
Anzeige am Seriellen Monitor:
Bild 2: Ausgabe der Texte und Zahlen des Testprogramm 1 am Seriellen Monitor
Testprogramm 2 Attiny85:
Das Testprogramm 2 auf Attiny überträgt die Messwerte Luftdruck und Luftfeuchte, die im Beispiel aus dem Luftdruck- und Luftfeuchtesensor BME280 ausgelesen, alle 10 Sekunden an den Arduino.
Verwendete Libraries: Neben der Standard-Library Wire und der hier vorgestellten MyOneWire-Library benötigt man noch für die Abfrage des Sensors BME280 meine Library MyBME280. Diese gibt es hier: Luftdr./-feuchte BME280
//Testprogramm fuer MyMOneW-Library mit Luftdrucksensor BME280
//Code fuer Attiny85
//Author Retian
//Version 2.0
//Prototypen
void leseMesswerte(void);
void ausgabeMesswerte(void);
#include <MyBME280.h>
#include <MyOneWire.h>MyBME280 BME(0x76);
MyOneWire MOneW;
unsigned long zeit;
float luftDruck, luftFeuchte;
void setup() {
MOneW.begin(3);
if (BME.isReady())
{
MOneW.begin(3); //OneWire-Datenleitung auf PB3
MOneW.writeln("BME280 ok");
MOneW.writeln();
BME.setWeatherMonitoring(); //Setze Parameter für Wetterueberwachung
BME.init();
//Beim Initialisieren des Parametersatzes für Wetterueberwachung (Forced-Mode)
//wird bereits eine Messung vom Sensor durchgeführt und als Rohwerte gespeichert
leseMesswerte();
ausgabeMesswerte();
}
else
{
MOneW.writeln("BME280 Fehler");
while (1); //hier geht es im Fehlerfall nicht weiter
}
zeit = millis();
}
void loop() {
if (millis() > zeit + 10000) //Messung alle 10 Sekunden
{
BME.startSingleMeas();
leseMesswerte();
ausgabeMesswerte();
zeit = millis();
}
}
void leseMesswerte()
{
luftDruck = BME.readPress();
luftFeuchte = BME.readHumidity();
}
void ausgabeMesswerte()
{
MOneW.write("Luftdruck : ");
MOneW.write(luftDruck, 0);
MOneW.writeln(" hPa");
MOneW.write("Luftfeuchte: ");
MOneW.write(luftFeuchte, 1);
MOneW.writeln(" %");
MOneW.writeln();
}
Anzeige am Seriellen Monitor:
Bild 3: Ausgabe der Messwerte des Testprogramm 2 am Seriellen Monitor