RF Protokoll - JULA-Anslut
JULA 'Anslut' protokoll
Inledning
JULA har en serie självlärande fjärrstyrda uttag i serien 'Anslut', liknande NEXA RF_Protokoll_-_Nexa_självlärande. De säljs idag, September 2010, för 99kr för ett paket med 3 on/off-mottagare och en fjärrkontroll. Ett bra pris för en kul leksak som är perfekt för lite hacking.
Teknikdetaljer
Kontroldata skickas på en 433.92MHz radiolänk. Modulationen är en simpel on/off modulation av bärvågen, vilket gör att man kan använda i stort sett alla 433.92MHz sändare, FM eller AM spelar ingen roll.
Sändarkretsen är en Holtek HT46R01T3 [1] som internt består av två delar, en MCU och en sändare. MCU'n skickar data till sändaren på en I/O pinne som är internt kopplat. Men denne pinne är delat med vanlig I/O och tillgänglig på utsidan av kretsen. Då MCU'n har en separat spänningsförsörjning, kan man koppla bort denna, och då går det att modulera sändaren externt.
Pin 12 på kretsen är VCC till MCU'n. Denna pinne lyftas från kretskortet, eller klipps av. På Pin 1 kan man nu modulera sändaren med ett 3.3V signal.
Det intressanta med dessa självlärande system, är att de användar en unik kod för varje fjärr. I detta fall är koden 26 bitar lång. Det betyder att man, om man själv konstruerar data med en CPU eller PC, kan ha ett mycket stort antal enheter och använda olika koder för varje (eller för grupper). Det enda problem i denna sammanhang är att man då inte kan använda den "vanliga" fjärrkontroll.
Bit format
'0' bit: _____ | | | | | |_____ |-----|-----| T T '1' bit: _____ | | | | | |_________________________ |-----|-------------------------| T 5T 'START' bit: _____ | | | | | |__________________________________________________ |-----|--------------------------------------------------| T 10T 'STOP' bit: _____ | | | | | |_______________________ . . . ____ |-----|----------------------- . . . ----| T 40T T = 250 us (5T = 1250 us) (10T = 2500 us) (40T = 10 ms)
Bitkodning
Data på länken är "kodat" så att för varje databit skickas det två bitar på radiolänken. '0' => '01' skickas '1' => '10' skickas
Exempel: För dataströmmen 0111, skickas det 01101010 över radion.
Paketformat
Varje datapaket består av en startbit föld av 26 + 2 + 4 (totalt 32 databitar) och avslutas med en stopbit.
För varje knapptryckning skickas det likadana 3 datapaket.
HHHH HHHH HHHH HHHH HHHH HHHH HHGO EEEE
H = De första 26 bitar är kod som är unik för varje fjärrkontroll och det är denna "home" kod, som mottagarna lär sig att känna igen.
G = Gruppkommando, denna bit är satt till 1 om kommandot är för hela gruppen.
O = On/Off bit. Satt till 1 för on, 0 för off.
EEEE = Enhet som ska tändas/släckas. Enhetsnumet är "inverterat", 1111 = enhet 0, 1110 = enhet 1, o.s.v.
Kodexempel
Här är ett kodexempel som slår en enhet av och på varje 500 ms :
// // JULA protokoll exempel för ATmega88 // // Jesper Hansen, Sept. 2010 // #include <avr/io.h> #define MY_HOMECODE 0x9394ff80 #define RF_ON PORTB |= (1<<0) #define RF_OFF PORTB &= ~(1<<0) #define TSHORT 250 // 250 #define TLONG (TSHORT * 5) // 1250 #define TSTART (TSHORT*10) // 2500 #define TSTOP (TSHORT*40) // 10000 #define REPEATS 3 #define TIMERRESOLUTION 542 //nS // busy wait // up to 35.5 mS void twait(uint32_t us) { us *= 1000; us /= TIMERRESOLUTION; TCNT1 = 0; while (TCNT1 < (us & 0xFFFF)); } // // set a level on the output pin and delay // void set_level(uint8_t polarity, uint16_t time) { if (polarity) RF_ON; else RF_OFF; twait(time); } // // output a '1' bit // void one_bit(void) { set_level(1, TSHORT); set_level(0, TLONG); } // // output a '0' bit // void zero_bit(void) { set_level(1, TSHORT); set_level(0, TSHORT); } // // send a 32-bit sequence, including start and stop bits // void shift_out(uint32_t data) { uint8_t bit; // send lead-in set_level(1, TSHORT); set_level(0, TSTART); // send data for (bit=0;bit<32;bit++) { if (data & 0x80000000) // one-bit { one_bit(); zero_bit(); } else { zero_bit(); one_bit(); } data <<= 1; } // stop bit set_level(1, TSHORT); set_level(0, TSTOP); } // // send an RF command // void send_data(uint32_t id, int group, int onoff, int channel) { int i; for (i=0;i<REPEATS;i++) { id &= 0xFFFFFFC0; // mask off ID part id |= ((group & 1) << 5); // add group bit id |= ((onoff & 1) << 4); // add on/off bit id |= ((~channel) & 15); // add channel addressing shift_out(id); // send the pattern } } void delayms(uint16_t v) { while (v--) twait(1000); } int main(void) { // start timer 1 // CPU clock is assumed to be 14.7456MHz in this example TCCR1A = 0; TCCR1B = (1<<ICNC1) | (1<<ICES1) | 2; // clk / 8 -> 542nS DDRB |= (1<<0); // set RF modulator pin as output while (1) { send_data(MY_HOMECODE, 0, 0, 0); delayms(500); send_data(MY_HOMECODE, 0, 1, 0); delayms(500); } }