PPM dekoódolás

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

PPM dekoódolás

Hozzászólás Szerző: doncarlos »

Hello!

PPM dekódolást szeretnék megvalósítani egy m128cal. a PPM jel egy Futaba FC-16os modell rádióból származik. elvileg "szabvány" PPM. Egy hangkártyából infot kiszedő program (RCAudio a neve) felismeri a PPM-jelet annak mind a 8 csatornájával (6ot használok 2 üres). Tehát a csatornák adatait szeretném megkapni a m128cal.
annyit észrevettem az RCAudio programból "táplálkozó" AudioPPMView

program képén hogy a ppm jelek nálam a lentitől eltérően igy néznek ki:

Kód: Egész kijelölése

----    ---------    ---------    ---------    -----
    |  |         |  |         |  |         |  |
     --           --           --           --
(csak egy pl.ábra itt is van sync pulse ami olyan 10msec meg minden)

Találtam az mcselec forumán egy kódot ami hasonló célt szolgált:

Kód: Egész kijelölése

'============================================================================== 
' Vex Receiver Decode Example V1 
' By: Glen Aidukas 2008-08-22 
' Compiler: Bascom-AVR V1.11.9.2 
' 
' This is an example program for decoding the pulses that com from the VEX 
' robot RC receiver. 
' 
' Theory of operation: 
' 
' The VEX receiver output is a simple single wire signal using pulse width 
' modulated signals for each of the 6 channels. 
' There are 7 PWM pulses total.  The first being a sync pulse and then 
' followed by 6 more varying width pulses (one for each channel). 
' 
'  -              -    -    -    -    -    - 
' | |            | |  | |  | |  | |  | |  | |  ... 
'    ------------   --   --   --   --   --   -- 
' 
' |  sync pulse  | c1 | c2 | c3 | c4 | c5 | c6 |  next sync pulse... 
' 
' The sync pulse varies between (about) 6 and 12 mSecs long. 
' Then the other 6 pulses very between 1 to 2 mSecs long. 
' 
' Note: While the sync pulse varies the total for the complete cycle is always 
' 20 mSecs long or 50 complete cycles per second. 
'============================================================================== 
$regfile    = "attiny2313.dat" 
$crystal    = 8000000 
$hwstack    = 32 
$swstack    = 10 
$framesize  = 40 
$baud       = 38400           ' uart speed 

dim x       as byte           ' channel index for printing 
dim z       as byte           ' channel index for in side the isr 
dim chan(6) as word           ' holds the channel values (in uSecs) 
dim cnt     as word           ' hold the current pulse in the isr 
dim sync    as word           ' hold the sync value for debug (not needed) 

const SyncPulse = 5000        ' the sync pulse is somthing over 5000 uSecs 

' configure port 
config portb.6 = input        ' imput from vex (ICP) 
portd.6 = 1                   ' turn on pullup resistor (no external parts needed) 

' Configuring Timer1 for 1 uSec ticks - crystal 8000000 / 8 = 1 uSec 
Config Timer1 = Timer, Capture Edge = Rising, prescale = 8 
on capture1 PulseCapture_isr  ' main code for getting pulse values 
enable Capture1 
enable interrupts 

print chr(27) ; "[2J";        ' ansi clear screen... 
print "starting..." 

' Main loop... 
do 
   print chr(27) ; "[2;1H";                  ' move cursor to the second line 
   for x= 1 to 6 
     print "Chan"; x; ": "; chan(x); "    "  ' show the value of a give (x) channal 
   next 
   print "Sync : "; sync; "    "             ' show the leanth of the sync pulse 
   waitms 100 
loop 


' All work is handled in the following isr 
PulseCapture_isr: 
   cnt = Capture1             ' get the current pulse value 
   timer1= 0                  ' reset the timer for the next pulse 
   if cnt  > SyncPulse then   ' check for sync pulse 
      sync = cnt              ' save the current pulse value for debug 
      z=1                     ' set the index to the first channel 
   elseif z < 7 then          ' assign 1-6 and then wait for sync pulse 
      chan(z) = cnt           ' assign the pulse value to the proper channel 
      incr z                  ' next channel... 
   endif 
return 
a m128 eredetileg 11.0592mhzes kvarcrol ment de a példához átállitottam a belső 8mhzre. Csak sajnos a program csak 0-kat ir ki. a kezdeti fázisban véletlenül a vezetéket hozzáérintettem az rádio antennájához akkor minden kapott értéket szóval a program fut. a jelvezeték a m128 D6os lábára van kötve. a fenti kódon annyit változtattam még h átirtam a "6osokat 8asokra" hogy a megfelelő mennyiségü csatornát lássam. Van valakinek ötlete hogy mi lehet a megoldás? sajnos nem vagyok jártas ezekben a dolgokban :S

