Identifiera IR-signaler
Identifiera IR-signaler
Skulle behöva tips på länkar eller hur jag ska programmera en pic för att kunna identifiera 4 olika amplitudmodulerade ir-signaler som blinkar med olika periodtid. 50% on 50% off.
- Schnegelwerfer
- Inlägg: 1863
- Blev medlem: 8 november 2004, 13:46:56
- Schnegelwerfer
- Inlägg: 1863
- Blev medlem: 8 november 2004, 13:46:56
Ok.ankan skrev:Sändaren amplitudmodulerar (on/off) en 38kHz "bärvåg" med 4 olika frekvenser med perioder mellan 1 - 10 ms.
(Skrev fel först)
Om du tar emot IR-signalen med en vanlig, avstämd mottagare för 38kHz kommer du att få ut en fyrkantsvåg med 4 olika frekvenser beroende på vilken signal du tar emot.
Dessa 4 frekvenser kan du nu detektera i din uC genom att starta en timer som jag beskrev tidigare... men om frekvenserna är blandade blir det ju lite mer komplicerat.
Jag har inte så bra koll på hur timer fungerar. Finns ju 3st i PIC16F628an tex. Jag förstår inte riktigt vad CCP gör men det låter som att det är något jag skulle kunna ha användning för.
Någon som kan förklara lite mer hur jag ska gå till väga. Jag måste mäta av periodtiden på insignalen och sedan jämföra med 4st olika intervall för att bedömma vilken av de 4 frekvenserna signalen är på.
Någon som kan förklara lite mer hur jag ska gå till väga. Jag måste mäta av periodtiden på insignalen och sedan jämföra med 4st olika intervall för att bedömma vilken av de 4 frekvenserna signalen är på.
CCP är Capture - Compare - PWM. Du behöver Capture-funktionen.
Det Capture gör är att den, på valda flank (vi säger stigande här) , latchar in Timer1 värdet och ger en interrupt om man har vald det.
Man kan då göra så at man sparar förra tid och subtraherar från denna tiden, då får man differensen = pulsbredden. Håller man sig under Timer1 totala cyklustid kan man göra det utan så mycket mankemang (16 bit - 16 bit) men jag har ett projekt som kan mäta 34359 sek (9:32:39) med en upplösning på 8µs!
Alltså för varje CCP-interrupt: (C-kod)
unsigned int Previous, Now, Difference; // Variabla att jobba med, 16 bit
PIR1.CCP1IF = 0; // Jupp, jag har den
*(byte*)&Now = CCPR1L; // Kopiera låga byten till 'Now'
*(byte*)(&Now + 1) = CCPR1H; // Kopiera höga byten till 'Now'
Difference = Now - Previous; // Räkna ut pulsbredden
Previous = Now; // Spara denna tid till senare
// Sedan gör man med 'Difference' vad som behövs, delar in den i 4 grupper eller så
Det Capture gör är att den, på valda flank (vi säger stigande här) , latchar in Timer1 värdet och ger en interrupt om man har vald det.
Man kan då göra så at man sparar förra tid och subtraherar från denna tiden, då får man differensen = pulsbredden. Håller man sig under Timer1 totala cyklustid kan man göra det utan så mycket mankemang (16 bit - 16 bit) men jag har ett projekt som kan mäta 34359 sek (9:32:39) med en upplösning på 8µs!
Alltså för varje CCP-interrupt: (C-kod)
unsigned int Previous, Now, Difference; // Variabla att jobba med, 16 bit
PIR1.CCP1IF = 0; // Jupp, jag har den
*(byte*)&Now = CCPR1L; // Kopiera låga byten till 'Now'
*(byte*)(&Now + 1) = CCPR1H; // Kopiera höga byten till 'Now'
Difference = Now - Previous; // Räkna ut pulsbredden
Previous = Now; // Spara denna tid till senare
// Sedan gör man med 'Difference' vad som behövs, delar in den i 4 grupper eller så
> Jag måste mäta av periodtiden på insignalen och sedan jämföra med 4st olika intervall
Vilka intervall ? Hur mycket skilljer de sig från varandra ?
Med lite smart programmering kan man kanske göra detta
väldigt enkelt. T.ex gnom att välja lämplig "fart" på TMR1 direkt
genom bit-test på lämplig bitar i "captured" värded direkt kunna
säga vilken av de 4 perioderna det var. I så fall behövs ingen
direkt beräkning eller matchnig mot olika intervall.
Vilka intervall ? Hur mycket skilljer de sig från varandra ?
Med lite smart programmering kan man kanske göra detta
väldigt enkelt. T.ex gnom att välja lämplig "fart" på TMR1 direkt
genom bit-test på lämplig bitar i "captured" värded direkt kunna
säga vilken av de 4 perioderna det var. I så fall behövs ingen
direkt beräkning eller matchnig mot olika intervall.
Något gör så att det inte lirar..
Får aldrig CCPR1L eller CCPR1H att ändras.
De ska väll spara aktuella värdet i TIMER1 när det kommer en pulsstart eller pulsslut (beroende på konf) men det händer inget.
TIMER1 jobbar på och jag har en switch på RB0 som jag switchar fram och tillbaka utan resultat.
RB0 är konfad i MPLAB för CCP1 Mux och CCP1CON är konfad 0b00000101.
GIE och PEIE är självklart enablade också samt CCP1IE.
Jag kan sätta CCP1IF till 1 under simulering och det händer ändå inget.
Får aldrig CCPR1L eller CCPR1H att ändras.
De ska väll spara aktuella värdet i TIMER1 när det kommer en pulsstart eller pulsslut (beroende på konf) men det händer inget.
TIMER1 jobbar på och jag har en switch på RB0 som jag switchar fram och tillbaka utan resultat.
RB0 är konfad i MPLAB för CCP1 Mux och CCP1CON är konfad 0b00000101.
GIE och PEIE är självklart enablade också samt CCP1IE.
Jag kan sätta CCP1IF till 1 under simulering och det händer ändå inget.
> Skrev fel.. Menade RB3...
Hm, är det det enda som är fel ?
Det är mycket bättre att du *visar* vad du har gjort istället för att
försöka *beskriva* det.
Fixa ett kort "test-case" som uppvisar de problem du beskriver.
Skala bort allt som inte har med problemet att göra.
Se till att det är kommenterat så att det framgår vad du *tänkte*
när du skrev koden, ifall det inte stämmer överens (inte ovanligt)...
Hm, är det det enda som är fel ?
Det är mycket bättre att du *visar* vad du har gjort istället för att
försöka *beskriva* det.
Fixa ett kort "test-case" som uppvisar de problem du beskriver.
Skala bort allt som inte har med problemet att göra.
Se till att det är kommenterat så att det framgår vad du *tänkte*
när du skrev koden, ifall det inte stämmer överens (inte ovanligt)...
> Någon som kanske har någon bra länk för info om hur man sätter upp CCP.
http://ww1.microchip.com/downloads/en/D ... 40044D.pdf
Och igen,
fixa ett kort "test-case" som uppvisar de problem du beskriver, det skulle underlätta...
http://ww1.microchip.com/downloads/en/D ... 40044D.pdf
Och igen,
fixa ett kort "test-case" som uppvisar de problem du beskriver, det skulle underlätta...