esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
415 stars 26 forks source link

Add RF Transceiver 868MHz CC1101 #59

Open christiaandouma opened 5 years ago

christiaandouma commented 5 years ago

What new integration would you wish to have? Would it be able to add RF Transceiver 868MHz CC1101?

*If possible, provide a link to an existing library for the integration:** https://github.com/incmve/Itho-WIFI-remote

*Please describe your use case for this integration and alternatives you've tried:** I currently made a temp sensor send via mqtt and recieive command for the rf868mhz from mqtt. This Will send a rf signaal to the itho ventilation

I want to use esphomelib as i think this a lot cleaner.

Additional context: Thx.

Emacee commented 5 years ago

For me this would also be really nice! Unfortunately I don’t have enough coding experience to get us any further, maybe someone else is able and willing to jump in?

jvanderneutstulen commented 4 years ago

I have been working a itho fan component, which works for my Itho Ecofan. I you want to try it, you can check out the itho-ecofanrft branch of my fork. Supports sending commands, and will report current fan speed.

Configuration example for esp8266:

spi:
    clk_pin: D5
    mosi_pin: D7
    miso_pin: D6

itho_ecofanrft:
    id: ecofan
    cs_pin: D8
    irq_pin: D2
    rf_address: "01:02:03"

fan:
   - platform: itho_ecofanrft
     name: "MV"

and for esp32:

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

itho_ecofanrft:
  cs_pin: GPIO5
  irq_pin: GPIO2
  id: ecofan
  rf_address: "51:52:53"
  peer_rf_address: "50:49:48"

fan:
  - platform: itho_ecofanrft
    name: "Ventilation"

switch:
  - platform: template
    name: "Join Remote"
    turn_on_action:
      - itho_ecofanrft.join: ecofan

peer_rf_address is the rf address for the ventilation, when you leave it out, the component will log all the addresses it sees. My unit sends it status every 2 minutes. For the ventilation unit to accept commands you must send a join command after powercycling the unit. See last example how you can expose a "join switch".

Emacee commented 4 years ago

Nice work @jvanderneutstulen! I'm using the Hass.io add-on of ESPHome. I tried to add the Itho component included in your branch. However, I cannot find where the Hass.io add-on it stores its components so I cannot add your branch to have a look myself. How do you use your own branch?

christiaandouma commented 4 years ago

Nice! I will try do setup a nodemcu with esphome to test this once i got the time

Thanks for the great work!

jvanderneutstulen commented 4 years ago

Nice work @jvanderneutstulen! I'm using the Hass.io add-on of ESPHome. I tried to add the Itho component included in your branch. However, I cannot find where the Hass.io add-on it stores its components so I cannot add your branch to have a look myself. How do you use your own branch?

