sebmillet / rf433send

GNU Lesser General Public License v3.0
9 stars 3 forks source link

Sending 4 bytes and a half (36 bits long) #2

Open Janitor4 opened 1 year ago

Janitor4 commented 1 year ago

Hi @sebmillet! I'm sending you this "issue" in order to ask for some help using rf433send.

The main point here is: How do i get to send a 36bit long message?

Believe me, the message i need to send is not 32 nor 40 bits long, it is 36 bit long.

Using your rf433snif i managed to decode the communication between the Outdoor and Indoor unit of Baldr Thermometer. It doesnt use any standard protocol so, i had to use Microsoft Excell to have it decoded.

In a few words, Outdoor Unit (TX) starts transmitting with a short 488ms followed by 3852ms long. After that, i have 36 bits (488ms,916ms -> 0 or 488ms,1912ms ->1).

Parameters are set as below:

RfSendEncoding::TRIBIT_INVERTED,

    3852,    // initseq                                         //ALTERADO EM 09/09/23 ERA 5500                                        
    0,     // lo_prefix                                       //ALTERADO EM 09/09/23 ERA 0 (488)
    0,     // hi_prefix                                       //ALTERADO EM 09/09/23 ERA 0 (488)
    488,     // first_lo_ign                                    //ALTERADO EM 09/09/23 ERA 0 (488)
    488,     // lo_short                                        //ALTERADO EM 09/09/23 ERA 1150
    488,     // lo_long                                         //ALTERADO EM 09/09/23 ERA 2330
    924,     // hi_short                                        //ALTERADO EM 09/09/23 ERA 0
    1912,    // hi_long                                         //ALTERADO EM 09/09/23 ERA 0
    0,     // lo_last                                         //ALTERADO EM 09/09/23 ERA 0 (488)
    3852,    // sep                                             //ALTERADO EM 09/09/23 ERA 5500
    36        // nb_bits                                         //ALTERADO EM 09/09/23 ERA 32
);

So far, i've tried to change nb_bits (line 63) and data [] (line 68) by changing its lengh and content (data). If i send 8, 16, 24 or 32 bit long....no problem but, if i try to send a 36bit....it ended up filling the "missing" bits with zeros (0000).

I also tried to insert a second (byte n = tx_whatever->send(sizeof(data), data);) inside void loop but it only sends after first send is done and it makes a interval between data and "data2".

I'm using Logic 2 from Saleae to check the output data from the S1000a connected to Arduino Uno. It doesnt seems to be any phisycal issue, it seems to be my "no standard" data lengh.

Could you give me any help on how to overcome this? i read .cpp files but (so far) i'm not that familiar with coding.

Please let me know if you need any .ino file, Saleae Logic Capture or serial monitor output.

I thought that decoding the signal would be the harder part....not anymore.

Janitor4 commented 1 year ago

Hi @sebmillet. Just to let you know that i managed to solve the issue.

As it may be useful for other users, i'll share what i've done: In the content of data [] (line 68) i have inserted 4 fake bits at the very beginning of sequence. After that, i adjusted the nb_bits (line 63) to 36 (should be 40 to send 5 bytes). Checking the Logic 2 analyser, it can be seen that by setting nb_bits shorter than data content results in the sending of the last 36 bits out of 40 bit long content. The first 4 bits are left behind.

Solved! I'm already able to send customized temperature to Indoor Unit. It works.

Thanks in advance.

sebmillet commented 1 year ago

Hello

thanks for this feedback. Could you share the code involved? (= the code that DOES NOT work along with the one that DOES). I'm interested in understanding what went wrong, either to fix a bug (?) or improve documentation as needed.

Thanks, Sébastien Millet

Janitor4 commented 1 year ago

Hi @sebmillet. It will be my pleasure to share what i have done. In addition to it, i would like to tell that i also managed to make your code run in NodeMCU (ESP8266) by making "some adjustments".

First the code that was unable to send 36 bits:

