Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
jed
Inlägg: 4
Blev medlem: 14 december 2009, 11:07:58

Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av jed »

Jag köpte en pickit2 med en 16f690 för att fräsha upp mina (mycket) gamla kunskaper i mikrodatorteknik. Jag testade dom grundläggande grejorna som att blinka med en lysdiod, dimma den med pwm osv och det fungerar.

Nu vill jag läsa av en kanal på min mottagare, den skickar ut en puls som är hög 1.5-2.5ms, i perioder på ca 20ms.
Just nu vill jag bara läsa av en kanal, senare kanske jag vill läsa av 2 eller 3 (jag har 3 kanaler lediga just nu), jag är lite osäker på om 16f690 har 1 eller 2 pwm kanaler. Blir inte riktigt klok på databladet...

Mitt första problem är att jag inte är säker på att jag har valt rätt ben som inkanal, jag har satt den på pinne 5 (RC5/CCCP1/P1A) och sen har jag satt 3 lysdioder på pinne 11-13 för att indikera vilken signal jag får in.
Har jag valt rätt ben för att läsa av en inkommande PWM-signal? Jag har sökt massor på google, läst en hel del här inne och i databladet men inte kommit fram till vilket/vilka ben som kan läsa av en pwm. Ben 5 kan iaf skicka ut en pwm :)


Jag testar ett språk som heter JALv2 som påminner en del om pascal, lätt att komma igång i och bör klara av det jag är ute efter. Det är opensource och kompilatorn är gratis oavsett storlek på koden. Planerar att gå över på C, kanske assembler senare men har tyvärr inte tid till det nu (frugan tycker jag hackar för mycket redan nu :)
När jag får det att fungera ska jag använda en switch som har tre lägen och tända/släcka navigationsljus/landningsljus på en quadcopter.

Här är koden:

Kod: Markera allt

include 16f690
pragma target CLOCK     8_000_000
pragma target OSC       INTOSC_NOCLKOUT
pragma target WDT       disabled
enable_digital_io()                             
include pulse


alias   pulse1      is pin_C5
pin_C5_direction    =  input


alias   led1        is pin_B4
alias   led2        is pin_B5
alias   led3        is pin_B6
pin_B4_direction    =  output
pin_B5_direction    =  output
pin_B6_direction    =  output

led1 = off
led2 = off
led3 = off


var word duration  = 0

forever loop
   hi_pulse_in (pulse1, duration)

   if (duration > 0 & duration < 250) then
      led1 = off
      led2 = off
      led3 = off
   elsif (duration > 251 & duration < 500) then
      led1 = off
      led2 = off
      led3 = on
   elsif (duration > 501 & duration < 750) then
      led1 = off
      led2 = on
      led3 = off
   elsif (duration > 751 & duration < 1000) then
      led1 = off
      led2 = on
      led3 = on
   elsif (duration > 1001 & duration < 1500) then
      led1 = on
      led2 = off
      led3 = off
   elsif (duration > 1501 & duration < 2000) then
      led1 = on
      led2 = off
      led3 = on
   elsif (duration > 2001 & duration < 2500) then
      led1 = on
      led2 = on
      led3 = off
   elsif (duration > 2501 & duration < 3000) then
      led1 = on
      led2 = on
      led3 = on
   end
end loop
edit: 1 eller 2 pwm kanaler ska det vara, inte 2 eller 3
Senast redigerad av jed 5 augusti 2010, 21:49:43, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av Icecap »

Det är ganska vansinnigt att köra med JAL men det är ditt val, det är inte kompatibelt med något annat, supporten är icke-existerande och portning går inte.

Men OK, du vill fånga pulsens längd. I mitt tycke har du vald den sämsta lösning där också, du har en Capture-enhet i PIC'en och borde använda den istället!

Dock är den lite besvärlig då den bara kan fånga antingen stigande flank eller fallande flank men jag har ett projekt som fångar båda vid att kolla nivå när interrupten kommer och sedan styra allt efter detta, den byter helt enkelt flank-läge i iSR'n. Det fungerar i övrigt jättebra och är såld i ett antal exemplar.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av blueint »

Under förutsättning att pulslängden är längre än exekveringstiden för interruptrutinen.

Ingen möjlighet att nyttja två capture enheter parallellt, en för positiv- och en för negativ flank.

Utgår från att capture enheten driver en räknarare från klockan och sparar räknarens värde vid flank "event". Varvid detta värde kan läsas senare.
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av Icecap »

RC-servo pulser bör definitivt vara längre än ISR-tiden, i annat fall kör man antingen med en sjukt låg klocka eller en mycket speciell RC-servo som avviker kraftigt från de vanliga 1,5ms ±0,5ms.

Så att byta flank under ISR-delen är inget problem alls!
jed
Inlägg: 4
Blev medlem: 14 december 2009, 11:07:58

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av jed »

Jag kör med jal för att det är enkelt att komma igång med igen, det var 16 år sen jag skrev assembler sist så jag minns inte så mycket av det, C var runt 10 år sen ;) Planen är som sagt att gå över till c/assembler senare när jag har mer tid.

Det kommer inte att kopplas in något servo, jag vill bara veta hur lång pulsen är för att kunna dra 1, 2 eller 3 relän (dvs, sätta någon av utgångsportarna hög). Dom servon som finns styrs av mottagaren.

Jag kör med klockan på 8MHz, så jag bör definitvt hinna läsa av den i interuptet.

Ska kolla igenom databladet efter capture enheten och hur den används.


