[DefiDIY25] Émetteur/récepteur IRverse

Bonjour à tous,

Étant en plein projet de domotiser/piloter ma soufflerie de sèche-serviette ACOVA IR (évitant au passage un module propriétaire) et ma hotte de cuisine Roblin également en IR, je me suis mis au boulot pour fabriquer un émetteur/récepteur de mes propres mains. En plus, en cours de route un concours pour présenter son projet est sorti, timing parfait :smiley: .

Je vais déposer mon projet sur github afin que tout le monde puisse l’utiliser et peut-être l’améliorer car il s’adapte, je pense à beaucoup d’appareils de notre maison (hotte aspirante, TV, unité intérieure de climatisation, radiateur, home cinéma, etc.)

Le petit (pour certain, moi c’est déjà énorme) défi lancé à moi-même et que le besoin est identifié il fallait établir la liste du matériel nécessaire :

  • 1* D1 Mini Pro 16Mb avec antenne externe : Le cerveau de mon projet, il va gérer l’émission IR et alimenté tous mes composants.

  • 1 * LED IR « TSAL6100 » : Pour émettre une lumière IR et communiquer avec mon appareil IR

  • 1 * Résistance 220 Ohms : Montage en série sur l’anode de la LED pour limiter le courant et éviter qu’elle ne grille

  • 1* Résistance 10 kOhms : Montage en pull-up avec le TSOP38238

  • 1 * Condensateur 100nF céramique : Pour le découplage et filtrer les hautes-fréquences

  • 1 * Condensateur 100uF électrolytique : Stabilisation globale de l’alimentation

  • 1 * PCB sur mesure pour monter tout ça proprement

  • 1 * Module d’alimentation HLK-PM01 : Passer du 230V AC vers du 5V DC

  • 2 * Borniers 2P 5.08mm pour aliment soit le phase + neutre ou le 5VDC/0V

Un morceau de câble 2G1.5 ou câble USB, presse-étoupe PG9 pour la version alimentation embarqué ou un PG7 pour la version alimentation séparée (pour le boîtier), etc.

Il faudrait également un boîtier en impression 3D pour les deux modèles pour tout mettre proprement à l’intérieur, mais il n’est pas encore dessiné, il devrait néanmoins, arriver très rapidement :sweat_smile:

Tout le matériel a été acheté sur aliexpress, et j’estime le coût du projet à environ 7€ version sans alimentation et 10€ version alimentation.

Après avoir apprivoisé Kicad pour dessiné un PCB le plus compact possible avec tout ce beau monde et bien, j’ai poussé le vice un peu plus loin en fabricant un module pouvant être raccordé directement au 230V plus de la version où il faut amener un 5VDC via USB, ça me permet de palier à toutes les situations :shaking_face:

Version alimentation séparée (il faut raccorder un 5VDC environnant avec un micro-USB par exemple) :

Shéma IR v2 - Alimentation séparée

Version alimentation embarquée (une arrivée en 230V) :

shéma kicad émetteur-recepteur ir

Après avoir fait les différents tests (ERC et DRC), Kicad ne me remonte aucune erreur donc c’était parti pour la fabrication !

Et voilà le PCB beau, tout neuf !

Et hop, tous les composants de soudés :

Bon, maintenant que la partie hardware est là, faut s’attaquer au programme, après des essais et des essais, du sniffage de code, beaucoup de loupés, madame qui m’a entendu râler, je vous présente mon programme pour ma hotte aspirante Roblin fonctionnel (je suis pas peu fier de le dire :rofl: )

esphome:
  name: esp8266-roblin-ir
  friendly_name: ESP8266-Roblin_IR

esp8266:
  board: d1_mini_pro

logger:

api:
  encryption:
    key: "tacléapi"

ota:
  platform: esphome
  password: "0a1abb4344477f1f0dd6a6e9c7143608"

wifi:
  ssid: "tonwifi"
  password: "tonmotdepasse"
  ap:
    ssid: "Esp8266-Roblin-Ir"
    password: "cvi91SvuVJfn"

captive_portal:

remote_transmitter:
  id: my_remote
  pin: D5
  carrier_duty_percent: 50%

# --- Récepteur IR pour sniffer ---
remote_receiver:
  pin:
    number: D4
    inverted: true
  dump: all

