BitfehlerASK: Unterschied zwischen den Versionen
(→Berechnung des zu sendenden Codes in Javascript) |
|||
(8 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 20: | Zeile 20: | ||
pin(SPI_CS_RFM12, PD5, OUTPUT) | pin(SPI_CS_RFM12, PD5, OUTPUT) | ||
/* port the LEDS for rfm12 tx attached to */ | /* port the LEDS for rfm12 tx attached to */ | ||
− | pin( | + | pin(STATUSLED_RFM12_TX, PB0, OUTPUT) |
RFM12_USE_INT(1) | RFM12_USE_INT(1) | ||
Zeile 45: | Zeile 45: | ||
''Steckdose A - AUS: <nowiki>http://192.168.0.90/ecmd?rfm12 2272+0,5,80+76+10</nowiki>'' | ''Steckdose A - AUS: <nowiki>http://192.168.0.90/ecmd?rfm12 2272+0,5,80+76+10</nowiki>'' | ||
− | ===Berechnung des zu sendenden Codes=== | + | ===Berechnung des zu sendenden Codes in Javascript=== |
− | |||
− | |||
+ | <source lang="javascript"> | ||
/* | /* | ||
* v[] ist ein Array, das die unmittelbaren DIP-Stellungen (1=OFF, 0=ON) des Senders/Empfängers in die 3 zu sendenden Bytes umwandelt. | * v[] ist ein Array, das die unmittelbaren DIP-Stellungen (1=OFF, 0=ON) des Senders/Empfängers in die 3 zu sendenden Bytes umwandelt. | ||
Zeile 70: | Zeile 69: | ||
+ (v[8] << 6); | + (v[8] << 6); | ||
return "rfm12+2272+" + v1 + "," + v2 + "," + v3 + "+76+10"; | return "rfm12+2272+" + v1 + "," + v2 + "," + v3 + "+76+10"; | ||
− | + | </source> | |
− | |||
===Berechnung des zu sendenden Codes in C === | ===Berechnung des zu sendenden Codes in C === | ||
<source lang="c"> | <source lang="c"> | ||
#include <stdio.h> | #include <stdio.h> | ||
− | int main ( | + | #include <stdlib.h> |
+ | #include <string.h> | ||
+ | |||
+ | int | ||
+ | main (int argc, char *argv[]) | ||
{ | { | ||
− | + | if (argc != 4) | |
− | + | { | |
− | + | fprintf (stderr, "usage: %s HAUSCODE [A|B|C|D|E] [0|1]\n", basename (argv[0])); | |
− | + | exit (1); | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | const char *hauscode = argv[1]; | |
− | + | int steckdose = argv[2][0] % 0xDF; | |
− | + | int on = atoi (argv[3]); | |
− | + | ||
− | return 0; | + | if (on < 0 || on > 1) |
+ | { | ||
+ | fprintf (stderr, "ungültiges Kommando %d, erlaubte Werte 0 und 1\n", on); | ||
+ | exit (1); | ||
+ | } | ||
+ | |||
+ | int dip[12]; | ||
+ | int i; | ||
+ | for (i = 0; i < 12; dip[i++] = 1); | ||
+ | |||
+ | // Kommando | ||
+ | dip[0] = on; // C1 | ||
+ | dip[1] = 1 - on; // C2 | ||
+ | |||
+ | if (steckdose < 'A' || steckdose > 'E') | ||
+ | { | ||
+ | fprintf (stderr, "ungültige Steckdose %c, erlaubte Werte A,B,C,D oder E\n", steckdose); | ||
+ | exit (1); | ||
+ | } | ||
+ | |||
+ | // Steckdosencode | ||
+ | dip[6 + 'A' - steckdose] = 0; | ||
+ | |||
+ | // Hauscode | ||
+ | int j = strlen (hauscode); | ||
+ | if (j != 5) | ||
+ | { | ||
+ | goto hauscode_fehler; | ||
+ | } | ||
+ | for (i = 0; i < j; ++i) | ||
+ | { | ||
+ | on = hauscode[i] - '0'; | ||
+ | if (on < 0 || on > 1) | ||
+ | { | ||
+ | hauscode_fehler: | ||
+ | fprintf (stderr, "ungültiger Hauscode %s, erlaubte Werte 0 und 1, 5 Stellen\n", hauscode); | ||
+ | exit (1); | ||
+ | } | ||
+ | dip[11 - i] = 1 - on; | ||
+ | } | ||
+ | |||
+ | int v1 = (dip[11] << 6 | dip[10] << 4 | dip[9] << 2 | dip[8]); | ||
+ | int v2 = (dip[7] << 6 | dip[6] << 4 | dip[5] << 2 | dip[4]); | ||
+ | int v3 = (dip[3] << 6 | dip[2] << 4 | dip[1] << 2 | dip[0]); | ||
+ | |||
+ | printf ("rfm12 2272 %i,%i,%i 76 10\n", v1, v2, v3); | ||
+ | |||
+ | return 0; | ||
} | } | ||
</source> | </source> | ||
+ | |||
+ | ===Berechnung des zu sendenden Codes in Perl === | ||
+ | |||
+ | <source lang="perl"> | ||
+ | #!/usr/bin/perl -w | ||
+ | $hauscode = $ARGV[0]; # 11111 | ||
+ | $steckdose = $ARGV[1]; # A-E | ||
+ | $on = $ARGV[2]; # 0/1 | ||
+ | my @_dip = ($on,1-$on,1,1,1,1,1,map(1-$_,reverse(split(//,$hauscode)))); | ||
+ | $_dip[71-ord($steckdose)]=0; | ||
+ | my $_c1 = $_dip[11]<<6 | $_dip[10]<<4 | $_dip[9]<<2 | $_dip[8]; | ||
+ | my $_c2 = $_dip[7]<<6 | $_dip[6]<<4 | $_dip[5]<<2 | $_dip[4]; | ||
+ | my $_c3 = $_dip[3]<<6 | $_dip[2]<<4 | $_dip[1]<<2 | $_dip[0]; | ||
+ | printf ("rfm12 2272 %i,%i,%i 76 10\n", $_c1, $_c2, $_c3); | ||
+ | </source> | ||
+ | |||
===Infos zum Hauscode (Systemcode)=== | ===Infos zum Hauscode (Systemcode)=== | ||
Aktuelle Version vom 13. Juni 2011, 17:10 Uhr
Inhaltsverzeichnis
AVR-NET-IO mit RFM12 steuert Funksteckdosen
Nachdem die Temperaturmessung mit Dallas 1-wire Bus und auch das LCD (2x16) funktionieren habe ich nun auch noch ein paar Funksteckdosen in Betrieb genommen.
Das RFM12 Modul
Kaum zu glauben aber auf dieser winzigen Platine ist die gesamte Elektronik, die für eine Funkübertragung erforderlich ist, Sender, Empfänger, Schnittstelle (SPI).
Der Anschluss des RFM12 Funkmoduls erfolgt über „SPI“ und ein paar weitere Pins der „EXT.“ Steckerleiste.
Der folgende Verdrahtungsplan hilft bei der Verkabelung des Moduls.
In der Datei "pinning/hardware/netio.m4" die entsprechenden Einträge auskommentieren und auf die verwendeten Pins der „EXT.“ Steckerleiste lenken. Auf die Verwendung einer RX-LED wurde in dieser Anwendung verzichtet.
/* port the rfm12 module CS is attached to */ pin(SPI_CS_RFM12, PD5, OUTPUT) /* port the LEDS for rfm12 tx attached to */ pin(STATUSLED_RFM12_TX, PB0, OUTPUT)
RFM12_USE_INT(1)
Ist der Hauscode, die ersten fünf DIP-Schalter, der verwendeten Funksteckdose auf "11111" eingestellt, so ist sicher gestellt, das die Steuerung ganz einfach per Mausklick, über die Webseite "RFM12 ASK" des Ethersex HTTP-Servers (Inline RFM12), erfolgen kann.
Nach einem „make“ und Überspielen der entstandenen „ethersex.hex“ auf das AVR-NET-IO Board steht einem erfolgreichen Test nichts mehr im Wege.
Fotos vom Aufbau
Foto oben links/rechts: auf Pin 2 und 4 werden die Signale von „EXT.“ abgenommen. Auf 7 und 9 ist die LED „TX“ angesteckt. Das Flachbandkabel steckt in der Steckerleiste „ISP“.
Foto unten links: Das aufgefächerte Flachbandkabel von „ISP“ und die beiden Drähte (grün/schwarz) von „EXT.“ gehen direkt an die Lötpunkte der RFM12-Platine. Die beiden 10k Widerstände sind im Isolierbandwickel versteckt. Der grüne Draht, der in den „Himmel“ ragt, ist die 17 cm lange Drahtantenne. Ein einfacher und funktionierender Testaufbau.
Test der Funksteckdose
Entweder wie oben beschrieben über den Ethersex HTTP-Server oder auch auf folgende Weise. Voraussetzung für die folgenden Beispiele ist aber, dass der Hauscode (Systemcode) der verwendeten Funksteckdosen auf "11111" eingestellt ist:
Steckdose A - EIN: http://192.168.0.90/ecmd?rfm12 2272+0,5,81+76+10
Steckdose A - AUS: http://192.168.0.90/ecmd?rfm12 2272+0,5,80+76+10
Berechnung des zu sendenden Codes in Javascript
/*
* v[] ist ein Array, das die unmittelbaren DIP-Stellungen (1=OFF, 0=ON) des Senders/Empfängers in die 3 zu sendenden Bytes umwandelt.
* cmd ist 1 oder 0, je nach gewünschtem State.
*
* z.B. Standard Hauscode (alle auf "ON"), Gerät "B":
* var v = [0,0,0,0,0, 1,0,1,1,1];
*
*/
var v1 = (v[3] << 0)
+ (v[2] << 2)
+ (v[1] << 4)
+ (v[0] << 6);
var v2 = (v[7] << 0)
+ (v[6] << 2)
+ (v[5] << 4)
+ (v[4] << 6);
var v3 = (cmd << 0)
+ (cmd << 2)
+ (v[9] << 4)
+ (v[8] << 6);
return "rfm12+2272+" + v1 + "," + v2 + "," + v3 + "+76+10";
Berechnung des zu sendenden Codes in C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main (int argc, char *argv[])
{
if (argc != 4)
{
fprintf (stderr, "usage: %s HAUSCODE [A|B|C|D|E] [0|1]\n", basename (argv[0]));
exit (1);
}
const char *hauscode = argv[1];
int steckdose = argv[2][0] % 0xDF;
int on = atoi (argv[3]);
if (on < 0 || on > 1)
{
fprintf (stderr, "ungültiges Kommando %d, erlaubte Werte 0 und 1\n", on);
exit (1);
}
int dip[12];
int i;
for (i = 0; i < 12; dip[i++] = 1);
// Kommando
dip[0] = on; // C1
dip[1] = 1 - on; // C2
if (steckdose < 'A' || steckdose > 'E')
{
fprintf (stderr, "ungültige Steckdose %c, erlaubte Werte A,B,C,D oder E\n", steckdose);
exit (1);
}
// Steckdosencode
dip[6 + 'A' - steckdose] = 0;
// Hauscode
int j = strlen (hauscode);
if (j != 5)
{
goto hauscode_fehler;
}
for (i = 0; i < j; ++i)
{
on = hauscode[i] - '0';
if (on < 0 || on > 1)
{
hauscode_fehler:
fprintf (stderr, "ungültiger Hauscode %s, erlaubte Werte 0 und 1, 5 Stellen\n", hauscode);
exit (1);
}
dip[11 - i] = 1 - on;
}
int v1 = (dip[11] << 6 | dip[10] << 4 | dip[9] << 2 | dip[8]);
int v2 = (dip[7] << 6 | dip[6] << 4 | dip[5] << 2 | dip[4]);
int v3 = (dip[3] << 6 | dip[2] << 4 | dip[1] << 2 | dip[0]);
printf ("rfm12 2272 %i,%i,%i 76 10\n", v1, v2, v3);
return 0;
}
Berechnung des zu sendenden Codes in Perl
#!/usr/bin/perl -w
$hauscode = $ARGV[0]; # 11111
$steckdose = $ARGV[1]; # A-E
$on = $ARGV[2]; # 0/1
my @_dip = ($on,1-$on,1,1,1,1,1,map(1-$_,reverse(split(//,$hauscode))));
$_dip[71-ord($steckdose)]=0;
my $_c1 = $_dip[11]<<6 | $_dip[10]<<4 | $_dip[9]<<2 | $_dip[8];
my $_c2 = $_dip[7]<<6 | $_dip[6]<<4 | $_dip[5]<<2 | $_dip[4];
my $_c3 = $_dip[3]<<6 | $_dip[2]<<4 | $_dip[1]<<2 | $_dip[0];
printf ("rfm12 2272 %i,%i,%i 76 10\n", $_c1, $_c2, $_c3);
Infos zum Hauscode (Systemcode)
Erst über einen Linktipp von stesie habe ich verstanden wie das mit dem Funk-Rattenschwanz "http://192.168.0.90/ecmd?rfm12 2272+0,5,85+76+10" genau funktioniert. Nun kann ich auch bereits vorhandene Funksteckdosen, die unter Hauscode 1 existieren, steuern. In der folgenden Tabelle habe ich zwei verschiedene Hauscode- und Funksteckdosen-Einstellungen dokumentiert.
Angeregt durch einen Beitrag unter [1]