Raspberry + RFM2Pi +TinyTX mit 00_JeeLink.pm & 18_JSN.pm

Begonnen von mattes1007, 07 Dezember 2013, 14:47:41

Vorheriges Thema - Nächstes Thema

hexenmeister

@mattes1007

Hallo und vielen Dank, das ist ja in der Tat sehr preiswert und recht schnell! Zusammen mit 'nem Atmel (1 EUR) und FRM12B (4,50 EUR) bekommt man eine preislich unschlagbare Option!  :D

Grüße,

Alexander
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

justme1968

laut minicom werden die daten auch drei mal gesendet.

schau dir mal event-on-change-reading und min-interval an.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

mattes1007

Zitat von: justme1968 am 26 Dezember 2013, 09:28:13
laut minicom werden die daten auch drei mal gesendet.

schau dir mal event-on-change-reading und min-interval an.

gruss
  andre

Danke, schaue ich mir mal an.

Der Auzug aus minicom waren aber 3 Minuten.
Jede Minute kommt so eine Zeile mit den Daten an.
Und fhem schreibt ja je Paket die Daten 3x in den Log.

Gruß mattes

mattes1007

Erstmal Frohes Neues,

soweit läuft jetzt alles.
Leider gibts schon wieder neue Probleme:

negative Temperaturen

2014-01-02_18:44:01 JSN_24 temperature: 22.06
2014-01-02_18:44:01 JSN_24 temperature1: 21.43
2014-01-02_18:44:01 JSN_24 Vcc: 3218
2014-01-02_18:49:43 JSN_24 temperature: 22.06
2014-01-02_18:49:43 JSN_24 temperature1: 21.5
2014-01-02_18:49:43 JSN_24 Vcc: 3218
2014-01-02_18:55:26 JSN_24 temperature: 22
2014-01-02_18:55:26 JSN_24 temperature1: [color=red]643.11[/color]
2014-01-02_18:55:26 JSN_24 Vcc: 3218


Mittlerweile habe ich schon rausgefunden das eigentlich alles richtig übermittelt wird....

binary
1111101100110111
binary bytes
11111011 00110111
decimal
[color=red]64311[/color]
decimal (formatted)
64,311
hex bytes
FB 37
hexidecimal
FB37

