Arduino Asksin library

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

Vorheriges Thema - Nächstes Thema

east

#1125
Hallo Dietmar,

also denke das dein Wissen schon detailierte als meines ist. Wollte eigentlich den 6Fach-Taster der alten Lib verstehen und in NewAsksin integrieren. Mein ursprüngliches Vorhaben ist es, einen HM_LC_SW4 mit einem 6-Fach-Taster in einem Programm zusammen laufen zu lassen. Weiss auch, dass das wohl ein grosses Vorhaben werden wird, da ich wohl in der CCU bzw. FHEM eine Config anfertigen muss.

Daher benötige ich dringend eine lauffähige Version der alten Asksin. Um diese in Atmel Studio zu integrieren.


Also soweit ich das mit der Relay-Funktion cmSwitch verstanden habe, müsste ich mir eine eigene zb. cmButton bauen, um einen 6 Fach Taster aufzubauen. Bitte korrigiert mich, wenn ich falsch liege.

Da ich in Vergangenheit noch nicht so sehr mit Pointern beschäfftigt habe, werde ich wohl noch einige Zeit brauchen, um überhaupt auf Euren stand zu kommen.
Würde mich gerne beteiligen. Habe auch schon Erfolgreich eigene Platine mit CC1101 geätzt und zum laufen bekommen.

Was aber glaube mein Hauptproblem ist, dass bisher selbst HM noch kein Modul angeboten hat, das beide Funktionen von Wandtaster und Relay-PCB anbietet. Ist mein Vorhaben vielleicht zu hoch gegriffen? BZW. Geht das überhaupt?

Dazu müssten ja Zwei Funktionen Zeitgleich auf einem Arduino laufen. Einmal zb. cmButton mit bw. 4 Tasten und cmSwitch mit bw. 4 Relayausgängen.

Gruß
East

Dietmar63

#1126
also ich habe auch erst mal mit der alten bib angefangen und schon nach kurzer Zeit keine List mehr gehabt.
Die neue bib ist aus meiner Sicht leichter zu verstehen, weil sie die verschiedenen Hardwarekomponenten klarer abbildet.

Kompilieren geht mit der neuesten Arduino 1.6.9

ZitatWas aber glaube mein Hauptproblem ist, dass bisher selbst HM noch kein Modul angeboten hat, das beide Funktionen von Wandtaster und Relay-PCB anbietet. Ist mein Vorhaben vielleicht zu hoch gegriffen? BZW. Geht das überhaupt?
Das Problem werde ich auch noch lösen müssen, da ic haber in fhem schon mehrre Moduel betreue, glaube ich dass das Problem lösbar ist, wenn erst mal der Rest funktioniert

ZitatDazu müssten ja Zwei Funktionen Zeitgleich auf einem Arduino laufen. Einmal zb. cmButton mit bw. 4 Tasten und cmSwitch mit bw. 4 Relayausgängen.

Das sind den wahrscheinlich mehrer Kanäle in HM.
Was ich aus dem Code herausgelesen habe ist folgendes:

Im Arduino läuft eine Endlosschleife, und ruft immer hm.poll() auf.

hm.poll() fragt intern sämtliche Hardwarekomponenten ab, ob was anliegt oder passiert ist.  Darunter sind auch die von dir neu zu bauenden Kanäle/Geräte. Wenn nichts zu tun ist legt sich der Arduino wieder schlafen. Über setpowermode() kann man einstellen wie lange er schlafen soll: gar nicht, 250ms, 8s.

Der Arduino verfällt dann in Tiefschlaf und verbraucht dann praktisch keinen Strom, wichtig für Batteriebetrieb. Gleichzeitig kann man Interrupts auf PINs legen. Immer wenn auf denen dann etwas los ist, wacht der kleine auf und führt ein wenig Code aus. Man kann sich also dann einem Tastendruck merken und im nächsten Aufwachzyklus auswerten.

Wenn du also mehrere Kanäle erzeugt hast, werden sie nach korrekter  Registrierung immer per poll() abgefragt. Eigentlich ist vieles von dem was du brauchst schon in der Klasse configButton (NeuAskSin) vorhanden.

ich habe mal eine Grobstruktur von newasksin dokumentiert:

// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
register
     ee
     AS:hm
     cmModel:cm (cmBlind, ...)
     //Listen
     devDef, modTbl, peerTbl, cnlTbl, devIdnt

     everyTimerStart (
         cmMyBlind.regInHM(1, 3, &hm);                                                              // register user module
         cmMyBlind.config(&initBlind, &blindUpdateState, eeVars.initialPos);   
     )
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
cmModel(cmBlind, ...)   
    peerSingle, peerOdd, peerEven

    class cmChannelModel (cmMyBlind) {
       // Contains all register from list 1
       lstCnl
       // Contains all register from list 3
       lstPeer
       // Contains all register from list 3 without short or long prefix
       l3

       AS*:hm

       void (*fInit)(uint8_t);                                                                                                   // pointer
       void (*fUpdateState)(uint8_t, uint8_t, uint32_t); 
       
       // stati und viele Standardmetheoden + Trigger{11,40,41}
    }
}
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
AS:hm {
   public:
      CB confButton;          ///< config button
      EE ee;                  ///< eeprom module
      SN sn;                  ///< send module
      RG rg;                  ///< user module registrar
      LD ld;                  ///< status led
      PW pw;                  ///< power management
      CC cc;                  ///< load communication module
      BT bt; 
private 
   RV rv;
   struct s_confFlag {                           // - remember that we are in config mode, for config start message receive
   struct s_stcSlice {                           // - send peers or reg in slices, store for send slice function
   struct s_stcPeer  {
   struct s_l4_0x01  {

}

extern AS hm;
class waitTimer
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
sketch.ino

Setup()
     {}
Loop()
    {HM.poll() }

ISR()
   {cm.LEDBlinkDetected() }


Mein Plan ist es ein cmStromGasImpulsCounter zu bauen, dass 15 Minuten lang Impulse zählt und dann die Ergebnisse in der fhem-Zentrale abliefert. cmStromGasImpulsCounter soll von Superklasse ChannelModel abgeleitet werden, eine Klasse, die gemeinsamen Code aller cm... aufnehmen soll.  Schon übersetzbar, aber ich habe noch keine Ahnung davon was spezifsch und was allgemeingültig in einem channel ist. Aber das wird schon noch.

Dazu möchte ich gern die Kontrolle über die Interrupts bekommen, was mir im Moment nicht möglich ist, da die Interrupts schon belegt sind. Muss ich also wahrscheinlich umbauen, hat Dirk in MotorControl auch gemacht.

Bei Tests gestern habe ich  es hinbekommen die Ereignisse eines Tasters, eines Reedkontakts und eines Fototransistors  per Interrupt zu zählen. Wenn die hardware kommt, geht es das erste mal an die Kommunikation mit der Zentrale über HM.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

east

#1127
Also mit deinem Projekt hört sich das schon vielversprechend an. Super.

Ich weiss jetzt gerade nicht (Kann ich nochmal schauen), ob der 328p das kann, aber ich hatte mal ein wenig mit OpenMCP (AtxMega) zu tun.
Dort ist es so, das es verschiedene InterruptHandler gibt, die verschiedene Modis haben. Soll heissen das die Eventabhängig in unterschiedlichen Wichtigkeitsstufen abgearbeitet werden ( Master , Slave usw...). Das wäre, wenn der ATM328p das kann eine möglichkeit, dieses Problem zu umgehen.

Hier ein Auszug des Xmega 128A1....

"29
[Not recommended for new designs - Use
XMEGA A1U series] XMEGA A1 [DATASHEET]
8067O–AVR–06/2013
14.
Interrupts and Programmable
Multilevel Interrupt Controller
14.1    Features

Short and predictable interrupt response time

Separate interrupt configuration and vector address for each interrupt

Programmable multilevel interrupt controller

Interrupt prioritizing according to level and vector address

Three selectable interrupt levels for all interrupts: low, medium and high

Selectable, round-robin priority scheme within low-level interrupts

Non-maskable interrupts for critical functions

Interrupt vectors optionally placed in the application section or the boot loader section"


@Dietmar

Schaue gerade wie der 328p belegt ist. Ich sehe das da noch einige PCINTx frei sind.

Dietmar63

#1128
Ich habe nicht das Problem, dass es prinzipiell nicht geht.

Es ist aber so dass ich wegen NewAskSin nicht so Zugriff habe wie ich es will. Ich muss aufpassen, das die Logik des ConfigButtons erhalten bleibt, der obendrein an einem Pin hängt, den ich auch nicht genau identifizieren kann.

Vorrangregeln gibt es am 328p nicht.

So stelle ich mir vor, die Interrupts auszunutzen:

/*
Pullup sketch
a switch connected to pin 2 lights the LED on pin 13
*/

#include <PinChangeInt.h>
// #include <PinChangeIntConfig.h>

const int ledPin     = 13;

const int reedPin    = 2;
const int fotoPin    = 3;
const int buttonPin  = 4;

volatile byte foto   = 0;
volatile byte reed   = 0;
volatile byte button = 0;

// output pin for the LED
// input  pin for the switch

void setup() {
   Serial.begin(57600);
   
   pinMode(ledPin,   OUTPUT);
   
   pinMode     (fotoPin, INPUT);                           //set the pin to input
   digitalWrite(fotoPin, HIGH);                            //use the internal pullup resistor
   PCintPort::attachInterrupt(fotoPin, fotoCount, RISING); // attach a PinChange Interrupt to our pin on the rising ed

   pinMode     (reedPin, INPUT);                           //set the pin to input
   digitalWrite(reedPin, HIGH);                            //use the internal pullup resistor
   PCintPort::attachInterrupt(reedPin, reedCount, RISING); // attach a PinChange Interrupt to our pin on the rising ed

   pinMode     (buttonPin, INPUT);                             //set the pin to input
   digitalWrite(buttonPin, HIGH);                              //use the internal pullup resistor
   PCintPort::attachInterrupt(buttonPin, buttonCount, RISING); // attach a PinChange Interrupt to our pin on the rising ed
   
}

void loop(){
   Serial.print("reedcount:\t");
   Serial.print(reed,   DEC);
   
   Serial.print("  buttoncount:\t");
   Serial.print(button, DEC);
   
   Serial.print("  fotocount:\t");
   Serial.println(foto, DEC);
   
   delay(5000);
}

void reedCount()   { reed++;   digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin, LOW);}
void fotoCount()   { foto++;   digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW);}
void buttonCount() { button++; digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW);}

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

trilu

Ich habe in letzter Zeit ziemlich viel im DevAES Zweig geändert und das PCI handling komplett erneuert.
Der config button wird in hardware.h im Sketch Ordner definiert.

//- configuration key  ----------------------------------------------------------------------------------------
#define CONFIG_KEY             PIN_B0 // define the config key pin port


Die PC Interrupt functions findest Du in der HAL.h

extern void    registerPCINT(uint8_t PINBIT, volatile uint8_t *DDREG, volatile uint8_t *PORTREG, volatile uint8_t *PINREG, uint8_t PCINR, uint8_t PCIBYTE, volatile uint8_t *PCICREG, volatile uint8_t *PCIMASK, uint8_t PCIEREG, uint8_t VEC);
extern uint8_t checkPCINT(uint8_t PINBIT, volatile uint8_t *DDREG, volatile uint8_t *PORTREG, volatile uint8_t *PINREG, uint8_t PCINR, uint8_t PCIBYTE, volatile uint8_t *PCICREG, volatile uint8_t *PCIMASK, uint8_t PCIEREG, uint8_t VEC, uint8_t debounce);
extern uint8_t checkPCINT(uint8_t port, uint8_t pin, uint8_t debounce); // function to poll if an interrupt had happened, gives also status of pin
extern void    maintainPCINT(uint8_t vec); // collects all interrupt vectors and maintains the callback address for external pin change interrupt handling


Den zugehörigen code in hal_extern.h.

Wenn Du also einen Interrupt für einen Pin vom 328'er brauchst, dann registriere den Interrupt mit
registerPCINT(PINBIT, DDREG, PORTREG, PINREG, PCINR, PCIBYTE, PCICREG, PCIMASK, PCIEREG, VEC);
oder per Macro mit
registerPCINT(PIN_C0); Die Macros für die PIN's sind in HAL_atmega328.h definiert.

Jetzt kannst die Interrupts per checkPCINT pollen. Pollen wegen des debounce, also Entprellen...

extern uint8_t checkPCINT(uint8_t PINBIT, volatile uint8_t *DDREG, volatile uint8_t *PORTREG, volatile uint8_t *PINREG, uint8_t PCINR, uint8_t PCIBYTE, volatile uint8_t *PCICREG, volatile uint8_t *PCIMASK, uint8_t PCIEREG, uint8_t VEC, uint8_t debounce);
extern uint8_t checkPCINT(uint8_t port, uint8_t pin, uint8_t debounce); // function to poll if an interrupt had happened, gives also status of pin


Wenn kein Entprellen notwendig ist, kannst Du eine Sprungadresse angeben und wirst im User sketch über Interrupts informiert. Dazu in der hardware.h im User sketch Ordner die Zeile

//#define PCINT_CALLBACK // enables the pin change interrupt callback in user sketch

auskommentieren und im User Sketch die Funktion:

void pci_callback(uint8_t vec, uint8_t pin, uint8_t flag) {
//dbg << "cb, vec:" << vec << ", pin:" << pin << ", flag:" << flag << '\n';
}

einbauen.
Ich hoffe das löst Dein Problem.
Viele Grüße
Horst

Dietmar63

Hört sich erst einmal gut an!
Danke dafür - sehe ich mir nachher an
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

@trilu :
Habe die neue Version gefunden. Die Veränderungen scheinen wie für mich gemacht zu sein.

Leider lassen sich die Beispiele nicht übersetzten. Fast immer hat es mit Definitionen EE::xxx zu tun. Kannst du mir erklären wie ich sie lauffähig bekomme.

Zum Teil reicht es const voranzustellen. In manchen Fällen müssen aber mehr Variablen ergänzt werden. Mangels einer
einer Ahnung,  was die bedeuteten,  weiß ich nicht was ich tun muss
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

trilu

Ich habe die letzten Wochen ziemlich viel an der Lib geändert. Derzeit lässt sich nur der pcb Sketch kompilieren und betreiben. Die anderen Beispiele muss ich erst noch nach Ziehen...

east

#1133
Hallo Trilu,

habe mir mal deine DEV-AES angeschaut. Habe ein Problem die cmSwitch.h zu kompilieren. Diese meckert über die enum.... Einträge für Action und JT usw. Sie würden zu keiner Klasse gehören. Obwohl ich die zugehörigkeit zu cmSwitch sehe.

Hättest da ne Idee?

in cmSwitch.cpp....

zb.: l3>ACTIONTYPE = ACTION::INACTIVE;

Habe das erste Problem so gelöst:

zb.: l3->ACTIONTYPE = cmSwitch::ACTION(INACTIVE);

Des Weiteren kommen wie schon bei Dietmar beschrieben die Konflikte für beispielsweise EE::s_peerTbl peerTbl[] = hinzu.

Selbst auch mit der PCB, die eigentlcih laufen sollte.


trilu

Bin gerade in Bella Italia und kann nicht kompilieren. Bin am Samstag wieder zurück. Mit was kompilierst du?
Und welche Fehler gibt das Ding von sich?

east

OH... Danke für die Antwort. Und auch noch in deinem Urlaub.

Sorry. Aber ich habe versucht mit arduino 1.6.5 und 1.6.4 zu kompilieren. Da ist es so, das der garnicht kompiliert, da das kompilieren bei ca 1/3 kleben bleibt. Bei beiden Versionen auf verschiedenen Rechnern.

Dann habe ich zusätzlich in Atmel Studio 7 mit der Arduino Ide probiert. Dort haut er mir das raus.....


Error      conflicting declaration 'EE::s_peerTbl peerTbl []'   und....

Error      no matching function for call to 'cmRemote::regInHM(int, int, AS*)'   

Dietmar63

#1136

Error      conflicting declaration 'EE::s_peerTbl peerTbl []'   und....

Error      no matching function for call to 'cmRemote::regInHM(int, int, AS*)'


Die Fehler hatte ich auch - hat nix mit dem Compiler zu tun.
Beim ersten Fehler muss man const voranstellen
Beim zweiten Fehler entfällt der dritte Parameter.

etwa so:

const EE::s_peerTbl peerTbl []

...remote[i].regInHM(int, int)


Ich vermute, dass sich in AS einiges geändert hat, die Beispiele aber nicht angepasst wurden.

Bei mir lässt sich pb6 compilieren, aber irgendwie scheint loop() nicht zu laufen

Ich Nutze arduino 1.6.9 auf Linux.
Fehler beim compilieren haben in der Regel nichts mit der Version des Compilers zu tun - glaube ich jedenfalls.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

Die nicht ausgeführte loop() hat sich erst einmal geklärt.
Da ich noch kein cc1101 Modul angeschlossen habe, kommt die init() Funktion nicht zum Ende.

Also mein Problem und wahrscheinlich gelöst.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

trilu

Der init vom cc1101 fängt Fehler nicht ab, deshalb wird init bei einem fehlenden Modul nie beendet. Der pb6 lässt sich vermutlich kompilieren, der ist aber work in progress. Da fehlt noch die komplette Sende Funktion. Der Switch ist das Einzige was im Moment funktioniert. Ich mach nächste Woche wieder weiter...

Dietmar63

#1139
Ok,
Kein großes Problem - warte jetzt erst mal bis ich mein cc1101 gelötet habe.

Wenn du wieder zurück bist quäle ich dich vielleicht nochmals mit etwas Hintergrundwissen, trigger{40,41,11}. Würde es nicht vielleicht Sinn machen eine Superklasse für alle cmXXXXXX zu bauen. Sie alle haben Methoden, die weitestgehend gleich sind. Und der Pflegaufwand würde sinken.

apropo Senden:
ich habe gesehen, dass die Sendefunktion immer in AS eingebaut werden muss. Macht es nicht Sinn eine SendeFunktion so allgemein zzu schreiben, dass man ihr alles an Nutzdaten mitgeben kann? So, muss man NewAskSin immer wieder verändern. 

Ist es überhaupt einfach und damit sinnvoll ein eigenes HM-Gerät zu bauen. Ich müsste ja die gesendeten Datenpakete auch noch in Readings verwandeln. Generisch scheint das in CUL_HM auch nicht zu sein.

Aber erstmal schönen Urlaub in Italien - wäre auch gern dort!
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm