AskSin++ Library

Begonnen von papa, 08 September 2016, 11:11:25

Vorheriges Thema - Nächstes Thema

east

#255
Ahh Super ok. Danke.



#include <MultiChannelDevice.h>
#include <Remote.h>
#include <SwitchChannel.h>



// we use a Pro Mini
// Arduino pin for the LED
// D4 == PIN 4 on Pro Mini
#define LED_PIN 4
#define LED_PIN2 6

// Arduino pin for the config button
// B0 == PIN 8 on Pro Mini
#define CONFIG_BUTTON_PIN 8

// relay output pins compatible to the HM_Relay project
#define RELAY1_PIN 5
#define RELAY2_PIN 7

#define BUTTON1_PIN 14
#define BUTTON2_PIN 15

// number of available peers per channel
#define PEERS_PER_SWCHANNEL 2
#define PEERS_PER_BTNCHANNEL 10

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

/**
* Configure the used hardware
*/
typedef AvrSPI<10,11,12,13> SPIType;
typedef Radio<SPIType,2> RadioType;
typedef DualStatusLed<6,4> LedType;
typedef BatterySensor<22,19> BatteryType;
typedef AskSin<LedType,BatteryType,RadioType> BaseHal;
class Hal : public BaseHal {
public:
  void init () {
    BaseHal::init();
    // measure battery every 1h
    battery.init(seconds2ticks(60UL*60),sysclock);
  }
} hal;



typedef RemoteChannel<Hal,PEERS_PER_BTNCHANNEL> BtnChannel;
typedef SwitchChannel<Hal,PEERS_PER_SWCHANNEL> SwChannel;

class MixDevice : public ChannelDevice<Hal,VirtBaseChannel<Hal>,4,SwitchList1> {
public:
  VirtChannel<Hal,BtnChannel> c1,c2;
  VirtChannel<Hal,SwChannel> c3,c4;
public:
  typedef ChannelDevice<Hal,VirtBaseChannel<Hal>,4,SwitchList1> DeviceType;
  MixDevice (uint16_t addr) : DeviceType(addr) {
    DeviceType::registerChannel(c1,1);
    DeviceType::registerChannel(c2,2);
    DeviceType::registerChannel(c3,3);
DeviceType::registerChannel(c4,4);
  }
  virtual ~MixDevice () {}

  BtnChannel& btn1Channel () { return c1; }
  BtnChannel& btn2Channel () { return c2; }
  SwChannel&  Sw1Channel  () { return c3; }
  SwChannel&  Sw2Channel  () { return c4; }
};
MixDevice sdev(0x20);

ConfigButton<MixDevice> cfgBtn(sdev);

// map number of channel to pin
// this will be called by the SwitchChannel class
uint8_t SwitchPin (uint8_t number) {
switch( number ) {
case 2: return RELAY2_PIN;

}
return RELAY1_PIN;
}


void setup () {
  DINIT(57600,ASKSIN_PLUS_PLUS_IDENTIFIER);
  sdev.init(hal);
  buttonISR(cfgBtn,CONFIG_BUTTON_PIN);
  remoteChannelISR(sdev.btn1Channel(),BUTTON1_PIN);
  remoteChannelISR(sdev.btn2Channel(),BUTTON2_PIN);
 
}

void loop() {
  bool pinchanged = sdev.btn1Channel().checkpin();
  pinchanged |= sdev.btn2Channel().checkpin();

  bool worked = hal.runready();
  bool poll = sdev.pollRadio();
  if( pinchanged == false && worked == false && poll == false ) {
    // deep discharge protection
    // if we drop below critical battery level - switch off all and sleep forever
    if( hal.battery.critical() ) {
      // this call will never return
      hal.activity.sleepForever(hal);
    }
    // if nothing to do - go sleep
    hal.activity.savePower<Sleep<>>(hal);
  }
}


papa

Sieht gut aus - bis auf das Device-Template. Die SwitchList1 muss weg