It is the standard 01_send from the RF433send library. To make it even more clear....as below:

`// 01_send.ino

// Simple example of sending codes with a Radio Frequencies device. // Sends code 4 times every 5 seconds.

/* Copyright 2021 Sébastien Millet

`RF433send' is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

`RF433send' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see https://www.gnu.org/licenses. */

// Schematic: // RF433 TRANSMITTER data pin plugged on Arduino D4

include "RF433send.h"

define PIN_RFOUT 4

RfSend *tx_whatever;

void setup() { pinMode(PIN_RFOUT, OUTPUT);

Serial.begin(115200);

    // rfsend_builder performs some asserts that, it failed, write details
    // to Serial and then block execution.
    // If construction is done before setup() execution (as is the case with
    // global variables), no output is done and we loose interesting debug
    // information.
    // Therefore I prefer this style over using a global radio object.

tx_whatever = rfsend_builder(
    RfSendEncoding::MANCHESTER,
    PIN_RFOUT,
    RFSEND_DEFAULT_CONVENTION,  // Do we want to invert 0 and 1 bits? No.
    4,       // Number of sendings
    nullptr, // No callback to keep/stop sending (if you want to send
             // SO LONG AS a button is pressed, the function reading the
             // button state is to be put here).
    5500,    // initseq
    0,       // lo_prefix
    0,       // hi_prefix
    0,       // first_lo_ign
    1150,    // lo_short
    2330,    // lo_long
    0,       // hi_short
    0,       // hi_long
    0,       // lo_last
    5500,    // sep
    32       // nb_bits
);

}

byte data[] = { 0x03, 0x14, 0x15, 0x93 }; void loop() { static int count = 0;

byte n = tx_whatever->send(sizeof(data), data);
Serial.print("Envoi effectué ");
Serial.print(n);
Serial.print(" fois\n");

delay(5000);

}

// vim: ts=4:sw=4:tw=80:et`

The code below allowed me to send 36 bits in a NodeMCU (ESP8266) every 56,5 seconds.

NodeMCU doesn't work well with delay statements....so a replace your delay by a void using millis () functions (refer to lines 161 and 163 from the code below).

`#define BLYNK_TEMPLATE_ID "XXXXXXXXXXX"

define BLYNK_DEVICE_NAME "XXXXX"

define BLYNK_AUTH_TOKEN "XXXXXXXXXXX" //ADICIONADO EM 09/01/2023 auth original YYYYYYYYYYY

//////////////////////////////////////////////////////// BLYNK //////////////////////////////////////////////////////

define BLYNK_PRINT Serial //SUSPENSO EM 03/05/2022

include

include

//#include //INCLUSO EM 10/05/2022

include "SPISlave.h"

// You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = BLYNK_AUTH_TOKEN; //MANTIDO EM 27/12/2022 auth original WWWWWWWWWW // reserva "ZZZZZZZZZZZZ"

// Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "AAAAAAAAAA"; char pass[] = "BBBBBBBBB"; //

BlynkTimer timer;

/////////////////////////////////////////////////////////// WI-FI & BLYNK CONNECTION WITHOUT WIFI AT SETUP //////////////////////

//boolean conectado = Blynk.connect(); unsigned long tentaconectar = 0; // guarda o tempo da última tentativa de conexão ao servidor Blynk

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 01_send.ino

// Simple example of sending codes with a Radio Frequencies device. // Sends code 4 times every 5 seconds.

/* Copyright 2021 Sébastien Millet

`RF433send' is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

`RF433send' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see https://www.gnu.org/licenses. */

// Schematic: // RF433 TRANSMITTER data pin plugged on Arduino D4

include "RF433send.h"

define PIN_RFOUT 4 //ALTERADO EM 09/09/23 ERA 4

RfSend *tx_whatever;

int tempteste; int primeiroenvio = 10; int primeirarecupera = 1;

void setup() {

Serial.setDebugOutput(true); // SUSPENSO EM 03/05/2022 Serial.println("Começando o programa"); // REMANEJEI EM 09/05/2022 delay (3000); // SUSPENSO EM 16/05/2022 //Serial.println("Chegou no Blynk.begin"); // SUSPENSO EM 16/05/2022

//Blynk.begin(auth, ssid, pass); // SUSPENSO EM 10/05/2022 //WiFi.mode(WIFI_STA); // ADICIONADO EM 10/05/2022 //Serial.println("Passou pelo Wifimode"); // ADICIONADO EM 09/05/2022 WiFi.begin(ssid, pass); // ADICIONADO EM 10/05/2022

Serial.println("Passou pelo Wifibegin"); // ADICIONADO EM 09/05/2022 Blynk.config(auth, "64.225.16.22" , 8080); // ATUALIZEI O IP PARA A NEW BLYNK EM 28/12/2022 ANTIGO ERA 45.55.96.146 Serial.println("Passou pelo blynk.config"); // ADICIONADO EM 09/05/2022

pinMode(PIN_RFOUT, OUTPUT);

Serial.begin(115200);

// rfsend_builder performs some asserts that, it failed, write details // to Serial and then block execution. // If construction is done before setup() execution (as is the case with // global variables), no output is done and we loose interesting debug // information. // Therefore I prefer this style over using a global radio object.

tx_whatever = rfsend_builder( RfSendEncoding::TRIBIT_INVERTED, //ALTERADO EM 09/09/23 ERA MANCHESTER PIN_RFOUT, RFSEND_DEFAULT_CONVENTION, // Do we want to invert 0 and 1 bits? No. 12, // Number of sendings //ALTERADO EM 09/09/23 ERA 4 nullptr, // No callback to keep/stop sending (if you want to send // SO LONG AS a button is pressed, the function reading the // button state is to be put here). 3852, // initseq //ALTERADO EM 09/09/23 ERA 5500 0, // lo_prefix //ALTERADO EM 09/09/23 ERA 0 (488) 0, // hi_prefix //ALTERADO EM 09/09/23 ERA 0 (488) 470, // first_lo_ign //ALTERADO EM 09/09/23 ERA 0 (488) 460, // lo_short //ALTERADO EM 09/09/23 ERA 1150 (488) 470, // lo_long //ALTERADO EM 09/09/23 ERA 2330 (488) 930, // hi_short //ALTERADO EM 09/09/23 ERA 0 (924) 1912, // hi_long //ALTERADO EM 09/09/23 ERA 0 0, // lo_last //ALTERADO EM 09/09/23 ERA 0 (488) 3850, // sep //ALTERADO EM 09/09/23 ERA 5500 (3852) 36 // nb_bits //ALTERADO EM 09/09/23 ERA 32 );

}

//byte data[] = { 0b11011101,0b00110011,0b11011101,0b00110011,0b00110011}; //ALTERADO EM 09/09/23 ERA 0x03, 0x14, 0x15, 0x93 (,0x3) { 0xBD, 0x81, 0x18, 0xF0 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

BLYNK_CONNECTED() {

Serial.println("Conectou e sincronizou com o servidor Blynk"); //Serial.print("O valor do acesoantes estava em: "); //Serial.println(acesoantes); //Serial.print("O valor do apagadoantes estava em: "); //Serial.println(apagadoantes);

//Blynk.virtualWrite(V3, barra); // ATUALIZA A BARRA DE TEMPERATURA NO APP / SERVIDOR Blynk.syncVirtual(V6); // RECUPERA O TEMPO DE USO TOTAL DO SERVIDOR }

BLYNK_WRITE(V6) { //int tempteste; tempteste = param.asInt(); // ATUALIZA O TEMPO DE USO NO NODEMCU COM BASE NO QUE ESTAVA NO SERVIDOR Serial.println("Recuperou a temperatura do outro NodeMCU"); Serial.print("A Temperatura recuperada foi de "); Serial.println(tempteste); if (primeirarecupera == 1){ Serial.println("Recuperou a primeira vez"); primeirarecupera =0; primeiroenvio = 1; } //Serial.println(" segundos"); }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int j = 0; int enviado = 0; char dadotx [37] = {0}; unsigned long ultimoenviotempRF = 0; // guarda o tempo do último envio da temperatura

void alternatemp () {

if (((millis() - ultimoenviotempRF) >= 56523 )|| primeiroenvio == 1) {

ultimoenviotempRF = millis();
primeiroenvio = 0;
//Serial.print("entrou no void alternatemp");                 //SUSPENSO EM 13/09/2023

byte data0[] = { 0b00001011, 0b11011000, 0b00010010, 0b01111111, 0b00000010};                                  //INSERIDO EM 10/09/23 (29,5)
byte data1[] = { 0b00001011, 0b11011000, 0b00010011, 0b01101111, 0b00000001};                                  //INSERIDO EM 10/09/23 (31,0)
byte data2[] = { 0b00001011, 0b11011000, 0b00001111, 0b11111111, 0b00000010};                                  //INSERIDO EM 10/09/23 (25,5)
byte data3[] = { 0b00001011, 0b11011000, 0b00000111, 0b10001111, 0b00000010};                                  //INSERIDO EM 10/09/23 (12,0)
byte datatx[] = { 0b00001011, 0b11011000, 0b00000000, 0b00001111, 0b00000010};                                  //INSERIDO EM 11/09/23 (0,0)

//static int count = 0;                                       //SUSPENSO EM 13/09/2023

//int temptx = int tempteste;
int temptxdez = tempteste * 10;                                  //MULTIPLICA A TEMPERATURA POR 10
//Serial.println("A temperatura inteira em bytes é de:");
//Serial.println(temptxdez, BIN);

byte tempembytes = lowByte(temptxdez);
//Serial.println("O byte baixo da temperatura é de:");
//Serial.println(tempembytes, BIN);

byte tempembytes2 = highByte(temptxdez);
//Serial.println("O byte alto da temperatura é de:");
//Serial.println(tempembytes2, BIN);

byte byte4 = (tempembytes << 4);                          // PEGA OS 4 BITS MAIS BAIXOS E SOBE 4 BITS NO BYTE 4
//Serial.println("Os 4 bits mais baixos deslocados da temperatura é de:");
//Serial.println(byte4, BIN);

byte byte4t = 0x0F | byte4;                       // COMBINA OS 4 BITS MAIS BAIXOS DA TEMPERATURA COM O MODELO
byte datatx1[] = {byte4t};
//Serial.println(byte4t, BIN);

byte byte3 = (tempembytes >> 4);                          // PEGA OS 4 BITS MAIS ALTOS E DESCE 4 BITS NO BYTE 3
//Serial.println("Os 4 bits mais altos deslocados da temperatura é de:");
//Serial.println(byte3, BIN);

byte byte3t = 0x00 | byte3;                       // COMBINA OS 4 BITS MAIS BAIXOS DA TEMPERATURA COM O MODELO
byte byte3a = (tempembytes2 << 4);

//Serial.println(byte3t, BIN);
//Serial.println(byte3a, BIN);
byte byte3m = byte3a | byte3t;                   // COMBINA 8 BITS PARA FORMAR O BYTE 3 DA TEMPERATURA
//Serial.println(byte3m, BIN);

byte datatx2[] = {byte3m};

byte datatxRF[] = {0b00001011, 0b11011000, byte3m, byte4t, 0b00000010};

byte n = tx_whatever->send(sizeof(datatxRF), datatxRF);
//j = j + 1;
enviado = 1;
//sprintf(dadotx, "%B", data0);
//Serial.print(dadotx);
Serial.print("A temperatura enviada foi de: ");
Serial.print(tempteste);
Serial.println("°C");
//Serial.print(datatx10[0], BIN);
//Serial.print(datatx10[1], BIN);
//Serial.print(datatx10[2], BIN);
//Serial.print(datatx10[3], BIN);
//Serial.println(datatx10[4], BIN);

//Serial.print("Envoi effectué ");
//Serial.print(n);
//Serial.print(" fois\n");

//Serial.println(sizeof(data));                                    //INSERIDO EM 10/09/23
//Serial.println(m,BIN);                                         //INSERIDO EM 10/09/23

//delay(56523);                                                     //ALTERADO EM 09/09/23 ERA 5000 (56523)

enviado = 0;

}

}

void loop() {

Blynk.run(); timer.run(); alternatemp(); //INSERIDO EM 11/09/23 }

// vim: ts=4:sw=4:tw=80:et`