[color=red]Negative number -1,225 (two's complement hex 0xFB37)[/color]


Wie bringe ich das jetzt dem 18_JSN.pm Modul bei ??
Oder wie löst man so etwas am geschicktesten ?

Gruß mattes

mattes1007

#19
Hallo,

wie kann ich so etwas

if $value > 32768
   $value -= 65536

in der 18_JSN.pm realisieren ?

Hab es so probiert

{
# Sensor-Data Bytes to Values
# lowBit HighBit reverse ....
@SData = reverse(@SData);
my $raw_value = join("",@SData);
my $value = "";
map {$value .= sprintf "%02x",$_} @SData;
$value = hex($value);
       if ($value > 32768
       $value -= 65536);

Log 5, "JSN PARSE DATA $NodeID - $SType - " . join(" " , @SData) . " -> " . $value;

my $reading_name = $data{JEECONF}{$SType}{ReadingName};
$readings{$reading_name} = $value;
if(defined($data{JEECONF}{$SType}{CorrFactor})) {
  my $corr = $data{JEECONF}{$SType}{CorrFactor};
  $readings{$reading_name} = $value * $corr;


aber das stimmt wohl nicht ganz. Kann mir da einer von den Experten evtl. einen Tipp geben ?
Ist das überhaupt der richtige Ansatz um die -Temperaturen angezeigt zu bekommen ?

Habe es mit dem Python Script aus Emoncms getestet. Das funktioniert das mit den neg. Temperaturen.
Das sieht das ganze so aus

# Recombine transmitted chars into signed int
                        values = []
                        for i in range(1,len(received),2):
                            value = received[i] + 256 * received[i+1]
                            if value > 32768:
                                value -= 65536
                            values.append(value)


Gruß mattes

//edit

hab es geschafft :-)

if ( $value > 32767 ) {
       $value    = $value - 65536;
       }

muss es heißen.
Jetzt geht´s mit den negativen Temperaturen.

boelle

i know its been almost a year since this topic has been in use but i have a very related question

as i understant the RFM2Pi module can be used to get data in to fhem,

but can same module also be used to read the status of conrad window sensors? and can i control radiator valves from conrad?

i write in english but i can read german almost ok...

micmuec

#21
Hallo zusammen

ich hab da leider ein Problem mit meinen Funk Temperatur Sensoren.
in fhem kommt zwar was an, aber leider nicht das was ankommen soll.
und zwar kommt bei mir nur das an:
2015.02.02 20:20:35 3: my_JeeLink: Unknown code OKG 210 22 403 403 403 403 403 403, help me!
2015.02.02 20:20:54 3: my_JeeLink: Unknown code OKG 210 24 403 403 403 403 403 403, help me!
2015.02.02 20:21:44 3: my_JeeLink: Unknown code OKG 210 22 403 403 403 403 403 403, help me!
2015.02.02 20:22:04 3: my_JeeLink: Unknown code OKG 210 24 403 403 403 403 403 403, help me!


was mich ein bisschen stutzig macht ist, das in minicom nichts ankommt.

Edit: es kommt doch was an in minicom, und zwar das selbe....
OKG 210 22 403 403 403 403 403 403

ich mach da jetzt schon geschlagene drei Wochen Rum.
und weis nicht mehr weiter.
über eure Hilfe würde ich mich sehr freuen.

Konfiguration hab ich so gemacht wie mattes1007 es hier und im forum-raspberrypi.de schreibt.
ich hab auch seine Sketches verwendet.
auf dem Empfänger diesen hier:
// RF12Demo for Attiny84_RFM12b
// Configure some values in EEPROM for easy config of the RF12 later on.
// 2009-05-06 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <SoftwareSerial.h>
#define rxPin 7 //PA3
#define txPin 3 //PA7

SoftwareSerial mySerial(rxPin, txPin);

/*
                     +-\/-+
               VCC  1|    |14  GND
          (D0) PB0  2|    |13  AREF (D10)
          (D1) PB1  3|    |12  PA1 (D9)
             RESET  4|    |11  PA2 (D8)
INT0  PWM (D2) PB2  5|    |10  PA3 (D7)
      PWM (D3) PA7  6|    |9   PA4 (D6)
      PWM (D4) PA6  7|    |8   PA5 (D5) PWM
                     +----+
*/


#include <JeeLib.h>
#include <util/crc16.h>
#include <util/parity.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>

#define LED_PIN     8   

#define COLLECT 0x20 // collect mode, i.e. pass incoming without sending acks

static unsigned long now () {
    // FIXME 49-day overflow
    return millis() / 1000;
}

static void activityLed (byte on) {

    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, on);

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RF12 configuration setup code

typedef struct {
    byte nodeId;
    byte group;
//    char msg[30-4];
    word crc;
} RF12Config;

struct {
  byte temp_type;
  int  temp_data;
//  byte rf12lowbat_type;
//  byte rf12lowbat_data;
  byte vcc_type;
  int vcc_data;
} payload;

static RF12Config config;

static char cmd;
static byte value, stack[20], top, sendLen, dest, quiet;
static byte testbuf[20], testCounter;


static void saveConfig () {
    // save to EEPROM

    eeprom_write_byte(RF12_EEPROM_ADDR ,config.nodeId);
    eeprom_write_byte(RF12_EEPROM_ADDR +1 ,config.group);

    config.crc = ~0;
    config.crc = _crc16_update(config.crc, config.nodeId);     
    config.crc = _crc16_update(config.crc, config.group);       
       
    for (int i=2; i < RF12_EEPROM_SIZE-2; i++) {
        eeprom_write_byte(RF12_EEPROM_ADDR + i, 0);
        config.crc = _crc16_update(config.crc, 0);       
    }

    eeprom_write_byte(RF12_EEPROM_ADDR + RF12_EEPROM_SIZE-2 ,config.crc);
    eeprom_write_byte(RF12_EEPROM_ADDR + RF12_EEPROM_SIZE-1 ,config.crc>>8);
   
    if (!rf12_config())
        mySerial.println("config save failed");
}


char helpText1[] PROGMEM =
    "\n"
    "Available commands:" "\n"
    "  <nn> i     - set node ID (standard node ids are 1..26)" "\n"
    "               (or enter an uppercase 'A'..'Z' to set id)" "\n"
    "  <n> b      - set MHz band (4 = 433, 8 = 868, 9 = 915)" "\n"
    "  <nnn> g    - set network group (RFM12 only allows 212, 0 = any)" "\n"
    "  <n> c      - set collect mode (advanced, normally 0)" "\n"
    "  ...,<nn> a - send data packet to node <nn>, with ack" "\n"
    "  ...,<nn> s - send data packet to node <nn>, no ack" "\n"
    "  <n> l      - turn activity LED on DIG8 on or off" "\n"
    "  <n> q      - set quiet mode (1 = don't report bad packets)" "\n"
;

static void showString (PGM_P s) {
    for (;;) {
        char c = pgm_read_byte(s++);
        if (c == 0)
            break;
        if (c == '\n')
            mySerial.print('\r');
        mySerial.print(c);
    }
}

static void showHelp () {
    showString(helpText1);
    mySerial.println("Current configuration:");
    config.nodeId = eeprom_read_byte(RF12_EEPROM_ADDR);
    config.group = eeprom_read_byte(RF12_EEPROM_ADDR + 1);

/*
    mySerial.println("EEPROM config: ");       
    uint16_t crc = ~0;
    for (uint8_t i = 0; i < RF12_EEPROM_SIZE; ++i){
        crc = _crc16_update(crc, eeprom_read_byte(RF12_EEPROM_ADDR + i));
       mySerial.print(eeprom_read_byte(RF12_EEPROM_ADDR + i),HEX);
    }
    mySerial.println("");       
   
    mySerial.print("crc:");       
    mySerial.print(crc);       
    mySerial.print(" ");           
*/

    byte id = config.nodeId & 0x1F;
    mySerial.print('@' + id,DEC);
    mySerial.print(" i");
    mySerial.print( id,DEC);
    if (config.nodeId & COLLECT)
         mySerial.print('*');
   
    mySerial.print(" g");
    mySerial.print(config.group,DEC);
   
    mySerial.print(" @ ");
    static word bands[8] = { 315, 433, 868, 915 };
    word band = config.nodeId >> 6;
    mySerial.print(bands[band],DEC);
    mySerial.println( " MHz ");


    rf12_config();
}

static void handleInput (char c) {
    if ('0' <= c && c <= '9')
        value = 10 * value + c - '0';
    else if (c == ',') {
        if (top < sizeof stack)
            stack[top++] = value;
        value = 0;
    } else if ('a' <= c && c <='z') {
        mySerial.print("> ");
        mySerial.print((int) value);
        mySerial.println(c);
        switch (c) {
            default:
                showHelp();
                break;
            case 'i': // set node id
                config.nodeId = (config.nodeId & 0xE0) + (value & 0x1F);
                saveConfig();
                break;
            case 'b': // set band: 4 = 433, 8 = 868, 9 = 915
                value = value == 8 ? RF12_868MHZ :
                        value == 9 ? RF12_915MHZ : RF12_433MHZ;
                config.nodeId = (value << 6) + (config.nodeId & 0x3F);
                saveConfig();
                break;
            case 'g': // set network group
                config.group = value;
                saveConfig();
                break;
            case 'c': // set collect mode (off = 0, on = 1)
                if (value)
                    config.nodeId |= COLLECT;
                else
                    config.nodeId &= ~COLLECT;
                saveConfig();
                break;
            case 'a': // send packet to node ID N, request an ack
            case 's': // send packet to node ID N, no ack
                cmd = c;
                sendLen = top;
                dest = value;
                memcpy(testbuf, stack, top);
                break;
            case 'l': // turn activity LED on or off
                activityLed(value);
                break;
            case 'q': // turn quiet mode on or off (don't report bad packets)
                quiet = value;
                break;
        }
        value = top = 0;
        memset(stack, 0, sizeof stack);
    } else if ('A' <= c && c <= 'Z') {
        config.nodeId = (config.nodeId & 0xE0) + (c & 0x1F);
        saveConfig();
    } else if (c > ' ')
        showHelp();
}

void setup() {
   
    activityLed(1);
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);
   
    // set the data rate for the NewSoftmymySerial port
    mySerial.begin(9600);
   
    mySerial.print("\n[RF12demo.Attiny84]\n\r");

    delay(2000);

    if (rf12_config()) {
        config.nodeId = eeprom_read_byte(RF12_EEPROM_ADDR);
        config.group = eeprom_read_byte(RF12_EEPROM_ADDR + 1);
    } else {
        config.nodeId = 0x81; // node A1 @ 868 MHz
        config.group = 0xD2;  //210
        rf12_initialize(config.nodeId&0x1F, config.nodeId >> 6 ,config.group);       
        saveConfig();
    }
   
    showHelp();
    activityLed(0);
}

void loop() {
    if (mySerial.available())
        handleInput(mySerial.read());

    if (rf12_recvDone() & (rf12_crc == 0) ) {
        mySerial.print("OK");
        activityLed(1);     
        byte n = rf12_len;

        if (config.group == 0) {
            mySerial.print("G ");
            mySerial.print((int) rf12_grp);
        }
        mySerial.print(' ');
        mySerial.print((int) rf12_hdr);
        for (byte i = 0; i < n; ++i) {
            mySerial.print(' ');
            mySerial.print((int) rf12_data);
        }
        mySerial.println();
       
        activityLed(0);
           
        if (rf12_crc == 0) {
            activityLed(1);
           
            if (RF12_WANTS_ACK && (config.nodeId & COLLECT) == 0) {
                mySerial.println(" -> ack");
                rf12_sendStart(RF12_ACK_REPLY, 0, 0);
            }
           
            activityLed(0);
        }
    }

    if (cmd && rf12_canSend()) {
        activityLed(1);

        mySerial.print(" -> ");
        mySerial.print((int) sendLen);
        mySerial.println(" b");
        byte header = cmd == 'a' ? RF12_HDR_ACK : 0;
        if (dest)
            header |= RF12_HDR_DST | dest;
        rf12_sendStart(header, testbuf, sendLen);
        cmd = 0;

        activityLed(0);
    }
}


und auf dem Sender diesen:
//--------------------------------------------------------------------------------------
// TempTX-tiny ATtiny84 Based Wireless Temperature Sensor Node
// By Nathan Chantrell http://nathan.chantrell.net
// Updated by Martin Harizanov (harizanov.com) to work with DS18B20
// To use with DS18B20 instead of DS18B20, a 4K7 resistor is needed between the Digital 9 and Digital 10 of the ATTiny (Vdd and DQ)
// To get this to compile follow carefully the discussion here: http://arduino.cc/forum/index.php?topic=91491.0
// GNU GPL V3
//--------------------------------------------------------------------------------------

#include <JeeLib.h> // https://github.com/jcw/jeelib
#include "pins_arduino.h"

#include <OneWire.h>
#include <DallasTemperature.h>






ISR(WDT_vect) { Sleepy::watchdogEvent(); } // interrupt handler for JeeLabs Sleepy power saving

#define myNodeID 22      // RF12 node ID in the range 1-30
#define network 210     // RF12 Network group
#define freq RF12_868MHZ // Frequency of RFM12B module
#define ONE_WIRE_BUS 10
#define tempPower 9     
#define LED_PIN 8
/*
                     +-\/-+
               VCC  1|    |14  GND
          (D0) PB0  2|    |13  AREF (D10)
          (D1) PB1  3|    |12  PA1 (D9)
             RESET  4|    |11  PA2 (D8)
INT0  PWM (D2) PB2  5|    |10  PA3 (D7)
      PWM (D3) PA7  6|    |9   PA4 (D6)
      PWM (D4) PA6  7|    |8   PA5 (D5) PWM
                     +----+
*/

// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

//################################################################################​########################################

static void activityLed (byte on) {

    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, on);

}
//################################################################################​########################################
//Data Structure to be sent
//################################################################################​########################################