Előre is köszönöm a segítséget!

Üdv: Zsolti
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Itt elvan írva B6-ot veted bemenetnek, nem D6-ot?

' configure port
config portb.6 = input ' imput from vex (ICP)
portd.6 = 1 ' turn on pullup resistor (no external parts

:lol:
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

Hozzászólás Szerző: doncarlos »

Köszi hogy megnézted! Sajnos nem ez volt a gond mert ezt átirtam csak a másik gépen van a bascom (mert win7tel nem tudtam megetetni) és csak a netes kodot másoltam be ide amit meg nem javitottam. szoval a portd.6ot használom inputnak és ugy nem jó :cry:
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Nem sok ez: const SyncPulse = 5000 ' the sync pulse is somthing over 5000 uSecs
Ha jól értem, csak akkor kezd el venni, ha Capture1 nagyobb, mint 5000.
Próbáld így kiegésszítve?:

Kód: Egész kijelölése

Z = 1
Dim Vanjel As Byte                                          'Vétel kész jelzö
Vanjel = 0

' Main loop...
do
If Vanjel = 1 Then                                          'Csak akkor irki ha vett jelet
   print chr(27) ; "[2;1H";                  ' move cursor to the second line
   For X = 1 To 8
     print "Chan"; x; ": "; chan(x); "    "  ' show the value of a give (x) channal
   next
   print "Sync : "; sync; "    "             ' show the leanth of the sync pulse
   Vanjel = 0                                               'Ki irás megtörtént, várunk uj jelre
   '   waitms 100
End If
Loop


' All work is handled in the following isr
PulseCapture_isr:
   Stop Timer1
   cnt = Capture1             ' get the current pulse value
   timer1= 0                  ' reset the timer for the next pulse
   Start Timer1
   if cnt  > SyncPulse then   ' check for sync pulse
      sync = cnt              ' save the current pulse value for debug
      z=1                     ' set the index to the first channel
      Vanjel = 0
   Elseif Z < 9 Then                                        ' assign 1-6 and then wait for sync pulse
      chan(z) = cnt           ' assign the pulse value to the proper channel
      incr z                  ' next channel...
     End If
   If Z = 9 Then
   Vanjel = 1                                               'Jelezi, hogy megvan mind a 8 érték
   End If

Return
A hozzászólást 1 alkalommal szerkesztették, utoljára kapu48 2009. július 13. hétfő, 21:55-kor.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Esetleg timer1-est számlálónak configozni?
Config Timer1 = Counter, Capture Edge = Rising, prescale = 8

Nézd meg Robi, hogy csinálta:
Külső impulzus megszámlálása
http://avr.tavir.hu/modules.php?name=Co ... age&pid=18
:arrow:
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

Hozzászólás Szerző: doncarlos »

Megnézem mindjárt. amugy ha nagyobb mint 5ms akkor szinkronjel ha nem akkor az 1ik csatornánk jele elvileg.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Valahogy így kellene! Csak Z = 1 re indulna a chan(z) tömb feltöltése.
Így biztos csak szinkron jelre indulna.

Kód: Egész kijelölése

' All work is handled in the following isr
PulseCapture_isr:
   Stop Counter1
   cnt = Capture1             ' get the current pulse value
   timer1= 0                  ' reset the timer for the next pulse
   Start Counter1
   if cnt  > SyncPulse then   ' check for sync pulse
      sync = cnt              ' save the current pulse value for debug
      z=1                     ' set the index to the first channel
      Vanjel = 0
   Elseif Z > 0 And Z < 9 Then                              ' assign 1-6 and then wait for sync pulse
      chan(z) = cnt           ' assign the pulse value to the proper channel
      incr z                  ' next channel...
   End If
   If Z = 9 Then
   Vanjel = 1                                               'Jelezi, hogy megvan mind a 8 érték
   Z = 0                                                    'biztositja, hogy csak a szinkron jelre induljon
   End If

Return
:idea:
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

Hozzászólás Szerző: doncarlos »

átirtam de nem mér ez semmit! :cry:
itt egy kép a jelről hátha

Kép
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Az új programot is tedd ide! :?:
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

Hozzászólás Szerző: doncarlos »

ujprogram:

Kód: Egész kijelölése

