Author |
Topic |
Lash
Member
814 Posts |
Posted - 2003/03/06 : 22:26:54
|
Jag tror att det är så att om ben A är 0 och ben B är 1 samtidigt innan du rört encodern och sedan vrider encodern åt höger så blir ben A 1 och ben B 1. Stämmer det? Interupt borde väl bara behövas på ett av benen? Och du måste nog kolla båda benen, annars kan ju inte picen veta om du ändrar från 11 till 00 eller 10 om picen inte har koll på första biten(A).
Pulståg "medurs".
A B --------- 0 0 0 1 1 1 1 0
|
Edited by - Lash on 2003/03/06 22:33:49 |
|
|
loovet
Member
354 Posts |
Posted - 2003/03/06 : 22:48:27
|
Funderar på en sak, säg att jag använder mig av ett ben för interrupt och detta är satt som pullupmostdånd. Jag förstår då att PIC:en kommer att se det som en händelse, interrupt, när den går från 1 till 0, men kommer den att starta en ny händelse, interrupt, när den går tillbaka från 0 till 1?
/loovet |
// det blev en aleph 1.7 // |
|
|
Nagref
Member
113 Posts |
Posted - 2003/03/06 : 22:50:12
|
Jepp vid varje förändring så blir det ett interrupt men de kan du ju snabbt kolla först i interruptrutinen vilket läge 'benet' är i och om det är fel så är det bara att hoppa ur intterruptrutinen.. |
Assisterar Holographic Audio och Larsen Hifi VD för Acoustic Landscape R&D-ansvarig för Acoustic Illusion |
|
|
Lash
Member
814 Posts |
Posted - 2003/03/06 : 22:54:14
|
Jag tog det här härifrån http://www.mstracey.btinternet.co.uk/pictutorial/progtut11.htm
----------------------------------- Interrupt Flag
In our INTCON register, bit 1 is the interrupt flag, called INTF. Now, when any interrupt occurs, this flag will be set to 1. While there isn’t an interrupt, the flag is set to 0. And that is all it does. Now you are probably thinking ‘what is the point?’ Well, while this flag is set to 1, the PIC cannot, and will not, respond to any other interrupt. So, let’s say that we cause an interrupt. The flag will be set to 1, and the PIC will go to our routine for processing the interrupt. If this flag wasn’t set to 1, and the PIC was allowed to keep responding to the interrupt, then continually pulsing the pin will keep the PIC going back to the start of our interrupt routine, and never finishing it. ----------------------------------
Du måste manuelt ställa tillbaka "interrupt flaggen" till noll efter du kört din interrupt rutin, innan du går tillbaka till huvudprogrammet.
Något jag undrar över är om det går att ha flera olika interrupts, att varje ben som har interrupt har en egen interruptrutin. Volymkontrollen ska ju ha sin egen och irmotagaren sin tex. och andra knappar man vill ha på interupt.
|
Edited by - Lash on 2003/03/06 22:59:26 |
|
|
swede
Member
1091 Posts |
Posted - 2003/03/06 : 23:33:03
|
Eller så kan man bygga en enkel krets med AND/NAND-kretsar som är kopplade till RB0. Om NÅGOT händer, så är det bara att börja polla alla olika ben. Det tror jag är ett (av många) sätt att lösa det hela.
Problemet när man börjar koda assembler för PIC (eller något annat överhuvud taget), är att man känner sig lite inkompetent. Därför ser man alla problem som mer komplexa än de är. Att man får slösa bort lite minnesplats för att kolla "nästan" samma sak flera gånger, är inte så illa som det känns till en början. Även om man kollar om och om och om igen, så blir koden för en enkel rotaryavkodare inte så stor. Man kommer under 100 byte, enkelt.
Jämför det med vilken Wintendo-maskin som helst, som nuförtiden kräver hundratals megabyte för att ens starta. Jag kommer ihåg en assembleruppgift i skolan, där man löste en kvadratrot med 7 assemblerrader... Det funkar om man tänker till.
Så, mitt råd är att undvika interrupt. Slösa på minne, så länge man har minne över. Prestanda i PIC'en är tillräcklig ändå. Vi skall inte övervaka något kärnkraftverk. Det är ju en volymkontroll det handlar om.
Lycka till, //magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
|
|
Lash
Member
814 Posts |
Posted - 2003/03/06 : 23:45:30
|
Vilket kommando använder du för att kolla vad som händer på encodern, jämför du sedan det första resultatet av ben A & B med nästa och lägger till/tar bort 1 av ett "volym" register beroende på om det ändrarde från höger eller vänster? Kan du klistra in en bit kod? |
Edited by - Lash on 2003/03/07 01:27:48 |
|
|
swede
Member
1091 Posts |
Posted - 2003/03/07 : 09:24:14
|
Tjenare,
Så här gör jag... Dock är jag ju inte helt klar med min kod och min koppling. Men jag har en fungerande avkodare för rotaryencodern.
* Rotary encodern är kopplad till RB0 och RB1.
För att kolla ifall något hänt (alltså att någon vridit på encodern) kör jag en loop som den här. Mina kommentarer är säkert blandade på engelska och svenska. Fråga mig inte varför. Det bara blir så.
C equ 0
Z equ 2
TRISB equ 86h ;Address of the tristate register for port B
PORTB equ 06h ;Address of Port B
Rotary_Loop
movf PORTB,0 ; Read in rotary state
andlw b'00000011' ; Just the two lower bits are important
bcf STATUS,Z
movwf NEW_STATE ; Store state as "new"
subwf OLD_STATE,0 ; Compare to old state
btfsc STATUS,Z ; If zero flag is clear, skip next instruction
goto Rotary_Loop
; if something happens, call decode_statechange
call Decode_Statechange
movf VOLUME,0
call Shift_Out ; Skicka ut volymen till reläerna
movf NEW_STATE,0 ; Save the state as old_state
movwf OLD_STATE
Short_delay
decfsz COUNT1,1 ;Subtract 1 from 255
goto Short_delay ;If COUNT is zero, carry on.
goto Rotary_Loop
Så där. Det där är själva grunden.
movf PORTB,0 (första raden) kollar om något hänt på ingångarna. Jag maskar bort allt jag inte är intresserad av med "andlw". För att kolla ifall denna avläsning är lika som föregående, subtraherar jag nuvarande från den gamla. Om INTE 'Z' (zero flaggan) är satt efter subtraktionen, så är de olika. Då hoppar man över nästa instruktion (goto Rotary_loop). Om man hoppar över goto (alltså något har hänt), så anropas Decode_Statechange (som troligtvis är den lilla kodsnutt du är mest intresserad av). Där avkodas riktning och volymen ändras. När riktningen avkodats och volymen ändrats, så är det dags att skicka ut det hela till reläkortet, vilket görs med ett anrop till "Shift_Out".
Avkodningen ser ut så här:
Decode_Statechange
test_increase_statechange
t11_to_01 ; From 11 to 01 -> Increase
movlw b'00000011'
subwf OLD_STATE,0
btfss STATUS,Z ; if equal check more
goto t01_to_00
movlw b'00000001'
subwf NEW_STATE,0
btfss STATUS,Z ; if equal check more
goto t01_to_00
goto increase
t01_to_00 ; From 01 to 00 -> Increase
movlw b'00000001'
subwf OLD_STATE,0
btfss STATUS,Z ; if equal check more
goto t00_to_10
movlw b'00000000'
subwf NEW_STATE,0
btfss STATUS,Z ; if equal check more
goto t00_to_10
goto increase
t00_to_10 ; From 00 to 10 -> Increase
movlw b'00000000'
subwf OLD_STATE,0
btfss STATUS,Z ; if equal check more
goto t10_to_11
movlw b'00000010'
subwf NEW_STATE,0
btfss STATUS,Z ; if equal check more
goto t10_to_11
goto increase
t10_to_11 ; From 10 to 11 -> Increase
movlw b'00000010'
subwf OLD_STATE,0
btfss STATUS,Z ; if equal check more
goto test_decrease_statechange
movlw b'00000011'
subwf NEW_STATE,0
btfss STATUS,Z ; if equal check more
goto test_decrease_statechange
increase
goto increase_volume
test_decrease_statechange
; From 00 to 01 -> Decrease
; From 01 to 11 -> Decrease
; From 11 to 10 -> Decrease
; From 10 to 00 -> Decrease
decrease
goto decrease_volume
;***************************************************
;***************************************************
; 2003-07-03
; ML increase_volume
;***************************************************
increase_volume
movlw d'1'
addwf VOLUME,1
return
;***************************************************
; 2003-07-03
; ML decrease_volume
;***************************************************
decrease_volume
movlw d'1'
subwf VOLUME,1
return
Min kod för att avkoda riktningen kanske ser lite lång ut, men den är egentligen ganska rättfram. Den kollar steg för steg ifall någon av reglerna gäller. Jag kommenterar den första delen (t11_to_01). Där kollar jag först ifall förra pollningen var b'11'. Ifall detta gäller kollar jag ifall den nya pollningen är b'01'. Ifall detta gäller har vi en "matchning" och jag önskar öka volymen (goto increase). Om inte någon av dessa premisser stämmer, så hoppar programmet till nästa kontroll (t01_to_00) o.s.v.
Om inte någon av "increase" kontrollerna gäller, så är det antingen en "decrease" eller "illegal" state change. Båda resulterar i en sänkning av volymen i mitt program.
Så "enkelt" har jag löst det hela. Kanske går det att göra enklare, men jag har inte kodat PIC förr, så jag har inte någon större aning om ifall det finns bättre lösningar.
Lycka till, //magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
Edited by - swede on 2003/03/07 13:57:37 |
|
|
swede
Member
1091 Posts |
Posted - 2003/03/09 : 18:51:50
|
Tjenare,
I och för sig käns det nästan som att jag diskuterar med mig själv, men jag använder det här forumet lite som en dagbok, så det gör inte så mycket.
Nu har jag suttit och pulat en massa med hårdvaran för kontrollenheten och byggt lite mjukvara kring det hela. Jag kom på att jag egentligen inte bestämt mig för hur frontpanelen skall se ut och hur många input-möjligheter jag skall ha. Inte heller hur användarinterfacet skall se ut. Jag har lite idéer.
* 8 LEDar (blå så klart) som visar vilken volym (och ev balans) man har. * 4 LEDar som visar vilken input som är aktiv * 1 LED som visar muting (eller om man skall låta de 8 LEDarna blinka för att visa att man har muting igång)
Det var väl allt för idag. Min mjukvara verkar fungera bra. Får vänta tills i morgon, när Urban kommer hem från Sverige, så jag kan bygga reläkorten. Han har med sig lite prylar till mig.
//magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
|
|
Lash
Member
814 Posts |
Posted - 2003/03/09 : 19:10:48
|
En ide som jag funderat på är att sätta lysdioderna för volym bakomför volymkontrolen, så det lyser medurs roterande(beroende på volym) fram från baksidan av den om ni fattar hur jag menar. Man skulle kunna använda plexiglas format så ljuset blir lite mer riktat. Det skulle ju se bra ut när det är lite mörkare i rummet iaf. Förövrigt har jag köpt en 2x2x nånting LCD som ska visa ingång och volym. Men jag tänkte prova lysdioderna bakom volymkontrolen endå sedan när det nu blir av(håler på med proac fanerandet nu).
Vilka reläer tänkte ni andra använda? Dom här funderar jag på http://www.elfa.se/elfa/produkter/se/20/2022017.htm |
Edited by - Lash on 2003/03/09 19:19:28 |
|
|
Freddie
Member
322 Posts |
|
loovet
Member
354 Posts |
Posted - 2003/03/09 : 20:42:29
|
Även jag sitter just nu och funderar på hur jag skall ha mina ingångar.
Det lutar åt att jag kommer att använda mig av två ingångar för att driva balanserat och två stycken för att driva obalanserat, totalt fyra ingångar.
/loovet |
// det blev en aleph 1.7 // |
|
|
loovet
Member
354 Posts |
Posted - 2003/03/09 : 20:52:11
|
Någon mer än jag som funderar på att ha nätdelen och PIC:arna i en separat låda?
/loovet |
// det blev en aleph 1.7 // |
|
|
Lash
Member
814 Posts |
Posted - 2003/03/09 : 21:19:12
|
Vaför ska nätdelen o PICarna vara i en egen låda? |
Edited by - Lash on 2003/03/09 21:20:10 |
|
|
loovet
Member
354 Posts |
Posted - 2003/03/09 : 22:16:24
|
Allt för att inte traffon och "klockorna" skall hållas så långt borta från övriga delar.
Kolla in X0.2 på www.passlabs.com
Inte för att jag vet om det påverkar, men tycker att det kan var kul att dela upp det hela. Det tar ju knappast dubbel så lång tid att göra två lådor.
/loovet |
// det blev en aleph 1.7 // |
|
|
Freddie
Member
322 Posts |
Posted - 2003/03/09 : 22:18:18
|
quote: Någon mer än jag som funderar på att ha nätdelen och PIC:arna i en separat låda?
loovet, jag kommer att ha "allt" i en låda. Funderar på en sådan här låda. RCG-132SW http://www.trimlog.se/19.htm Med en egentillverkad ratt, en VFD display samt två knappar på fronten för att skifta mellan ingångarna.
Hur går det med programmeringen förresten?
/Freddie
|
Edited by - Freddie on 2003/03/09 22:20:31 |
|
|
loovet
Member
354 Posts |
Posted - 2003/03/09 : 22:31:08
|
Har inte kommit så långt med programeringen ännu. Har beställt en programerare och tänkte att jag skulle invänta den innan jag sätter fart, roligare när man kan prova sakerna direkt, i stället för att bara simulera i datorn. Vet inte om jag tycke att simuleringsdelen i MPLAB är det bästa ;-)
Vad gäller lådan till min stärkare så är det väl där som jag skall försöka lägga ner lite tid sedan, har en kompis som har en liten mekanisk verkstad. Idag har jag gjort iordning en liten experimentlåda, en aluminiumplåt med lite bockade kanter, som jag har fäst kort och kontakter på. Enklare att sätta fast de olika korten på en gemensam plåt än att ha dem lösa.
Jag tänkte att jag skulle ha min front i borstad 10mm alu. Har du lyckats hitta några snygga knappar?
Freddie, vist bor du i STHLM? Vore kul om vi kunde träffas någon gång för att se hur det går med varandras byggen?
/loovet
|
// det blev en aleph 1.7 // |
|
|
swede
Member
1091 Posts |
Posted - 2003/03/09 : 23:38:24
|
Lash: Jag tror de relärne kommer fungera bra. Själv använder jag denna:
http://www.elfa.se/elfa/produkter/se/20/2021520.htm
Ingen större skillnad.
Jag har samma idé om volymkontrollen. Jag vill inte ha någon LCD-display, då jag inte ser någon vits med den. Det blir 8 stycken LED i en halvcirkel kring volymkontrollen. Dessutom skall jag nog pröva att använda följande pulsgivare/rotaionssensor:
http://www.elfa.se/elfa/produkter/se/20/2021547.htm
Den har en tryckströmbrytare inbygd, så om man trycker in volymkontrollen, så tänker jag ha balans-inställning eller ingångs-väljare där. (se tryckströmbrytaren som en "shift"-knapp). Vi får se.
//magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
|
|
Freddie
Member
322 Posts |
Posted - 2003/03/10 : 07:18:04
|
quote: Freddie, vist bor du i STHLM? Vore kul om vi kunde träffas någon gång för att se hur det går med varandras byggen?
Jo, jag bor i sthlm. |
|
|
loovet
Member
354 Posts |
Posted - 2003/03/10 : 11:47:21
|
Freddie; om du har lust så får du gärna komma förbi någon dag och kolla på mina prylar.
/loovet |
// det blev en aleph 1.7 // |
|
|
CF
Member
63 Posts |
Posted - 2003/03/13 : 09:51:22
|
Nu har jag fått till en fyr tråds alfanumerisk display 16x2 + en IR mottagare som triggas av interrupt. Rippade koden från nätet för RC5 avkodningen. Nästa steg är en rotary encoder. Jag vill köra den på RB6 och RB7 för att kunna utnyttja Interrupt on change.
Är det någon som vet hur långa flankerna är fron encodern? http://www.elfa.se/pdf/35/03584745.pdf
Jag vill vara säker på att jag alltid hinner utföra min isr innan nästa flank byte sker så att man inte missar några pulser!
Får jag till det så att all extern input genererar Interrupts så kan jag utnyttja sleep mode.
///CF
|
|
|
swede
Member
1091 Posts |
Posted - 2003/03/13 : 13:45:37
|
Eh, det vet du ju inte, för de är ju beroende på hur snabbt du snurrar encodern.
//magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
|
|
CF
Member
63 Posts |
Posted - 2003/03/13 : 14:08:49
|
Så det beror på hastigheten helt och hållet. Då får jag ta och mäta hur korta jag kan lyckas få när jag snurrar så snabbt jag kan. Kanske spänna fast den i pelarborrmaskinen ;)
PS
Skojade bara |
|
|
Wolfie
Member
752 Posts |
Posted - 2003/03/13 : 15:25:18
|
Najsigt! Någon av er som har fått igång en fullt funktionerande fjärrstyrd Aleph P?
Lägg isf gärna ut en länk med bilder, info o asm kod(?) ;)
Ni som programerar: Kom ihåg att koda dem i sådan ordning att endast en av bitarna i taget ändrar tillstånd (graykodning). Mao 00->01->11->10 med 2 bitar. 000->001->011->010->110->111->101->100 med 3 bitar. På så vis vet man att något skumt inträffat om 2 eller fler bitar ändrar tillstånd samtidigt. Varför man brukar göra så här får ni läsa i böcker om ;) |
Ingen ordning utan kaos! |
|
|
swede
Member
1091 Posts |
Posted - 2003/03/13 : 15:44:44
|
Tja, om du räknar klockcykler, så kaske du kommer fram till att du behöver en pelarborrmaskin för att komma upp i sådana hastigheter att du missar några pulser. ;=)
Premiss: 4MHz klocka. Om det tar dig ca 100 klock-cykler att avkoda ett interrupt från rotary-encodern, så betyder det att du det i runda slängar tar 25 mikrosekunder att avkoda rotaryn. För att missa en puls, måste det komma en ny puls inom 25 mikrosekunder.
En alps rotary har väl ca 100 flankbyten per varv på encodern. Det betyder att det tar 10.000 mikrosekunder (0.01 sekunder) mellan flankbytena om du snurrar encoderna ett varv per sekund, baserat på 100 klockcykler för avkodningen, men du borde vara grym på att koda, så vi räknar med det. ;=)
Så, vi har:
* 100 flankbyten / varv. * 100 klockcykler för avkodning -> 25 mikrosekunders brytgräns
Fråga: Hur många varv per sekund måste man snurra för att "missa" en puls?
Ekvation: f=1/t
Frekvensen = 1 / ( 100 (flankbyten per varv) * 25*10e-6 (max mikrosekunder / flankbyte))
Frekvensen = 400 varv per sekund.
Slutsats: Jo, du får nog spänna fast encodern i pelarborrmaskinen för att missa pulserna. ;=)
Kommentar: I de 100 klockcyklerna har jag inte räknat med kontaktstudsar och sånt, vilket kanske drar ner frekvensen 10 - 50 gånger, men i sådana fall behöver du fortfarande snurra 8 - 40 varv per sekund i alla fall. Det blir till att använda borrmaskinen ändå.
Kram, //magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
|
|
swede
Member
1091 Posts |
Posted - 2003/03/14 : 08:49:38
|
Då har jag borrat första reläkortet till frukost. Hoppas kunna börja populera det snarast.
//magnus |
perl -ne'chomp;$a.=pack"b*",$_;END{print"\n$a\n\n"}'<<RM 10000010001101101010011000001110000101100000010001001110 101011100011011010100110110011101000010001010000 RM |
|
|
Topic |
|
|
|