AVR Ethersex Schieberegister

Aus Wiki
Zur Navigation springen Zur Suche springen

Porterweiterung

Mit Hilfe von 74HC595 Schieberegistern ist es möglich, die Ausgabeports beinahe beliebig zu erweitern. Die Schieberegister können hintereinander gekoppelt werden (Daisy Chain). Pro Schieberegister stehen 8 weitere Ausgabeports zur Verfügung. Dabei werden lediglich 3 Portpins vom AVR Microcontroller in Anspruch genommen - unabhängig davon, ob 1 Schieberegister oder 5 zum Einsatz kommen.

Anschluss

Zum Anschluss eines oder mehrer Schieberegister sind lediglich 3 beliebige Portpins des AVR Controllers erforderlich. Hier im Besipiel werden zwei Schieberegister mit Hilfe der Pins PA4 (Data), PA5 (Clock) und PA6 (Store) angesteuert. Das erste Schieberegister erhält die seriellen Daten direkt von Portpin PA4, der Dateneingang des zweiten Registers wird mit dem seriellen Datenausgang QH* verbunden. Clock und Store Enable werden an beide Schieberegister parallel angeschlossen.

HC595.png

Warning.png Achtung:

Belastung der Ausgangspins beachten

  • Pro Ausgangspin max +/-35mA
  • Alle Ausgänge zusammen max. 70mA


Anpassung Konfiguration

cd ~/Dokumente/ethersex
make menuconfig

Folgende Option aktivieren:

|- I/O
|   |-HC595 Output expansion
|   |   |-Number of HC595 Registers: Anzahl der angeschlossenen Schieberegister

Pinkonfiguration anpassen:

gedit pinning/hardware/netio.m4 

Folgende Zeilen einfügen und die Ports entsprechend dem Anschluss des Schieberegisters anpassen:

pin(HC595_DATA, PA4)
pin(HC595_CLOCK, PA5)
pin(HC595_STORE, PA6)


Funktionstest

Ethersex neu kompilieren und zum AVR übertragen.

Funktionstest (ECMD) siehe auch (hier):

io set port 4 FF

Dieser Befehl schaltet sämtliche Ausgänge vom 1. Schieberegister (Port=4 ; Port 0..3 = PortA...D vom AVR Controller) auf High.

io set port 5 00

Dieser Befehl schaltet sämtliche Ausgänge vom 2. Schieberegister auf LOW.


Einbindung in Named Pins

Neben der oben beschriebenen rudimentären Low-Level Ansteuerung drängt sich aber die Einbindung in die Named Pins geradezu auf, damit die Ausgänge auch via Weboberfläche verfügbar sind, und einzelne Pins angesteuert werden können anstatt immer der komplette Port in einem Zug ausgegeben werden muss. Leider enthält Ethersex mehrere Bugs, die verhindern, dass dies "out of the Box" zu realisieren ist.

Sourcecode anpassen

Um Named Pins am Schieberegister zu ermöglichen, sind mehrere Änderungen am Sourcecode nötig.

  • File portio.c
gedit core/portio/portio.c

Am Anfang des Files im Bereich der #includes folgende Zeile einfügen:

#include "string.h"

In Funktion void portio_init(void) die markierten Zeilen ergänzen, damit der Abschnitt folgendermassen aussieht:

#ifdef HC595_SUPPORT
 for (i = IO_HARD_PORTS; i < (IO_HARD_PORTS + HC595_REGISTERS); i++) {
   memset(&vport[i], 0, sizeof(virtual_port_t));
   vport[i].write_port = hc595_write_port;
   vport[i].read_port = hc595_read_port;
   vport[i].write_ddr = hc595_write_ddr;
   vport[i].read_pin = hc595_read_port;
   vport[i].read_ddr = hc595_read_ddr;
 }
  • File hc595.c
gedit hardware/io_expander/hc595.c

Die folgenden Funktionen vor dem Block (/* -- Ethersex META -- ... */ ) einfügen:

uint8_t 
hc595_read_ddr(uint8_t port) 
{
  return 255;
}

uint8_t 
hc595_write_ddr(uint8_t port) 
{
  return 0;
}