You should a setup a dev using my fork (see https://esphome.io/guides/contributing.html#setting-up-development-environment) and compile/upload from there (for now). Then you can use the normal HA esphome integration to discover the fan.

christiaandouma commented 4 years ago

Trying to get IT to work but somehow IT doesn't work. Whats irq, where is IT Needed for. I could map the old PINS but irq i dont know.

I do see it in ha but it doesn't respond on high etc and join Actions

jvanderneutstulen commented 4 years ago

irq_pin should be the pin which is GDO2 (pin 6 on my module). It triggers an interrupt when the c1101 has received a packet.

christiaandouma commented 4 years ago

Cool

Thanks, currently I am only sending so that should be the issue.

Seems that i am also not able to join. Should i see something when joining?

Op zo 13 okt. 2019 20:56 schreef Jasper van der Neut - Stulen < notifications@github.com>:

irq_pin should be the pin which is GDO2 (pin 6 on my module). It triggers an interrupt when the c1101 has received a packet.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/esphome/feature-requests/issues/59?email_source=notifications&email_token=AKZTDY5IQARCVOJIAKGORWLQONVMDA5CNFSM4GXJMH2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBC5FZQ#issuecomment-541446886, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKZTDY5L6YGWVG6EVOU2KQDQONVMDANCNFSM4GXJMH2A .

jvanderneutstulen commented 4 years ago

No, when joining the fan should spin up briefly, I didn't see any RF message. My unit does send some sort of message on poweron, when it's accepting join commands. (Use loglevel VERY_VERBOSE to see the received packet payload.)

christiaandouma commented 4 years ago

Hi Jasper,

Got it, forgot I had to cut the power to the fan for a moment for the join to work. Works like a charm now.

Thanks for the help.

Op zo 13 okt. 2019 21:23 schreef Jasper van der Neut - Stulen < notifications@github.com>:

No, when joining the fan should spin up briefly. My unit does send some sort of message on poweron, when it's accepting join commands. (Use loglevel VERY_VERBOSE to see the received packet payload.)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/esphome/feature-requests/issues/59?email_source=notifications&email_token=AKZTDY6BF5YFNPRFFZUYR43QONYS5A5CNFSM4GXJMH2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBC52HI#issuecomment-541449501, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKZTDYZOD35Q7B4DAEMSCZ3QONYS5ANCNFSM4GXJMH2A .

christiaandouma commented 4 years ago

Hi,

Seems there is an issue when you try to do the join and the FAN isnt found. The joining wont stop on the ESP and blocks everything. Might be good to add a timer for trying?

kr,

Christiaan

On Sun, Oct 6, 2019 at 4:51 PM Jasper van der Neut - Stulen < notifications@github.com> wrote:

I have been working a itho fan component, which works for my Itho Ecofan. I you want to try it, you can check out the itho-ecofanrft branch https://github.com/jvanderneutstulen/esphome/tree/itho-ecofanrft of my fork. Supports sending commands, and will report current fan speed.

Configuration example for esp8266:

spi: clk_pin: D5 mosi_pin: D7 miso_pin: D6 itho_ecofanrft: id: ecofan cs_pin: D8 irq_pin: D2 rf_address: "01:02:03" fan:

  • platform: itho_ecofanrft name: "MV"

and for esp32:

spi: clk_pin: GPIO18 mosi_pin: GPIO23 miso_pin: GPIO19 itho_ecofanrft: cs_pin: GPIO5 irq_pin: GPIO2 id: ecofan rf_address: "51:52:53" peer_rf_address: "50:49:48" fan:

  • platform: itho_ecofanrft name: "Ventilation" switch:
  • platform: template name: "Join Remote" turn_on_action:
    • itho_ecofanrft.join: ecofan

peer_rf_address is the rf address for the ventilation, when you leave it out, the component will log all the addresses it sees. My unit sends it status every 2 minutes. For the ventilation unit to accept commands you must send a join command after powercycling the unit. See last example how you can expose a "join switch".

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/esphome/feature-requests/issues/59?email_source=notifications&email_token=AKZTDY26TF5FHCUJ6T23PYLQNH3NZA5CNFSM4GXJMH2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAOL3EA#issuecomment-538754448, or mute the thread https://github.com/notifications/unsubscribe-auth/AKZTDYYBEBD3OBCTNLAQT53QNH3NZANCNFSM4GXJMH2A .

--

jvanderneutstulen commented 4 years ago

Can you post your configuration (without secrets)? And maybe some logs?

christiaandouma commented 4 years ago

Hi,

I think its easy reproducable. Just make sure the ITHO is not online (no power) and press join on the ESP. It will stay in a infinite loop and won't respond anymore. I did comment the peer_rf_address and added a temperature DHT11 sensor.

esphome: name: ${name} platform: ESP8266 board: nodemcuv2

wifi: ssid: ${ssid} password: ${wifipass}

mqtt: broker: ${mqttbroker} discovery: True

Enable logging

logger: level: VERY_VERBOSE

ota: password: ${ota_pwd}

sensor:

- platform: uptime

name: ${name}_Uptime Sensor

spi: clk_pin: D5 mosi_pin: D7 miso_pin: D6

itho_ecofanrft: id: ecofan cs_pin: D8 irq_pin: D2 rf_address: "51:52:53"

peer_rf_address: "50:49:48"

fan:

switch:

Logs:

INFO Reading configuration ./itho.yaml...INFO Starting log output from itho_ecofanrft/debug[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][itho_ecofanrft.cc1101:077]: CC1101 check MARCSTATE for IDLE[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15...[19:41:32][VV][spi:093]: Enabling SPI Chip on pin 15...[19:41:32][VV][spi:015]: Disabling SPI Chip on pin 15

On Wed, Oct 23, 2019 at 5:56 PM Jasper van der Neut - Stulen < notifications@github.com> wrote:

Can you post your configuration (without secrets)? And maybe some logs?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/esphome/feature-requests/issues/59?email_source=notifications&email_token=AKZTDY2AJIZI43Y2G2I222DQQBXZ3A5CNFSM4GXJMH2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECB55OA#issuecomment-545513144, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKZTDY4TQEL7TWOVIAV5XMTQQBXZ3ANCNFSM4GXJMH2A .

--

dbuezas commented 2 years ago

Three cc1101 at different frequencies on one single esp8266 transmitting & receiving.

All the preexisting door sensors, garage door (scary) and a bunch of switches and new cheap door sensors in my house use non-rolling codes and manchester encoding, so I was able to reuse the existing "remote_transmitter" and "remote_receiver" components and integrate everything together.

The trick here is that the lib I'm using puts the cc1101 in a "direct" mode so it works like the classic rf chips, but still allows to set the frequency in software. Also, multiple chips are all hooked on the same spi bus, and each uses 1 single extra pin both to transmit and receive the raw data, so the "mode" needs to be changed before and after transmitting.

Each cc1101 therefore needs two dedicated pins (chip select and "raw" data), plus the 3 spi pins used all chips at the same time. The d1 mini looks like a spider. I'm really impressed by this chip, even the raw dump is quiet almost all the time and the range is quite good. Plus the frequency can be changed in software, which is amazing.

Note: there are two different board versions for 433 (red/blue) and 868 (green), each optimised for their frequency, but they both work in all frequencies (although with reduced range).

image

I'm using all of these


rf_gateway_cc1101.yaml

esphome:
  name: rf_gateway_cc1101
  platform: ESP8266
  board: d1_mini
  build_path: ./build/rf_gateway_cc1101
  includes:
    - rf_gateway_cc1101/custom_component.h
  libraries:
    - SPI
    - "SmartRC-CC1101-Driver-Lib"

packages:
  doors_package: !include rf_gateway_cc1101/433.325.yaml 
  rc_package: !include rf_gateway_cc1101/433.92.yaml
  r868_package: !include rf_gateway_cc1101/868.yaml

wifi:
  ssid: !secret wifi_name
  password: !secret wifi_pass
  fast_connect: true

logger:
api:
ota:      

rf_gateway_cc1101/433.92.yaml

packages:
  three_btn_white_switch: !include 433.92.three-btn-white-switch.yaml
  door_sensor: !include 433.92.door_sensor.yaml
  rc: !include 433.92.rc.yaml
custom_component:
  - lambda: |-
      // chip 1 (red) - RC
      auto transciver_433_92 = new CC1101Transciver(D5, D6, D7, D3, D1, 158.03, 433.92);
      return {transciver_433_92};
    components:
      - id: transciver_433_92

remote_transmitter:
  - id: transmitter_rc
    pin: D1
    carrier_duty_percent: 100%

# note that the transmitter is defined first and the receiver last. This seems to let the pin on input mode at startup, which is what we want.

remote_receiver:
  - id: receiver_rc
    pin:
      # Don't use D3,D4,D8,TX, boot often fails.
      # Can't be D0 or GPIO17 b/c no interrupts
      # Can be D1,D2,D5,D6,D7,Rx
      number: D1
    dump:
      - raw
    tolerance: 50%
    filter: 35us
    idle: 2ms
    buffer_size: 1kb

The other two files for different frequencies:

are equivalent to this one. Only the CS (D3) and "data" pin (D1) change. (and the frequency of course)


rf_gateway_cc1101/433.92.rc.yaml

binary_sensor:
  ####### RC1
  - platform: remote_receiver
    receiver_id: receiver_433_92
    id: rc1_on
    name: "RC1 button ON"
    filters:
      delayed_off: 100ms
    on_press:
      - switch.turn_on: rc1
    raw:
      code:
        # prettier-ignore
        [+166,-500,...etc]
  - platform: remote_receiver
    receiver_id: receiver_433_92
    id: rc1_off
    name: "RC1 button OFF"
    filters:
      delayed_off: 100ms
    on_press:
      - switch.turn_off: rc1
    raw:
      code:
        # prettier-ignore
        [+166,-500,...etc]

switch:
  - platform: template
    name: RC1 - Switch
    id: rc1
    optimistic: true
    turn_on_action:
      - lambda: |-
          // here's the trick: swap to transmit mode only while doing it
          ((CC1101Transciver *)transciver_433_92)->beginTransmission();
      - remote_transmitter.transmit_raw:
          transmitter_id: transmitter_433_92
          code:
            # prettier-ignore
            [+166,-500,...etc]
          repeat:
            times: 10
            wait_time: 4.733ms
      - lambda: |-
           // and back to receive mode after sending
          ((CC1101Transciver *)transciver_433_92)->endTransmission();
    # turn_off_action: ... the same

The other two files:

are equivalent


rf_gateway_cc1101/custom_component.h

#ifndef CC1101TRANSCIVER_H
#define CC1101TRANSCIVER_H

#include <ELECHOUSE_CC1101_SRC_DRV.h>

int CC1101Transciver_module_number = 0;
class CC1101Transciver: public Component{
  int _SCK;
  int _MISO;
  int _MOSI;
  int _CSN;
  int _GDO0;
  float _bandwidth;
  float _freq;
  float _moduleNumber;
  void setup(){
    pinMode(_GDO0, INPUT);
    ELECHOUSE_cc1101.addSpiPin(_SCK, _MISO, _MOSI, _CSN, _moduleNumber);
    ELECHOUSE_cc1101.setModul(_moduleNumber); 
    ELECHOUSE_cc1101.Init(); 
    ELECHOUSE_cc1101.setRxBW(_bandwidth);
    ELECHOUSE_cc1101.setMHZ(_freq); 
    ELECHOUSE_cc1101.SetRx(); 
  }
public:
  CC1101Transciver(int SCK, int MISO, int MOSI, int CSN, int GDO0, float bandwidth, float freq) {
    _SCK = SCK;
    _MISO = MISO;
    _MOSI = MOSI;
    _CSN = CSN;
    _GDO0 = GDO0;
    _bandwidth = bandwidth;
    _freq = freq;
    _moduleNumber = CC1101Transciver_module_number++;
  }

  void beginTransmission(){
    ELECHOUSE_cc1101.setModul(_moduleNumber);
    ELECHOUSE_cc1101.SetTx();
    pinMode(_GDO0, OUTPUT);
    noInterrupts(); // workaround for https://github.com/esphome/issues/issues/2811
  }
  void endTransmission(){
    interrupts();
    pinMode(_GDO0, INPUT);
    ELECHOUSE_cc1101.setModul(_moduleNumber);
    ELECHOUSE_cc1101.SetRx();
    ELECHOUSE_cc1101.SetRx(); // yes, twice
  }  
};

#endif

Contribution

I'd love to make a self contained component, but I found no way to include the remote_transmitter and remote_receivers from within the custom component, so I ended up with this functional Frankenstransciver. If somebody knows how to do this and could assist me a bit, I'm more than willing to try to make an actual PR. I'm not aware of any other platform that can achieve this trickery.

frma71 commented 2 years ago

@dbuezas Thanks for an excellent description. I've done the stuff above and it seems to be somewhat working. It's properly receiving and transmitting rf data. But, after I've done by first transmission reception stops working.

Any ideas ? What version of SmartRC-CC1101-Driver-Lib are you using ?

dbuezas commented 2 years ago

Im using the version of the lib fetched by

libraries:
    - "SmartRC-CC1101-Driver-Lib"

If reception stops after a transmission, look at the last lambda after the transmission. I'd guess the chip is not set back to Rx mode,and the pin to input mode

dbuezas commented 2 years ago

I've added an RSSI sensor component and I have the ambition of making a PR for a real component to avoid all this yaml hacks

frma71 commented 2 years ago

@dbuezas Looking forward to it. I have the lambdas. Relevant parts of my configuration below:

custom_component:
  - lambda: |-
      // chip 1 (red) - RC
      // SCK, MISO, MOSI, CSN, GDO0, channel, bandwidth, freq
      // add DRate !!
      auto transciver_868 = new CC1101Transciver(2, 4, 17, 16, 15, 0, 158.03, 433.92);
      return {transciver_868};
    components:
      - id: transciver_868

remote_transmitter:
  - id: transmitter_rc
    pin: 15
    carrier_duty_percent: 100%

remote_receiver:
  - id: receiver_rc
    pin:
      # Don't use D3,D4,D8,TX, boot often fails.
      # Can't be D0 or GPIO17 b/c no interrupts
      # Can be D1,D2,D5,D6,D7,Rx
      number: 15
    dump:
      - rc_switch
    tolerance: 50%
    filter: 35us
    idle: 2ms
    buffer_size: 1kb

switch:
  - platform: template
    name: RF Outlet 1 On
    turn_on_action:
      - lambda: |-
          ((CC1101Transciver *)transciver_868)->beginTransmission();
      - remote_transmitter.transmit_rc_switch_raw:
          transmitter_id: transmitter_rc
          #                                                           SS
          code: '1101010010110010110011001010110010110011001101001101001010101010' #ON
          protocol:
            pulse_length: 250
            sync: [1, 5]
            zero: [1, 5]
            one:  [1, 1]
          repeat:
            times: 10
            wait_time: 4.733ms
      - lambda: |-
          ((CC1101Transciver *)transciver_868)->endTransmission();
dbuezas commented 2 years ago

I see the following issues:

frma71 commented 2 years ago

@dbuezas I appreciate your help.

Just to clear, reception works fine until I transmit the first time and transmit always works. So I doubt it's something trivial like that. I'm using the much faster esp32 so maybe there is some timing issue.

dbuezas commented 2 years ago

Oh I see. I haven't tried it in an esp32 myself. The only test I can think of is to remove the interrupt disabling in begin/endTransmission. This is there just to avoid getting the sent signal in the receiver, so if you send and receive the same codes, you'll need a boolean and a filter to disable reception temporarily.

mortelil commented 2 years ago

I've added an RSSI sensor component and I have the ambition of making a PR for a real component to avoid all this yaml hacks

Thanks a lot for working on this. How is the PR coming a long? I have a 868mhz CC1101 myself that I'm hoping to use to controll some lights in my house, but I'm way too intimidated by the yaml you posted to have tried it out yet. Hope to see this device integrated natively in ESPHome some day as a simple remote reciever/transmitter.

dbuezas commented 2 years ago

sorry @mortelil I never got to it, not sure when I will. If you want I can post the 2 files directly in the meantime, it is not that much :)

mortelil commented 2 years ago

sorry @mortelil I never got to it, not sure when I will. If you want I can post the 2 files directly in the meantime, it is not that much :)

