Capteur infrarouge pour clone Saleae


Voici un moyen de décoder des signaux infrarouge depuis un clone de Saleae.
J’avais besoin de décoder des signaux infrarouges pour reverse le protocole d’une télécommande un peut spéciale.

Le Principe

Afficher les trames IR de manière ultra précise .
Il se compose d’un clone SALEAE (ou usbee), d’un récepteur IR,il faudra aussi un switch et un bout de fil.

Montage

Pour le montage on gratte les pistes sous le PCB en dessous du port usb le 5v et la masse.
Puis on y soude le capteur IR.
puis on prend la pâte restante et on la relie au switch.
pour le switch on gratte le plan de masse du PCB et on s’en sert pour souder l’interrupteur en
place, la pâte restante du switch on la soude sur le channel 1.

Modele 3D

Modele 3D

Il vous faudra PulseView ainsi que le script plus bas.
Bien que PulseView dispose deja d’un décodeur IR intégré celui ci n’apprécie pas les longueur de code exotiques.

Premiere chose on branche le dispositif a notre mac.
On lance PulseView

On le configure comme suit

et D0 comme suit avec la detection de front descendant

Puis on clique sur run situé en haut a gauche

on appuis sur le bouton voulu du dispositif IR et on obtient 

Maintenant l’enregistrement du fichier en .vcd

On lance maintenant le script ou l’application compilée pour mac et on entre le chemin du fichier

Et on clique sur OK et voila le fichier decodé avec touts les details.

Script de decodage:

Voici le petit script python permetant de decoder les trames et sa version compilée pour macOS

from Tkinter import *                                           #Importation du module qui permet de creer des fenetres
def openFile():                                                 #Fonction appellee par le bouton "Buttfind"
    FileName = EntryNomFile.get()                               #recupère le nom du fichier a ouvrir et efface l'entry
    EntryNomFile.delete(first=0,last=100)                       #recupere la precision rentree et si il y en a aucune, alors mettre la precision a 100
    precision = EntryPrecision.get()
    EntryPrecision.delete(first=0,last=100)
    if precision:
        precision = int(precision)
    else:
        precision = 100
    i=0                                                         #initialise les tableaux et les variables
    tabTime=[]
    tabValue=[]
    tabDiffTimeValue=[]
    moyennePrecision0=0
    number0=0
    resultatBin=""
    moyenneOneOn=numberOneOn=0
    moyenneZeroOn=numberZeroOn=0
    moyenneOneOff=numberOneOff=0
    moyenneZeroOff=numberZeroOff=0
    if FileName:                                                #verifie si le nom rentre n'est pas vide
        file=open("Files/"+FileName,"r")                                 #ouvre le fichier
        for ligne in file:                                      #Boucle s'executant pour chaque ligne dans le fichier
            if "$" not in ligne and "Acquisition" not in ligne:
                ligne = ligne[1:]                               #retire toutes les lignes commençant avec un $ ou avec le mot Acquisition
                ligne = ligne[:-2]
                time = ligne[:-2]                               #Retire les caracteres de fin et de début
                value = ligne[-1:]
                tabTime.append(int(time))                       #rajoute les valeurs time et value dans leur case respective dans le tableau
                tabValue.append(int(value))
                if i>=1:                                        #A partir du moment ou i est egale a 1 : on calcul la difference entre les Time
                    tabDiffTimeValue.append(int(tabTime[i]-tabTime[i-1]))
                i=i+1                                           #incremente la valeur de i, qui corresponda l'index courant du tableau
        tabTime.pop(len(tabTime)-1)                             #Supprime la derniere valeur ainsi que les 2 premieres
        tabValue.pop(len(tabValue)-1)
        tabTime.pop(0)
        tabValue.pop(0)
        HeaderOff=tabDiffTimeValue[0]
        tabDiffTimeValue.pop(0)
        tabTime.pop(0)
        tabValue.pop(0)
        HeaderOn=tabDiffTimeValue[0]
        tabDiffTimeValue.pop(0)
        for i in range (0, len(tabValue)):                      #calcul la moyenne quand la courbe est a 0
            if tabValue[i]==0:
                moyennePrecision0+=tabDiffTimeValue[i]
                number0+=1
        moyennePrecision0 = moyennePrecision0/number0
        for i in range (0, len(tabValue)):                      #Verifie si c'est un 0 ou un 1
            if tabValue[i]==1:
                if tabDiffTimeValue[i] >= moyennePrecision0+precision:
                    resultatBin= resultatBin+"1"
                    moyenneOneOn+=tabDiffTimeValue[i]
                    numberOneOn+=1
                    moyenneZeroOn+=tabDiffTimeValue[i-1]
                    numberZeroOn+=1
                else:
                    resultatBin= resultatBin+"0"
                    moyenneOneOff+=tabDiffTimeValue[i]
                    numberOneOff+=1
                    moyenneZeroOff+=tabDiffTimeValue[i-1]
                    numberZeroOff+=1
        resultat=int(resultatBin, 2)                            #Affiche le resultat en binaire, puis en hex
        resultatBin=bin(resultat)
        LabelBinaire.configure(text=resultatBin)
        resultatHex=hex(resultat)
        LabelHexadecimal.configure(text=resultatHex)
        LabelHeaderOn.configure(text=HeaderOn)
        LabelHeaderOff.configure(text=HeaderOff)
        LabelOneOn.configure(text=int(moyenneOneOn/numberOneOn))
        LabelOneOff.configure(text=int(moyenneOneOff/numberOneOff))
        LabelZeroOn.configure(text=int(moyenneZeroOn/numberZeroOn))
        LabelZeroOff.configure(text=int(moyenneZeroOff/numberZeroOff))