Har ni någon koll på vilken/vilka pinnar som kan användas för att läsa av inkommande pwm-signal? Vilken ingång som helst? Bara CCCP1 (som jag har nu)?
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av Marta »

Koppla in så Du kan fånga den odekodade signalen i mottagaren. Från detektorn matas den in på antingen en räknare eller ett shiftregister som sedan är kopplat till de enskilda utgångarna, så den är lätt att plocka ut.

Du får då samma flank hela tiden, samt alla överföringsfunktioner tillgängliga på en gång. Nackdelen är att Du måste hantera synkning och separation själv, men det är inget svårt alls.

Stoppa ner JAL i ett djupt hål och lägg något riktigt tungt över. Annars kommer Du snart att ångra all tid och ansträngning Du spillt på detta.
Rekommenderar starkt att Du använder assembler, det är IMHO det kraftfullaste alternativet när Du skall göra denna typ av applikation. Allt annat blir bara till en vägg av begränsningar som Du får lägga ansträngning på att kringgå, finns ingen tid att vinna på att kämpa med de klumpiga lösningar som framtvingas. Dessutom slukas det processorkraft helt i onödan.
Användarvisningsbild
Andy
Inlägg: 5893
Blev medlem: 26 september 2004, 18:24:52
Ort: Södern

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av Andy »

"Dessutom slukas det processorkraft helt i onödan."

På vilket sätt slukas det kraft från processorn? Koden (JAL) kompileras innan den körs, är tolken dåligt skriven eller varför?
T ex kompilerad PICBasic drar ingen extra kraft och blir inte långsammare än assembler och tar ibland t o m mindre plats!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av sodjan »

Alltså, verken JAL, BASIC eller C drar mer kraft än ASM om man i ASM skriver
samma sak som den ASM som de olika kompilatorerna genererar. Självklart...

Problemet är (speciellt för en nybörjare) att det kan vara väldigt svårt att
veta/bedöma vilken kod olika "burkade" (libar) funktioner kommer att generera.
Därav att vad som på pappret igentligen är samma applikation/funktion kan
uppträda väldigt olika beroende på verktyg (och även beroende på hur de
olika verktygen används).

Det är ett ofta förekommande missförstånd att bara för att JAL/BASIC/C/whatever
har en del trevliga inbyggda funktioner så behöver man inte lära sig eller förstå
vad som igentligen händer. Det är fel. Det är faktiskt mer jobb att lära sig
programmera med JAL/BASIC/C från början eftersom man både behöver lära
sig hur processorn fungerar och lära sig hur verktyget fungerar på samma gång.
Det upplevs kanske inte så i början, men det visar sig med tiden.

> ...är tolken dåligt skriven eller varför?

JAL har ingen tolk, det är en kompilator.

> jag är lite osäker på om 16f690 har 1 eller 2 pwm kanaler...

Hur det än är med det, så har det inget med det aktuella problemet att göra.
PWM (notera versaler) modulen används av PIC processorn gör att generera
PWM signaler, inte för att göra mätningar på inkommande PWM signaler. Det
gör med timers, capture o.s.v. beroende på hur det akutella problemet ser ut.

Så här skulle jag tänka:

- Vänta på start av pulsen (kan ske på olika sätt beroende på vad koden/processorn gör för övrigt).
- Starta en timer när pulsen kommer.
- Vänta på slut av puls (samma sak här, kan göras på olika sätt)
- Stoppa timern.
- Jämför timer värdet med dina tre "gränser".

Genom att välja timer prescaler o.s.v smart så underlättar man sista steget ovan.
D.v.s så att du får värden i timern som är enkla att kolla.

Sen vill man sannolikt ha lite hysteres så att utgångarna inte står och
"fladdrar" om pulsen ligger på eller nära en gräns o.s.v...
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av vfr »

Som Marta säger, är smart! Om du behöver flera kanaler så är det mycket bättre att mäta på den sammansatta signalen där du har alla kanalerna. Då behöver du bara en ingång på mikrokontrollern för alla kanalerna. Sedan lite programvara som sorterar ut rätt kanaler ur signalen.

Nu pratar vi iofs om en tradionell analog radiostyrning. En modern digital dito med PCM-överföring fungerar helt annorlunda och har säkerligen ingen sådan sammansatt signal, eftersom radiosignalen överförs helt annorlunda.

Fast principen för att mäta av pulslängden är densamma oavsett om det är en muxad signal eller den sammansatta.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Läsa av r/c-mottagare (inkommande pwm i 16f690) med jal

Inlägg av Marta »

Ett annat sätt som kanske är enklast för en nybörjare skulle kunna vara att använda en grindad räknare samt skippa allt vad interrupt heter. Det underlättar både initiering och programlogik en hel del så massor av felkällor försvinner.

Anslut en av de ordinarie utgångarna så att den styr den grindade räknaren att räkna då den är 1, samt att det även går att läsa av om ingången är 1 eller 0.

Gör sedan detta i programmet:

1. Nolla räknaren.
2. Vänta på att ingången blir 1.
3. Vänta på att ingången blir 0.
4. Läs av räknaren.
5. Jämför med föregående sparade värde, sätt OK-flagga om avvikelsen är liten.
6. Spara nytt föregående värde.
7. Gör det som skall göras om värdet var OK.
8. Upprepa från 1.


Angående ineffektiv kod så genereras det generellt en hel del onödigt krafs av s.k. högnivåspråk. En bra optimerande C-kompilator kan väl åstadkomma ett drägligt resultat, men (generellt sett) ju mindre och mera udda produkten är, ju mera anledning finns det att befara ett dåligt resultat.
Skriv svar