Yeah the 2 extra files would be great. I hope I can make sense of this stuff. Thanks in advance! :)

dbuezas commented 2 years ago

@mortelil Here is the repo with the yaml file examples an custom component c file

https://github.com/dbuezas/esphome-cc1101

I'd recommend you to start with the basic one and then try the advanced one with an RSSI sensor and the ability to tweak the frequency and bandwidth on the fly to maximise reception/transmission distance. have fun! :)

mortelil commented 2 years ago

@mortelil Here is the repo with the yaml file examples an custom component c file

https://github.com/dbuezas/esphome-cc1101

I'd recommend you to start with the basic one and then try the advanced one with an RSSI sensor and the ability to tweak the frequency and bandwidth on the fly to maximise reception/transmission distance. have fun! :)

Thanks a lot for the repo! The files were way easier to understand for a n00b like me. I was actually able to both receive and send raw data after a bit of trial and error. Now I just have to figure out why my stupid rf-lightswitch sends out different data for each press, and how to make the timing of the data I'm sending match the timing of the data coming from the switch. I'll make it work some day! Thanks again :)

dbuezas commented 2 years ago

Try shortening the idle time to 2000us. Maybe you are getting multiple bursts in one

mortelil commented 2 years ago

@dbuezas I've been using Universal Radio Hacker and my RTL-SDR to look at the signal sent by my switch and by the CC1101. I figured out that the switch sent an FSK signal, so I read some SmartRC-CC1101 examples and added the line ELECHOUSE_cc1101.setModulation(0); to cc1101.h, which worked and made the signal match my switch more. Here is my cc1101.yaml:

