• 10 dec 2017: forum version update. In case of issues use this topic.
  • 30 nov 2017: pilight moved servers. In case of issues use this topic.
Hello There, Guest! Login Register


Idea: PIR wireless motion sensor
#41
Some info on improved-vcc-measurement: LINK LINK
 
Reply
#42
Nice work guys Smile

At this moment we have some working protocol in pilight, capable of receiving 15 sensors for 1 device.
I have humidity and temperature working, co-worker has PIR movement working. Waiting for a batch of ebay PIR's to integrate in the module (only one PIR module available in our project)

Code:
"code": {
                "id": 8934000,
                "temperature": 203
        },
        "origin": "receiver",
        "protocol": "probe",
        "uuid": "0365-00-00-65-000300",
        "repeats": 1
}

        "code": {
                "id": 8934000,
                "humidity": 470
        },
        "origin": "receiver",
        "protocol": "probe",
        "uuid": "0365-00-00-65-000300",
        "repeats": 1
}
 
Reply
#43
Nice! Are you guys gonna share your 'probe' protocol ? Think people already could use it....

Send from tapatalk phone...
 
Reply
#44
Yes, we will share, but at the moment it's not finished yet.
pilight side is only capable of receiving, attiny side is only capable of sending Tongue
 
Reply
#45
OK, here is the pilight protocol Smile
Just follow this guide to put in pilight : http://www.pilight.org/development/protocols/#where

probe.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../../pilight.h"
#include "common.h"
#include "log.h"
#include "protocol.h"
#include "hardware.h"
#include "binary.h"
#include "gc.h"
#include "probe.h"

void probeInit(void) {
    protocol_register(&probe);
    protocol_set_id(probe, "probe");
    protocol_device_add(probe, "probe", "Probe protocol");
        //protocol_plslen_add(probe, 293);
        //protocol_plslen_add(probe, 294);
        protocol_plslen_add(probe, 297);
        probe->devtype = RAW;
        probe->hwtype = RF433;
        probe->pulse = 4;
        probe->rawlen = 164;
        probe->lsb = 3;

        options_add(&probe->options, 'i', "id", has_value, config_id, "^([0-9]{1,7}|[1-5][0-9]{7}|6([0-6][0-9]{6}|7(0[0-9]{5}|10([0-7][0-9]{3}|8([0-7][0-9]{2}|8([0-5][0-9]|6[0-3]))))))$");
        options_add(&probe->options, 's', "sensor", has_value, config_id, "^([0-9]{1}|[1][0-5])$");
        options_add(&probe->options, 'v', "value", has_value, config_value, "^([0-9]{1}|[1][0-5])$");
        options_add(&probe->options, 't', "temperature", has_value, config_value, "^([0-9]{1}|[1][0-5])$");
        options_add(&probe->options, 'h', "humidity", has_value, config_value, "^([0-9]{1}|[1][0-5])$");
        
        probe->parseBinary=&probeParseBinary;
        probe->createCode=&probeCreateCode;
        probe->printHelp=&probePrintHelp;
        probe->checkValues=&probeCheckValues;
}

void probeParseBinary(void) {
        int value = binToDecRev(probe->binary, 30, 39);
        int sensor = binToDecRev(probe->binary, 26, 29);
        int id = binToDecRev(probe->binary, 0, 25);        

        probeCreateMessage(id, sensor, value);
}

void probeCreateMessage(int id, int sensor, int value) {
        probe->message = json_mkobject();
        json_append_member(probe->message, "id", json_mknumber(id));

        if(sensor ==  3) {
                json_append_member(probe->message, "temperature", json_mknumber(value));
        }

        if(sensor ==  2) {
                json_append_member(probe->message, "humidity", json_mknumber(value));
        }
}