$regfile = "m128def.dat"
'$crystal = 11059200
$crystal = 8000000
'$baud = 115200
$baud = 9600
$hwstack = 100
$swstack = 120
$framesize = 100

Config Graphlcd = 240 * 64 , Dataport = Portc , Controlport = Porta , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6       'LCD beállítás

Dim X As Byte                                               ' channel index for printing
Dim Z As Byte                                               ' channel index for in side the isr
Dim Chan(9) As Word                                         ' holds the channel values (in uSecs)
Dim Cnt As Word                                             ' hold the current pulse in the isr
Dim Sync As Word                                            ' hold the sync value for debug (not needed)

Const Syncpulse = 5000                                      ' the sync pulse is somthing over 5000 uSecs

' configure port
Config Portd.6 = Input                                      ' imput from vex (ICP)
Portd.6 = 1
' Configuring Timer1 for 1 uSec ticks - crystal 8000000 / 8 = 1 uSec
Config Timer1 = Counter , Capture Edge = Rising , Prescale = 8
On Capture1 Pulsecapture_isr                                ' main code for getting pulse values
Enable Capture1
Enable Interrupts
Cursor Off
Cls
Locate 1 , 1 : Lcd "PPM decoder"
Print Chr(27) ; "[2J";                                      ' ansi clear screen...
Print "starting..."
Z = 0
Dim Vanjel As Bit
Vanjel = 0
' Main loop...
Do
   Print Chr(27) ; "[2;1H";                                 ' move cursor to the second line
   For X = 1 To 9
     Print "Chan" ; X ; ": " ; Chan(x) ; "    "             ' show the value of a give (x) channal
   Next
   Print "Sync : " ; Sync ; "    "                          ' show the leanth of the sync pulse
   Print "vanjel: " ; Vanjel ; "    "
   Waitms 100
Loop


' All work is handled in the following isr
Pulsecapture_isr:
   Stop Counter1
   Cnt = Capture1                                           ' get the current pulse value
   Timer1 = 0
   Start Counter1                                           ' reset the timer for the next pulse
   If Cnt > Syncpulse Then                                  ' check for sync pulse
      Sync = Cnt                                            ' save the current pulse value for debug
      Z = 1
      Vanjel = 0                                            ' set the index to the first channel
   Elseif Z > 0 And Z < 9 Then                              ' assign 1-6 and then wait for sync pulse
      Chan(z) = Cnt                                         ' assign the pulse value to the proper channel
      Incr Z                                                ' next channel...
   End If
   If Z = 9 Then
      Vanjel = 1
      Z = 0
   End If
Return
azért nézek 9 csatornát mert a képen 9 látszik.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Tisztázzuk mit is, szeretnél Te?
Két bejövő lefutó él közti időt megmérni, és azt kiíratni?
Mert akkor az egész nem jó!
Timer1 Capture

A Timer1 konfigurálható ún. 'Capture' (kb. megfogás) módba is. Ez azt jelenti, hogy a Timer1 számolja a kontroller órajelét a meghatározott osztásviszony és az ICP1 bemeneten (PortD.4, 29. láb) impulzus érkezik a Timer1 regiszter tartalma a capture regiszterbe másolódik. Ezen az úton nagyon pontosan lehetséges mérni két impulzus közt eltelt időt.

Kód: Egész kijelölése

Config Timer1 = Timer, Prescale = 8, Capture Edge = Falling  ’Eső él

Dim Wtime As Byte
Dim Timercounter As Word

On Capture1 Captmr

Wtime = 100
Timercounter = 0

Enable Interrupts
Enable Capture1

Do
  Cls
  Lcd "phossz:  " ; Timercounter
  Waitms Wtime
Loop

Captmr:
  Timercounter = Capture1
  Timer1 = 0
Return

End
A megszakításrutinban a Timer1 értéke (Capture1 néven is ugyanezt jelenti) másolódik át a Timercounter-be. Ezután a Timer1 újraindul. A következő impulzus az ICP1 lábon érkezik, ugyanez történik. Így a Timercounter megméri a két impulzus közötti időt az ICP1 bemeneten.

Ezzel szemben T1 bemeneten:
Külső impulzus megszámlálása

A Timer1 konfigurálható úgy, hogy a kívülről érkező impulzusokat számlálja a T1 bemeneti lábakon.
Config Timer1 = Counter, Prescale = 8 , Edge = Rising|Falling