i've tried to put the .ino file a couple of times....all result in broken code.....i don't know what i've done wrong.

Hope it can be useful. Feel free if you want to know something about what i've made.

sebmillet commented 11 months ago

Hello

Thanks for feedback. I understand from the above that possibly, rf433send is flawed when bit length is not a multiple of 8. I'll do some more tests and fix what looks like a bug in rf433send.

Regards, Sébastien Millet

Janitor4 commented 11 months ago

Hi @sebmillet. I believe it happens in RF433any (receiver) too. That's why i wasn't able to see data content using RF433any. If it interest you, after changing bit lengh at RF433send, you may try receiving a sample using RF433any.

If i'm not wrong, in its standard example, you'll be able to find out transmission parameters (nullptr, initseq , lo_prefix, i_prefix, first_lo_ign , lo_short, lo_long, hi_short, hi_long, lo_last, sep and nb_bits) but not data (if it's not multiple of 8).

Once again, my intention here is only help to make RF433 send and RF433any even better that already are.

Regard, Janitor.

sebmillet commented 10 months ago

Hello

I did some tests and I could see that it works with number of bits non-multiple of 8. I tested with 36. I tested it on both RF433any and RF433recv (sending done by rf433send).

FYI sender code (I show only the rf sender construct):

... tx_whatever = rfsend_builder( RfSendEncoding::TRIBIT_INVERTED, PIN_RFOUT, RFSEND_DEFAULT_CONVENTION, 7, nullptr, 7000, // initseq 0, // lo_prefix 0, // hi_prefix 600, // first_lo_ign 600, // lo_short 1200, // lo_long 0, // hi_short 0, // hi_long 0, // lo_last 7000, // sep 36 // nb_bits ); ...

and this resulted in the below RF433any output (using 01_main.ino):

-----CODE START----- // [WRITE THE DEVICE NAME HERE] rf.register_Receiver( RFMOD_TRIBIT_INVERTED, // mod 7048, // initseq 0, // lo_prefix 0, // hi_prefix 620, // first_lo_ign 620, // lo_short 1206, // lo_long 0, // hi_short (0 => take lo_short) 0, // hi_long (0 => take lo_long) 568, // lo_last 7048, // sep 36 // nb_bits ); -----CODE END-----

and also rf433recv code (again, left only the rf construct code):

... rf.register_Receiver( RFMOD_TRIBIT_INVERTED, // mod 7000, // initseq 0, // lo_prefix 0, // hi_prefix 600, // first_lo_ign 600, // lo_short 1200, // lo_long 0, // hi_short (0 => take lo_short) 0, // hi_long (0 => take lo_long) 0, // lo_last 7000, // sep 36, // nb_bits callback, 0 ); ...

and reception was OK.

Note that I also did same tests with simple tribit (I mean, tribit NOT inverted) and it works fine, too.

IMPORTANT Keep in mind, when you want rf433send to work with 36 bits of data, the provided array must be 5-byte long. For example in my tests above, the sender code did contain:

... byte data[] = { 0xfc, 0xcc, 0x00, 0x18, 0x35 }; ... byte n = tx_whatever->send(sizeof(data), data); ...

Regards