int probeCreateCode(JsonNode *code) {
        int id = -1;
        int sensor = -1;
        int value = -1;
        char *tmp;
        
        json_find_number(code, "id", &id);
        json_find_number(code, "sensor", &sensor);
        json_find_number(code, "value", &value);
        
        if(json_find_string(code, "id", &tmp) == 0)
                id=atoi(tmp);
        if(json_find_string(code, "sensor", &tmp) == 0)
                sensor = atoi(tmp);
        if(json_find_string(code, "value", &tmp) == 0)
                value = atoi(tmp);

        if(id == -1 || sensor == -1 || value== -1) {
                logprintf(LOG_ERR, "probe: insufficient number of arguments ");
                return EXIT_FAILURE;
        } else if(id > 67108863 || id < 1) {
                logprintf(LOG_ERR, "probe: invalid id range");
                return EXIT_FAILURE;
        } else if(sensor > 15 || sensor < 0) {
                logprintf(LOG_ERR, "probe: invalid sensor range");
                return EXIT_FAILURE;
        } else if(value > 1023 || value < 0) {
                logprintf(LOG_ERR, "probe: invalid value range");
                return EXIT_FAILURE;
        } else {
                probeCreateMessage(id, sensor, value);
                probeCreateStart();
                probeClearCode();
                probeCreateId(id);
                probeCreateSensor(sensor);
                if(value > -1) {
                        probeCreateValue(value);
                }
                probeCreateFooter();
        }
        return EXIT_SUCCESS;
}

void probeCreateStart(void) {
        probe->raw[0]=probe->plslen->length;
        probe->raw[1]=(10*probe->plslen->length);
}

void probeClearCode(void) {
        probeCreateLow(2,164);
}

void probeCreateId(int id) {
        int binary[255];
        int length = 0;
        int i=0, x=0;

        length = decToBin(id, binary);
        for(i=0;i<=length;i++) {
                if(binary[i]==1) {
                        x=((length-i)+1)*4;
                        probeCreateHigh(106-x, 106-(x-3));
                }
        }
}

void probeCreateSensor(int sensor) {
        int binary[255];
        int length = 0;
        int i=0, x=0;

        length = decToBin(sensor, binary);
        for(i=0;i<=length;i++) {
                if(binary[i]==1) {
                        x=((length-i)+1)*4;
                        probeCreateHigh(122-x, 122-(x-3));
                }
        }
}

void probeCreateValue(int value) {
        int binary[255];
        int length = 0;
        int i=0, x=0;

        length = decToBin(value, binary);
        for(i=0;i<=length;i++) {
                if(binary[i]==1) {
                        x=((length-i)+1)*4;
                        probeCreateHigh(162-x, 162-(x-3));
                }
        }
}

void probeCreateFooter(void) {
        probe->raw[163]=(PULSE_DIV*probe->plslen->length);
}

void probePrintHelp(void) {
        printf("\t -s --sensor=sensor\t\t\tcontrol a device with this sensor code\n");
        printf("\t -i --id=id\t\t\tcontrol a device with this id\n");
        printf("\t -a --all\t\t\tsend command to all devices with this id\n");
        printf("\t -d --dimlevel=dimlevel\t\tsend a specific dimlevel\n");
}

int probeCheckValues(JsonNode *code) {
    // Need some checking :P
    return 0;
}

void probeCreateLow(int s, int e) {
        int i;

        for(i=s;i<=e;i+=4) {
                probe->raw[i]=(probe->plslen->length);
                probe->raw[i+1]=(probe->plslen->length);
                probe->raw[i+2]=(probe->plslen->length);
                probe->raw[i+3]=(probe->pulse*probe->plslen->length);
        }
}

void probeCreateHigh(int s, int e) {
        int i;

        for(i=s;i<=e;i+=4) {
                probe->raw[i]=(probe->plslen->length);
                probe->raw[i+1]=(probe->pulse*probe->plslen->length);
                probe->raw[i+2]=(probe->plslen->length);
                probe->raw[i+3]=(probe->plslen->length);
        }
}

probe.h
Code:
#ifndef _PROTOCOL_PROBE_H_
#define _PROTOCOL_PROBE_H_

struct protocol_t *probe;
void probeInit(void);

void probeCreateMessage(int id, int sensor, int value);
void probeParseBinary(void);
//int probeCheckSettings(JsonNode *code);
int probeCreateCode(JsonNode *code);
void probeCreateLow(int s, int e);
void probeCreateHigh(int s, int e);
void probeClearCode(void);
void probeCreateStart(void);
void probeCreateId(int id);
void probeCreateSensor(int sensor);
void probeCreateValue(int value);
void probeCreateFooter(void);
void probePrintHelp(void);
int probeCheckValues(JsonNode *code);

#endif

Would be really nice if someone could get the SENDING working from pilight.

As you can see, sensor 3 = temperature and sensor 2 = humidity.
You can use the same range of ID's as the KaKu_new protocol, a total of 15 sensors and value range from 0 to 1023.

Enjoy Smile
 
Reply
#46
Thx! Will look into it. Hopefully DIY people go and use it with pilight.

Send from tapatalk phone...
 