void hc595_pin_set(uint8_t port, uint8_t pin)
{
   if ((port>IO_HARD_PORTS-1)&&(port<IO_PORTS)&&(pin<8))
     vport[port].write_port(port, vport[port].read_port(port) | _BV(pin));
}

void hc595_pin_clear(uint16_t port, uint16_t pin)
{
  if ((port>IO_HARD_PORTS-1)&&(port<IO_PORTS)&&(pin<8))
     vport[port].write_port(port, vport[port].read_port(port) & ~ _BV(pin));
}

void hc595_pin_toggle(uint16_t port, uint16_t pin)
{
  if ((port>IO_HARD_PORTS-1)&&(port<IO_PORTS)&&(pin<8)){
     if (vport[port].read_port(port) &  _BV(pin))
        hc595_pin_clear(port,pin);
     else
        hc595_pin_set(port,pin);
  }
}

  • File hc595.h
gedit hardware/io_expander/hc595.c

Die beiden markierten Funktionsdefinitionen einfügen, sodass der Block folgendermassen aussieht:

void hc595_init(void);
uint8_t hc595_write_port(uint8_t port, uint8_t data);
uint8_t hc595_read_port(uint8_t port);
uint8_t hc595_read_ddr(uint8_t port);
uint8_t hc595_write_ddr(uint8_t port);
void hc595_pin_set(uint8_t port, uint8_t pin);
void hc595_pin_clear(uint8_t port, uint8_t pin);
void hc595_pin_toggle(uint8_t port, uint8_t pin);


Named Pins konfigurieren

gedit ~/Dokumente/ethersex/pinning/named_pins/default

Das 1. Schieberegister wird mit Port E (PE0...7), das zweite mit Port F (PF0...7), usw. angesprochen. Z.B.

# PIN | IN/OUT | When active? | Name
#-----+--------+--------------+----------------
PC4	OUTPUT	 HIGH		Steckdose_1
PC5	OUTPUT	 HIGH		Steckdose_2
PC6	OUTPUT	 HIGH		Steckdose_3
PC7	OUTPUT	 HIGH		Steckdose_4
PC2	OUTPUT	 HIGH		Reed_1
PC3	OUTPUT	 HIGH		Reed_2
PB0     INPUT    LOW            Taster_1
PD7     INPUT    LOW            Taster_2
PD6     INPUT    LOW            Taster_3
PD4     INPUT    LOW            Taster_4
PE0	OUTPUT	 HIGH		OUT_595_1
PE1	OUTPUT	 HIGH		OUT_595_2
PE2	OUTPUT	 HIGH		OUT_595_3
PE3	OUTPUT	 HIGH		OUT_595_4
PE4	OUTPUT	 HIGH		OUT_595_5
PE5	OUTPUT	 HIGH		OUT_595_6
PE6	OUTPUT	 HIGH		OUT_595_7
PE7	OUTPUT	 HIGH		OUT_595_8
PF0	OUTPUT	 HIGH		OUT_595_9
PF1	OUTPUT	 HIGH		OUT_595_10
PF2	OUTPUT	 HIGH		OUT_595_11
PF3	OUTPUT	 HIGH		OUT_595_12
PF4	OUTPUT	 HIGH		OUT_595_13
PF5	OUTPUT	 HIGH		OUT_595_14
PF6	OUTPUT	 HIGH		OUT_595_15
PF7	OUTPUT	 HIGH		OUT_595_16

Neu kompilieren und zum AVR übertragen.

Funktionstest via Weboberfläche Weboberfläche Bereich Named Pins aufrufen:

Ethersex6.png


Verwendung in Control6 Scripts

Leider wurde bisher keine Möglichkeit gefunden, diese Named_Pins am HC595 Schieberegister innerhalb von Control6 Scripten zu verwenden. Stattdessen wurde mit den oben eingefügten Funktionen hc595_pin_set, hc595 _pin_clear und hc595_pin_toggle eine brauchbare Alternative geschaffen.

Alle drei Funktionen erwarten als ersten Parameter den Port (Port=4 für 1. Schieberegister, Port=5 für 2. Schieberegister, usw.). Der zweite Parameter ist der anzusteuernde Pin (0...7). Verwendung z.B.:

hc595_pin_set(4,0);
hc595_pin_clear(5,5);
hc595_pin_toggle(4,7);

Neu kompilieren und zum AVR übertragen.