struct {
  byte temp_type;
  int  temp_data;
  byte vcc_type;
  int vcc_data;
} payload;

//################################################################################​########################################

void setup() {

  rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
  // Adjust low battery voltage to 2.2V
  rf12_control(0xC040);
  rf12_sleep(0);                          // Put the RFM12 to sleep
  pinMode(tempPower, OUTPUT); // set power pin for DS18B20 to output

  digitalWrite(tempPower, HIGH); // turn sensor power on
  Sleepy::loseSomeTime(50); // Allow 50ms for the sensor to be ready

  // Start up the library
  sensors.begin();
}

void loop() {   
  payload.vcc_type = 19; //Vcc
  payload.vcc_data = readVcc(); //Vcc
  digitalWrite(tempPower, HIGH); // turn DS18B20 sensor on
  Sleepy::loseSomeTime(50); // Allow 50ms for the sensor to be ready
 
  sensors.requestTemperatures(); // Send the command to get temperatures 

  sensors.getTempCByIndex(0);
 
  payload.temp_type = 11;
  payload.temp_data =(sensors.getTempCByIndex(0)*100); // read sensor 1
  //temptx.temp2sensors.getTempCByIndex(1)*100); // read second sensor.. you may have multiple and count them upon startup but I only need two

  digitalWrite(tempPower, LOW); // turn DS18B20 sensor off
 
  //temptx.supplyV = readVcc(); // Get supply voltage

  rfwrite(); // Send data via RF

  pinMode(tempPower, INPUT); // set power pin for TMP36 to input before sleeping, saves power
  digitalWrite(tempPower, LOW);

  for(byte j = 0; j < 1; j++) {    // Sleep for 5 minutes
    Sleepy::loseSomeTime(30000); //JeeLabs power save function: enter low power mode for 60 seconds (valid range 16-65000 ms)
  }

  pinMode(tempPower, OUTPUT); // set power pin for TMP36 to output 


}