class MixDevice : public ChannelDevice<Hal,VirtBaseChannel<Hal>,4,SwitchList1> {
public:
  VirtChannel<Hal,BtnChannel> c1,c2;
  VirtChannel<Hal,SwChannel> c3,c4;
public:
  typedef ChannelDevice<Hal,VirtBaseChannel<Hal>,4,SwitchList1> DeviceType;


muss so


class MixDevice : public ChannelDevice<Hal,VirtBaseChannel<Hal>,4> {
public:
  VirtChannel<Hal,BtnChannel> c1,c2;
  VirtChannel<Hal,SwChannel> c3,c4;
public:
  typedef ChannelDevice<Hal,VirtBaseChannel<Hal>,4> DeviceType;


Es wird dann automatisch die Default List0 verwendet.

Und die SwitchPin-Funktion muss noch abgeändert werden. Die Switches sind als Channel 3 & 4 angemeldet - also muss der Switch/case entsprechend geändert werden.

Wenn das Gerät nicht mit Batterie betrieben wird, kann noch NoBattery als BatterType verwendet werden. Außer dem kann der Batteriecode in der loop-Funktion rausgeschmissen werden. Schau mal in der Switch-Example. Das sollte so passen.
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

east

Ja super. Vielen Dank. Aber nen bisschen rumbasteln ist schon was anderes als richtiges programmieren.... :-[
Vielen Dank für die geduld.

andirs

#258
Hallo papa, danke für deine Library. Damit habe ich schon gute Erfolge erzielt beim Erstellen meines eigenen Universalsensors. Dabei messe ich neben Temperatur und Feuchtigkeit noch die Helligkeit und Bewegungen mit einem PIR. Ich benutze den master tree und übertrage die Messwerte alle 2 Minuten.

Allerdings wäre es bei dem Bewegungssensor natürlich sinnvoll wenn die Erkennung einer Bewegung sofort gesendet wird. Im Prinzip definiere ich mit

attachInterrupt(digitalPinToInterrupt(DIGITAL_MOTION_INPUT_PIN), measureISR, CHANGE);

einen Interrupt und müsste eine measureISR() Funktion erzeugen, welche sofort ohne Wartezeit die Messwerte übermittelt.

Hat jmd. einen Vorschlag wie ich das elegant umsetzen kann? Kann im Prinzip noch nicht wirklich C++ programmieren. Danke :)

Hier mein bisheriges .ino file:

//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------

// define all device properties
#define DEVICE_ID HMID(0x11,0x12,0x13) // HM Address
#define DEVICE_SERIAL "USWZ111111" // HM Serial number
#define DEVICE_MODEL  0x00,0x3d
#define DEVICE_FIRMWARE 0x10
#define DEVICE_TYPE DeviceType::THSensor
#define DEVICE_INFO 0x03,0x01,0x00

#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <TimerOne.h>
#include <LowPower.h>

#include <MultiChannelDevice.h>
#include "HC-SR501.h"
#include "DHT22.h"
#include "LM393-LLS.h"

// Arduino Pro Mini
#define LED_PIN 4
#define CONFIG_BUTTON_PIN 8

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

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

/**
* Configure the used hardware
*/
typedef AvrSPI<10,11,12,13> SPIType;
typedef Radio<SPIType,2> RadioType;
typedef StatusLed<4> LedType;
typedef BatterySensor<22,19> BatteryType;
typedef AskSin<LedType,BatteryType,RadioType> BaseHal;
class Hal : public BaseHal {
public:
  void init () {
    BaseHal::init();
    // measure battery every 1h
    battery.init(seconds2ticks(60UL*60),sysclock);
  }
} hal;

class WeatherEventMsg : public Message {
public:
  void init(uint8_t msgcnt,int16_t temp,uint8_t humidity, uint8_t luminosity, bool motion, bool batlow) {
    uint8_t t1 = (temp >> 8) & 0x7f;
    uint8_t t2 = temp & 0xff;
    if( batlow == true ) {
      t1 |= 0x80; // set bat low bit
    }
    Message::init(0xe,msgcnt,0x70,Message::BIDI,t1,t2); // first byte determines message length; pload[0] starts at byte 13
    pload[0] = humidity;
    pload[1] = luminosity;
    pload[2] = motion;
  }
};

class WeatherChannel : public Channel<Hal,List1,EmptyList,List4,PEERS_PER_CHANNEL>, public Alarm {

  WeatherEventMsg msg;
  uint8_t         msgcnt;
  int16_t         temp;
  uint8_t         humidity;
  uint8_t         luminosity;
  bool            motion;

public:
  WeatherChannel () : Channel(), Alarm(5), msgcnt(0), temp(0), humidity(50), luminosity(0), motion(0) {}
  virtual ~WeatherChannel () {}

  virtual void trigger (AlarmClock& clock) {
    // reactivate for next measure
    tick = delay();
    clock.add(*this);
    measure();
    msg.init(msgcnt++,temp,humidity,luminosity,motion,false);
    device().sendPeerEvent(msg,*this);
  }

  // here we do the measurement
  void measure () {
    temp = measureTemperature();
    humidity = measureHumidity();
    luminosity = measureLuminosity();
    motion = measureMotion();
  }

  // here we calc when to send next value
  uint32_t delay () {
    return seconds2ticks(120);
  }

  void setup(Device<Hal>* dev,uint8_t number,uint16_t addr) {
    Channel::setup(dev,number,addr);
    sysclock.add(*this);
  }

  uint8_t status () const {
    return 0;
  }

  uint8_t flags () const {
    return 0;
  }

};

typedef MultiChannelDevice<Hal,WeatherChannel,1> WeatherType;
WeatherType sdev(0x20);

ConfigButton<WeatherType> cfgBtn(sdev);

void setup () {
  DINIT(57600,ASKSIN_PLUS_PLUS_IDENTIFIER);
  sdev.init(hal);
  buttonISR(cfgBtn,CONFIG_BUTTON_PIN);
  //attachInterrupt(digitalPinToInterrupt(DIGITAL_MOTION_INPUT_PIN), measureISR, CHANGE);
}

void loop() {
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();
  if( worked == false && poll == false ) {
    hal.activity.savePower<Sleep<>>(hal);
  }
}

papa

Am einfachsten ist es, im Interrupt ein Flag zu setzen und dann im Mainloop bei gesetztem Flag die Nachricht zu senden. Würde dann wie folgt aussehen. Die Funktion measureAndSend() muss dann noch im Channel implementiert werden.


...
ConfigButton<WeatherType> cfgBtn(sdev);

volatile bool pir=false;
void pirISR () {
  pir=true;
}

void setup () {
  DINIT(57600,ASKSIN_PLUS_PLUS_IDENTIFIER);
  sdev.init(hal);
  buttonISR(cfgBtn,CONFIG_BUTTON_PIN);
  enableInterrupt(DIGITAL_MOTION_INPUT_PIN, pirISR, RISING);
}

void loop() {
  if( pir == true ) {
    pir = false;
    sdev.channel(1).measureAndSend();
  }
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();
...
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

andirs

Super, danke schonmal.

Das konnte ich ja jetzt im .ino anlegen. Für measureAndSend() müsste ich aber in die Library oder?
Könntest du das bitte im Github machen? Dann kann ich mir immer die Library Updates ziehen ohne da noch reinpfuschen zu müssen und andere User hätten auch was davon.

Wär sehr nett, danke :)

Dietmar63

Ich würde sagen das musst du in deinen Weather Channel hineinbauen
Das Framework ist so aufgebaut, dass Papa normalerweise nichts machen 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

papa

Zitat von: andirs am 13 Mai 2017, 07:11:04
Super, danke schonmal.

Das konnte ich ja jetzt im .ino anlegen. Für measureAndSend() müsste ich aber in die Library oder?
Könntest du das bitte im Github machen? Dann kann ich mir immer die Library Updates ziehen ohne da noch reinpfuschen zu müssen und andere User hätten auch was davon.
r nett, danke :)

Einfach noch folgende Methode in die WeatherChannel Klasse einfügen und gut.


  void measureAndSend() {
    measure();
    msg.init(msgcnt++,temp,humidity,luminosity,motion,false);
    device().sendPeerEvent(msg,*this);
  }
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

andirs

Ah da stand ich ziemlic hauf dem Schlauch.

Danke  8)

Dietmar63

#264
@papa:

wie bestellt - habe drei Versionen gefunden - eine hm-sec-rhs war nicht dabei.
Wenn ich den Code anders generieren soll, bitte dann melden.

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

papa

BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

0xFFFF

#266
Ich muss nochmal nachfragen, wie das jetzt mit den Pins zu verstehen ist.
Auf einer Seite zuvor wird gesagt, PIN A3 ist 17...wie kommt man darauf? Oder anders gefragt, worauf bezieht sich die Nummerierung? Sowohl für den ConfigButton als auch für den Anschluss vom CC1101.

In den Beispielen wird der ConfigButton immer als PIN 8 definiert und der CC1101 über PINs 10-13 angesprochen...wobei er ja eigentlich auch 6 anschlüsse hat (und VCC/Masse).

Dietmar63


https://forum.arduino.cc/index.php?topic=147582.0


Arduinos basieren auf Atmel Prozessoren. Die Pins des Atmel (es gibt viele verschiedene ) haben von Atmel sBezeichnungen bekommen, die die bit Position in Ports abgebildet hat(PB7) ist bit 7 in PortB. Die Arduinos haben dies Bezeichnungen nicht auf die Nummerierung der Pins übernommen, sonder reihum durchgezählt. Die IDE und die C++ Bibliotheken versuchen diesen Sachverhalt zu verstecken. Du must nur wissen an welchem PIN du etwas anschließen willst, die  bits des passenden Ports ermitteln die Funktionen stellen alles richtig ein.

Unter dem obigem Link sind die verschiedenen Bezeichnungen der Pins eines Nano pro abgebildet. A3=17=pc3=pcint11 und noch viel mehr.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

papa

Das ist die Arduino-Pinnummerierung. Siehe auch hier https://playground.arduino.cc/Learning/Pins

Das CC1101 ist über SPI angebunden. Die SPI-Hardware im AVR ist auf den Pins 10-13 herausgeführt. Die restlichen Pins habe ich so festgelegt. Das hängt halt von der Hardware ab. Alle Beispiele haben den Config-Taster am Pin 8 gegen Masse. Die Led(s) an Pin 4 (und 5 - falls zwei). Das könnte man aber auch ganz anders machen.

Hoffe das hilft.
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

east

#269
Habe mal die Pinouts für den Pro Mini angehangen.....



Noch mal ne Frage ......

Wenn ich per eagle Schaltpläne bzw. Platinen bastel, kann ich diese hier auch kund tun?
Habe jetzt ne mini Platine für MixDevices ( HM-SW4 und HM-RC4 ) gebastelt.

Die Platine kann wahlweise mit 12V oder 5V gespeist werden. Benutze dafür Mini Supplies für PCB-Montage von Meanwell.

Bei dem jetzigen Board das ich erstellt habe, entnehme ich die 12V einem Codeschloss, das mit 12V gespeist wird.