Avkoda SonyEricsson IR-fjärr (med AVR)

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Användarvisningsbild
13th.Marine
EF Sponsor
Inlägg: 7265
Blev medlem: 31 december 2004, 16:26:37
Ort: Trelleborg

Avkoda SonyEricsson IR-fjärr (med AVR)

Inlägg av 13th.Marine »

När jag köpte min laddningsstation till telefonen fick jag med en liten gullig fjärr som man tydligen skulle styra den med, något som är helt irrelevant för mig, däremot kam jag snabbt på iden att använda den till mitt förstärkarprojekt,.

Naiv som man är så fixade jag fram ett program som avkodar RC5-protokollet, men efter lite mätningar med skåpet så visar det sig att den använder inte alls RC5 utan något "hemmaknåpat" protokoll. Istället för att skicka samma kommando om och om igen så skickar den kommandot först, sedan skickar den ett kortare paket a'la "fortfarande intryckt".

Eftersom det är IR så har jag aktivt låg på ingången.

Preamblen eller vad jag ska kalla det har jag avkodat till:
X (9ms) Y
-----_______-----_- ....
Där Y varierar beroende på om den är en ny knapptryckning eller inte, är Y halva X så är den ett nytt kommando, är Y en fjärdedels X så är knappen fortfarande intryckt.
Är det ett nytt kommando så kommer det 32bitar data där de första 16 är samma för alla kommandon, de efterföljande 8 är olika för de olika knapparna och de sista 8 är deras komplement.

Bitarna skickas sedan som olika långt intervall mellan pulserna, där jag har definierat en etta som kort intervall och en norra som långt. ett kort intervall är X/8 och ett långt är X/4.
ex.
0 1 1 0 1
----_--_-_-_--_-_------

För att avgöra allt detta så använder jag interrupt och en timer, när jag får ett interrupt så lagrar jag timervärdet och nollar det.
För att kolla vad som händer sparar jag undan några värden och skriver ut dessa på en LCD, när jag felsöker så går det inte riktigt som jag vill, när jag får rätt värden på X vägrar den räkna vidare, men får jag fel värde (1/20 på X) så funkar det oftast.

Jag har suttit ett tag och pillat med detta man kan inte komma fram till vad som är fel, är det någon som kanske kan se något?

Kod: Markera allt

#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#define IDLE 0
#define NEW 1
#define MODE 2
#define RECIEVE 3
#define DONE 4

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>   

#include <stdlib.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include "lcd_lib.h"

	volatile int STATE = IDLE;
	volatile int lenght = 0;
	volatile int recieved = 0;
	volatile int header = 0;
	volatile char data1 = 0;
	volatile char data2 = 0;
	volatile int temp, first, second = 0;
	volatile int ref, ref1, ref2, ref3 = 0;
	

// - - - - Main Loop - - - - //
int main (void) {
	init_lcd();
	init_ir();
	delay_ms(10);
	lcd_clear();
	sei();

	lcd_puts("ELLU WoRLD");
	delay_ms(2000);	
	//lcd_clear();
	while(1){
		asm volatile("nop");
	}
}
void init_ir()
{
	//Enable pin-change interrupt
	PCICR |= _BV(PCIE1);
	PCMSK1 |= _BV(PCINT13);   
	//Start timer
	//TCCR1B |= _BV(CS11) | _BV(CS10);
	
	//Init buffer 
}   

