Arduino Asksin library

Begonnen von trilu, 06 August 2013, 10:02:17

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Soll, um Himmels willen, keine negative Äußerung sein. Es wäre aber schade, wenn Eure ganzen Überlegungen bei der Programmierung so langsam verloren gingen.

LG

pah


LJ_Skinny

#586
Hallo zusammen,

ich möchte hier mal mein Projekt vorstellen: http://forum.fhem.de/index.php/topic,18510.0.html

Dort will ich  eine Art PanStamp Modul mit dem STM32 realisieren. Die Mikrocontroller haben einen ARM Cortex an Board und sind sehr gut ausgestattet und zudem gibt es diese zu einem sehr günstigen Preis. Somit sollten sie sich für jede Menge Projekte in der Hausautomatisierung verwendet lassen. Da ich persönlich mit diesen Prozessoren sehr gute Erfahrungen sammeln konnte, werde ich diesen für meine Projekte verwenden.

Da ich daheim bereits Homematic-Komponenten habe, möchte ich gerne diese Bibliothek für mein Board verwenden. Dazu muss ich die vorhandene Library portieren.

Besteht dafür Interesse, sodass der Code auch entsprechend im Repository eingepflegt werden soll?

Der Hauptteil wird sich wohl in der cc110x.cpp abspielen, da der Zugriff beim AVR und STM32 sehr unterschiedlich sein werden. Sinnvoll wäre es dort wohl eine entspreche HAL einzubauen, dann wäre man von der HW unabhängig.

Ich kenne die Arduino-Entwicklungsumgebung nicht. Wie werden dort die ino-Dateien eingebunden? Außerdem werden in der HM Klasse einige Arduino spezifische Bibliotheken eingebunden. Muss mal schauen wie man das am schönsten umsetzen kann.

Wäre super, wenn ich hier ein wenig Unterstützung bekommen können.

Soweit mal von mir.

Viele Grüße und noch ein schönes Wochenende!

Grüße

Holger

PS: Nachtrag: Ich habe hier mal die Bibliothek und deren Zusammenhänge dargestellt:

(http://forum.fhem.de/index.php?action=dlattach;topic=14140.0;attach=15014;image)


PeterS

Hallo Horst

Ich habe nun doch mal ein Panstamp Entwicklungskit besorgt, da die Kombi Arduino Nano-CC1101 bei mir nicht stabil genug läuft. (Pairing, etc.)

Mein Ziel ist es den AVR als Homematic-Blackbox mit 4 Eingängen (z.B. 4-fach Funk-Taster-Schnittstelle - HM-PBI-4-FM) und 4 Ausgängen (z.B. 4-Kanal-Schaltaktor - HM-LC-Sw4-Ba-PCB) zu betreiben.

Ist diese Konstellation denkbar ? (Der Sketch HM_LC_SW1_BA_PCB.ino ist ja bereits in den Beispielen enthalten)

Gruss Peter

Meta

Vorneweg erstmal ein dickes LOB für die lib und die ganze Mühe die drinsteckt.
Ich bin gerade dabei die lib mal auszuprobieren und habe schon die ersten Probleme die ich mangels gefundener Doku
hier mal zur Lösung anbiete :)

1. Wenn ich das LedLampeRelay Beispiel kompiliere und auf einen Arduino Uno spiele bekomme ich folgende Ausgabe:
Starting sketch...