# --- Scripts pour appuis longs ---
script:
  - id: lumiere_min
    then:
      - delay: 3s
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000B 0000 0021 001A 001E 001A 001E 0019 003C 0034 001E 001A 001F 0019 001F 0019 001F 0019 001E 001B 001E 001A 001D 0181"

  - id: mode_24h_on
    then:
      - delay: 3s
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 003E 0035 001E 0019 003B 0019 001E 0034 001F 001A 001E 001A 003B 0034 001F 001A 001E 0181"

  - id: mode_24h_off
    then:
      - delay: 3s
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 003D 0034 001F 0019 003C 0019 001F 0034 001F 0019 001E 001A 003C 0035 001E 0019 001F 0181"

# --- Tous les boutons ---
button:
  # Lumière
  - platform: template
    name: "Lumière ON (max)"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 0021 0018 001F 0018 003C 0034 001E 001A 001E 001A 003B 006A 001E 001A 001E 001A 0057 0181"

  - platform: template
    name: "Lumière ON (min) - appui long"
    on_press:
      - script.execute: lumiere_min

  - platform: template
    name: "Lumière OFF"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 0021 0018 001F 0018 003C 0034 001E 001A 001E 001A 003A 006A 001E 001A 001E 001A 0057 0181"

  # Hotte
  - platform: template
    name: "Hotte ON"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 0021 0018 001F 0033 003C 001A 001E 001A 001E 0035 003B 004F 001E 0034 001E 001A 003B 0181"

  - platform: template
    name: "Hotte OFF"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 0021 0019 001F 0034 003C 0019 001F 0019 001F 0034 003B 004E 001F 0033 001F 001A 003B 0181"

  # Aspiration
  - platform: template
    name: "Aspiration +1"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0008 0000 0021 0018 0059 0019 001E 001A 001E 001A 0057 001A 001E 004F 0057 0034 003B 0181"

  - platform: template
    name: "Aspiration -1"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0008 0000 0021 0033 003C 0018 001F 0019 001E 0035 003B 001A 001E 006A 003B 0034 003B 0181"

  # Boost
  - platform: template
    name: "Boost ON"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0008 0000 0021 0018 003C 0033 001F 001A 001E 001A 003B 0035 001E 004F 003B 004F 003B 0181"

  - platform: template
    name: "Boost OFF"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0008 0000 0021 0019 003C 0033 001F 001A 001E 001A 003B 0034 001E 004F 003B 004F 003B 0181"

  # Arrêt différé
  - platform: template
    name: "Arrêt différé ON"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0006 0000 0020 0034 003B 0034 001E 004F 003C 004F 001D 0034 003B 0181"

  - platform: template
    name: "Arrêt différé OFF"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0006 0000 0021 0034 003B 0034 001F 004E 003B 004E 001E 0034 003C 0181"

  # Mode 24H
  - platform: template
    name: "Mode 24H ON - appui long"
    on_press:
      - script.execute: mode_24h_on

  - platform: template
    name: "Mode 24H OFF - appui long"
    on_press:
      - script.execute: mode_24h_off

  # Réserve / Inconnu
  - platform: template
    name: "Réserve / Inconnu"
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0009 0000 0021 0018 001F 0033 001F 0018 001F 0034 001E 0034 001E 0034 001E 001A 001E 0034 001E 0181"

Un début de programme pour la soufflerie de mon sèche-serviette ACOCA (j’ai brické le WEMOS lui étant dédié donc j’en ai recommandé un d’urgence pour pouvoir poursuivre le projet) :

esphome:
  name: esp8266-acova-ir
  friendly_name: ESP8266-Acova_IR

esp8266:
  board: d1_mini_pro

logger:

api:
  encryption:
    key: "takeyapi"

ota:
  platform: esphome
  password: "0a1abb4344477f1f0dd6a6e9c7143608"

wifi:
  ssid: "tonwifi"
  password: "tonmotdepasse"
  ap:
    ssid: "Esp8266-Acova-Ir"
    password: "RD8YW3fHcbNL"

captive_portal:

globals:
  - id: last_raw
    type: std::vector<int>
    initial_value: 'std::vector<int>()'

remote_receiver:
  pin:
    number: D4
    inverted: true
  dump: all
  on_raw:
    then:
      - lambda: |-
          ESP_LOGD("IR", "IR code received with size: %d", x.size());
          id(last_raw) = x;

remote_transmitter:
  pin: D5
  carrier_duty_percent: 50%