Megadható, hogy a számlálandó impulzus lefutó (falling) vagy felfutó (rising) élére (edge) lépjen. Valamint megadható, hogy hány bejövő impulzusonként lépjen egyet a számláló (prescale).
Jellemzően a Timer1 érdekesebb, mert ez a számláló 65535-ig "lépked", mikoris túlcsordulást és megszakítást okoz.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Kicsit finomítgattam:
Az ICP1 = PIND.4 (29.láb) EZ LEGYEN A JEL BEMENET!!!!

Kód: Egész kijelölése

$regfile = "m128def.dat"
'$crystal = 11059200
$crystal = 8000000
'$baud = 115200
$baud = 9600
$hwstack = 100
$swstack = 120
$framesize = 100

Config Graphlcd = 240 * 64 , Dataport = Portc , Controlport = Porta , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6       'LCD beállítás

Dim X As Byte                                               ' channel index for printing
Dim Z As Byte                                               ' channel index for in side the isr
Dim Chan(9) As Word                                         ' holds the channel values (in uSecs)
Dim Cnt As Word                                             ' hold the current pulse in the isr
Dim Sync As Word                                            ' hold the sync value for debug (not needed)

Const Syncpulse = 5000                                      ' the sync pulse is somthing over 5000 uSecs
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' configure port
'Az ICP1 = PIND.4 (29.láb) EZ LEGYEN A JEL BEMENET!!!!
Config Pind.4 = Input                                       ' imput from vex (ICP)
Portd.4 = 1
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' Configuring Timer1 for 1 uSec ticks - crystal 8000000 / 8 = 1 uSec
Config Timer1 = Timer , Capture Edge = Falling , Prescale = 8       'Eső élre
On Capture1 Pulsecapture_isr                                ' main code for getting pulse values

Enable Interrupts
Enable Capture1


Cursor Off
Cls
Locate 1 , 1 : Lcd "PPM decoder"
Print Chr(27) ; "[2J";                                      ' ansi clear screen...
Print "starting..."
Z = 0
Dim Vanjel As Bit
Vanjel = 0
' Main loop...
Do
If Vanjel = 1 Then
   Print Chr(27) ; "[2;1H";                                 ' move cursor to the second line
   For X = 1 To 9
     Print "Chan" ; X ; ": " ; Chan(x) ; "    "             ' show the value of a give (x) channal
   Next
   Print "Sync : " ; Sync ; "    "                          ' show the leanth of the sync pulse
   Vanjel = 0
End If
'   Waitms 100
Loop


' All work is handled in the following isr
Pulsecapture_isr:
'   Stop Counter1
   Cnt = Capture1                                           ' get the current pulse value
   Timer1 = 0
'   Start Counter1                                           ' reset the timer for the next pulse
   If Cnt > Syncpulse Then                                  ' check for sync pulse
      Sync = Cnt                                            ' save the current pulse value for debug
      Z = 1
      Vanjel = 0                                            ' set the index to the first channel
   Elseif Z > 0 And Z < 10 Then                             ' assign 1-9 and then wait for sync pulse
      Chan(z) = Cnt                                         ' assign the pulse value to the proper channel
      Incr Z                                                ' next channel...
   End If
   If Z = 10 Then
      Vanjel = 1
      Z = 0
   End If
Return
:arrow: :?:[/b]
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

Hozzászólás Szerző: doncarlos »

Nagyon szépen köszi!!! jövök 1 sörrel vagy borral vagy üditővel teával...

Az volt itt a probléma leginkább hogy benéztem ezt az ICP lábat. köszi még1x hogy ennyit foglalkoztál vele! még annyit az egészhez hogy ér valamit az a noise cancell? vagy inkább ne foglalkozzak vele? vagy van valami jo modszer az ugrálás szürésére?
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Ezért írtam, hogy : Nézd meg Robi, hogy csinálta!
De végül csak nekem kellett megnéznem!
:(
Avatar
doncarlos
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2007. október 14. vasárnap, 6:00

Hozzászólás Szerző: doncarlos »

Meg is néztem de ott is tinyröl volt szó ott is a 6ost irták. én meg megnéztem a megán a d.6ot az is timer1el kapcsolatos és azt hittem jó lesz :oops: sajnos nem vagyok otthon ennyire ebbe

felmerült bennem hogy most a belső 8asról jár ami mst jó de pl. ha nagyobb baudot akarok használni meg azt láttam valahol hogy a külső kvarc stabilabb is, de nekem 16mhz meg 11.0592mhzesek vannak, de ezekkel h lehet 1useces "felbontást" előállítani? Az utóbbi pl. szépen vitte a 115200 as baudot.
Válasz küldése