Available commands:
  p                - start pairing with master
  r                - reset device
  b[0]  b[n]  s    - send a string, b[0] is length (50 bytes max)

  c                - print configuration

  $nn for HEX input (µù

Danach ist der Arduino eingefroren und nimmt keine Kommandos mehr an und sagt auch nix mehr. Wenn ich die Ausgabe des Hilfetexts auskommentiere
gehts normal weiter.

2.
Das Pairen mit FHEM funktioniert nicht. Ich setze in FHEM hmPairForSec auf beispielsweise 100. Dann auf dem Arduino ein reset (r) und pair (p) bringt folgende Ausgabe:
Sta²÷ing sketch...
freeMem: 1053 byte

pair: 00 00 00

reset device, clear eeprom...
prep eeprom
reset done
<- 1A 00 A2 00 F4 B6 5D 00 00 00 15 00 11 54 4C 55 30 30 30 32 30 30 33 10 01 01 00 (l:27) (6270)
<- 1A 00 A2 00 F4 B6 5D 00 00 00 15 00 11 54 4C 55 30 30 30 32 30 30 33 10 01 01 00 (l:27) (6970)
<- 1A 00 A2 00 F4 B6 5D 00 00 00 15 00 11 54 4C 55 30 30 30 32 30 30 33 10 01 01 00 (l:27) (7671)
-> NA (8367)

Warum sind hier jetzt komische Zeichen im "Starting Sketch" ?!?
Die dtRegs in der Register.h stehen auf 0. Gibts da noch einen Tip woran es noch hängen kann?

3.
Wenn ich die Beispiele compile krieg ich teilweise Fehler:
AskSin\AskSinMain.cpp.o: In function `fastdelegate::DelegateMemento::SetMementoFrom(fastdelegate::DelegateMemento const&)':
/utility/Fastdelegate.h:640: undefined reference to `modTbl'
/utility/Fastdelegate.h:640: undefined reference to `modTbl'
/utility/Fastdelegate.h:641: undefined reference to `modTbl'
/utility/Fastdelegate.h:641: undefined reference to `modTbl'
AskSin\AskSinMain.cpp.o: In function `HM::regCnlModule(unsigned char, fastdelegate::FastDelegate5<unsigned char, unsigned char, unsigned char, unsigned char*, unsigned char, void>, unsigned int*, unsigned int*)':
D:\Programme\Arduino\libraries\AskSin/AskSinMain.cpp:249: undefined reference to `modTbl'
AskSin\AskSinMain.cpp.o:D:\Programme\Arduino\libraries\AskSin/AskSinMain.cpp:249: more undefined references to `modTbl' follow

PeterS

Hallo Meta

Das Einfrieren von manchen Befehlen (z.B. "r") hatte ich früher auch.
Welche Hardware verwendest du ?

Gruss Peter

Meta

Ich hab einen Arduino Uno auf dem das Sketch läuft und ein Funkmodul (bei ebay geschossen) das eigentlich nur ein Breakout für den CC1101 Chip ist.
Gestern habe ich 2 Funkmodule mittels der panstamp library mal reden lassen, was auch funktioniert hat. Die Module funktionieren also.

Bennemannc

Hallo,

die Fehlermeldung bekomme ich auch - keine Ahnung warum. Mich würde auch interessieren woran das liegt.

Gruß Christoph
Cubietruck, Fhem 5.8
CC-RT-DN|LC-SW2-FM|RC-12|RC-19|LC-SW4-BA-PCB|LCp-SW1-BA-PCB|ES-PMSw1-Pl|LC-Bl1PBU-FM|PBI-4-FM|CC-VD|CC-TC|SEC-SC(2)|RC-KEY3-B|LC-Sw1PBU-FM|PB-2-FM|WDS100-C6-O|WDC7000|LC-Bl1-FM
Module: Dewpoint,FB_Callmonitor,HCS,Panstamp,at,notify,THRESHOLD,average,DOIF

trilu

Das hängen bleiben hatte ich anfangs auch mal - damals lag es am SPI Bus timing.
Schalte mal im Modul cc1101.h das Debuggen ein:
#define CC_DBG

Ich hatte mal das Problem beim pairen das der Master zu nah am Gerät lag - du brauchst mindestens einen Meter Abstand zwischen den Geräten.
Aber auch hier hilft das Debugflag von cc1101 um den Fehler einzugrenzen.

undefined reference to `modTbl'
Dieser Fehler ist ziemlich eindeutig :-)
Ich habe den modTbl erst nach einigen Beispielen eingebaut und jetzt sucht die Lib in der Register.h danach.
Je nach Beispiel, bzw. Anzahl der Kanäle sowas einfügen:
HM::s_modtable modTbl[] = {
{0,0,(s_mod_dlgt)NULL},
{0,0,(s_mod_dlgt)NULL},
}; // 16 byte

Es muss eine Zeile pro Kanal da sein - Kanäle zählen ab 0, dieses Beispiel ist also für ein Gerät mit einem Kanal.

ZitatMein Ziel ist es den AVR als Homematic-Blackbox mit 4 Eingängen (z.B. 4-fach Funk-Taster-Schnittstelle - HM-PBI-4-FM) und 4 Ausgängen (z.B. 4-Kanal-Schaltaktor - HM-LC-Sw4-Ba-PCB) zu betreiben.
Das kann die Lib jetzt schon, du musst nur eine Entsprechende Register.h generieren.

Das wäre die passende devDefinition.pm
use strict;
#Beispiel
# ========================switch =====================================
# battery powered 1 channel temperature
#  "003D" => {name=>"HM-WDS10-TH-O"           ,st=>'THSensor'          ,cyc=>'00:10' ,rxt=>'c:w:f'  ,lst=>'p'            ,chn=>"",},
# 1 device
# 1 kanal
# 6 peers je kanal erlaubt
#----------------define reglist types-----------------
package usrRegs;
my %listTypes = (
      regDev =>{ intKeyVisib=>1, burstRx=>1, pairCentral=>1,
              },
      regKey =>{
                 sign=>1, longPress=>1, dblPress=>1,
                 peerNeedsBurst=>1, expectAES=>1,   
          },
      regAct =>{ 
                sign          =>1,    #|     literal        |          | signature (AES) options:on,off
                lgActionType  =>1,    #|     literal        | required |  options:toggleToCntInv,off,toggleToCnt,jmpToTarget
                lgCtDlyOff    =>1,    #|     literal        | required | Jmp on condition from delayOff options:geLo,between,outside,ltLo,geHi,ltHi
                lgCtDlyOn     =>1,    #|     literal        | required | Jmp on condition from delayOn options:geLo,between,outside,ltLo,geHi,ltHi
lgCtOff       =>1,    #|     literal        | required | Jmp on condition from off options:geLo,between,outside,ltLo,geHi,ltHi
                lgCtOn        =>1,    #|     literal        | required | Jmp on condition from on options:geLo,between,outside,ltLo,geHi,ltHi
lgCtValHi     =>1,    #|   0 to 255         | required | Condition value high for CT table
                lgCtValLo     =>1,    #|   0 to 255         | required | Condition value low for CT table
lgMultiExec   =>1,    #|     literal        | required | multiple execution per repeat of long trigger options:on,off
lgOffDly      =>1,    #|   0 to 111600s     | required | off delay
lgOffTime     =>1,    #|   0 to 111600s     | required | off time, 111600 = infinite
lgOffTimeMode =>1,    #|     literal        | required | off time mode options:minimal,absolut
lgOnDly       =>1,    #|   0 to 111600s     | required | on delay
lgOnTime      =>1,    #|   0 to 111600s     | required | on time, 111600 = infinite
lgOnTimeMode  =>1,    #|     literal        | required | on time mode options:minimal,absolut
lgSwJtDlyOff  =>1,    #|     literal        | required | Jump from delayOff options:on,off,dlyOn,no,dlyOff
lgSwJtDlyOn   =>1,    #|     literal        | required | Jump from delayOn options:on,off,dlyOn,no,dlyOff
lgSwJtOff     =>1,    #|     literal        | required | Jump from off options:on,off,dlyOn,no,dlyOff
lgSwJtOn      =>1,    #|     literal        | required | Jump from on options:on,off,dlyOn,no,dlyOff
shActionType  =>1,    #|     literal        | required |  options:toggleToCntInv,off,toggleToCnt,jmpToTarget
shCtDlyOff    =>1,    #|     literal        | required | Jmp on condition from delayOff options:geLo,between,outside,ltLo,geHi,ltHi
shCtDlyOn     =>1,    #|     literal        | required | Jmp on condition from delayOn options:geLo,between,outside,ltLo,geHi,ltHi
shCtOff       =>1,    #|     literal        | required | Jmp on condition from off options:geLo,between,outside,ltLo,geHi,ltHi
shCtOn        =>1,    #|     literal        | required | Jmp on condition from on options:geLo,between,outside,ltLo,geHi,ltHi
shCtValHi     =>1,    #|   0 to 255         | required | Condition value high for CT table
shCtValLo     =>1,    #|   0 to 255         | required | Condition value low for CT table
shOffDly      =>1,    #|   0 to 111600s     | required | off delay
shOffTime     =>1,    #|   0 to 111600s     | required | off time, 111600 = infinite
shOffTimeMode =>1,    #|     literal        | required | off time mode options:minimal,absolut
shOnDly       =>1,    #|   0 to 111600s     | required | on delay
shOnTime      =>1,    #|   0 to 111600s     | required | on time, 111600 = infinite
shOnTimeMode  =>1,    #|     literal        | required | on time mode options:minimal,absolut
shSwJtDlyOff  =>1,    #|     literal        | required | Jump from delayOff options:on,off,dlyOn,no,dlyOff
shSwJtDlyOn   =>1,    #|     literal        | required | Jump from delayOn options:on,off,dlyOn,no,dlyOff
shSwJtOff     =>1,    #|     literal        | required | Jump from off options:on,off,dlyOn,no,dlyOff
shSwJtOn      =>1,    #| 
          },
     );
#      -----------assemble device -----------------
my %regList;
$regList{0}={type => "regDev",peers=>1};
$regList{1}={type => "regKey",peers=>6};
$regList{2}={type => "regKey",peers=>6};
$regList{3}={type => "regKey",peers=>6};
$regList{4}={type => "regKey",peers=>6};
$regList{5}={type => "regAct",peers=>2};
$regList{6}={type => "regAct",peers=>2};
$regList{7}={type => "regAct",peers=>2};
$regList{8}={type => "regAct",peers=>2};

sub usr_getHash($){
  my $hn = shift;
  return %regList       if($hn eq "regList"      );
  return %listTypes     if($hn eq "listTypes"       );
}

Danach einfach "perl destillregs.pl" und du bekommst die Register.h geliefert.

Viele Grüße
Horst

kuek

Servus zusammen,

Großes Lob! wirklich eine super lib!
Nach viel Lesen frage ich mich, ob der Speicher reicht, um einen Aktor und einen Sensor zu realisieren. Konkret möchte ich einen Schalter mit 6 Tastern und 6 LEDs in Größe eines Einbaurahmens nutzen, um zu schalten und den Schaltzustand zu visualisieren. Ala HM-PB-6-WM55 nur mit zusätzlicher LED Visualisierung. Oder brauche ich zwei Arduinos und zwei RF interfaces?


trilu

der speicher reicht dicke - die tasten haben nur zwei config flags.
einzig die io's könnten knapp werden, aber du kannst ja die leds auch multiplexen...

PeterS

Ja, ein Beispiel mit 6 Eingängen und 6 Ausgängen wäre schon hilfreich, dann müsste ich es nur noch auf 4 reduzieren  ;D

Danke trilu für die Tipps.

PS: Sieht die lib eigentlich schon den 24h alive modus (spätestens alle 24h ein Lebenszeichen) vor, oder ist dies im sketch abzufackeln ?

Gruss Peter

kuek

Wahrscheinlich reichen schon die aktuellen beispiele mit der led lampe relay und dem 6fach taster. Werde mich mal in ein paar wochen dran setzen, sobald ich zeit habe. Es sei denn mir kommt jemand zuvor.

Grüße

LJ_Skinny

Hallo zusammen,

ich bin noch dabei, die AskSin Library mit einem Hardware Abtraction Layer zu versehen, damit man diese auch auf anderen Plattformen verwenden kann. Siehe mein Post weiter oben.

Habe gerade noch einen kleinen Bug gefunden, den ich euch nicht vorenthalten will:

Zitat
uint32_t HM::getHMID(void) {
   uint8_t a[3];
   a[0] = dParm.HMID[2];
   a[1] = dParm.HMID[1];
   a[2] = dParm.HMID[0];
   a[3] = 0;
   return *(uint32_t*)&a;
}

Das Array sollte eine Größe von 4 haben, sonst kracht es irgendwann mal auf dem Stack!  ;)

Grüße

Holger

trilu

Hi Holger,

wieso siehst du das Array für die HM ID als Bug?
Soweit ich mich erinnere behandle ich die HM ID unterschiedlich zu den Peers, dürfte also nicht krachen weil es nur 3 Byte hat.
Die HM ID wird ja eigentlich nur zur Adressierung verwendet und hat folglich nur die 3 Byte.
Ich versuche die Lib auch gerade etwas weiter zu modularisieren, lagere gerade das EEprom Handling in eine eigene Class aus.
Das habe ich dann auch für send und receive vor...

Viele Grüße
Horst

LJ_Skinny

#599

uint32_t HM::getHMID(void) {
  [color=red] uint8_t a[3]; //dieses Array hat nur 3 Byte[/color]
   a[0] = dParm.HMID[2];
   a[1] = dParm.HMID[1];
   a[2] = dParm.HMID[0];
  [color=red] a[3] = 0; //Hier schreibst du in eine Adresse, für die kein Speicher mehr reserviert ist[/color]
   return *(uint32_t*)&a;
}


Wenn der Kompiler für die Funktion und deren lokalen Variablen den Stack verwendet, kann es unter Umständen sein, dass mit der Aktion "a[3] = 0;"  ein Wert vorher aus dem Programm überschrieben wird. Bei den AVRs wächst der Stack nach unten. Wenn du Glück hast, dann verwendet er nur die CPU Register und schreibt später eh einen anderen Wert dort wieder rein. Zur Sicherheit aber


uint32_t HM::getHMID(void) {
   [color=green]uint8_t a[4]; //jetzt kann sicher in a[3] geschrieben werden[/color]
   a[0] = dParm.HMID[2];
   a[1] = dParm.HMID[1];
   a[2] = dParm.HMID[0];
   [color=green]a[3] = 0; //Hier kann nun sicher beschrieben werden[/color]
   return *(uint32_t*)&a;
}


Evtl macht es sind Sinn den Endianess gleich bei der Initialisierung anzupassen und als Struct ein Union zu verwenden. Verbraucht ein Byte mehr, der Zugriff ist allerdings schneller. Falls die Struktur dParm   allerdings direkt für den zuübertragenden Protokoll-Stream verwendet wird, dann geht es nicht. Soweit war ich allerdings noch nicht. ;-)


union HmId_T
{
uint8 hmid[4];
uint32 hmIdWord:
}

inline uint32_t HM::getHMID(void) {
  return = dParm.hmIdWord;
}

Zur Überarbeitung des Biliothek:
Die Eeprom Zugriffe sind mir auch schon aufgefallen. Die habe ich bei meiner Version auch schon bereinigt.

Ebenso ist mir das WatchDog und das Power-Handling aufgefallen.  Teilweise werde ich da das PowerHandling für den CC1101 in dessen Klasse packen.

Mein Ziel ist es die AskSin Klasse nur als Protokoll-Stack Implementierung zu haben. (Da sollten keine direkten AVR Register Zugriffe mehr vorhanden sein und spezielle HW vorausgersetzt sein.) Ist noch ein wenig Arbeit, deswegen komme ich nicht so schnell voran wie ich möchte. ;-) Beispielsweise habe ich schon alle GPIO, I2C, SPI, TIMER, EEPROM Zugriffe in HAL Interfaces verpackt und greife von AskSin Lib generisch drauf zu. Das Pendant für die Treiber des AVRs fehlen dann noch.

Wenn du willst können wir uns gern mal darüber unterhalten.

Grüße

Holger