BitfehlerASK: Unterschied zwischen den Versionen

Aus Ethersex_Wiki
Wechseln zu: Navigation, Suche
(ISP -> SPI)
(Berechnung des zu sendenden Codes in Javascript)
 
(12 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
== [[AVR Net-IO]] mit RFM12 steuert Funksteckdosen ==
+
== [[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.
 
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.
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(RFM12_TX_PIN, PB0, OUTPUT)  
+
  pin(STATUSLED_RFM12_TX, PB0, OUTPUT)  
  
 
  RFM12_USE_INT(1)
 
  RFM12_USE_INT(1)
Zeile 44: Zeile 44:
  
 
''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 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.
 +
  * 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";
 +
</source>
 +
 +
===Berechnung des zu sendenden Codes in C ===
 +
<source lang="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;
 +
}
 +
</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

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).

Rfm12-chip.jpg


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.

Myrfm12.jpg

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

Myrfm12-foto.jpg

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.

Hauscode-2.jpg

Angeregt durch einen Beitrag unter [1]