FlexBasic SIRC Spin program usage
in Propeller 1
I am trying to use a Spin program developed by Tom Doyle called IR_Remote_NewCog.spin, which I am calling sirc.spin, in a FlexBasic program, not having much success.
The below program, sirc.bas, compiles, but it is not working as expected. When I run the program, p26 turns on, but pressing other keys on the remote, does not turn off p26. Not sure why p26 is turning on, it is not supposed to go on until a button on the remote is pressed. I am using the FLiP module for this experiment.
I am wondering if there is an easier way to do this. The OBEX is a disaster for trying to find things now, let alone downloading. I think Jon MacPhallen had some sirc objects, but could not find those. The SIRC PROPGCC code, has not shown up in FlexGUI, so I cannot use that.
I guess I could try to convert the Tom Doyle program from spin to FlexBasic, but I think it should be made easier to just use existing spin objects.
Thanks
Ray
sirc.bas
The below program, sirc.bas, compiles, but it is not working as expected. When I run the program, p26 turns on, but pressing other keys on the remote, does not turn off p26. Not sure why p26 is turning on, it is not supposed to go on until a button on the remote is pressed. I am using the FLiP module for this experiment.
I am wondering if there is an easier way to do this. The OBEX is a disaster for trying to find things now, let alone downloading. I think Jon MacPhallen had some sirc objects, but could not find those. The SIRC PROPGCC code, has not shown up in FlexGUI, so I cannot use that.
I guess I could try to convert the Tom Doyle program from spin to FlexBasic, but I think it should be made easier to just use existing spin objects.
Thanks
Ray
sirc.bas
dim sirc as class using "sirc.spin"
dim IRcode,lcode as byte
sirc.Start(16,IRcode)
do
if IRcode <> sirc.NoNewCode then
sirc.Start(16,IRcode)
lcode = IRcode
select case lcode
case sirc.one
pinhi(26)
case sirc.two
pinlo(26)
end select
end if
pausems(250)
loop
{{
IR_Remote_NewCog.spin
Tom Doyle
2 March 2007
Panasonic IR Receiver - Parallax #350-00014
Receive and display codes sent from a Sony TV remote control.
See "Infrared Decoding and Detection appnote" and "IR Remote for the Boe-Bot Book v1.1"
on Parallax website for additional info on TV remotes.
The procedure uses counter A to measure the pulse width of the signals received
by the Panasonic IR Receiver. The procedure waits for a start pulse and then decodes the
next 12 bits. The entire 12 bit result is returned. The lower 7 bits contain the actual
key code. The upper 5 bits contain the device information (TV, VCR etc.) and are masked off
for the display.
Most TV Remotes send the code over and over again as long as the key is pressed.
This allows auto repeat for TV operations like increasing volume. The volume continues to
increase as long as you hold the 'volume up' key down. Even if the key is pressed for a
very short time there is often more than one code sent. The best way to eliminate the
auto key repeat is to look for an idle gap in the IR receiver output. There is a period of
idle time (20-30 ms) between packets. The getSonyCode procedure will wait for an idle period
controlled by the gapMin constant. This value can be adjusted to eliminate auto repeat
while maintaining a fast response to a new keypress. If auto repeat is desired the indicated
section of code at the start of the getSonyCode procedure can be commented out.
The procedure sets a tolerance for the width of the start bit and the logic level 1 bit to
allow for variation in the pulse widths sent out by different remotes. It is assumed that a
bit is 0 if it is not a 1.
The procedure to read the keycode ( getSonyCode ) is run in a separate cog. This allows
the main program loop to continue without waiting for a key to be pressed. The getSonyCode
procedure writes the NoNewCode value (255) into the keycode variable in main memory to
indicate that no new keycode is available. When a keycode is received it writes the keycode
into the main memory variable and terminates. With only 8 cogs available it seems to be a
good idea to free up cogs rather than let them run forever. The main program can fire off
the procedure if and when it is interested in a new keycode.
}}
CON
_CLKMODE = XTAL1 + PLL16X ' 80 Mhz clock
_XINFREQ = 5_000_000
NoNewCode = 255 ' indicates no new keycode received
gapMin = 2000 ' minimum idle gap - adjust to eliminate auto repeat
startBitMin = 2000 ' minimum length of start bit in us (2400 us reference)
startBitMax = 2800 ' maximum length of start bit in us (2400 us reference)
oneBitMin = 1000 ' minimum length of 1 (1200 us reference)
oneBitMax = 1400 ' maximum length of 1 (1200 us reference)
' Sony TV remote key codes
' these work for the remotes I tested however your mileage may vary
one = 0
two = 1
three = 2
four = 3
five = 4
six = 5
seven = 6
eight = 7
nine = 8
zero = 9
chUp = 16
chDn = 17
volUp = 18
volDn = 19
mute = 20
power = 21
last = 59
VAR
byte cog
long Stack[20]
PUB Start(Pin, addrMainCode) : result
{{
Pin - propeller pin connected to IR receiver
addrMainCode - address of keycode variable in main memory
}}
stop
byte[addrMainCode] := NoNewCode
cog := cognew(getSonycode(Pin, addrMainCode), @Stack) + 1
result := cog
PUB Stop
{{
stop cog if in use
}}
if cog
cogstop(cog~ -1)
PUB getSonyCode(pin, addrMainCode) | irCode, index, pulseWidth, lockID
{{
Decode the Sony TV Remote key code from pulses received by the IR receiver
}}
' wait for idle period (ir receiver output = 1 for gapMin)
' comment out "auto repeat" code if auto key repeat is desired
' start of "auto repeat" code section
dira[pin]~
index := 0
repeat
if ina[Pin] == 1
index++
else
index := 0
while index < gapMin
' end of "auto repeat" code section
frqa := 1
ctra := 0
dira[pin]~
' wait for a start pulse ( width > startBitMin and < startBitMax )
repeat
ctra := (%10101 << 26 ) | (PIN) ' accumulate while A = 0
waitpne(0 << pin, |< Pin, 0)
phsa:=0 ' zero width
waitpeq(0 << pin, |< Pin, 0) ' start counting
waitpne(0 << pin, |< Pin, 0) ' stop counting
pulseWidth := phsa / (clkfreq / 1_000_000) + 1
while ((pulseWidth < startBitMin) OR (pulseWidth > startBitMax))
' read in next 12 bits
index := 0
irCode := 0
repeat
ctra := (%10101 << 26 ) | (PIN) ' accumulate while A = 0
waitpne(0 << pin, |< Pin, 0)
phsa:=0 ' zero width
waitpeq(0 << pin, |< Pin, 0) ' start counting
waitpne(0 << pin, |< Pin, 0) ' stop counting
pulseWidth := phsa / (clkfreq / 1_000_000) + 1
if (pulseWidth > oneBitMin) AND (pulseWidth < oneBitMax)
irCode := irCode + (1 << index)
index++
while index < 11
irCode := irCode & $7f ' mask off upper 5 bits
byte[addrMainCode] := irCode
Comments
So, the idea of having Spin objects available, for FlexGUI, does not lead to a plug and play scenario. You still have to know something, a lot, about the Spin language, and PASM in some cases. Not sure what the best approach for doing this is. If I have to know a lot about Spin, then why not just use Spin? But I am starting to like FlexBasic, and I am not sure if I know enough to start creating drivers in FlexBasic. I think at this point only Eric knows enough about FlexBasic to even consider doing a lot of drivers in FlexBasic. And if he does that, then it might as well be available for FlexC.
This is a heck of a dilemma, I am considering getting the new P2 Eval board, but it seems like there is long way to go, before any substantial code comes along to really use the board properly.
Ray
I'm a simpleton; I program in Spin and PASM and am happy as a clam. It's not that I won't "play" with other ideas, but for client work, Spin and PASM have always done the job, and I've never once had a client question my use of a "non-standard" language. In the end, they only care that their product works.
I waited until Spin was available to really jump into the P2, and now I'm having a blast -- I really like it. Yes, it will take a while for a large library to be built up, but then, if you're expecting every possible object/library you ever wanted to be available when you want it, in my opinion you're going to end up disappointed. You've been around the forum a long time -- crafting a library that you need should be second nature. Again, my opinion.
Don't give up! The promise of mixing C, Basic, Spin, and Spin 2 is there. There just might be little typos like ersmith just posted. Getting the first one working is always the hardest part.
Since I like FlexGUI, I might try doing some Spin work, again. First project, I guess, would be the Tom Doyle IR_Remote_NewCog.spin program. Then I could try creating some kind of Spin library with a lot of the methods that are normally used, when programming.
I still think that Spin is not my first choice for some easy program prototyping. I have found that using Python scripts was easier than doing something in Spin. But I started to dislike Python because of that indentation, caused a lot of problems, when you missed some indentation.
This is almost like starting from scratch again, all the user IO routines that are readily available in FlexBasic and FlexC will have to be crafted in Spin. Did not see any libraries for that kind of stuff, readily available.
When I look at the Propeller scheme of things, empirically, there is a lot of stuff, but its like a bunch of bits and pieces all over the place. You would think that after fifteen years or so, everything would have been sorted out to make programming the Propeller an easy task, for the old timers and some of the new people that are showing up.
Ray