# https://github.com/dbuezas/esphome-cc1101
esphome:
  name: cc1101
  platform: ESP32
  board: esp32dev
  includes:
    - cc1101.h
  libraries:
    - SPI
    - "SmartRC-CC1101-Driver-Lib"

wifi:
  ssid: 
  password: 
  fast_connect: true
  power_save_mode: HIGH

logger:
api:
ota:

sensor:
  - platform: custom
    lambda: |-
      auto my_sensor = new CC1101(
        18, // SCK
        19, // MISO
        23, // MOSI
        5, // CSN
        22, // GDO0
        200, // bandwidth_in_khz
        868 // freq_in_mhz
      );
      App.register_component(my_sensor);
      return {my_sensor};
    sensors:
      id: transciver
      internal: true
remote_transmitter:
  - pin: GPIO22 # This is GDO0
    carrier_duty_percent: 100%

remote_receiver:
  - pin: # This is GDO0
      number: GPIO22
      # on the esp8266 use any of D1,D2,D5,D6,D7,Rx
      # Don't use D3,D4,D8,TX, boot often fails.
      # Can't be D0 or GPIO17 b/c no interrupts
    dump:
      - raw

button:
  - platform: template
    name: Garage
    on_press:
      - lambda: get_cc1101(transciver).beginTransmission();
      - remote_transmitter.transmit_raw:
          code: [-124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 373, -124, 124, -248, 124, -373, 124, -124, 124, -124, 248, -248, 124, -124, 124, -124, 124, -124, 248, -124, 124, -373, 124, -124, 622, -248, 622, -248, 124, -124, 373, -248, 248, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 373, -124, 124, -248, 124, -373, 124, -124, 124, -124, 248, -248, 124, -124, 124, -124, 124, -124, 248, -124, 124, -373, 124, -124, 622, -248, 622, -248, 124, -124, 373, -248, 248, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 373, -124, 124, -248, 124, -373, 124, -124, 124, -124, 248, -248, 124, -124, 124, -124, 124, -124, 248, -124, 124, -373, 124, -124, 622, -248, 622, -248, 124, -124, 373, -248, 248, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 373, -124, 124, -248, 124, -373, 124, -124, 124, -124, 248, -248, 124, -124, 124, -124, 124, -124, 248, -124, 124, -373, 124, -124, 622, -248, 622, -248, 124, -124, 373, -248, 248, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 124, -124, 373, -124, 124, -248, 124, -373, 124, -124, 124, -124, 248, -248, 124, -124, 124, -124, 124, -124, 248, -124, 124, -373, 124, -124, 622, -248, 622, -248, 124, -124, 373, -248, 248]
          repeat:
            times: 7
            wait_time: 99ms
      - lambda: get_cc1101(transciver).endTransmission();

It still doesn't work though, and looking at the analog signals in URH, there are two obvious differences. I'm using repeat: in my yaml to repeat the signal. This makes the CC1101 just keep sending the "slow" signal during the wait between the repeats. See screenshot here (original on top, CC1101 on the bottom). My original switch stops sending data between the signal repeats. Second problem: The wavelenghts of the slow signal doesn't match, see screenshot here. Any way I can decide the wavelenghts of the different parts of the signal?

dbuezas commented 2 years ago

@mortelil Let's continue in the repo to avoid spamming esphome :) https://github.com/dbuezas/esphome-cc1101/discussions/1

wiltet commented 8 months ago

Hello @all,

unluckily I could not get my cc1101 board working (simple, cheap, green pcb 868MHz) on ESP8266 neither on ESP32 with @dbuezas solution. Is there meanwhile a easyer, official integration in esphome for people with little knowledge about these things or got this project stucked at this level?

Ist there anybody special/known to be involved in this and be asked to maybe continue?

thanks for reading :)

nullbyte-software commented 1 month ago

+1 for support this in Esphome