switch:
  - platform: template
    name: "Acova BOOST"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004B 0028 0025 004D 004A 0027 0023 0028 0024 004E 0022 0028 0023 004E 0049 004F 0048 0027 004A 0027 004A 004D 0023 0028 0023 0027 0181"
    restore_mode: ALWAYS_OFF

  - platform: template
    name: "Acova ON/OFF"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004B 0028 0025 004D 004A 0027 0023 0028 0024 004E 0022 0028 0023 004E 0049 004F 0048 0027 004A 0027 004A 004D 0023 0028 0023 0027 0181"
    restore_mode: ALWAYS_OFF

Pour terminer, j’utilise une antenne externe donc il faut bien penser à déplacer la résistance “0 Ohms” de 90 degrés afin de profiter d’un signal optimal (en toute fin du projet !).

En espérant inspirer d’autres novices comme moi et que mon projet vous soit utile :smiley:

9 « J'aime »

Du nouveau, j’ai dessiné deux modèles de boitiers pour la version avec l’alimentation embarqué :

Des plots permettant d’apposer proprement le PCB dans le boitier. Un trou pour l’antenne externe, un autre pour monter un presse-étoupe PG9 pour amener l’alimentation. Une version ou la LED émettrice pointra vers le haut et une seconde version pour que la LED soit positionnée latéralement en la coudant délicatement. “Normalement”, le couvercle doit se clipser dessus avec, un léger jeu et j’ai une encoche pour permettre de l’ouvrir avec un petit tournevis plat, par exemple :slight_smile:.

Un logo gravé dedans baptisant le projet au passage : IRverse :fire:

Je vais voir pour faire deux modèles similaires pour la version avec alimentation via le 5V :grinning_face:

Pour terminer, je conseille de passer sur une TSAL6400 qui a son cône d’émission plus large (environ 25° contre 12° pour la TSAL6100)

EDIT: Chose promise, chose due ! Voici le boitier avec l’alimentation séparée et du coup plus compact. Le trou pour l’arrivée de l’alimentation est déporté et un prévoit un presse-étoupe PG7 pour être étanche.

2 « J'aime »

Voici le github du projet fraichement créé : IRverse-Hub-IR-DIY-universel/README.md at main · Quentin90000/IRverse-Hub-IR-DIY-universel · GitHub

J’espère ne rien avoir omis pour que les personnes intéressées puissent créer leur PCB et se lancer.

Bonjour,

A combien te reviens le PCB ?

Merci

Salut,

Je suis passé par Aisler pour faire fabriquer mes PCB, pour 3 exemplaires (alimentation embarquée), ça m’est revenu à 21€ avec les frais de ports. Je pense qu’auprès de PCBWay ou autre tu peux en avoir pour moins cher.

C’est raisonnable pour une si petite quantité, je pensais que les premiers exemplaires seraient ‘hors de prix’ !!

Merci

Oui c’est correct comme prix. Les élements les plus cher du produits sont le PCB, le Wemos et le module d’alimentation HLK.

Le projet est ,je pense, abordable par rapport à son utilisation :slight_smile: .

Salut !

Un petit peu de neuf : J’ai réceptionné mon nouveau Wemos D1 et j’ai bidouillé dessus avec cette soufflerie ACOVA. Donc ça y est tout fonctionne enfin après quelques heures de test, sniffage, re-test etc :zany_face:

Je partage le code (ne sait-on jamais si quelqu’un est équipé du même matériel que moi et qu’il décide de se lancer) :

esphome:
  name: esp8266-acova-ir
  friendly_name: ESP8266-Acova_IR

esp8266:
  board: d1_mini_pro

logger:

api:
  encryption:
    key: "tacléAPI"

ota:
  platform: esphome
  password: "0a1abb4344477f1f0dd6a6e9c7143608"

wifi:
  ssid: "tonssidwifi"
  password: "tonmotdepasse"
  ap:
    ssid: "Esp8266-Acova-Ir"
    password: "RD8YW3fHcbNL"

captive_portal:

remote_transmitter:
  pin: D5
  carrier_duty_percent: 50%

remote_receiver:
  pin:
    number: D4
    inverted: true
  dump: all

