Pilotage clim via infra rouge

Bonjour,
je souhaite piloter ma clim via l'infra rouge pour ce faire j'utilise la lib IRremote.
Pour le moment je n'y suis toujours pas arrivé (c'est pour ça que j'ouvre ce topic :wink: ), j'ai fait différentes recherches, surtout pour connaitre le protocole utilisé car celui ci n'est pas reconnu par la librairie.
j'ai réussi à trouver ce document

En regardant le code de la librairie j'ai vu ceci:

TIMER_ENABLE_PWM; // Enable pin 3 PWM output
#define TIMER_ENABLE_PWM     (TCCR2A |= _BV(COM2B1))

Quelqu'un peut il m'expliquer à quoi cela ça sert, il me semblait qu'il fallait juste (pour du 38kHz) allumer ou éteindre la led pendant 26 microsecondes?
Je n'ai peut être pas tout saisi.
Es-ce le bon protocole pour ma télécommande? Je ne pense pas qu'ils s'amusent à créer des protocoles pour chaque télécommandes, non plus.
Bref un peu d'aide srait la bievenue :slight_smile:

Bonjour
la télécommande utilise une porteuse, c-à-d une fréquence de 38 Khz modulée en tout ou rien.
Chaque message est un train d'impulsions modulant cette porteuse.
Chaque message est constitué

  • d'une entête soit 125 cycles de porteuse émise suivi de 62 cycles de porteuse non émise.
  • d'un corps de message constitué d'une série de mots (16) de 8 bits.
  • un bit 1 est constitué de 16 cycles de porteuse émise et de 16 cycles de porteuse non émise.
  • un bit 0 est constitué de 16 cycles de porteuse émise et de 46 cycles de porteuse non émise.
  • d'une fin de message soit 16 cycles de porteuse émise et d'au moins 305 cycles de porteuse non émise.
    On entend par cycle, une période de la porteuse soit +- 26,3 µS.
    Il faut donc créer cette porteuse : un signal carré de 38 Khz, compter le nombre de périodes durant lesquelles elle sera émise ou non suivant ce que l'on veut envoyer.
    A+

Bon c'est déjà ça, j'ai eu le même raisonnement ce dont je ne suis pas certain, c'est si il faut rajouter ou non l'entête et le fin de message pour la fonction off. Voilà à quoi ressemble la déclaration de mon tableau.

unsigned int clim[]={420,1209,420,1209,420,420,420,1209,420,420,420,1209,420,1209,420,1209,420,420,420,420,420,1209,420,1209,420,1209,420,420,420,420,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,420,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,420,420,1209,420,1209,420,1209,420,1209,420,420,420,1209,420,1209,420,1209,420,1209,420,1209,420,1209,420,420,420,1209,420,420,420,420,420,420,420,420,420,420,420,420};

Une dernière question, dans le code de la biblio j'ai aussi vu USECPERTIC doit je en prendre compte/m'en servir?

Salut