Reply
#47
(03-19-2014, 05:38 PM)creamers Wrote: Thx! Will look into it. Hopefully DIY people go and use it with pilight.

Send from tapatalk phone...

I hope so to!
Any other ideas about extra sensors for the module are welcome.
I'm playing with the idea to add 1 or more LED's to the module, so pilight can send information to the module.
A dim glowing red LED could mean the central heating is on? A green blinking LED could mean you have new mail or some app wants your attention? Or whatever notification that may be.

All ideas for a module are welcome! We have 15 sensors in the protocol, and if needed we can increase that number.
To focus on developping fnctionality we don't want to make it battery powered in the first place, but powered with 5v micro-USB. Perhaps later we can focus on low power usage.
 
Reply
#48
Code voor the attiny :

NewRemoteTransmitter.cpp
Code:
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
* See NewRemoteTransmitter.h for details.
*
* License: GPLv3. See license.txt
*/

#include "NewRemoteTransmitter.h"


NewRemoteTransmitter::NewRemoteTransmitter(unsigned long address, byte pin, unsigned int periodusec, byte repeats) {
    _address = address;
    _pin = pin;
    _periodusec = periodusec;
    _repeats = (1 << repeats) - 1; // I.e. _repeats = 2^repeats - 1

    pinMode(_pin, OUTPUT);
}

void NewRemoteTransmitter::sendGroup(boolean switchOn) {
    for (int8_t i = _repeats; i >= 0; i--) {
        _sendStartPulse();

        _sendAddress();

        // Do send group bit
        _sendBit(true);

        // Switch on | off
        _sendBit(switchOn);

        // No unit. Is this actually ignored?..
        _sendUnit(0);

        _sendStopPulse();
    }
}

void NewRemoteTransmitter::sendUnit(byte unit, boolean switchOn) {
    for (int8_t i = _repeats; i >= 0; i--) {
        _sendStartPulse();

        _sendAddress();

        // No group bit
        _sendBit(false);

        // Switch on | off
        _sendBit(switchOn);

        _sendUnit(unit);

        _sendStopPulse();
    }
}

void NewRemoteTransmitter::sendSensor(byte sensor, unsigned long value) {
    for (int8_t i = _repeats; i >= 0; i--) {
        _sendStartPulse();

        _sendAddress();

        _sendUnit(sensor);
        
        _sendValue(value);
        
        _sendStopPulse();
    }
}

/************
* NewRemoteReceiver

Protocol. (Copied from Wieltje, http://www.circuitsonline.net/forum/view/message/1181410#1181410,
but with slightly different timings, as measured on my device.)
        _   _
'0':   | |_| |_____ (T,T,T,5T)
        _       _
'1':   | |_____| |_    (T,5T,T,T)
        _   _
dim:   | |_| |_     (T,T,T,T)

T = short period of ~260µs. However, this code tries
to figure out the correct period

A full frame looks like this:

- start pulse: 1T high, 10.44T low
- 26 bit:  Address
- 1  bit:  group bit
- 1  bit:  on/off/[dim]
- 4  bit:  unit
- [4 bit:  dim level. Only present of [dim] is chosen]
- stop pulse: 1T high, 40T low

************/

void NewRemoteTransmitter::sendDim(byte unit, byte dimLevel) {
    for (int8_t i = _repeats; i >= 0; i--) {
        _sendStartPulse();

        _sendAddress();

        // No group bit
        _sendBit(false);

        // Switch type 'dim'
        digitalWrite(_pin, HIGH);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, LOW);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, HIGH);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, LOW);
        delayMicroseconds(_periodusec);

        _sendUnit(unit);

        for (int8_t j=3; j>=0; j--) {
           _sendBit(dimLevel & 1<<j);
        }

        _sendStopPulse();
    }
}

void NewRemoteTransmitter::_sendStartPulse(){
    digitalWrite(_pin, HIGH);
    delayMicroseconds(_periodusec);
    digitalWrite(_pin, LOW);
    delayMicroseconds(_periodusec * 10 + (_periodusec >> 1)); // Actually 10.5T insteat of 10.44T. Close enough.
}

void NewRemoteTransmitter::_sendAddress() {
    for (int8_t i=25; i>=0; i--) {
       _sendBit((_address >> i) & 1);
    }
}

void NewRemoteTransmitter::_sendUnit(byte unit) {
    for (int8_t i=3; i>=0; i--) {
       _sendBit(unit & 1<<i);
    }
}

void NewRemoteTransmitter::_sendValue(unsigned long value) {
    for (int8_t i=9; i>=0; i--) {
       _sendBit((value >> i) & 1);
    }        
}