# --- Scripts pour appuis longs (ON/OFF uniquement) ---
script:
  - id: acova_on_long
    then:
      # Phase 1 : Code ON normal (3 fois)
      - repeat:
          count: 3
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004B 0028 004A 004D 0049 0028 0023 0029 0023 004D 0024 0027 0024 0029 0023 0029 0022 0029 0048 0029 0048 0027 004A 004D 0023 0029 0181"
            - delay: 250ms
      # Phase 2 : Code "appui maintenu" (4 fois)
      - repeat:
          count: 4
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004B 0029 0024 0027 0049 0028 0024 0027 0024 004E 0049 004F 0049 0028 0022 0027 0025 004D 0049 0027 0049 004E 0049 004E 0023 004F 0181"
            - delay: 250ms
      # Phase 3 : Code de relâchement (1 fois)
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004B 0028 004A 004C 004A 0027 0024 0029 0023 004C 0025 0027 0024 0028 0024 0027 0024 0028 0049 0027 004A 0028 0049 004D 0023 0028 0181"

  - id: acova_off_long
    then:
      # Phase 1 : Code OFF normal (3 fois)
      - repeat:
          count: 3
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004B 0029 0049 004D 0024 0027 0024 0028 0024 0027 0023 0027 0025 0027 0023 0027 0025 0027 004A 004D 0023 0029 0023 0027 0023 0028 0181"
            - delay: 250ms
      # Phase 2 : Code "appui maintenu" (4 fois)
      - repeat:
          count: 4
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004B 0028 0025 0027 0023 0028 0024 0028 0023 0027 004A 004D 004A 0028 0024 0027 0023 004E 0049 004E 0023 004D 0025 0027 0023 004F 0181"
            - delay: 250ms
      # Phase 3 : Code de relâchement (1 fois)
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004B 0028 004A 004D 0025 0027 0023 0027 0025 0027 0023 0028 0024 0028 0023 0029 0023 0027 004A 004D 0023 0029 0023 0027 0024 0028 0181"

# --- Tous les switches ---
switch:
  # Boost ON/OFF - Séquence complète automatique
  - platform: template
    name: "Acova BOOST ON"
    turn_on_action:
      - repeat:
          count: 3
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004C 0028 0025 004C 004A 0026 0024 0026 0026 004C 0024 0027 0024 004F 0048 004D 004A 0026 004B 0026 004B 004C 0024 0027 0024 0027 0181"
            - delay: 250ms
      - repeat:
          count: 4
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004C 0027 0026 0027 0049 0028 0024 0026 0025 004D 004B 004C 004A 0027 0024 0027 0025 004B 004B 0026 004A 004D 004B 004B 0024 004D 0181"
            - delay: 250ms
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004C 0028 0025 004C 004B 0026 0025 0028 0024 004B 0025 0027 0024 004D 004A 004D 004A 0026 004B 0027 004A 004C 0024 0028 0024 0026 0181"

  - platform: template
    name: "Acova BOOST OFF"
    turn_on_action:
      - repeat:
          count: 3
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004C 0027 004B 004C 004A 0026 0025 0027 0024 004C 0026 0027 0024 0027 0024 0026 0024 0027 004A 0026 004B 0026 004B 004C 0024 0027 0181"
            - delay: 250ms
      - repeat:
          count: 4
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000A 004D 0027 0026 0026 004A 0027 0025 0026 0025 004D 004B 004B 004B 0026 0024 0028 0024 004C 004A 0026 004A 004D 004C 004A 0025 004D 0181"
            - delay: 250ms
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004C 0027 004B 004B 004C 0025 0025 0027 0024 004C 0026 0026 0025 0027 0025 0026 0025 0027 004A 0026 004B 0026 004B 004B 0026 0026 0181"

  # Timer Boost +/- (ajout/retrait de 15 minutes) - Séquence complète
  - platform: template
    name: "Acova BOOST + (timer)"
    turn_on_action:
      - repeat:
          count: 3
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004C 0027 0026 004C 004A 0027 0024 0026 0026 004B 0024 0028 0049 0027 004A 004F 0023 004C 004B 0026 0025 0027 0024 0026 004B 004C 0181"
            - delay: 250ms
      - repeat:
          count: 4
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004B 0028 0025 0026 004A 0027 0025 0026 0025 004D 004A 004D 004C 0025 0025 0026 0026 004B 004B 0026 004A 004D 004B 004B 0026 004C 0181"
            - delay: 250ms
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004C 0027 0026 004B 004B 0026 0025 0026 0026 004C 0024 0027 004B 0026 004A 004D 0025 004B 004B 0026 0025 0027 0025 0026 004B 004B 0181"

  - platform: template
    name: "Acova BOOST - (timer)"
    turn_on_action:
      - repeat:
          count: 3
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004C 0027 0026 004B 004B 0026 0024 0026 0026 004C 0024 0027 0025 004D 004A 004E 0049 0026 004B 0026 004B 004B 0025 0027 0025 0026 0181"
            - delay: 250ms
      - repeat:
          count: 4
          then:
            - remote_transmitter.transmit_pronto:
                data: "0000 006D 000E 0000 000C 004B 0027 0026 0027 0049 0027 0025 0026 0025 004D 004A 004D 004B 0027 0024 0026 0026 004B 004B 0026 004A 004E 004A 004C 0025 004D 0181"
            - delay: 250ms
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 000E 0000 000C 004C 0028 0025 004C 004B 0027 0024 0026 0027 004A 0024 0029 0023 004D 004A 004D 004A 0026 004B 0026 004B 004B 0026 0026 0024 0026 0181"

  # ON/OFF avec appui long (3 secondes)
  - platform: template
    name: "Acova ON - appui long 3s"
    turn_on_action:
      - script.execute: acova_on_long

  - platform: template
    name: "Acova OFF - appui long 3s"
    turn_on_action:
      - script.execute: acova_off_long

