Cheap dirty way to send a raw-mysensors message?



  • Hello,

    is it possible to "inject" a sensor-value into the gateway by hand-crafting a data packet?

    I recently got some of these little guys (https://wemakethings.net/chirp/)

    Now my idea was to slap a NRF24 on the ISP header (+2 extra pins for CE and CSN).

    So far so good .. now I want to craft a simple packet to get data to my gateways ..

    This is what I got so far but my gateway is not picking up anything.

        radio.begin(); // Start up the radio
        radio.setDataRate(RF24_250KBPS);
        radio.setAutoAck(1); // Ensure autoACK is enabled
        radio.setRetries(15,15); // Max delay between retries & number of retries
        byte station_address[] = { 0x00, 0xFC, 0xE1, 0xA8, 0xA8 };
        //byte station_address[] = { 0xA8, 0xA8, 0xE1, 0xFC, 0x00 };
        radio.openWritingPipe(station_address); // Write to device address 0x00,0xFC,0xE1,0xA8,0xA8
        radio.stopListening();
        byte test[] = { 250, 250, 0, 0b10000001 /* version_length */, 0b00100001,  7 /* S_HUM */ , 1 /* V_HUM */, 123};
        radio.write(test,8);
    

    And no .. I can't cram the mysensors library on the ATTINY44.

    I am currently happe that I got the basic chirp functunality for measuring the humidity of the soil, attiny debug serial and nrf24 all running on 4k of flash.

    Der Sketch verwendet **4046 Bytes (98%)** des Programmspeicherplatzes. Das Maximum sind 4096 Bytes.
    Globale Variablen verwenden 150 Bytes (58%) des dynamischen Speichers, 106 Bytes für lokale Variablen verbleiben. Das Maximum sind 256 Bytes.
    

    If anybody know if this is even possible I would like to hear from you.

    Best regards Marc


  • Mod

    The problem I think is that the gateway needs the node to register on the network so it knows what it should expect receiving, it is a 2 way communication not like those devices using RF link that only transmit and other only receives.
    Have you evaluated the button size node on openhardware? I think it could be an alternative for your needs



  • @gohan Thanks for your response. The problem is that I already have 5 "chirps" and just later came up with the idea of adding nrf24 to them. I might try to add a "relay" node which will listen for "normal" rf24 packets and then send them to my gateway using the mysensors library.



  • After many hours trial and error I present you .. the raw-mysensors-client!!

    MyGateway: ESP8266 + mysensorsMQTT
    MyNode: https://github.com/Miceuz/PlantWateringAlarm
    MyNode-MCU: Attiny44 (MemoryFootprint: 87% of 4KB)
    ArduinoCore: https://github.com/SpenceKonde/ATTinyCore
    ArduinoCore-PinLayout: Counterclockwise (like AttinyCore)
    Note: The default "counterclockwise"pinout is the alternate pinout shown here: https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/extras/ATtiny_x4.md

    The important hint is here (http://tmrh20.github.io/RF24/ATTiny.html)

    Connect MOSI of the RF24 to PA5 of the attiny and MISO of the RF24 to PA6 of the attiny.
    CE = 8
    CSN = 7

    To get the connection done right DONT .. i mean DO NOT BECAUSE IT DOESNT FUCKING WORK connect MOSI of the RF24 to MOSI of the attiny. RF24 uses a embedded implementation of the USI-engine found on some AtTiny's.

    radio-initilisation

        radio.begin(); // Start up the radio
        radio.setDataRate(RF24_250KBPS);
        radio.setAutoAck(1); // Ensure autoACK is enabled
        radio.setRetries(15,15); // Max delay between retries & number of retries
        //radio.setPayloadSize(8);
        radio.enableDynamicPayloads();
        radio.setPALevel(RF24_PA_MAX);
        byte tx_address[] = { 0x00, 0xFC, 0xE1, 0xA8, 0xA8 };
        //byte tx_address[] = { 0xA8, 0xA8, 0xE1, 0xFC, 0x00 };
        radio.openWritingPipe(tx_address);
        radio.stopListening();
    

    Send-Function:

    void sendHumidity(uint16_t humidity)
    {
        // snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR("%s/%d/%d/%d/%d/%d"), prefix, message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type);
        // X8X22<\0><\n>!<7>7AY0;255;3;0;9;TSF:MSG:READ,50-50-0,s=55,c=1,t=7,pt=1,l=1,sg=0:65<\n>
        // 0;255;3;0;9;Sending message on topic: domoticz/in/MyMQTT/50/55/1/0/7<\n>
        
        #define LAST_NODE_ID  50  // last
        #define NODE_ID       50  // sender
        #define GATEWAY_ID    0   // destination
        
                                  // version_length     // 5 bit - Length of payload // 1 bit - Signed flag // 2 bit - Protocol version
                                  // command_ack_payload // 3 bit - Payload data type // 1 bit - Is ack messsage - Indicator that this is the actual ack message. // 1 bit - Request an ack - Indicator that receiver should send an ack back. // 3 bit - Command type
        
        #define SENSOR_TYPE   7   // type S_HUM = 7
        #define SENSOR_ID     55  // sensor-id
        byte test[] = { LAST_NODE_ID, NODE_ID, GATEWAY_ID, 0b00010010, 0b01100001,  SENSOR_TYPE, SENSOR_ID, (uint8_t)(humidity & 0x00FF), (uint8_t)((humidity >> 8) & 0x00FF),  0x00 };
        radio.write(test,9);
    }
    

    I am not quite sure yet if the message-types etc. are right but I am trying to find this out. 'A' (dec 65) is the "value" of my humidity .. next step is to make this a real value ofc.

    Proof at domoticz:
    0_1499525234377_upload-22170821-6116-4d1a-a08b-c0631b3fac15

    @gohan: In the file MyConfig.h I commented this out:

    /**
     * @def MY_REGISTRATION_FEATURE
     * @brief If enabled, node has to register to gateway/controller before allowed to send sensor data.
     */
    // #define MY_REGISTRATION_FEATURE
    

    This will skip the whole hasse of registering the client properly (which I can't .. remember 87% of flash is full)


  • Mod

    @cimba007 very nice work! Great way to be compatible with the MySensors protocol/ecosystem on a limited device when the full MySensors feature set is not needed.



  • I might have run into a bug in the calculation of message length.

    In my handcrafted packet I use this as the 4thy byte send:

    0b10000001

    So to craft this I looked at MyMessage.h which showed me this:

    uint8_t version_length;		 // 2 bit - Protocol version
    		                 // 1 bit - Signed flag
    		                 // 5 bit - Length of payload
    

    So from my understanding:

    Protocol Version = 2 => 0b10
    Signed Flag = 0 => 0b0
    Length of Payload = 1 = 0b00001

    Which results in 0b10 0 00001 = 0b10000001

    But I get this error:

    LEN,8!=23
    

    So .. where might this come from?

    radio.write(test,8);
    

    Mycontroller received a packet with the length of 8 but expected a packet with the length of .. 23 ?!

    #define mGetLength(_message) ((uint8_t)BF_GET(_message.version_length, 3, 5)) //!< Get length field
    

    Which in essential is BF_GET ..

    #define BF_GET(y, start, len)   ( ((y)>>(start)) & BIT_MASK(len) ) //!< Extract a bitfield of length 'len' starting at bit 'start' from 'y'
    

    So what is happening?

    BF_GET(0b10000001, 3, 5)   ( ((0b10000001)>>(3)) & BIT_MASK(5) ) //!< Extract a bitfield of length 'len' starting at bit 'start' 
    

    Whoops? This will throw away all the length-information!!!
    (0b10000001)>>(3)
    This should result in:
    0b11110000 & BIT_MASK5 = 0b1111000 & 0b00011111 = 0b00010000 = 16 decimal

    const uint8_t expectedMessageLength = HEADER_SIZE + (mGetSigned(_msg) ? MAX_PAYLOAD : msgLength);
    
    const uint8_t expectedMessageLength = 7+ 16); // = 23
    

    Yeah .. the lib is right .. 8 != 23 .. but the handcrafted length = 1 + header_length (7) = 8

    Am I wrong or is this a bug?

    Edit: I might have read the comments in the source code the wrong way



  • From time to time I run into this bug .. not sure if this is related:

    0;255;3;0;9;TSM:READY:NWD REQ<\n>
    0;255;3;0;9;TSF:MSG:SEND,0-0-255-255,s=255,c=3,t=20,pt=0,l=0,sg=0,ft=0,st=OK:<\n>
    Fatal exception 28(LoadProhibitedCause):<\n>
    epc1=0x40202704, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000003, depc=0x00000000<\n>
    <\r><\n>
    

  • Hero Member

    I wish the chirp had been designed with an atmega328p. Cost and footprint for the smd is similar I believe



  • Its not "that" bad .. the Attiny44A is compatible with Arduino thanks to https://github.com/SpenceKonde/ATTinyCore

    For now I got Humidity and Voltage(VCC) running up fine.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.