void NewRemoteTransmitter::_sendStopPulse() {
    digitalWrite(_pin, HIGH);
    delayMicroseconds(_periodusec);
    digitalWrite(_pin, LOW);
    delayMicroseconds(_periodusec * 40);
}

void NewRemoteTransmitter::_sendBit(boolean isBitOne) {
    if (isBitOne) {
        // Send '1'
        digitalWrite(_pin, HIGH);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, LOW);
        delayMicroseconds(_periodusec * 5);
        digitalWrite(_pin, HIGH);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, LOW);
        delayMicroseconds(_periodusec);
    } else {
        // Send '0'
        digitalWrite(_pin, HIGH);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, LOW);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, HIGH);
        delayMicroseconds(_periodusec);
        digitalWrite(_pin, LOW);
        delayMicroseconds(_periodusec * 5);
    }
}

NewRemoteTransmitter.h
Code:
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
*
* License: GPLv3. See license.txt
*/

#ifndef NewRemoteTransmitter_h
#define NewRemoteTransmitter_h

#include <Arduino.h>

/**
* NewRemoteTransmitter provides a generic class for simulation of common RF remote controls, like the A-series
* 'Klik aan Klik uit'-system (http://www.klikaanklikuit.nl/), used to remotely switch lights etc.
*
* This class is meant for new-style remotes, usually accompanied by receivers with "code learning"
* capabilities. For other remotes, use the RemoteTransmitter class.
*
* Hardware required for this library: a 433MHz/434MHz SAW oscillator transmitter, e.g.
* http://www.sparkfun.com/products/10534
* http://www.conrad.nl/goto/?product=130428
*
* Notes:
* - I measured the period length with an oscilloscope, using a A-series KAKU transmitter. Other devices
*   or manufacturers may use other period length. Use the ShowReceivedCodeNewRemote example to find the
*   period length for your devices.
* - You can copy the address of your "real" remotes, so you won't have to learn new codes into the receivers.
*   In effect this duplicates a remote. But you can also pick a random number in the range 0..2^26-1.
*/
class NewRemoteTransmitter {
    public:
        /**
        * Constructor.
        *
        * To obtain the correct period length, use the ShowReceivedCodeNewRemote example, or you
        * can use an oscilloscope.
        *
        * @param address    Address of this transmitter [0..2^26-1] Duplicate the address of your hardware, or choose a random number.
        * @param pin        Output pin on Arduino to which the transmitter is connected
        * @param periodusec    Duration of one period, in microseconds. One bit takes 8 periods (but only 4 for 'dim' signal).
        * @param repeats    [0..8] The 2log-Number of times the signal is repeated. The actual number of repeats will be 2^repeats. 2 would be bare minimum, 4 seems robust, 8 is maximum (and overkill).
        */
        NewRemoteTransmitter(unsigned long address, byte pin, unsigned int periodusec = 260, byte repeats = 4);

        /**
         * Send on/off command to the address group.
         *
         * @param switchOn  True to send "on" signal, false to send "off" signal.
         */
        void sendGroup(boolean switchOn);

        /**
         * Send on/off command to an unit on the current address.
         *
         * @param unit      [0..15] target unit.
         * @param switchOn  True to send "on" signal, false to send "off" signal.
         */
        void sendUnit(byte unit, boolean switchOn);
        
        
        void sendSensor(byte sensor, unsigned long value);

        /**
         * Send dim value to an unit on the current address.
         *
         * @param unit      [0..15] target unit.
         * @param dimLevel  [0..15] Dim level. 0 for off, 15 for brightest level.
         */
        void sendDim(byte unit, byte dimLevel);

    protected:
        unsigned long _address;        // Address of this transmitter.
        byte _pin;                    // Transmitter output pin
        unsigned int _periodusec;    // Oscillator period in microseconds
        byte _repeats;                // Number over repetitions of one telegram

        /**
         * Transmits start-pulse
         */
        void _sendStartPulse();

        /**
         * Transmits address part
         */
        void _sendAddress();

        /**
         * Transmits unit part.
         *
         * @param unit      [0-15] target unit.
         */
        void _sendUnit(byte unit);
        
        /**
         * Transmits value part.
         *
         * @param unit      [0-15] target unit.
         */
        void _sendValue(unsigned long value);

        /**
         * Transmits stop pulse.
         */
        void _sendStopPulse();