ISR(PCINT1_vect)
{
	

	//PORTD = 0b11111111;
	temp = TCNT1;
	TCNT1 = 0;

	//New input
	if((STATE == IDLE) && !(PINC & _BV(PC5))) {
		TCCR1B |= _BV(CS11) | _BV(CS10);
		TCNT1 = 0;
		STATE = NEW;
		return;
	}


	if((STATE == NEW) && (PINC & _BV(PC5))){
		lenght = temp;
		STATE = MODE;
		return;
	}

	//New command or button still pushed.
	if((STATE == MODE) && !(PINC & _BV(PC5))){

		ref = (lenght>>3) + (lenght>>2);
		ref1 = (lenght>>4);
		ref2 = (lenght>>3) + (lenght>>4);
		ref3 = (lenght>>2) + (lenght>>4);
		if((temp > ref) && (temp < (ref + ref3))){//New command
			first = temp;
			STATE = RECIEVE;
			recieved = 0;
			header = 0;		
			data1 = 0;
			data2 =  0;
			return;
		}
		else if(temp < ref){ // Still pushed
			STATE = DONE;
			//data2 = 0b00000000; 
			return;
		}
		else{ //Ellol
			STATE = IDLE;
			TCCR1B &= ~(_BV(CS11) | _BV(CS10));
			return;
		}


	}
	//Recieve Data
	if((STATE == RECIEVE) && !(PINC & _BV(PC5))){
		if((temp > ref1) && (temp < ref2)){ // Is '1'

			if(recieved < 16){
				header |= _BV(recieved);
			}
			else if(recieved < 24){
				data1 |= _BV(recieved-16);
			}
			else if(recieved < 32){
				data2 |= _BV(recieved-24);
			}
			else{
				STATE = DONE;			
			}
			recieved++;
		}


		else if((temp > ref2) && (temp < ref3)){// Is '0'

			if(recieved < 16){
				//header[recieved] = 0;
			}
			else if(recieved < 24){
				//data1[(recieved-8)] = 0;
			}
			else if(recieved < 32){
				//data2[(recieved-16)] = 0;
			}
			else{
				STATE = DONE;
			}
			recieved++;
		}
		else{ //Fel
			STATE = IDLE;
			TCCR1B &= ~(_BV(CS11) | _BV(CS10));
			//data2 = 0b11111111;
		}
		return;

	}
	//Print data
	if((STATE == DONE) && (PINC & _BV(PC5))){
		//data2 &= 0b00001111; //Mask irrelevant bits
		lcd_clear();
		lcd_dec(data2);
		lcd_puts("-");
		lcd_dec(lenght);
		lcd_puts("-");
		lcd_dec(ref);
		lcd_puts("-");
		lcd_dec(first);
		lcd_jumptosec();
		//lcd_puts("-");
		lcd_dec(ref1);
		lcd_puts("-");
		lcd_dec(ref2);
		lcd_puts("-");
		lcd_dec(ref3);
		lcd_puts("-");
		lcd_dec(recieved);
		//PORTD = data2;
		STATE = IDLE;
		TCCR1B &= ~(_BV(CS11) | _BV(CS10));
		return;	
	}
}

Migrus
Inlägg: 13
Blev medlem: 18 maj 2009, 12:32:22
Ort: Umeå

Re: Avkoda SonyEricsson IR-fjärr (med AVR)

Inlägg av Migrus »

Dagens onödiga inlägg (eftersom jag tror du redan listat ut hur de kodar)
http://users.telenet.be/davshomepage/sony.htm

När jag lekte med rc5 avkodning på en pic så debuggade jag genom att toggla output på en annan pinne och sedan läsa av båda med skopet för att hitta mina timing-fel. Du kanske kan lägga in något sånt i din interrupt rutin för att se att den körs och när den körs.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Avkoda SonyEricsson IR-fjärr (med AVR)

Inlägg av blueint »

Här är finns sannolikt en riktigt bra förklaring:
http://www.arcfn.com/2010/03/understand ... -lirc.html

Allmänt:
http://en.wikipedia.org/wiki/Consumer_IR

Sony använder 940 nm lysdioder och 40 kHz modulering har jag för mig.
Användarvisningsbild
13th.Marine
EF Sponsor
Inlägg: 7265
Blev medlem: 31 december 2004, 16:26:37
Ort: Trelleborg

Re: Avkoda SonyEricsson IR-fjärr (med AVR)

Inlägg av 13th.Marine »

Ah, den har jag inte hittat, jo ungefär så, men 32bitar långt.

Tror iofs jag löst det nu, signalerna låg väldigt nära undre tröskelvärdet vilket gjorde att vissa hamnade under värdet och det blev fel.
Det tråkiga är att det verkar som att det lätt blir fel överföringen.
Skriv svar