RWE Zwischenstecker PSS mit Homematic FW flashen

In diesem Beitrag wollen wir alte RWE Zwischenstecker PSS Homematic fähig machen in dem wir sie mit einer neuen Firmware flashen. In diesem Fall nutzen wir einen Raspberry Pi als „Flash-Station“. Das eigentliche Flashen dauert ca. 30s. Die Vorbereitung natürlich etwas länger. Aber es lohnt sich insbesondere dann wenn man ein paar mehr Geräte flasht.

Im Prinzip ist dieser Beitrag eine Zusammenfassung aus dem Projekt AskSin++ (https://asksinpp.de/Projekte/), der Forumsdiskussion auf https://homematic-forum.de/forum/viewtopic.php?f=76&t=64286 und natürlich zuletzt auch den eigenen Erfahrungen.

Vorbereitung

Programmierschnittstelle

Man braucht einen ISP-Programmer für ATmega Mikrokontroller. Zum Beispiel den Waveshare AVRISP XPII. Nachteil an diesem Programmer ist, dass er erwartet dass die Versorgungsspannung von extern kommt. Vorteil ist, dass man nicht durch eine falsche Jumpereinstellung o.ä. aus Versehen den Controller oder Peripherie schrottet :). Praktisch ist auch, dass er mit einer Reihe von Adaptern geliefert wird, so dass er mit allen möglichen ISP-Stecker-Formaten genutzt werden kann.

Ein Alternativer ISP-Programmer der eine Versorgung mitbringt ist der Diamex AVR ISP, den es z.B. bei reichelt gibt.

Die ISP Schnittstelle findet man nach Öffnen des Gehäuses (dazu wird ein Torx TX6 benötigt) auf der Oberseite der Platine. Sie ist mit PRG1 bezeichnet und hat 6 Kontakte.

Anschluss (PRG1 von links nach rechts):

Anordnung PRG1SCKVCCMISOMOSIRESETGND
Aderfarbe WaveshareGrünRotGelbBlauWeißSchwarz
ISP Pin Nummer321456
PRG1

Die Pinbelegung der ISP-Schnittstelle des Programmers steht aber auch auf der Rückseite des waveshare Programmers.

Arduino IDE vorbereiten