        /**
         * Transmits a single bit.
         *
         * @param isBitOne    True, to send '1', false to send '0'.
         */
        void _sendBit(boolean isBitOne);
};
#endif

Sample for the attiny:

Code:
#include <OneWire.h> // http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip
#include <DallasTemperature.h> // http://download.milesburton.com/Arduino/MaximTemperature/DallasTemperature_LATEST.zip
#include <NewRemoteTransmitter.h>

#define txPin 10     // RF TRANSMITTER PIN
const int ledPin = 8; // LED PIN
#define ONE_WIRE_BUS 9 // DS18B20 PIN

OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature

void setup() {
    // Define outputs
    pinMode(ledPin, OUTPUT);
    pinMode(txPin, OUTPUT);
}

void loop() {
  Blink(ledPin,2);  
  NewRemoteTransmitter transmitter(8934000, txPin, 242,3);
  
  float temperature;

  sensors.begin(); //start up temp sensor
  sensors.requestTemperatures(); // Get the temperature
  temperature = sensors.getTempCByIndex(0); // Get temperature in Celcius

  int NewTemp = temperature * 10;
  transmitter.sendSensor(3,NewTemp);      
  
  delay(60000);
}

void Blink(int led, int times){
  for (int i=0; i< times; i++){
    digitalWrite(ledPin,HIGH);
    delay (50);
    digitalWrite(ledPin,LOW);
    delay (50);
  }
}

First prepare the transmitter object : NewRemoteTransmitter transmitter(8934000, txPin, 242,3)
Where '8934000' is the ID you want to use. The number 242 is the 'Duration of one period, in microseconds'. Original code uses 250, but in my specific situation I had to lower it to 242 to receive any code on the pilight. Just tweak it a little for your own situation.
The last number (3) is how many repeats you want to send.

When you want to send the value, you can use transmitter.sendSensor(3,value)
The number 3 is the sensor ID, you can use 1 -15, value is the sensor value you wnat to send in the range 0 -1023
 
Reply
#49
@Koffie

I have just installed the "probe" protocoll.Angel
when i insert your config it got not working.
Code:
"code": {
                "id": 8934000,
                "temperature": 203
        },
        "origin": "receiver",
        "protocol": "probe",
        "uuid": "0365-00-00-65-000300",
        "repeats": 1
}

        "code": {
                "id": 8934000,
                "humidity": 470
        },
        "origin": "receiver",
        "protocol": "probe",
        "uuid": "0365-00-00-65-000300",
        "repeats": 1
}

I tried several { , }, [ ,] but no result
Keep the same message:
Code:
[Mar 21 10:18:25:200766] pilight-daemon: ERROR: config is                                                           not in a valid json format

What do i missing ?Confused
 
Reply
#50
Do you get the error from the deamon with it recieves a signal from the attiny, or do you get the error when you start the deamon?
Can you post the part from your config.json where the probe devices is defined?

this shoudl work in the config.json:

Code:
"probe": {
                        "name": "Probe Device",
                        "uuid": "0365-00-00-65-000300",
                        "protocol": [ "probe" ],
                        "id": [{
                                "id": "8934000",
                                "sensor": 3
                        }],
                        "temperature": 196,
                        "value": 1,
                        "humidity": 222
                }
 
Reply
  


Possibly Related Threads...
Thread Author Replies Views Last Post
  using serial/uart to connect a CO2 sensor behrisch 15 7,853 10-15-2021, 01:48 AM
Last Post: DesmondOrask
Question 433mhz wireless sensor for dormer window milde 3 4,937 12-06-2015, 07:18 PM
Last Post: pilino1234
  weatherstation sensor p4co86 37 27,724 02-15-2015, 07:46 PM
Last Post: pilino1234
  TFA-Dostmann T/H-sensor not in pilight-receive fozed 0 3,453 02-10-2015, 12:59 PM
Last Post: fozed
  wired sensor Brn 3 4,015 11-29-2014, 11:36 AM
Last Post: curlymo
  Conrad no name wireless switch keesse 9 9,206 09-11-2014, 07:40 AM
Last Post: wo_rasp
  ELV power consumption sensor p4co86 0 3,186 07-06-2014, 05:40 PM
Last Post: p4co86
  Arduino sensor jpoilux 1 4,030 07-02-2014, 07:21 PM
Last Post: curlymo
  About RF and Wireless, useful links... Gregstah 0 2,317 02-12-2014, 02:23 PM
Last Post: Gregstah

Forum Jump:


Browsing: 1 Guest(s)