fen=Tk()                                                        #creation de la fenetre (avec les widgets la composant, ainsi que sa taille et de son nom) visible par l'utilisateur
fen.title("IR Decoder")
#fen.maxsize(width=500,height=190)
#fen.minsize(width=500,height=190)
lblMenu=Label(text = "Fichier :").grid(column=0,row=0, padx=10, pady = 5)
EntryNomFile=Entry()
EntryNomFile.grid(column=1,row=0, padx=10, pady = 5)
lblMenu1=Label(text = "Precision (default 100) :").grid(column=0,row=1, padx=10, pady = 5)
EntryPrecision=Entry()
EntryPrecision.insert(0, "100")
EntryPrecision.grid(column=1,row=1, padx=10, pady = 5)
Buttfind=Button(text="OK", command = openFile).grid(column=2,rowspan=2,row=0, padx=10, pady = 5)
LabelBinaireInfo=Label(text="Binaire : ").grid(column=0,row=3, padx=10)
LabelBinaire=Label(text="0b00")
LabelBinaire.grid(column=1,row=3, padx=10)
LabelHexadecimalInfo=Label(text="Hexadecimal : ").grid(column=0,row=4, padx=10)
LabelHexadecimal=Label(text="0x00")
LabelHexadecimal.grid(column=1,row=4, padx=10)
LabelOn=Label(text="ON").grid(column=1,row=5, padx=10)
LabelOff=Label(text="OFF").grid(column=2,row=5, padx=10)
LabelHeader=Label(text="Header").grid(column=0,row=6, padx=10)
LabelHeaderOn=Label(text="0")
LabelHeaderOn.grid(column=1,row=6, padx=10)
LabelHeaderOff=Label(text="0")
LabelHeaderOff.grid(column=2,row=6, padx=10)
LabelOne=Label(text="One").grid(column=0,row=7, padx=10)
LabelOneOn=Label(text="0")
LabelOneOn.grid(column=1,row=7, padx=10)
LabelOneOff=Label(text="0")
LabelOneOff.grid(column=2,row=7, padx=10)
LabelZero=Label(text="Zero").grid(column=0,row=8, padx=10)
LabelZeroOn=Label(text="0")
LabelZeroOn.grid(column=1,row=8, padx=10)
LabelZeroOff=Label(text="0")
LabelZeroOff.grid(column=2,row=8, padx=10)
fen.mainloop()                                                  #Ouvre la fenetre