J'ai fais le même projet que toi et il est fonctionnel maintenant.
Je suis capable de piloter ma thermopompe fredrich (c'est du fujistsu) via internet.
Lorsque je travaillais sur ce projet (ca date d'un peu plus d'un an je crois) j'avais trouvé le pdf dont tu fais référence.
Je n'avais RIEN compris du tout :slight_smile: J'ai donc commencé moi même à essayer de decoder les trames. A l'époque je n'avais pas d'analyseur logique. J'avais donc utilisé une led IR branché dans la prise micro de ma carte son et analysé les trames avec audacity.

Ca marchait très bien.

Au final, une fois que j'avais compris comment fonctionnait les trames, je m'étais apercu que c'était le meme protocole que dans le PDF sauf que j'avais plus d'option sur la mienne car elle ne fait pas juste air climatisé mais également chauffage.

Tu n'a pas précisé quel est ton modèle de clim? et quel est le modèle de ta télécommande?

EDIT: j'ai utilisé ce montage là:
http://forum.arduino.cc/index.php?topic=137665.msg1034761#msg1034761

Salut,
C'est vrai que j'ai oublié l'essentiel, le modèle de ma clim (qui est une réversible également) est ASYG12LMCA et celui de ma télécommande AR-REB1E.

Content de trouver quelqu'un qui à fait un projet similaire au mien.

Voici le code que j’utilise
Mais attention, mon projet utilise deux arduinos:

Le 1er: Un arduino qui a un module ENCJ qui est branché a mon routeur (qui recoit la temperature a mettre). Il a aussi un module radio NRFL01 qui envoit l’info a l’autre arduino

Le 2eme: L’autre arduino est devant la clim, il revoit l’info de la temperature via le NRFL01
Et ensuite, il construit la trame a envoyé via infrarouge, et il l’envoit.

Ce que je donne comme code, c’est celui du 2eme arduino:

/*
 Copyright (C) 2012 N. Janik <nicolas.janik@gmail.com>
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

#include <OneWire.h> 
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include "IRremote.h"


#define WORD_TEMP 9
#define WORD_MODE 10 
#define WORD_FAN  11
#define WORD_CHECKSUM 16


#define MODE_AUTO 0
#define MODE_COOL 1
#define MODE_DRY  2
#define MODE_FAN  3
#define MODE_HEAT 4


#define FAN_AUTO   0
#define FAN_HIGH   1
#define FAN_MEDIUM 2
#define FAN_LOW    3
#define FAN_QUIET  4


#define FIRST_SPACE 3200
#define FIRST_MARK 1600
#define ONE_IN_MS 1183
#define ZERO_IN_MS 350
#define SPACE_IN_MS 445



//---------------

IRsend irsend;
unsigned char currentTemp;
unsigned char currentMode;
unsigned char currentFan;

unsigned char mode;
unsigned char temp;
unsigned char fan;  


unsigned char trame[16] = {0x28, 0xc6, 0x0, 0x8, 0x8, 0x7f, 0x90, 0xc, 0x7, 0x20, 0x40, 0x0, 0x0, 0x0, 0x4, 0x53};
unsigned char trameOFF[7] = {0x28, 0xc6, 0x00, 0x08, 0x08, 0x40, 0xbf};

unsigned int times[259] = {FIRST_SPACE, FIRST_MARK, SPACE_IN_MS};   //259 = 16 words * (8 bytes + 8 spaces) +  first space + first mark + 1 space in ms
unsigned int timesOFF[115] = {FIRST_SPACE, FIRST_MARK, SPACE_IN_MS};  // 115 =  7 words * (8 bytes + 8 spaces) +  first space + first mark + 1 space in ms


uint32_t timer;

// Radio Hardware configuration
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 

RF24 radio(9,10);

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };





int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
//Temperature chip i/o
OneWire ds(DS18S20_Pin);  // on digital pin 2


unsigned long timerTempCheck = 0;
unsigned int roomTemp;

void setup() {                
  
  

  
  pinMode(13, OUTPUT);    
  Serial.begin(9600);
  
  
  printf_begin();
  printf("\n\r INIT \n\r");


  // Setup and configure rf radio

  radio.begin();

  // optionally, increase the delay between retries & # of retries
  radio.setRetries(20,50);

  radio.setPayloadSize(sizeof(unsigned int));


  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);


  radio.startListening();

  radio.printDetails();  


  
}




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


void loop(void)
{
  
  
  //get the room temp every 35 seconds
  if (millis() > timer) {
    timer = millis() + 35000;
    roomTemp = getTemp();
  } 
  
  
  // if there is data ready
  if ( radio.available() )
  {
    // Dump the payloads until we've gotten everything
    unsigned int dataCommand;
    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &dataCommand, sizeof(unsigned int) );

      // Spew it
      printf("Got payload %i...",dataCommand);
      
      
      // Delay just a little bit to let the other unit 
      // make the transition to receiver
      delay(30);      

      // First, stop listening so we can talk
      radio.stopListening();

      switch(dataCommand){
        case 0:
			sendOff();
			Serial.println("Received OFF command");
        break;
            
        case 9999:
			//Serial.println("Ask for temp");
			radio.write(&roomTemp, sizeof(unsigned int) );
        break;
            
        default:

            radio.write(&dataCommand, sizeof(unsigned int) );

            Serial.println("default command");
			mode = dataCommand / 1000;
			temp = (dataCommand / 10) % (mode*100);
			fan = dataCommand - ((mode * 1000) + (temp * 10));
			
			
			Serial.println(dataCommand);
			Serial.println("Mode:");
			Serial.println(mode);
			Serial.println("Temp:");
			Serial.println(temp);
			Serial.println("Fan:");
			Serial.println(fan);  

            setMode(mode);
            setTemp(temp);
            setFan(fan);
            check();
            checksum();
            trameToTime();
            sendIR();

        break;
       }
    }


    // Now, resume listening so we catch the next packets.
    radio.startListening();
  }
  
  
  if(timerTempCheck < millis()){
	
	roomTemp = getTemp();
	timerTempCheck = millis() + (1000 * 10);
        Serial.println("Room Temp:");
        Serial.println(roomTemp);
	  
  }
}




void sendOff(){
	
	
  unsigned char mask; 
  unsigned char value;	
  int i,j;
  unsigned int index=3;
  

  for(i=0; i<7; i++){
    mask = 0x80;  //10000000
    for(j=0; j<8; j++){

      value = trameOFF[i];

      if(value & mask){
        timesOFF[index++] = ONE_IN_MS;
      }else{
        timesOFF[index++] = ZERO_IN_MS;
      }
      timesOFF[index++] = SPACE_IN_MS;
      mask = mask >> 1;
    }
  }
  
  irsend.sendRaw(timesOFF,115,38);  //38khz
	
}

void sendCommand(unsigned char mode, unsigned char temp, unsigned char fan){

}

void sendIR(){
  irsend.sendRaw(times,259,38);  //38khz
}


void setFan(unsigned char value)
{
  if(!(value == FAN_AUTO || value == FAN_HIGH || value == FAN_MEDIUM || value == FAN_LOW || value == FAN_QUIET))
  {
    Serial.println("Error setFan: unknown value");
    return;   
  }
  
  currentFan = value;
  
  value = Bit_Reverse(value);
  trame[WORD_FAN-1] = value;
  
  
}


void setMode(unsigned char value)
{
  if(!(value == MODE_AUTO || value == MODE_COOL || value == MODE_DRY || value == MODE_FAN || value == MODE_HEAT))
  {
    Serial.println("Error setMode: unknown value");
    return;   
  }  
  
  currentMode = value;
  
  value = Bit_Reverse(value);
  trame[WORD_MODE-1] = value;
}




void setTemp(unsigned char value)
{
  
  if(value<60 || value>88){
    Serial.println("Error setTemp: Temp not in range (60 to 88)");
    return;
  }
  
  if ( (value & 0x01) != 0) { 
    Serial.println("Error setTemp: Temp value must be even");
    return;
  }

  currentTemp = value;

  //60F = 0    61F = 1   ...  88F = 14
  value = (value - 60)/2;
  
  
  value = value << 4;
  value = value & 0xFF;
  value = Bit_Reverse(value);
  
  value = value | 0x80; //set the first bit to 1 to always POWER ON 
  
  trame[WORD_TEMP-1] = value;
  

  
}









char checksum(){

  int sum = 0;
  char value;
  
  for(int i=8; i<=15; i++){
    char value = trame[i-1];
    value = Bit_Reverse(value);
    sum+=value;
  }
  
  value = sum % 0xFF;
  value = 0X100 - sum;
  value = Bit_Reverse(value);
  
  
  trame[WORD_CHECKSUM-1] = value;
 

}


void check(){

   if(currentMode == MODE_DRY && currentFan != FAN_AUTO){
        setFan(FAN_AUTO);
   }

}



void trameToTime()
{
  
  unsigned char mask;
  unsigned char value;	
  int i,j;
  unsigned int index=3;
  

  check();


  for(i=0; i<16; i++){
    mask = 0x80;  //10000000
    for(j=0; j<8; j++){

      value = trame[i];

      if(value & mask){
        times[index++] = ONE_IN_MS;
      }else{
        times[index++] = ZERO_IN_MS;
      }
      times[index++] = SPACE_IN_MS;
      mask = mask >> 1;
    }
  }
    
}



// Reverse the order of bits in a byte. 
// I.e. MSB is swapped with LSB, etc. 
unsigned char Bit_Reverse( unsigned char x ) 
{ 
    x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa); 
    x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc); 
    x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0); 
    return x;    
}




float getTemp(){
  //returns the temperature from one DS18S20 in DEG Celsius
	
	//j'ai enlevé le code pour que ca ne soit pas trop long
 
  
}