Wir gehen davon aus, dass die Arduino IDE bereits installliert ist (https://www.arduino.cc/en/software).

Wichtig: Version V1.8.19 verwenden und nicht die neue V2.x.x!

Ebenfalls wichtig: Unter Linux muss der Benutzer mit dem gearbeitet wird der dialout-Gruppe hinzugefügt werden, sonst kommt es zu Berechtigungsfehlermeldungen beim Hochladen: sudo adduser yourUserName dialout

Dann über den Library-Manager diese benötigten Bibliotheken installieren:

  • AskSinPP
  • EnableInterrupt
  • Low-Power

Zunächst müssen die Boards mit einer zusätzlichen URL ergänzt werden. Datei -> Voreinstellungen:

Zusätzliche URL eintragen: https://raw.githubusercontent.com/sleemanj/optiboot/master/dists/package_gogo_diy_atmega8_series_index.json

Dann können die DIY ATmega-Boards ausgewählt werden:

Dann die Boardeinstellungen anpassen:

Firmware / Sketch vorbereiten

Je CCU darf die DeviceID und die DeviceSerial nur einmal vorkommen. Werden mehrere Geräte geflashed so muss man darauf achten, dass man beide Werte vor dem Kompilieren und Hochladen anpasst:

const struct DeviceInfo PROGMEM devinfo = {
  {0x01, 0xd8, 0xaa},     // Device ID -> muss eindeutig sein
  "PSS1062416",           // Device Serial -> muss eindeutig sein

Deshalb sind auch im Sketch einige abweichende Einstellungen nötig gewesen. Dieser Sketch funktioniert mit dem ATmega644PA:

//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2021-01-29 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------
// ci-test=yes board=328p aes=no

// === PSS ATmega328P ===

// define this to read the device id, serial and device type from bootloader section
// #define USE_OTA_BOOTLOADER

#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <LowPower.h>

#include <Switch.h>

#define LED_PIN           8
#define CONFIG_BUTTON_PIN 0

// https://homematic-forum.de/forum/viewtopic.php?f=76&t=64286
//#define RELAY1_PIN        14
// orig:
#define RELAY1_PIN        A0



// number of available peers per channel
#define PEERS_PER_CHANNEL 8

#define USE_HW_SERIAL

// all library classes are placed in the namespace 'as'
using namespace as;

// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
  {0x01, 0xd8, 0xb4},     // Device ID
  "PSS1062416",           // Device Serial
  {0x00,0xd8},            // Device Model
  0x26,                   // Firmware Version
  as::DeviceType::Switch, // Device Type
  {0x01, 0x00}            // Info Bytes
};

/**
   Configure the used hardware
*/
//typedef AskSin<StatusLed<0>, NoBattery, Radio<AvrSPI<4, 5, 6, 7>, 10, 100>> Hal;
// orig:
typedef AvrSPI<10, 11, 12, 13> RadioSPI;
typedef AskSin<StatusLed<LED_PIN>, NoBattery, Radio<RadioSPI, 2> > Hal;


class PSSSwitchChannel : public ActorChannel<Hal,SwitchList1,SwitchList3,PEERS_PER_CHANNEL,List0,SwitchStateMachine> {
protected:
  typedef ActorChannel<Hal,SwitchList1,SwitchList3,PEERS_PER_CHANNEL,List0,SwitchStateMachine> BaseChannel;
  uint8_t pin;

public:
  PSSSwitchChannel () : BaseChannel(), pin(0) {}
  virtual ~PSSSwitchChannel() {}

  void init (uint8_t p,bool value=false) {
    pin=p;
    ArduinoPins::setOutput(pin);
    typename BaseChannel::List1 l1 = BaseChannel::getList1();
    this->set(l1.powerUpAction() == true ? 200 : 0, 0, 0xffff );
    this->changed(true);
  }

  uint8_t flags () const {
    return BaseChannel::flags();
  }


  virtual void switchState(__attribute__((unused)) uint8_t oldstate,uint8_t newstate,__attribute__((unused)) uint32_t delay) {
    if( newstate == AS_CM_JT_ON ) {
      ArduinoPins::setHigh(pin);
      device().led().invert(true);
    }
    else if ( newstate == AS_CM_JT_OFF ) {
      ArduinoPins::setLow(pin);
      device().led().invert(false);
    }
    this->changed(true);
  }
};

typedef PSSSwitchChannel swc;

typedef MultiChannelDevice<Hal, swc, 1> SwitchType;

Hal hal;
SwitchType sdev(devinfo, 0x20);
ConfigToggleButton<SwitchType> cfgBtn(sdev);

void initPeerings (bool first) {
  // create internal peerings - CCU2 needs this
  if ( first == true ) {
    HMID devid;
    sdev.getDeviceID(devid);
    for ( uint8_t i = 1; i <= sdev.channels(); ++i ) {
      Peer ipeer(devid, i);
      sdev.channel(i).peer(ipeer);
    }
  }
}

void setup () {
  DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  bool first = sdev.init(hal);
  sdev.channels(1);
  sdev.channel(1).init(RELAY1_PIN, false);

  buttonISR(cfgBtn, CONFIG_BUTTON_PIN);

  initPeerings(first);
  sdev.initDone();
}

void loop() {
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();
  if ( worked == false && poll == false ) {
    hal.activity.savePower<Idle<> >(hal);
  }
}
Vollständig anzeigen

Flashen mit Arduino IDE

Programmer AVRISP mkII einstellen. Dann Sketch -> Upload with external Programmer auswählen.

Unter Linux wird der passende USB Port für den AVRISP mkII mit avrdude automatisch gefunden 🙂

Flashen ohne Arduino IDE

Dies ist für ein Szenario gedacht in dem auf einem „normalen PC“ der Sketch angepasst und erzeugt wird und auf einem zweiten Rechner (z.B. Raspberry Pi) der ISP-Programmer angeschlossen ist.

Zunächst muss auf dem „Flash-Rechner“ avrdude installiert werden

sudo apt install avrdude

https://github.com/cactus-online/HM-Sys-sRP-Pl_PSR/wiki/Aufspielanleitung

https://asksinpp.de/Grundlagen/02_software.html#platformio

Optional: Zum Testen der Verbindung einmal den Flash auslesen.

sudo avrdude -c avrispmkII -Pusb -p m328p -Uflash:r:flash_pss_orig.hex:i

Dabei wird auch die originale Konfiguration der Fusebits mit ausgegeben. Die Bedeutung der Werte kann mit einem Fusecalculator (z.B. hier) leicht ermittelt werden.

  • Low = 0xFF
    • External Crystal Osc. 8 MHz
    • Start-up time: 16K CK + 65 ms
  • High = 0xDC
    • Boot Flash section size = 1024 words
    • Boot start address = $7C00
    • Boot Reset vector enabled
    • SPI enabled
    • Watchdog off
  • Extended = 0xFD
    • Brown-out detection level at VCC=2.7V

Hex-Datei mit avrdude flashen

In der Arduino IDE den Sketch übersetzen und die hex-Datei exportieren:

Damit wird eine .hex-Datei neben die .ino-Datei abgelegt. Sie hat hier den langen Namen bekommen: HM-LC-Sw1-Pl-DN-R1_PSS.ino_atmega328p_8000000L.hex

Die .hex-Datei kann dann auf den Rechner mit dem Programmer kopiert werden (z.B. mit scp über Netzwerk). Der Rechner ist in meinem Fall ein Raspberry Pi an den der ISP-Programmer angeschlossen ist. Auf diesen kann man sich dann mit ssh einloggen. Der Befehl zum flashen lautet

sudo avrdude -c avrispmkII -Pusb -p m328p -Uflash:w:HM-LC-Sw1-Pl-DN-R1_PSS.ino_atmega328p_8000000L.hex

Die Ausgabe sollte dann in etwa so aussehen:

Testen mit Homematic CCU3

Jetzt wird noch geprüft ob das Flashen erfolgreich war und das Gerät als Homematic Aktor erkannt wird. Wir testen mit der CCU3.

Einloggen in die CCU3-Weboberfläche, dann auf Geräte anlernen gehen und den Anlernmodus starten. Anschließend an dem anzulernenden Schaltaktor den Knopf ein paar Sekunden gedrückt halten. Dann sollte im Posteingang ein Gerät gemeldet werden:

Dort sehen wir dann unseren Schaltaktor mit den im Programm hinterlegten Parametern (Seriennummer und Bezeichnung):

Anschließend kann über Status und Bedienung der Zwischenstecker ein- und ausgeschaltet werden:


Beitrag veröffentlicht

in

von

Schlagwörter:

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert