Problème d'infra rouge

Bonjour, j'essaie désespérément de transmettre une information en infrarouge, c'est à dire éteindre ma télévision.
D'après cette image
il faut envoyer un code binaire avec l'infrarouge.
J'ai donc essayé ceci :

int led=3;

void setup()
{
   pinMode(led,OUTPUT);
}

void loop()
{
   delayMicroseconds(2400);
   digitalWrite(led, HIGH);
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, HIGH);
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, HIGH);
   
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, HIGH);
   
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   delayMicroseconds(600);
   digitalWrite(led, LOW);
   
   delay(45);
}

pour envoyer ce code : 101010010000 qui doit éteindre ma télévision.
Où est le problème ? Pour moi, quand on allume la led, ça correspond à un 1 en binaire non ? et le 0, c'est la led éteinte ?

Sinon, comment procéder ?
Car j'ai aussi vu une bibliothèque qui donnait ce code là en démo :

#include <IRremote.h>
IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
    for (int i = 0; i < 3; i++)
    {
      irsend.sendSony(0xa90, 12);
      delay(100);
    }
}

Cependant, mon téléviseur est un thomson et non un sony. =(

Merci de votre aide

Les télécommandes n'utilisent pas un signal tout ou rien directement. Le signal module une porteuse (généralement à 38kHz).

Bien, j'ai donc modifié un peu mon code, qui ne fonctionne toujours pas d'ailleur, et pourtant il devrait ..
Regardez : http://www.sbprojects.com/knowledge/ir/sirc.php
le protocole que je suis est pourtant bon non ? là je fais un teste sur un téléviseur sony

int led=3;

void setup()
{
   pinMode(led,OUTPUT);
}

void pulseOn(long microsecs)
{
   cli();
   
   while (microsecs > 0)
   {
      digitalWrite(led, HIGH); 
      delayMicroseconds(10);      
      digitalWrite(led, LOW); 
      delayMicroseconds(10);       
      microsecs -= 26;
   }
   
   sei();
}

void loop()
{
   delayMicroseconds(2400);
   
   pulseOn(1200);
   delayMicroseconds(600);
   //1
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(1200);
   delayMicroseconds(600);
   //1
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(1200);
   delayMicroseconds(600);
   //1
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(1200);
   delayMicroseconds(600);
   //1
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(600);
   delayMicroseconds(600);
   //0
   pulseOn(600);
   delayMicroseconds(600);
   //0
   
   delay(45);
}

Relis le post de fdufnews ...

Les temps d'exécution des fonction digitalWrite() sont du même ordre que tes délais.
Ca ne peut pas marcher.

je te propose 2 idées :

Solution 1 :

a) utiliser la lib digitalWriteFast (http://code.google.com/p/digitalwritefast/), ca va plus vite
b) dérouler les boucles pour éviter les tests
c) calibrer les délais en utilisant un oscilloscope ou un analyseur logique

Solution 2 :

a) Générer un 38kHz par un timer et sortir le 38kHz sur une broche (broches de sortie OC, voir la doc de l'ATmega)
b) Faire un ET logique entre ce 38kHz et un autre broche num qui pilotera les actif/inactif.
c) gérer dans ton code que les longueurs d'impulsions

B@tto:
Relis le post de fdufnews ...

@B@tto
Il l'a lut.
Il fait le 38kHz en soft : 26µs = 38kHz

@Kouaaks
PS: Apparemment tu as essayé de prendre en compte la durée d'exécution des digitalWrite puisque tu ne délaie que de 10µs au lieu de 13µs.
Est-tu sur que digitalWrite ne prend que 3µs ?
As tu vérifié la forme d'onde générée à l'oscilloscope ?

Bonjour, pour les delais, j'ai cherché un peu sur internet et j'ai trouvé que le temps d'éxécution était d'environ 3 µs et c'est pour cela que j'ai soustrait 3 à 13.
Par contre, je n'ai pas d'oscilloscope donc impossible pour moi de vérifier la forme du signal générée. :.

As tu une 2eme Arduino ?
Il est possible d'utiliser une Arduino en analyseur logique : Arduino Forum

Sinon il y a des solutions pas très chères :

Les instructions de boucle peuvent prendre du temps aussi. C'est pour cela que je conseille de les dérouler.
En utilisant micros() tu peux aussi mesurer le temps d’exécution, non pas des instructions élémentaires mais de la boucle.

Fait toi 2 fonctions : pulseOn600() et pulseOn2400() qui ne contiennent pas de boucle.

Cf le code ci attaché (vérifié avec mon analyseur logique : 604µs et 2425µs respectivement.

test_sirc.ino (4.43 KB)

Salut
Le codage de sony et le même que phillips, code RC5 ou RC6
le signal de la porteuse et en générale de 36KHz.
Regarde ici : A Multi-Protocol Infrared Remote Library for the Arduino

A+
chabot380

Chabot,

l'article que tu cite reste très imprécis : il dit (typically 36, 38, or 40KHz)
L'article que cite Kouaaks dit d'ailleurs 40kHz pour SIRC.

Kouaaks, si c'est bien 40kHz qu'il faut faire, et non pas 38kHz, il faut revoir les constantes.

Ci attaché code revu pour 40kHz

test_sirc_40kHz.ino (4.81 KB)

En lisant encore plus l'article, je vois :

  • Le pulse de start fait 2400µs
  • Le pulse de "1" fait 1200µs -> fonction a rajouter
  • Le pulse de "0" fait 600µs
  • Le rapport cyclique recommandé de la porteuse est de 1/4 ou 1/3

Il faut donc revoir PULSE_HIGH et PULSE_LOW pour avoir ce rapport cyclique au lieu d'un rapport 50/50.

Et ne pas oublier :

  • Les commandes sont répétées toutes les 45ms : 1 seule commande peut être ratée. Il est conseillé de répéter entre 2 et 4 fois chaque commande.

Bonjour

Cependant, mon téléviseur est un thomson et non un sony

Avec Thomson tout est possible !!
Selon les gammes, les sous-traitants éventuels..... le codage peut etre RC5 , RC6 ou tout simplement une variante de code NEC, Samsung....

Cependant, mon téléviseur est un thomson

La phrase qui tue
j'avais pas vu
quelle perte de temps

Il faut identifier le type de protocole
Scope obligatoire

Merci à tous pour vos réponses, je vais me pencher sur ce que vous m'avez dit et tester tous ça de ce pas. :slight_smile:

Salut

Pour ton information, j'ai réussis a émuler la telecommande de mon air climatisé (c'est un protocol assez compliqué)
Pour les timings précis, j'ai du faire plein de tests (essais et erreurs)
Pour cela, j'ai juste branché un recepteur infrarouge sur ma carte son et j'ai pu voir si mes signaux etait trop court, ou trop long et ajuster en conséquence.

Voici le schema que j'ai utilisé et qui a bien fonctionné:

Du coté software, j'ai utilisé audacity.

Bonne chance.

Ah oui je vois, interessant ça ! Merci

Kouaaks:
Ah oui je vois, interessant ça ! Merci

bonsoir
la librairie IrRemote

propose en exemple en programme de test qui permet de voir si la telco émet déjà sur des protocoles
courants :
NEC
SONY
RC5
RC6
SHARP
PANASONIC
JVC
SANYO
MITSUBISHI

Bonsoir
Ton télé thomson vieux ou récent ?
Thomson ne fabrique plus de télé depuis un bon moment !
C'est du Vestel fabriqué en Turquie.
Vestel utilise le code RC5/6, donc 36KHz.
J'ai travaillé plus de 35 ans dans le dépannage télé !!

A+
chabot380

Bonsoir, c'est un écran plat donc assez récent. Merci de l'information ! :slight_smile:
Sinon j'ai bien vu la librarie IrRemote, mais je souhaiterai le faire moi meme et non passer par une librairie.
Je me pencherai ce week end sur ce que vous m'avez donné, les différents schéma et code que j'observe un peu mieux.
Bonne soirée

Bonsoir! J'arrive avec de bonnes nouvelles :slight_smile:

Tout d'abord, grace à vos informations j'ai pu regarder le signal de ma télécommande via Audacity, et je l'ai bien annalysé et ce n'était en effet pas le meme que le signal qu'envoyait l'arduino.

Je me suis donc adapté mes propres réglages avec quelques tests, et tout marche parfaitement bien, j'ai du modifier la fréquence d'envoie et les impulsions de la LED IR afin d'obtenir au mieux le meme signal envoyé par ma télécommande, voyez ça :

Casiment identique, je vous met mon code :

int led=2;

void setup()
{
   pinMode(led,OUTPUT);
}

void pulseOn(long microsecs)
{
   cli();
   
   while (microsecs > 0)
   {
      digitalWrite(led, HIGH); 
      delayMicroseconds(10);      
      digitalWrite(led, LOW); 
      delayMicroseconds(10);       
      microsecs -= 14;
   }
   
   sei();
}

void TRAME_IR_SEND(int tr[13])
{
   for (int i=0; i<13; i++)
   {
      pulseOn(tr[i]);
      delayMicroseconds(530);
   }
}

void loop()
{
   delayMicroseconds(2400);
   
   int trame[13]={1200,630,320,630,320,630,320,320,630,320,320,320,320};
   TRAME_IR_SEND(trame);
  
   delay(23);
}

(du coup, je n'ai meme pas utilisé d'autre librairie)

Merci à tous, problème résolu.