//--------------------------------------------------------------------------------------------------
// Send payload data via RF
//--------------------------------------------------------------------------------------------------
static void rfwrite(){
   rf12_sleep(-1);     //wake up RF module
   while (!rf12_canSend())
   rf12_recvDone();
   rf12_sendStart(0, &payload, sizeof payload);
   rf12_sendWait(2);    //wait for RF to finish sending while in standby mode
   rf12_sleep(0);    //put RF module to sleep
}

//--------------------------------------------------------------------------------------------------
// Read current supply voltage
//--------------------------------------------------------------------------------------------------

long readVcc() {
   long result;
   // Read 1.1V reference against Vcc
   ADMUX = _BV(MUX5) | _BV(MUX0);
   delay(2); // Wait for Vref to settle
   ADCSRA |= _BV(ADSC); // Convert
   while (bit_is_set(ADCSRA,ADSC));
   result = ADCL;
   result |= ADCH<<8;
   result = 1126400L / result; // Back-calculate Vcc in mV
   return result;
}


hat evtl jemand eine Idee was da schief läuft?



Syntaxterror

Hallo,
ich gehe mal davon aus, dass ich statt dem RFM2Pi auch einen JeeLink-Clone nehmen kann, sehe ich das richtig?
Ich suche eine Lösung die günstigen TinyTX Sensoren mit den 84A zu verwenden, ohne den teuren TXRFX kaufen zu müssen.
:)
FHEM5.7produktiv Pi3+Pi2,CUL868,CUL433,ser2net,DS2482 mit ca.30Sensoren/Aktoren, ca.100xHomematic,Gertboard+GPIO, 10xLaCrosse

Feuerpfeil

Hallöchen,

ich schließe mich der Frage mal an.
Würde ebenfalls gerne die TinyTx mit dem Jeelink clone betreiben.

Gibt es da eine Möglichkeit?

Danke und Gruß,
Lars


hexenmeister

Ich betreibe meine letzten TinyTx (werden nach und nach durch MySensors ersetzt) zwar mit dem Original-JeeLink, sehe aber nichts, was gegen den Betrieb mit dem Clone sprechen sollte.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy