This is code I developed to re-engineer the user input to my amplifier. The idea is that control is either by an amp mounted rotary encoder, or by a infra red remote.
The issue with this is that the IR input routines are blocking so must be run on a separate picaxe and that the encoder debounce routines can be difficult.
The IR input is handled by an 08M2 (08M should work with minor mods)
This just reads the codes off the input and recodes them to standard ascii characters which it sends out on the serial output. I'm using my standard Sony TV remote to control the amplifier. The code includes an "acceleration" algorithm to separate individual button pushes but also allow continuous presses for scrolling up and down the volume.Code:#picaxe 08M2 setfreq M8 symbol last=b1 symbol repcount=b2 symbol pauselength=w2 main: irin c.3,b0 if b0<9 then b0=b0+49 'convert to an ascci number gosub rep sertxd (b0) b0=255 endif if b0=9 then b0=48 'convert to an ascci number gosub rep sertxd (b0) b0=255 endif if b0>15 and b0<29 then b0=b0+49 ' convert to capital A to M if b0="C" then: b0=">" :endif if b0="D" then: b0="<" :endif gosub rep sertxd (b0) b0=255 endif if b0>50 and b0<57 then b0=b0+27 ' convert to capital N to S gosub rep sertxd (b0) b0=255 endif if b0>75 and b0<83 then b0=b0+8 ' convert to capital T to Z gosub rep sertxd (b0) b0=255 endif if b0>115 and b0<118 then b0=b0-45 ' convert to capital G and H gosub rep sertxd (b0) b0=255 endif if b0=37 then gosub rep sertxd ("P")' convert to capital P b0=255 endif if b0=101 then gosub rep sertxd ("R")' convert to capital R b0=255 endif if b0=96 then gosub rep sertxd ("X")' convert to capital X b0=255 endif if b0=35 then gosub rep sertxd ("Y")' convert to capital Y b0=255 endif if b0=99 then gosub rep sertxd ("C")' convert to C b0=255 endif if b0=40 then gosub rep sertxd ("D")' convert to D b0=255 endif 'sertxd (b0,last,cr,lf) pauselength=repcount*repcount * 2 pauselength=500-pauselength pause pauselength goto main rep: if b0<>last then repcount=0 else repcount=repcount + 1 max 15 endif last=b0 return
The main processor listens to the serial port but also handles the encoder totally at the interrupt level. My original routines for this http://www.picaxeforum.co.uk/showthr...nterrupt-issue were blocking whilst the encoder completed a cycle but this would have caused inputs from the IR to be delayed if the encoder was left in a mid cycle state rather than at the detent (easy to do) so I have recoded them to exit all interrupts immediately but still only report the user event on cycle completion. The interrupt routine feeds the encoder output into the hardware serial buffer so that the main code only has one place to look for data and doesn't care where it arrives from.
Code:#picaxe 28X2 setfreq m8 symbol resetenc=bit0 symbol switchison = bit2 symbol rotatedleft=bit3 symbol rotatedright=bit4 symbol scratch=b1 symbol switched = b2 ' 'Connections ' Encoder switch pulled high and connected to A.1 ' Encoder output1 pulled high and connected to A.2 ' Encoder output2 pulled high and connected to A.3 ' ' symbol interruptmask = %00001110 ' allow interrupts on a.3,a.2, a.1 symbol rotated = %00000110 symbol clicked = %00000001 ' mask to test for c.1 high ' symbol true=1 symbol false=0 ' hsersetup B9600_8,1 dirsa=0 ptr=0 switchison=false rotatedright=false rotatedleft=false resetenc=true setint OR 0,interruptmask,A do do while ptr<>hserptr b10=@ptrinc sertxd (b10) 'Do required control actions here loop 'do required background actions here loop interrupt: switched=pinsa & interruptmask >> 1'look at just the three inputs on switched goto I0,I1,I2,I3,I4,I5,I6,I7 'whatever the cause set the next interrupt to look for a reverse I0: setint OR 14,interruptmask,A goto proc I1: setint OR 12,interruptmask,A goto proc I2: setint OR 10,interruptmask,A goto proc I3: setint OR 8,interruptmask,A goto proc I4: setint OR 6,interruptmask,A goto proc I5: setint OR 4,interruptmask,A goto proc I6: setint OR 2,interruptmask,A goto proc I7: setint OR 0,interruptmask,A proc: scratch=switched & clicked if scratch=0 then switchison=true else if switchison=true then put hserptr,"A" hserptr=hserptr+1 & $03FF switchison=false endif endif ' scratch=switched & rotated >>1 on scratch goto R0,R1,R2,R3 R0: if rotatedleft=true then put hserptr,"<" hserptr=hserptr+1 & $03FF rotatedleft=false endif if rotatedright=true then put hserptr,">" hserptr=hserptr+1 & $03FF rotatedright=false endif return R1: if resetenc=true then rotatedleft=true rotatedright=false resetenc=false endif return R2: if resetenc=true then rotatedright=true rotatedleft=false resetenc=false endif return R3: rotatedleft=false rotatedright=true resetenc=true return


Reply With Quote
Bookmarks