Au passage, une belle carte pour les commandes :

Voilà la code pour la carte :

type: vertical-stack
cards:
  # Header Card
  - type: custom:mushroom-title-card
    title: Radiateur Acova
    subtitle: Contrôle infrarouge

  # Boutons ON/OFF et BOOST
  - type: horizontal-stack
    cards:
      - type: custom:mushroom-template-card
        primary: ''
        secondary: ON
        icon: mdi:power
        icon_color: green
        layout: vertical
        tap_action:
          action: call-service
          service: switch.turn_on
          target:
            entity_id: switch.acova_on_appui_long_3s
        card_mod:
          style: |
            ha-card {
              background: rgba(76, 175, 80, 0.1);
              border: 1px solid rgba(76, 175, 80, 0.3);
            }

      - type: custom:mushroom-template-card
        primary: ''
        secondary: OFF
        icon: mdi:power-off
        icon_color: red
        layout: vertical
        tap_action:
          action: call-service
          service: switch.turn_on
          target:
            entity_id: switch.acova_off_appui_long_3s
        card_mod:
          style: |
            ha-card {
              background: rgba(244, 67, 54, 0.1);
              border: 1px solid rgba(244, 67, 54, 0.3);
            }

      - type: custom:mushroom-template-card
        primary: ''
        secondary: Boost ON
        icon: mdi:lightning-bolt
        icon_color: orange
        layout: vertical
        tap_action:
          action: call-service
          service: switch.turn_on
          target:
            entity_id: switch.acova_boost_on
        card_mod:
          style: |
            ha-card {
              background: rgba(255, 152, 0, 0.1);
              border: 1px solid rgba(255, 152, 0, 0.3);
            }

      - type: custom:mushroom-template-card
        primary: ''
        secondary: Boost OFF
        icon: mdi:lightning-bolt-outline
        icon_color: grey
        layout: vertical
        tap_action:
          action: call-service
          service: switch.turn_on
          target:
            entity_id: switch.acova_boost_off
        card_mod:
          style: |
            ha-card {
              background: rgba(158, 158, 158, 0.1);
              border: 1px solid rgba(158, 158, 158, 0.3);
            }

      - type: custom:mushroom-template-card
        primary: ''
        secondary: Timer +
        icon: mdi:plus-circle
        icon_color: blue
        layout: vertical
        tap_action:
          action: call-service
          service: switch.turn_on
          target:
            entity_id: switch.acova_boost_timer
        card_mod:
          style: |
            ha-card {
              background: rgba(33, 150, 243, 0.1);
              border: 1px solid rgba(33, 150, 243, 0.3);
            }

      - type: custom:mushroom-template-card
        primary: ''
        secondary: Timer -
        icon: mdi:minus-circle
        icon_color: purple
        layout: vertical
        tap_action:
          action: call-service
          service: switch.turn_on
          target:
            entity_id: switch.acova_boost_timer_2
        card_mod:
          style: |
            ha-card {
              background: rgba(156, 39, 176, 0.1);
              border: 1px solid rgba(156, 39, 176, 0.3);
            }

Plus qu’à faire une belle carte pour ma hotte et les boitiers 3D et mon projet sera enfin terminé ! :smiley:

Ce sujet a été automatiquement fermé après 30 jours. Aucune réponse n’est permise dorénavant.