|
|
(38 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) |
Zeile 1: |
Zeile 1: |
− | Bastel #1
| + | ==Allgemeines== |
− | == Warum brauche ich das? == | + | Jetzt ist der ursprüngliche Artikel doch schon recht lang geworden, so dass ich mich entschlossen habe in in mehrere Teile zu teilen. |
| + | Der Mikrocontroller kann in einer Vielzahl von Kombination betrieben werden. Um nur mal einige zu zeigen. |
| | | |
− | Sobald sich solche Szenen auf dem Schreibtisch abspielen und der Wunsch entsteht die angeschlossenen Gerätschaften auch noch irgendwie automatisiert an und aus zu schalten ist die Zeit reif für die nachfolgende Bastelei.
| + | [[Datei:Mikrocontroller Transceiver.png|600px]] |
− | [[Datei:433 Sender.png|mini|433 Senderensemble]] | |
| | | |
− | == Vorüberlegungen ==
| + | Dann kann man den kleinen Kerl schnell überfrachten, wenn man die Eierlegendewollmilchsau baut. |
| + | Ratzfatz stören sich die unterschiedlichen Libraries gegenseitig oder die Interrupts kommen sich in die Quere. |
| + | Es spricht natürlich nichts dagegen Untermodule mit je einem Arduino zu bilden und einen der die Informationen zusammmenfasst und die Verbindung zum Netz herstellt. |
| + | Da dieser Artikelzweig sowieso eine Ethernetanbindung (ESP8266 oder W5X00) beschreibt, drängt sich eine Spannungsversorgung über PoE auf. |
| + | Ich postuliere für mich. |
| + | # Komme ich an eine Montagestelle per Netzwerkkabel und lässt es die Ästetik zu, dann benutze PoE |
| + | # Komme ich an eine Stelle nur besser per "Steckdose" dann benutzt man sowieso besser ein Funkmodul. |
| + | # Und sollte gar keine Kabel möglich sein, dass folgt gezwungenermaßen aber erst als letzte Wahl der Batteriebetieb. |
| | | |
− | Um die Aktoren zu schalten wäre nur der Transmitter (Sender) notwendig.
| + | ==Unteratikel== |
| + | MQTT als Transportprotokoll |
| | | |
− | Warum also der Receiver (Empfänger)?
| + | Stromversorgung (kleiner 3 Watt) |
− | * Die Module sind beim Chinamann so billig, dass man als geübter Bastler nicht anders kann.
| |
− | * Man kann weiterhin die Handsender (auf einem anderen Code) benutzen und so den Arduino als Proxy benutzen.
| |
− | * Man kann den gesamten Datenverkehr des ISM-Bandes mitlauschen und somit ggf. digitale Störquellen ausfindig machen.
| |
| | | |
− | Der Arduino muss in ein Netz einbindbar sein. Ich habe mich in der ersten Variante für eine Kabelverbindung entschieden. Es gilt trotz oder gerade wegen allem WLAN immer noch Tibb's-Law: "Wo ein Kabel möglich, da benutze auch ein Kabel!"
| + | Power over Ethernet |
| | | |
− | Für die Smarthome-Integration steht dann auch noch eine Anbindung in FHEM in Aussicht.
| + | Battery Powered |
| | | |
− | == Bedingungen ==
| + | Arduino Ethernet Transceiver 433 MQTT |
| | | |
− | Egal ob Bastelarbeit oder komplexeres Projekt grundsätzlich sollte man sowohl hardwareseitig, als auch softwareseitig unbedingt wo immer möglich modular arbeiten. Wie oft habe ich PCBs nur einmal nutzen können oder eine Software neu geschrieben, weil das Umschreiben einfach zu aufwendig erschien. Wie oft habe ich schon gute Ideen im Internet gefunden, die mit viel Aufwand realisiert wurden, aber nur in Teilen zu meinen Anforderungen gepasst haben.
| + | Arduino Ethernet Transceiver 868 MQTT |
| | | |
− | Dieses Problem könnte diese Bastelei bzgl. der Frequenzwahl (433 MHz anstatt 866 MHz) oder der Netzwerkanbindung (RJ45 anstatt WLAN, Bluetooth, ZigBee) auch ereilen. Ich beginne jetzt mal in dieser Konfiguration und werde die anderen Kombinationen nach und nach ergänzen.
| + | Arduino Ethernet Transceiver IR MQTT |
− | | |
− | | |
− | ==Bestandteile==
| |
− | | |
− | * Arduino Nano
| |
− | * Netzwerkmodul ENC28J60
| |
− | * Sendemodul 433 MHz
| |
− | * Empfangsmodul 433 MHz
| |
− | * Shield für Nano
| |
− | * Stepup-Wandler 5 V -> 12 V für das Sendmodul
| |
− | | |
− | | |
− | ==Vorbereitungen==
| |
− | | |
− | '''TODO: Wikiseite für jede Komponente''' für diejeniegen, die sich für das 'Dahinter' interessieren.
| |
− | | |
− | ===Arduino Nano===
| |
− | Gelegentlich liest man von Problemen mit dem Bootloader von Nano-China-Clonen. Da wir an dieser Stelle einen großen Schritt zurück müssten habe ich das [[AVR Bootloader]]-Problem in eine eigene Wiki-Seite ausgelagert.
| |
− | | |
− | ===Schield===
| |
− | Genauer gesagt ein I/O Sensor Shield Expansion Breakout bekommt an z. B. [https://www.makershop.de/plattformen/arduino-shields/io-sensor-shield-nano/ hier]. Wer warten kann, kann es auch beim Ali (ca. 50 Cent) bestellen. Das Breakout-Board liefert durch seinen Spannungsregler für 3,3 V auch Spannung für das ENC28J60-Modul.
| |
− | | |
− | ===Funkmodule===
| |
− | Die Funkmodule sind unspektakulär. Sobald sie mit der richtigen Spannung (Receiver 5V, Transmitter 12 V) versorgt sind bekommt man einen Bitstream oder man stellt einen zur Verfügung. Das Protokoll des Bitstreams ist für die Module belanglos.
| |
− | Der unten beschriebene Aufbau ist auch 'problemlos' mit 868 MHz Modulen möglich.
| |
− | | |
− | ===Netzwerkmodul===
| |
− | Zum Einsatz kommt ein Modul mit dem ENC28J60 Chip. Bei Ebay oder beim Ali auch schon für kleines Geld zu haben. Einzig die Entscheidungsfrage ENC28J60 oder WZ5100 ist hier vielleicht von Bedeutung. Da der ENC28J60 im Gegensatz zu den Funkmodulen nicht einfach nur einen Bitstream 'umsetzt', sondern eine Controllerlogik mit einer Vielzahl von Konfigurationsregistern besitzt ist die Anpassungsarbeit bei Library-Problemen oder eigenen Anpassungen nicht trivial.
| |
− | | |
− | ===Stepup-Wandler===
| |
− | Das Modul erhöht die Versorgungsspannung von 5 V des Arduino auf 12 V des Funksendemoduls. Dies erhöht die Funkreichweite.
| |
− | Die Module gibt es im Netz auch wie Sand am Meer. Einfach bei der Suchmaschine deines Vertrauens 'XL6009' eingeben.
| |
− | | |
− | == 1. Version mit Sende- und Empfangsmodulen für 433 MHZ ==
| |
− | [[Datei:433 EtherTransceiver wired.JPG|800px|Fritzing Schematic Layout]]
| |
− | | |
− | [[Datei:433 EtherTransceiver Steckplatine.png|800px|EtherTransceiver Steckplatine]]
| |
− | | |
− | ==Testprogramm Empfänger==
| |
− | | |
− | Bei dem nachfolgenden Sample benötigt man keine zusätzliche Library. Es dient ausschließlich dazu den Empfänger auf Funktion zu testen. Als Sketch in der Arduino IDE oder besser mit der PlatformIO-Installation in den Nano laden und auf einer der 433 MHz Fernbedienungen ein paar Tasten drücken. Dann sollte man auf der seriellen Konsole den Empfang erkennen können.
| |
− | | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
| |
− | <div style="font-weight:bold;line-height:1.6;">Receiver Sketch</div>
| |
− | <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="c" line>
| |
− | #include "Arduino.h"
| |
− | | |
− | #define SAMPLESIZE 500
| |
− | | |
− | static unsigned int timings[SAMPLESIZE];
| |
− | static unsigned int pos = 0;
| |
− | static unsigned long lastTime = 0;
| |
− | | |
− | static int receiverPin = 2;
| |
− | | |
− | void handleInterrupt() {
| |
− | const long time = micros();
| |
− | timings[pos] = time - lastTime;
| |
− | lastTime = time;
| |
− | if (++pos > SAMPLESIZE-1) {
| |
− | pos = 0;
| |
− | }
| |
− | }
| |
− | | |
− | void setup() {
| |
− | Serial.begin(9600);
| |
− | attachInterrupt(digitalPinToInterrupt(receiverPin), handleInterrupt, CHANGE);
| |
− | pinMode(13, OUTPUT);
| |
− | digitalWrite(13, LOW);
| |
− | }
| |
− | | |
− | void loop() {
| |
− | for (int i = 5; i>0; i--) {
| |
− | Serial.print(i);
| |
− | Serial.print("... ");
| |
− | delay(900);
| |
− | digitalWrite(13, HIGH);
| |
− | delay(100);
| |
− | digitalWrite(13, LOW);
| |
− | }
| |
− | Serial.println();
| |
− | | |
− | detachInterrupt(digitalPinToInterrupt(receiverPin));
| |
− | | |
− | int finalstate = digitalRead(receiverPin);
| |
− |
| |
− | for (unsigned int i = pos + finalstate; i< SAMPLESIZE; i++) {
| |
− | Serial.print( timings[i] );
| |
− | Serial.print(",");
| |
− | }
| |
− | | |
− | for (unsigned int i = 0; i < pos; i++) {
| |
− | Serial.print( timings[i] );
| |
− | Serial.print(",");
| |
− | }
| |
− | | |
− | Serial.println("");
| |
− | Serial.println("Reset your Arduino to scan again...");
| |
− | | |
− | while(true) {}
| |
− | | |
− | }
| |
− | </syntaxhighlight>
| |
− | </div></div>
| |
− | | |
− | Kurzkommentierung:
| |
− | Neben den beiden bekannten Funktionen bei Arduino-Sketches (setup und loop) findet man in diesem Sketch nur eine weitere Funktion:
| |
− | | |
− | <syntaxhighlight lang="c" line>
| |
− | void handleInterrupt() {
| |
− | const long time = micros();
| |
− | timings[pos] = time - lastTime;
| |
− | lastTime = time;
| |
− | if (++pos > SAMPLESIZE-1) {
| |
− | pos = 0;
| |
− | }
| |
− | }
| |
− | </syntaxhighlight>
| |
− | | |
− | Diese Funktion ist die Interrupt Service Routine (ISR), die immer dann ausgeführt wird, wenn der verknüpfte Interrupt auslöst.
| |
− | In diesem Fall ist es ein Hardwareinterrupt an PIN 2 an dem der Receiver angeschlossen ist. Der ATmega328 des Nano hat auch nur 2 'voll' interruptfähige PINS, nämlich 2 (PD2/INT0) und 3 (PD3/INT1). Die allgemeinen Dinge will ich hier nicht wiederkäuen. Weitere Informationen findet man z. B. [https://www.arduino.cc/reference/de/language/functions/external-interrupts/attachinterrupt/ hier].
| |
− | Ein Verwirrung, die vielleicht der Auflösung bedarf, ist der erste Parameter der attachInterrupt 'pin'. Bei einigen Sketches findet man einfach nur den Interrupt pin eingetragen bei anderen irgenwie die Interrupt-Nummer und bei wieder anderen eine zusätzliche Funktion digitalPinToInterrupt(receiverPin).
| |
− | Dazu eine kleine Erläuterung: In einem Mikrocontroller befindet sich ein Tabelle, in diesem Fall des ATmega328 am Anfang des Flashspeichers (32768 Bytes) ganz am Anfang, also ab Adresse 0x0000. Um dies nachzuschauen reicht ein Blick in Daten die im Flashspeicher des AVR landen (i.d.R. durch avrdude) zu werfen. Avrdude erhält normalerweise ein hex-File, welches vom Compiler erstellt wurde zum Übrtragen in den AVR. Das (Intel-)hex-File ist zwar lesbar aber ohne Kenntnis des Aufbaus nicht ohne weiteres interpretierbar. Ich arbeite deshalb lieber mit einem bin-File, welches nebenbei bemerkt auch von avrdude übertragen werden kann. Um ein (Intel-)hex-File in eine bin-File zu wandeln genügt folgender Befehl im 'richtigen' Verzeichnis, oder mit vollständigen Pfadangaben.
| |
− | /PlatformIO/Projects/Receiver_433/.pio/build/nanoatmega328new # objcopy -I ihex firmware.hex -O binary firmware.bin
| |
− | Im erzeugten Bin-File kann man jetzt recht einfach sehen, welches Byte an welche Stelle im Flashspeicher geschrieben wird.
| |
− | Der Vollständigkeit halber habe ich hier mal das gesamte Bin-File des Receiver-Sketches aufgelistet.
| |
− | | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
| |
− | <div style="font-weight:bold;line-height:1.6;">firmware.bin</div>
| |
− | <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="text" line>
| |
− | /PlatformIO/Projects/Receiver_433/.pio/build/nanoatmega328new # hexdump -C firmware.bin
| |
− | 00000000 0c 94 62 00 0c 94 43 03 0c 94 1c 03 0c 94 8a 00 |..b...C.........|
| |
− | 00000010 0c 94 8a 00 0c 94 8a 00 0c 94 8a 00 0c 94 8a 00 |................|
| |
− | *
| |
− | 00000040 0c 94 d2 02 0c 94 8a 00 0c 94 90 03 0c 94 6a 03 |..............j.|
| |
− | 00000050 0c 94 8a 00 0c 94 8a 00 0c 94 8a 00 0c 94 8a 00 |................|
| |
− | 00000060 0c 94 8a 00 0c 94 8a 00 00 00 00 00 24 00 27 00 |............$.'.|
| |
− | 00000070 2a 00 00 00 00 00 23 00 26 00 29 00 00 00 00 00 |*.....#.&.).....|
| |
− | 00000080 25 00 28 00 2b 00 04 04 04 04 04 04 04 04 02 02 |%.(.+...........|
| |
− | 00000090 02 02 02 02 03 03 03 03 03 03 01 02 04 08 10 20 |............... |
| |
− | 000000a0 40 80 01 02 04 08 10 20 01 02 04 08 10 20 00 00 |@...... ..... ..|
| |
− | 000000b0 00 08 00 02 01 00 00 03 04 07 00 00 00 00 00 00 |................|
| |
− | 000000c0 00 00 04 05 11 24 1f be cf ef d8 e0 de bf cd bf |.....$..........|
| |
− | 000000d0 11 e0 a0 e0 b1 e0 e0 ec fa e0 02 c0 05 90 0d 92 |................|
| |
− | 000000e0 a4 34 b1 07 d9 f7 25 e0 a4 e4 b1 e0 01 c0 1d 92 |.4....%.........|
| |
− | 000000f0 a8 3d b2 07 e1 f7 10 e0 c2 e6 d0 e0 04 c0 21 97 |.=............!.|
| |
− | 00000100 fe 01 0e 94 53 05 c1 36 d1 07 c9 f7 0e 94 c2 03 |....S..6........|
| |
− | 00000110 0c 94 5e 05 0c 94 00 00 83 30 81 f0 28 f4 81 30 |..^......0..(..0|
| |
− | 00000120 99 f0 82 30 a1 f0 08 95 87 30 a9 f0 88 30 b9 f0 |...0.....0...0..|
| |
− | 00000130 84 30 d1 f4 80 91 80 00 8f 7d 03 c0 80 91 80 00 |.0.......}......|
| |
− | 00000140 8f 77 80 93 80 00 08 95 84 b5 8f 77 02 c0 84 b5 |.w.........w....|
| |
− | 00000150 8f 7d 84 bd 08 95 80 91 b0 00 8f 77 03 c0 80 91 |.}.........w....|
| |
− | 00000160 b0 00 8f 7d 80 93 b0 00 08 95 1f 93 cf 93 df 93 |...}............|
| |
− | 00000170 eb eb f0 e0 94 91 e7 ea f0 e0 d4 91 e3 e9 f0 e0 |................|
| |
− | 00000180 c4 91 cc 23 d1 f0 18 2f 99 23 19 f0 89 2f 0e 94 |...#.../.#.../..|
| |
− | 00000190 8c 00 ec 2f f0 e0 ee 0f ff 1f e4 58 ff 4f a5 91 |.../.......X.O..|
| |
− | 000001a0 b4 91 9f b7 f8 94 11 11 04 c0 8c 91 d0 95 d8 23 |...............#|
| |
− | 000001b0 02 c0 ec 91 de 2b dc 93 9f bf df 91 cf 91 1f 91 |.....+..........|
| |
− | 000001c0 08 95 3f b7 f8 94 80 91 37 05 90 91 38 05 a0 91 |..?.....7...8...|
| |
− | 000001d0 39 05 b0 91 3a 05 26 b5 a8 9b 05 c0 2f 3f 19 f0 |9...:.&...../?..|
| |
− | 000001e0 01 96 a1 1d b1 1d 3f bf ba 2f a9 2f 98 2f 88 27 |......?../././.'|
| |
− | 000001f0 82 0f 91 1d a1 1d b1 1d bc 01 cd 01 42 e0 66 0f |............B.f.|
| |
− | 00000200 77 1f 88 1f 99 1f 4a 95 d1 f7 08 95 8f 92 9f 92 |w.....J.........|
| |
− | 00000210 af 92 bf 92 cf 92 df 92 ef 92 ff 92 6b 01 7c 01 |............k.|.|
| |
− | 00000220 0e 94 e1 00 4b 01 5c 01 c1 14 d1 04 e1 04 f1 04 |....K.\.........|
| |
− | 00000230 f1 f0 0e 94 e1 00 dc 01 cb 01 88 19 99 09 aa 09 |................|
| |
− | 00000240 bb 09 88 3e 93 40 a1 05 b1 05 70 f3 21 e0 c2 1a |...>.@....p.!...|
| |
− | 00000250 d1 08 e1 08 f1 08 88 ee 88 0e 83 e0 98 1e a1 1c |................|
| |
− | 00000260 b1 1c c1 14 d1 04 e1 04 f1 04 19 f7 dd cf ff 90 |................|
| |
− | 00000270 ef 90 df 90 cf 90 bf 90 af 90 9f 90 8f 90 08 95 |................|
| |
− | 00000280 08 95 0e 94 e1 00 40 91 30 05 50 91 31 05 fa 01 |......@.0.P.1...|
| |
− | 00000290 ee 0f ff 1f e8 5b fe 4f 20 91 44 01 30 91 45 01 |.....[.O .D.0.E.|
| |
− | 000002a0 db 01 a2 1b b3 0b b1 83 a0 83 60 93 44 01 70 93 |..........`.D.p.|
| |
− | 000002b0 45 01 80 93 46 01 90 93 47 01 ca 01 01 96 84 3f |E...F...G......?|
| |
− | 000002c0 b1 e0 9b 07 28 f4 90 93 31 05 80 93 30 05 08 95 |....(...1...0...|
| |
− | 000002d0 10 92 31 05 10 92 30 05 08 95 cf 92 df 92 ef 92 |..1...0.........|
| |
− | 000002e0 ff 92 0f 93 1f 93 cf 93 df 93 6c 01 7a 01 8b 01 |..........l.z...|
| |
− | 000002f0 c0 e0 d0 e0 ce 15 df 05 81 f0 d8 01 6d 91 8d 01 |............m...|
| |
− | 00000300 d6 01 ed 91 fc 91 01 90 f0 81 e0 2d c6 01 09 95 |...........-....|
| |
− | 00000310 89 2b 11 f0 21 96 ee cf 7e 01 c7 01 df 91 cf 91 |.+..!...~.......|
| |
− | 00000320 1f 91 0f 91 ff 90 ef 90 df 90 cf 90 08 95 08 95 |................|
| |
− | 00000330 80 e0 90 e0 08 95 fc 01 53 8d 44 8d 25 2f 30 e0 |........S.D.%/0.|
| |
− | 00000340 84 2f 90 e0 82 1b 93 0b 54 17 10 f0 cf 96 08 95 |./......T.......|
| |
− | 00000350 01 97 08 95 fc 01 91 8d 82 8d 98 17 61 f0 82 8d |............a...|
| |
− | 00000360 df 01 a8 0f b1 1d 5d 96 8c 91 92 8d 9f 5f 9f 73 |......]......_.s|
| |
− | 00000370 92 8f 90 e0 08 95 8f ef 9f ef 08 95 fc 01 91 8d |................|
| |
− | 00000380 82 8d 98 17 31 f0 82 8d e8 0f f1 1d 85 8d 90 e0 |....1...........|
| |
− | 00000390 08 95 8f ef 9f ef 08 95 fc 01 91 8d 22 8d 89 2f |............"../|
| |
− | 000003a0 90 e0 80 5c 9f 4f 82 1b 91 09 8f 73 99 27 08 95 |...\.O.....s.'..|
| |
− | 000003b0 8b e3 95 e0 0e 94 cc 01 21 e0 89 2b 09 f4 20 e0 |........!..+.. .|
| |
− | 000003c0 82 2f 08 95 fc 01 84 8d df 01 a8 0f b1 1d a3 5a |./.............Z|
| |
− | 000003d0 bf 4f 2c 91 84 8d 90 e0 01 96 8f 73 99 27 84 8f |.O,........s.'..|
| |
− | 000003e0 a6 89 b7 89 2c 93 a0 89 b1 89 8c 91 83 70 80 64 |....,........p.d|
| |
− | 000003f0 8c 93 93 8d 84 8d 98 13 06 c0 02 88 f3 89 e0 2d |...............-|
| |
− | 00000400 80 81 8f 7d 80 83 08 95 ef 92 ff 92 0f 93 1f 93 |...}............|
| |
− | 00000410 cf 93 df 93 ec 01 81 e0 88 8f 9b 8d 8c 8d 98 13 |................|
| |
− | 00000420 05 c0 e8 89 f9 89 80 81 85 fd 26 c0 f6 2e 0b 8d |..........&.....|
| |
− | 00000430 10 e0 0f 5f 1f 4f 0f 73 11 27 e0 2e 8c 8d e8 12 |..._.O.s.'......|
| |
− | 00000440 0c c0 0f b6 07 fc fa cf e8 89 f9 89 80 81 85 ff |................|
| |
− | 00000450 f5 cf ce 01 0e 94 e2 01 f1 cf 8b 8d fe 01 e8 0f |................|
| |
− | 00000460 f1 1d e3 5a ff 4f f0 82 9f b7 f8 94 0b 8f ea 89 |...Z.O..........|
| |
− | 00000470 fb 89 80 81 80 62 0a c0 9f b7 f8 94 ee 89 ff 89 |.....b..........|
| |
− | 00000480 60 83 e8 89 f9 89 80 81 83 70 80 64 80 83 9f bf |`........p.d....|
| |
− | 00000490 81 e0 90 e0 df 91 cf 91 1f 91 0f 91 ff 90 ef 90 |................|
| |
− | 000004a0 08 95 cf 93 df 93 ec 01 88 8d 88 23 c9 f0 ea 89 |...........#....|
| |
− | 000004b0 fb 89 80 81 85 fd 05 c0 a8 89 b9 89 8c 91 86 fd |................|
| |
− | 000004c0 0f c0 0f b6 07 fc f5 cf 80 81 85 ff f2 cf a8 89 |................|
| |
− | 000004d0 b9 89 8c 91 85 ff ed cf ce 01 0e 94 e2 01 e7 cf |................|
| |
− | 000004e0 df 91 cf 91 08 95 80 e0 90 e0 89 2b 29 f0 0e 94 |...........+)...|
| |
− | 000004f0 d8 01 81 11 0c 94 00 00 08 95 00 97 69 f0 fc 01 |............i...|
| |
− | 00000500 01 90 00 20 e9 f7 31 97 af 01 48 1b 59 0b bc 01 |... ..1...H.Y...|
| |
− | 00000510 8b e3 95 e0 0c 94 6d 01 80 e0 90 e0 08 95 8f 92 |......m.........|
| |
− | 00000520 9f 92 af 92 bf 92 0f 93 1f 93 cf 93 df 93 cd b7 |................|
| |
− | 00000530 de b7 a1 97 0f b6 f8 94 de bf 0f be cd bf 19 a2 |................|
| |
− | 00000540 42 30 08 f4 4a e0 8e 01 0f 5d 1f 4f 84 2e 91 2c |B0..J....].O...,|
| |
− | 00000550 a1 2c b1 2c a5 01 94 01 0e 94 31 05 e6 2f b9 01 |.,.,......1../..|
| |
− | 00000560 ca 01 01 50 11 09 ea 30 14 f4 e0 5d 01 c0 e9 5c |...P...0...]...\|
| |
− | 00000570 d8 01 ec 93 23 2b 24 2b 25 2b 61 f7 c8 01 0e 94 |....#+$+%+a.....|
| |
− | 00000580 7d 02 a1 96 0f b6 f8 94 de bf 0f be cd bf df 91 |}...............|
| |
− | 00000590 cf 91 1f 91 0f 91 bf 90 af 90 9f 90 8f 90 08 95 |................|
| |
− | 000005a0 0e 94 59 05 1f 92 0f 92 0f b6 0f 92 11 24 2f 93 |..Y..........$/.|
| |
− | 000005b0 3f 93 8f 93 9f 93 af 93 bf 93 80 91 33 05 90 91 |?...........3...|
| |
− | 000005c0 34 05 a0 91 35 05 b0 91 36 05 30 91 32 05 23 e0 |4...5...6.0.2.#.|
| |
− | 000005d0 23 0f 2d 37 20 f4 01 96 a1 1d b1 1d 05 c0 26 e8 |#.-7 .........&.|
| |
− | 000005e0 23 0f 02 96 a1 1d b1 1d 20 93 32 05 80 93 33 05 |#....... .2...3.|
| |
− | 000005f0 90 93 34 05 a0 93 35 05 b0 93 36 05 80 91 37 05 |..4...5...6...7.|
| |
− | 00000600 90 91 38 05 a0 91 39 05 b0 91 3a 05 01 96 a1 1d |..8...9...:.....|
| |
− | 00000610 b1 1d 80 93 37 05 90 93 38 05 a0 93 39 05 b0 93 |....7...8...9...|
| |
− | 00000620 3a 05 bf 91 af 91 9f 91 8f 91 3f 91 2f 91 0f 90 |:.........?./...|
| |
− | 00000630 0f be 0f 90 1f 90 18 95 1f 92 0f 92 0f b6 0f 92 |................|
| |
− | 00000640 11 24 2f 93 3f 93 4f 93 5f 93 6f 93 7f 93 8f 93 |.$/.?.O._.o.....|
| |
− | 00000650 9f 93 af 93 bf 93 ef 93 ff 93 e0 91 02 01 f0 91 |................|
| |
− | 00000660 03 01 09 95 ff 91 ef 91 bf 91 af 91 9f 91 8f 91 |................|
| |
− | 00000670 7f 91 6f 91 5f 91 4f 91 3f 91 2f 91 0f 90 0f be |..o._.O.?./.....|
| |
− | 00000680 0f 90 1f 90 18 95 1f 92 0f 92 0f b6 0f 92 11 24 |...............$|
| |
− | 00000690 2f 93 3f 93 4f 93 5f 93 6f 93 7f 93 8f 93 9f 93 |/.?.O._.o.......|
| |
− | 000006a0 af 93 bf 93 ef 93 ff 93 e0 91 00 01 f0 91 01 01 |................|
| |
− | 000006b0 09 95 ff 91 ef 91 bf 91 af 91 9f 91 8f 91 7f 91 |................|
| |
− | 000006c0 6f 91 5f 91 4f 91 3f 91 2f 91 0f 90 0f be 0f 90 |o._.O.?./.......|
| |
− | 000006d0 1f 90 18 95 1f 92 0f 92 0f b6 0f 92 11 24 2f 93 |.............$/.|
| |
− | 000006e0 3f 93 4f 93 5f 93 6f 93 7f 93 8f 93 9f 93 af 93 |?.O._.o.........|
| |
− | 000006f0 bf 93 ef 93 ff 93 8b e3 95 e0 0e 94 e2 01 ff 91 |................|
| |
− | 00000700 ef 91 bf 91 af 91 9f 91 8f 91 7f 91 6f 91 5f 91 |............o._.|
| |
− | 00000710 4f 91 3f 91 2f 91 0f 90 0f be 0f 90 1f 90 18 95 |O.?./...........|
| |
− | 00000720 1f 92 0f 92 0f b6 0f 92 11 24 2f 93 8f 93 9f 93 |.........$/.....|
| |
− | 00000730 ef 93 ff 93 e0 91 4b 05 f0 91 4c 05 80 81 e0 91 |......K...L.....|
| |
− | 00000740 51 05 f0 91 52 05 82 fd 12 c0 90 81 80 91 54 05 |Q...R.........T.|
| |
− | 00000750 8f 5f 8f 73 20 91 55 05 82 17 51 f0 e0 91 54 05 |._.s .U...Q...T.|
| |
− | 00000760 f0 e0 e5 5c fa 4f 95 8f 80 93 54 05 01 c0 80 81 |...\.O....T.....|
| |
− | 00000770 ff 91 ef 91 9f 91 8f 91 2f 91 0f 90 0f be 0f 90 |......../.......|
| |
− | 00000780 1f 90 18 95 78 94 84 b5 82 60 84 bd 84 b5 81 60 |....x....`.....`|
| |
− | 00000790 84 bd 85 b5 82 60 85 bd 85 b5 81 60 85 bd 80 91 |.....`.....`....|
| |
− | 000007a0 6e 00 81 60 80 93 6e 00 10 92 81 00 80 91 81 00 |n..`..n.........|
| |
− | 000007b0 82 60 80 93 81 00 80 91 81 00 81 60 80 93 81 00 |.`.........`....|
| |
− | 000007c0 80 91 80 00 81 60 80 93 80 00 80 91 b1 00 84 60 |.....`.........`|
| |
− | 000007d0 80 93 b1 00 80 91 b0 00 81 60 80 93 b0 00 80 91 |.........`......|
| |
− | 000007e0 7a 00 84 60 80 93 7a 00 80 91 7a 00 82 60 80 93 |z..`..z...z..`..|
| |
− | 000007f0 7a 00 80 91 7a 00 81 60 80 93 7a 00 80 91 7a 00 |z...z..`..z...z.|
| |
− | 00000800 80 68 80 93 7a 00 10 92 c1 00 e0 91 4b 05 f0 91 |.h..z.......K...|
| |
− | 00000810 4c 05 82 e0 80 83 e0 91 47 05 f0 91 48 05 10 82 |L.......G...H...|
| |
− | 00000820 e0 91 49 05 f0 91 4a 05 8f ec 80 83 10 92 53 05 |..I...J.......S.|
| |
− | 00000830 e0 91 4f 05 f0 91 50 05 86 e0 80 83 e0 91 4d 05 |..O...P.......M.|
| |
− | 00000840 f0 91 4e 05 80 81 80 61 80 83 e0 91 4d 05 f0 91 |..N....a....M...|
| |
− | 00000850 4e 05 80 81 88 60 80 83 e0 91 4d 05 f0 91 4e 05 |N....`....M...N.|
| |
− | 00000860 80 81 80 68 80 83 e0 91 4d 05 f0 91 4e 05 80 81 |...h....M...N...|
| |
− | 00000870 8f 7d 80 83 81 e4 91 e0 90 93 01 01 80 93 00 01 |.}..............|
| |
− | 00000880 80 91 69 00 8c 7f 81 60 80 93 69 00 e8 9a e7 ea |..i....`..i.....|
| |
− | 00000890 f0 e0 24 91 e3 e9 f0 e0 84 91 88 23 99 f0 90 e0 |..$........#....|
| |
− | 000008a0 88 0f 99 1f fc 01 e8 59 ff 4f a5 91 b4 91 fc 01 |.......Y.O......|
| |
− | 000008b0 e4 58 ff 4f 85 91 94 91 8f b7 f8 94 ec 91 e2 2b |.X.O...........+|
| |
− | 000008c0 ec 93 8f bf 80 e0 0e 94 b5 00 25 e0 c2 2e d1 2c |..........%....,|
| |
− | 000008d0 e1 2c f1 2c 4a e0 c7 01 b6 01 0e 94 8f 02 86 e1 |.,.,J...........|
| |
− | 000008e0 91 e0 0e 94 7d 02 64 e8 73 e0 80 e0 90 e0 0e 94 |....}.d.s.......|
| |
− | 000008f0 06 01 81 e0 0e 94 b5 00 64 e6 70 e0 80 e0 90 e0 |........d.p.....|
| |
− | 00000900 0e 94 06 01 80 e0 0e 94 b5 00 81 e0 c8 1a d1 08 |................|
| |
− | 00000910 e1 08 f1 08 f9 f6 8b e1 91 e0 0e 94 7d 02 e8 98 |............}...|
| |
− | 00000920 80 e4 91 e0 90 93 01 01 80 93 00 01 e0 eb f0 e0 |................|
| |
− | 00000930 84 91 ec e9 f0 e0 d4 91 e8 e8 f0 e0 c4 91 cc 23 |...............#|
| |
− | 00000940 a1 f0 81 11 0e 94 8c 00 ec 2f f0 e0 ee 0f ff 1f |........./......|
| |
− | 00000950 ee 58 ff 4f a5 91 b4 91 ec 91 ed 23 91 e0 80 e0 |.X.O.......#....|
| |
− | 00000960 09 f4 90 e0 c9 2f d8 2f 02 c0 c0 e0 d0 e0 8b e3 |....././........|
| |
− | 00000970 95 e0 0e 94 aa 01 80 91 30 05 90 91 31 05 c8 0f |........0...1...|
| |
− | 00000980 d9 1f 8e 01 00 0f 11 1f 08 5b 1e 4f c4 3f e1 e0 |.........[.O.?..|
| |
− | 00000990 de 07 78 f4 f8 01 61 91 71 91 8f 01 80 e0 90 e0 |..x...a.q.......|
| |
− | 000009a0 4a e0 0e 94 8f 02 8e e1 91 e0 0e 94 7d 02 21 96 |J...........}.!.|
| |
− | 000009b0 ed cf 08 e4 11 e0 c0 e0 d0 e0 80 91 30 05 90 91 |............0...|
| |
− | 000009c0 31 05 c8 17 d9 07 78 f4 f8 01 61 91 71 91 8f 01 |1.....x...a.q...|
| |
− | 000009d0 80 e0 90 e0 4a e0 0e 94 8f 02 8e e1 91 e0 0e 94 |....J...........|
| |
− | 000009e0 7d 02 21 96 ea cf 8d e1 91 e0 0e 94 7d 02 8b e1 |}.!.........}...|
| |
− | 000009f0 91 e0 0e 94 7d 02 80 e2 91 e0 0e 94 7d 02 8b e1 |....}.......}...|
| |
− | 00000a00 91 e0 0e 94 7d 02 ff cf eb e3 f5 e0 13 82 12 82 |....}...........|
| |
− | 00000a10 88 ee 93 e0 a0 e0 b0 e0 84 83 95 83 a6 83 b7 83 |................|
| |
− | 00000a20 88 e0 91 e0 91 83 80 83 85 ec 90 e0 95 87 84 87 |................|
| |
− | 00000a30 84 ec 90 e0 97 87 86 87 80 ec 90 e0 91 8b 80 8b |................|
| |
− | 00000a40 81 ec 90 e0 93 8b 82 8b 82 ec 90 e0 95 8b 84 8b |................|
| |
− | 00000a50 86 ec 90 e0 97 8b 86 8b 11 8e 12 8e 13 8e 14 8e |................|
| |
− | 00000a60 08 95 a1 e2 1a 2e aa 1b bb 1b fd 01 0d c0 aa 1f |................|
| |
− | 00000a70 bb 1f ee 1f ff 1f a2 17 b3 07 e4 07 f5 07 20 f0 |.............. .|
| |
− | 00000a80 a2 1b b3 0b e4 0b f5 0b 66 1f 77 1f 88 1f 99 1f |........f.w.....|
| |
− | 00000a90 1a 94 69 f7 60 95 70 95 80 95 90 95 9b 01 ac 01 |..i.`.p.........|
| |
− | 00000aa0 bd 01 cf 01 08 95 ee 0f ff 1f 05 90 f4 91 e0 2d |...............-|
| |
− | 00000ab0 09 94 81 e0 90 e0 f8 94 0c 94 5e 05 f8 94 ff cf |..........^.....|
| |
− | 00000ac0 40 01 40 01 00 00 00 00 04 02 6d 01 9b 01 51 02 |@.@.......m...Q.|
| |
− | 00000ad0 cc 01 aa 01 be 01 2e 2e 2e 20 00 0d 0a 00 2c 00 |......... ....,.|
| |
− | 00000ae0 52 65 73 65 74 20 79 6f 75 72 20 41 72 64 75 69 |Reset your Ardui|
| |
− | 00000af0 6e 6f 20 74 6f 20 73 63 61 6e 20 61 67 61 69 6e |no to scan again|
| |
− | 00000b00 2e 2e 2e 00 |....|
| |
− | </syntaxhighlight>
| |
− | </div></div>
| |
− | | |
− | Im Handbuch des ATmega kann man nachlesen, an welche Stelle der Controller (Programmzähler) springt sobald ein Interrupt ausgelöst wird. In meinem Besipiel an die Adresse 0x0002 (INT0 Pin 2) sofern die Fusebits, BOOTRST und IVSEL) auf default stehen.
| |
− | | |
− | [[Datei:ATmega VectorsTable.png|600px]]
| |
− | | |
− | Aus dem Handbuch erfährt man weiterhin, dass an der entsprechenden Stelle der Reset und Vectors Interrupts Table wiederum ein Sprungbefehl (jmp) steht und dahinter eine Adresse der jeweiligen ISR.
| |
− | | |
− | [[Datei:ATmega VectorsTable 2.png|600px]]
| |
− | | |
− | Wenn man die (default-)Einträge aus dem Handbuch mit dem o.g. Beispiel vergleicht und jetzt noch im AVR Instruction Set Manual nachschlägt, dass der Opcode für JMP 1001 010k kkkk 110k kkkk kkkk kkkk kkkk (94|95 XC|XD XX XX) lautet, kann man erkennen, dass in meinem Beispiel die ersten beiden 'Jumps' (0c 94 62 00 0c 94 43 03) Reset und INT0 auf die Adressen
| |
− | Nebenbemerkung: Man beachte die umgekehrte Schreibweise der Bytes. Bei Wordzugriffen (16 Bit) ist die Reihenfolge der Bytes im Speicher oder wie hier in einem hexdump zu beachten. Es muss also festgelegt sein, ob das erste Byte in Richtung aufsteigender Adressen das höhere (Big Endian Motorla-Fromat) oder das niedrigere Byte (Little Endian Intel-Format) des Wortes ist. Beispiel:
| |
− | Adresse 0x0000 Byte AB Adresse 0x0001 EF ergibt im BigEndian(Motorola-Word):ABEF im LittleEndian (INTEL-Word): EFAB
| |
− | | |
− | In meinem Beispiel ist es also '940c 0062' und '940c 0343'. Die Sprungasdressen ergeben sich somit zu
| |
− | 940c 0062: 0 0000 0 0000 0000 0110 0010 jmp 0x00c4 (2*0x62)
| |
− | 940c 0343: 0 0000 0 0000 0011 0100 0011 jmp 0x0686 (2*0x343)
| |
− | | |
− | Aus dem .elf file kann man sich den Assembler-Code generieren.
| |
− |
| |
− | objdump -D firmware.elf >firmware.asm
| |
− | | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
| |
− | <div style="font-weight:bold;line-height:1.6;">firmware.asm</div>
| |
− | <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="text" line>
| |
− | Disassembly of section .text:
| |
− | | |
− | 00000000 <__vectors>:
| |
− | 0: 0c 94 62 00 jmp 0xc4 ; 0xc4 <__ctors_end>
| |
− | 4: 0c 94 43 03 jmp 0x686 ; 0x686 <__vector_1>
| |
− | 8: 0c 94 1c 03 jmp 0x638 ; 0x638 <__vector_2>
| |
− | c: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 10: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 14: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 18: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 1c: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 20: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 24: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 28: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 2c: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 30: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 34: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 38: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 3c: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 40: 0c 94 d2 02 jmp 0x5a4 ; 0x5a4 <__vector_16>
| |
− | 44: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 48: 0c 94 90 03 jmp 0x720 ; 0x720 <__vector_18>
| |
− | 4c: 0c 94 6a 03 jmp 0x6d4 ; 0x6d4 <__vector_19>
| |
− | 50: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 54: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 58: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 5c: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 60: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | 64: 0c 94 8a 00 jmp 0x114 ; 0x114 <__bad_interrupt>
| |
− | </syntaxhighlight>
| |
− | </div></div>
| |
− | | |
− | Interessant ist, dass der INT1 auch belegt ist, obwohl ich den im Programm gar nicht explizit benutzte. Um herauszufinden was da abgearbeitet wird, ist es mir zu mühsam jeden Mnemonic einzeln durchzugehen. Da hilft an dieser Stelle ein Simulator. Wen es interessiert sollte irgendwann später hier (TODO AVR Simulation) einen Blick reinwerfen.
| |
− | | |
− | Jetzt im Nachhinein betrachtet ist das Receiver-Test-Sketch ziemlich ungeschickt gewählt, da man außer einer nicht weiter deutbaren Zahlenreihenfolge keine weitere Ausgabe erhält. Das das Programm funktioniert kann man testen indem man den Pin2 mal abklemmt und nur Nullen erhält;-)
| |
− | | |
− | ==Testprogramm Sender==
| |
− | | |
− | Mit dem Sendertestprogramm habe ich mir weniger Mühe gegeben. Dort wird nur im Sekundetakt. Ein Pulspaket (1000 Pulse) ausgegeben. Mit einem Oszilloskop könnte man hier gerade noch die maximale Bitrate (des C-Programms!) bestimmen.
| |
− | | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
| |
− | <div style="font-weight:bold;line-height:1.6;">transmittertest.ino</div>
| |
− | <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="c" line>
| |
− | #include <Arduino.h>
| |
− | | |
− | void setup() {
| |
− | // initialize digital pin LED_BUILTIN as an output.
| |
− | pinMode(4, OUTPUT); //433 MHz Sender
| |
− | pinMode(13, OUTPUT); // Arduino LED
| |
− | }
| |
− | | |
− | // the loop function runs over and over again forever
| |
− | void loop() {
| |
− | digitalWrite(13, HIGH);
| |
− | for (unsigned int i=0;i<1000;i++){
| |
− | digitalWrite(4, HIGH);
| |
− | digitalWrite(4, LOW);
| |
− | }
| |
− | digitalWrite(13, LOW);
| |
− | delay(1000);
| |
− | }
| |
− | </syntaxhighlight>
| |
− | </div></div>
| |
− | | |
− | ==RC-Switch==
| |
− | | |
− | Als Library zum Testen benutzte ich diese [https://github.com/sui77/rc-switch/ https://github.com/sui77/rc-switch/].
| |
− | | |
− | Und als erstes das ReceiveDemo_Simple.
| |
− | | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
| |
− | <div style="font-weight:bold;line-height:1.6;">Receiver_Simple_433</div>
| |
− | <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="c" line>
| |
− | /*
| |
− | Simple example for receiving
| |
− |
| |
− | https://github.com/sui77/rc-switch/
| |
− | */
| |
− | | |
− | #include <Arduino.h>
| |
− | #include <RCSwitch.h>
| |
− | | |
− | | |
− | RCSwitch mySwitch = RCSwitch();
| |
− | | |
− | char* binaer(char* nibble, char hexziffer){
| |
− | strcpy(nibble,"XXXX");
| |
− | switch((int)hexziffer){
| |
− | case 48: strcpy(nibble,"0000");break;
| |
− | case 49: strcpy(nibble,"0001");break;
| |
− | case 50: strcpy(nibble,"0010");break;
| |
− | case 51: strcpy(nibble,"0011");break;
| |
− | case 52: strcpy(nibble,"0100");break;
| |
− | case 53: strcpy(nibble,"0101");break;
| |
− | case 54: strcpy(nibble,"0110");break;
| |
− | case 55: strcpy(nibble,"0111");break;
| |
− | case 56: strcpy(nibble,"1000");break;
| |
− | case 57: strcpy(nibble,"1001");break;
| |
− | case 65: strcpy(nibble,"1010");break;
| |
− | case 66: strcpy(nibble,"1011");break;
| |
− | case 67: strcpy(nibble,"1100");break;
| |
− | case 68: strcpy(nibble,"1101");break;
| |
− | case 69: strcpy(nibble,"1110");break;
| |
− | case 70: strcpy(nibble,"1111");break;
| |
− | }
| |
− | if (!strcmp(nibble,"XXXX") && !strcmp(nibble,"ZZZZ")){
| |
− | strcpy(nibble,"----");
| |
− | }
| |
− | return nibble;
| |
− | }
| |
− | | |
− | void setup() {
| |
− | Serial.begin(9600);
| |
− | mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
| |
− | Serial.println("Scanning ");
| |
− | }
| |
− | | |
− | void loop() {
| |
− | char hexadez[10]; // array fuer 9 Zeichen
| |
− | char binstr[5]="ZZZZ"; // array fuer 4 Zeichen
| |
− | int i; // Laufvariable
| |
− | | |
− | if (mySwitch.available()) { // sobald was empfangen wird
| |
− | Serial.print("."); // ueberfluessig ??
| |
− | Serial.print("Received ");
| |
− | Serial.print( mySwitch.getReceivedValue() );
| |
− | sprintf(hexadez," 0x%04lX ",mySwitch.getReceivedValue());
| |
− | Serial.print( hexadez );
| |
− | for (i=3;i<=8;i++){
| |
− | binaer(binstr,hexadez[i]);
| |
− | Serial.print(binstr);
| |
− | Serial.print(" ");
| |
− | }
| |
− | Serial.print("/ ");
| |
− | Serial.print( mySwitch.getReceivedBitlength() );
| |
− | Serial.print("bit ");
| |
− | Serial.print("Protocol: ");
| |
− | Serial.println( mySwitch.getReceivedProtocol() );
| |
− | | |
− | mySwitch.resetAvailable();
| |
− | }
| |
− | }
| |
− | </syntaxhighlight>
| |
− | </div></div>
| |
− | | |
− | Da der Received-Value wenig aussagekräftig ist habe ich das Programm etwas erweitert.
| |
− | | |
− | Für die ORNO Fernbedienung ergabt sich folgende Codierung (24 Bit, Protocol: 1):
| |
− | {| class="wikitable"
| |
− | |-
| |
− | ! Kanal !! Zustand !! Code (HEX) !! Code (BIN) !! Code HX2260 (s.u.)
| |
− | |-
| |
− | | 1 || ON || 0x545533 || 0101 0100 0101 0101 0011 0011 || F F F 0 F F F F 0 1 0 1
| |
− | |-
| |
− | | 1 || OFF || 0x54553C || 0101 0100 0101 0101 0011 1100 || F F F 0 F F F F 0 1 1 0
| |
− | |-
| |
− | | 2 || ON || 0x5455C3 || 0101 0100 0101 0101 1100 0011 || F F F 0 F F F F 1 0 0 1
| |
− | |-
| |
− | | 2 || OFF || 0x5455CC || 0101 0100 0101 0101 1100 1100 || F F F 0 F F F F 1 0 1 0
| |
− | |-
| |
− | | 3 || ON || 0x545703 || 0101 0100 0101 0111 0000 0011 || F F F 0 F F F 1 0 0 0 1
| |
− | |-
| |
− | | 3 || OFF || 0x54570C || 0101 0100 0101 0111 0000 1100 || F F F 0 F F F 1 0 0 1 0
| |
− | |-
| |
− | | 4 || ON || 0x545D03 || 0101 0100 0101 1101 0000 0011 || F F F 0 F F 1 F 0 0 0 1
| |
− | |-
| |
− | | 4 || OFF || 0x545D0C || 0101 0100 0101 1101 0000 1100 || F F F 0 F F 1 F 0 0 1 0
| |
− | |-
| |
− | | 5 || ON || 0x547503 || 0101 0100 0111 0101 0000 0011 || F F F 0 F 1 F F 0 0 0 1
| |
− | |-
| |
− | | 5 || OFF || 0x54750C || 0101 0100 0111 0101 0000 1100 || F F F 0 F 1 F F 0 0 1 0
| |
− | |-
| |
− | |}
| |
− | | |
− | Zum Vergleich auch mal noch eine (4 Kanal Fernbedienung mit einem PT2262. Hier gibt das Datenblat genau Auskunft über das Protokoll und lässt somit eine Kontrolle des Receivertestprogramms zu.
| |
− | | |
− | {| class="wikitable"
| |
− | |-
| |
− | ! Kanal !! Zustand !! Code (HEX) !! Code (BIN) !! Code PT2262 (s.u.)
| |
− | |-
| |
− | | A || ON || 0x140551 || 0001 0100 0000 0101 0101 0001 || 0 F F 0 0 0 F F F F 0 F
| |
− | |-
| |
− | | A || OFF || 0x140554 || 0001 0100 0000 0101 0101 0100 || 0 F F 0 0 0 F F F F F 0
| |
− | |-
| |
− | | B || ON || 0x141151 || 0001 0100 0001 0001 0101 0001 || 0 F F 0 0 F 0 F F F 0 F
| |
− | |-
| |
− | | B || OFF || 0x141154 || 0001 0100 0001 0001 0101 0100 || 0 F F 0 0 F 0 F F F F 0
| |
− | |-
| |
− | | C || ON || 0x141451 || 0001 0100 0001 0100 0101 0001 || 0 F F 0 0 F F 0 F F 0 F
| |
− | |-
| |
− | | C || OFF || 0x141454 || 0001 0100 0001 0100 0101 0100 || 0 F F 0 0 F F 0 F F F 0
| |
− | |-
| |
− | | D || ON || 0x141511 || 0001 0100 0001 0101 0001 0001 || 0 F F 0 0 F F F 0 F 0 F
| |
− | |-
| |
− | | D || OFF || 0x141514 || 0001 0100 0001 0101 0001 0100 || 0 F F 0 0 F F F 0 F F 0
| |
− | |-
| |
− | |}
| |
− | | |
− | Der 'Hauscode' ist hier (10011 ON=1 OFF=0).
| |
− | Erstes Problem: Obwohl das Programm einen 24 Bit Code und Protokoll: 1 ausgibt
| |
− | laut Datenblatt der Code des PT2262 aber nur 12 Bit + Sync Bit lang.
| |
− | Zweites Problem: Der Code verändert sich beim Festhalten der Taste. Das werde ich mit dem Oszilloskop dann doch nachprüfen müssen.
| |
− | | |
− | Auf den ersten Blick erkennt man kaum einen Zusammenhang zwischen dem 'Hauscode' und dem Festhalten der Taste(n), einzig das ON/OFF kann man in den letzten 4 Bit erahnen.
| |
− | | |
− | Die im einem Wiki recht gute Dokumentation sollte Aufschluss geben. Ich versuche mal die Infos von https://github.com/sui77/rc-switch/wiki/KnowHow_LineCoding etwas auszuweiten.
| |
− | | |
− | Das Datenblatt spricht beim Senden (/TE auf low) von einem '''Code Frame'''. Ein Code Frame sind 4 '''Code Words'''. Ein '''Code Word''' besteht aus 12 '''Daten/Address-Bits''' und einem '''Sync-Bit''' (SYNC). Die Oszillatorfrequenz liegt je nach Widerstand an den Pins 15,16 des PT2262 zwischen 6 kHz -60 kHz.
| |
− | Bei der UHF Nutzung wird ein 4,7 MOhm Widerstand empfohlen. Dann liegt die Frequenz je nach Eingangsspannung zwischen etwa 6 und 8 kHz.
| |
− | Was bei der Durchsicht des Datenblattes weiter auffällt ist die Tatsache, dass der PT2263 nicht nur '0' und '1' unterscheidet, sondern einen dritten Zustand 'float' erkennt und sendet.
| |
− | Zum Erkennen eines Bits muss man 32 Oszilatorzyklen (OSCZ) 'beobachten'. Für das SYNC eigentlich 128 OSCZ, da aber das SYNC-Bit wie ein 0-Bit oder F-Bit anfängt aber nach weiteren 12 OSCZ kein Wechsel nach 1 erfolgt kann man an dieser Stelle schon von einem Sync-Bit ausgehen.
| |
− | | |
− | * Eine 0 wird übertragen wenn der Adress-/Dateneingang auf VSS (Ground) liegt.
| |
− | * Eine 1 wird übertragen wenn der Adress-/Dateneingang auf VDD (Vplus) liegt.
| |
− | * Ein F (float) wird übertragen wenn der Adress-/Dateneingang weder an VSS noch an VDD angeschlossen ist, also in der Luft hängt.
| |
− |
| |
− | * Eine 0 hat die Form: 4 OSCZ = 1 12 OSCZ = 0 4 OSCZ = 1 12 OSCZ = 0
| |
− | * Eine 1 hat die Form: 12 OSCZ = 1 4 OSCZ = 0 12 OSCZ = 1 4 OSCZ = 0
| |
− | * Ein F hat die Form: 4 OSCZ = 1 12 OSCZ = 0 12 OSCZ = 1 4 OSCZ = 0
| |
− | * Ein S hat die Form: 4 OSCZ = 1 124 OSCZ = 0
| |
− | | |
− | Jetzt geht's an die Messungen.
| |
− | | |
− | [[Datei:HX2262 Sendertest.jpg|400px]]
| |
− | | |
− | Hier ist der die DIP 18 Variante verbaut.
| |
− | | |
− | {|
| |
− | |-
| |
− | | [[Datei:PT2262 CodeWord.jpg|200px]] || [[Datei:PT2262 Sync.jpg|200px]] || [[Datei:PT2262 CODEBITS.jpg|200px]] || [[Datei:PT2262 BIT1.jpg|200px]] || [[Datei:PT2262 Bit 0.jpg|200px]]
| |
− | |-
| |
− | |}
| |
− | | |
− | Aus den Screenshots des Oszilloskops kann man folgendes ablesen:
| |
− | * CodeWord: 44,8 ms (12*32+128) = 87,5 us
| |
− | * SyncGap: 10,6 ms (124) = 85,5 us
| |
− | * Bit (halb): 1,4 ms (16) = 87,5 us
| |
− | | |
− | Das ergibt bei meiner Testfernbediinung ca. 11,5 kHz.
| |
− | | |
− | Dann fangen wir mal an die RC-Switch-Library auseinander zu nehmen.
| |
− | | |
− | /**
| |
− | * Description of a single pule, which consists of a high signal
| |
− | * whose duration is "high" times the base pulse length, followed
| |
− | * by a low signal lasting "low" times the base pulse length.
| |
− | * Thus, the pulse overall lasts (high+low)*pulseLength
| |
− | */
| |
− | struct HighLow {
| |
− | uint8_t high;
| |
− | uint8_t low;
| |
− | };
| |
− | | |
− | /**
| |
− | * A "protocol" describes how zero and one bits are encoded into high/low
| |
− | * pulses.
| |
− | */
| |
− | struct Protocol {
| |
− | /** base pulse length in microseconds, e.g. 350 */
| |
− | uint16_t pulseLength;
| |
− | | |
− | HighLow syncFactor;
| |
− | HighLow zero;
| |
− | HighLow one;
| |
− | | |
− | /**
| |
− | * If true, interchange high and low logic levels in all transmissions.
| |
− | *
| |
− | * By default, RCSwitch assumes that any signals it sends or receives
| |
− | * can be broken down into pulses which start with a high signal level,
| |
− | * followed by a a low signal level. This is e.g. the case for the
| |
− | * popular PT 2260 encoder chip, and thus many switches out there.
| |
− | *
| |
− | * But some devices do it the other way around, and start with a low
| |
− | * signal level, followed by a high signal level, e.g. the HT6P20B. To
| |
− | * accommodate this, one can set invertedSignal to true, which causes
| |
− | * RCSwitch to change how it interprets any HighLow struct FOO: It will
| |
− | * then assume transmissions start with a low signal lasting
| |
− | * FOO.high*pulseLength microseconds, followed by a high signal lasting
| |
− | * FOO.low*pulseLength microseconds.
| |
− | */
| |
− | bool invertedSignal;
| |
− | };
| |
− | | |
− | Dies ist schon mal irritierend. Warum heißt der das Syncbit syncFactor und wo ist der float-Zustand :-(
| |
− | | |
− | | |
− | /* Format for protocol definitions:
| |
− | * {pulselength, Sync bit, "0" bit, "1" bit, invertedSignal}
| |
− | *
| |
− | * pulselength: pulse length in microseconds, e.g. 350
| |
− | * Sync bit: {1, 31} means 1 high pulse and 31 low pulses
| |
− | * (perceived as a 31*pulselength long pulse, total length of sync bit is
| |
− | * 32*pulselength microseconds), i.e:
| |
− | * _
| |
− | * | |_______________________________ (don't count the vertical bars)
| |
− | * "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse
| |
− | * and 3 low pulses, total length (1+3)*pulselength, i.e:
| |
− | * _
| |
− | * | |___
| |
− | * "1" bit: waveform for a data bit of value "1", e.g. {3,1}:
| |
− | * ___
| |
− | * | |_
| |
− | *
| |
− | * These are combined to form Tri-State bits when sending or receiving codes.
| |
− | */
| |
− | #if defined(ESP8266) || defined(ESP32)
| |
− | static const VAR_ISR_ATTR RCSwitch::Protocol proto[] = {
| |
− | #else
| |
− | static const RCSwitch::Protocol PROGMEM proto[] = {
| |
− | #endif
| |
− | { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1
| |
− | { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2
| |
− | { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3
| |
− | { 380, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4
| |
− | { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5
| |
− | { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 6 (HT6P20B)
| |
− | { 150, { 2, 62 }, { 1, 6 }, { 6, 1 }, false }, // protocol 7 (HS2303-PT, i. e. used in AUKEY Remote)
| |
− | { 200, { 3, 130}, { 7, 16 }, { 3, 16}, false}, // protocol 8 Conrad RS-200 RX
| |
− | { 200, { 130, 7 }, { 16, 7 }, { 16, 3 }, true}, // protocol 9 Conrad RS-200 TX
| |
− | { 365, { 18, 1 }, { 3, 1 }, { 1, 3 }, true }, // protocol 10 (1ByOne Doorbell)
| |
− | { 270, { 36, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 11 (HT12E)
| |
− | { 320, { 36, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 12 (SM5212)
| |
− | };
| |
− | | |
− | Mit pulselength ist hier die Dauer eines 'kurzen' Pulses gemeint. Der Begriff Pulse, bzw. Pulse Cycle wird allerdings in Datenblatt des PT2262 in einem anderen Sinn benutzt. Ein Puls besteht dort aus 16 OszillatorCycles. Hier in der Library sind es aber dann 4 OszillatorCycles. So dass mein PT2262 eine pulselength von 350 (4*87,5us) hat. Dies würde dem protocol 1 entsprechen.
| |
− | Sync 1,31 = 32 * 4 = 128 OK
| |
− | Zero 1,3 = 4 * 4 = 16 nicht gut 32!
| |
− | One 3,1 = 4 * 4 = 16 nicht gut 32!
| |
− | | |
− | Somit müsste falls es nicht im Programm abgefangen wird jedes Bit doppelt verarbeitet werden und das Float-Bit eigentlich als 01 erkannt werden. Wobei ein Pulsefolge 10 nicht zulässig wäre.
| |
− | | |
− | Wenn man sich an dieser Stelle mit der unsauberen Verwendung der Begriffe arrangiert hat ergeben Testergebnisse der obigen Tabelle jetzt sogar einen Sinn.
| |
− | Die 24 vom Testprogramm gemeldeten Bit sind in Wirklichkeit nur 12!
| |
− | | |
− | Ein Blick in das Innenleben der ORNO Fernbedienung
| |
− | | |
− | [[Datei:ORNO HX2260.jpg|400px]]
| |
− |
| |
− | offenbart folgendes:
| |
− | * A0 float 1 offen
| |
− | * A1 float 2 offen
| |
− | * A2 float 3 offen
| |
− | * A3 0 4 VSS Lötpunkt!
| |
− | * A4 float 5 offen
| |
− | * A5 Taste
| |
− | * A6/D5 Taste
| |
− | * A7/D4 Taste
| |
− | * A8/D3 Taste
| |
− | * A9/D2 Taste
| |
− | * D1 Taste
| |
− | * D0 Taste
| |
− | | |
− | * Oszillatorwiderstand 4,7 MOhm
| |
− | | |
− | Was man jetzt recht schön erkennen kann ist der 'Hauscode' der ORNO (1:AO:F 2:A1:F 3:A2:F 4:A3:0 5:A4:F) und die Stellung des Mäuseklaviers (1:ON:0 2:OFF:F 3:OFF:F 4:ON:0 5:ON:0)
| |