Strange problem with my test code
I have a strange (at least to me!) problem with some test code I am working on. Here is a quick summary of the hardware:
1) proto board
2) 3 digit 7 segment display that is driven via the 7-segment driver (works). Digits on pins 0-2 and segments on pins 24-32
3) Small I/O board with 4 switches and 8 leds/resistors. Four leds are hard wired to the switchs and four are used as indicators.
Switches on pins 8-11 and leds on pins 12-15. It's all wired to a pin header so I can just plug it into an IO "bank" on the proto board (pin headers installed) and go.
Tested and works fine on many projects.
code:
The problem is very strange. If you look at the section that starts with "If InA[noparse][[/noparse]Power] == Pressed" and look down, yoiu will see a simple line "temperature := 1".
Now, as this is written, this actually works exactly as expected. The display fires up, sets the default value of 350 to it and when I hit the "up" button, the displayed
value increases on each press of the button by 5 until 400 is reached. If I press the "down" button, the displayed value will decrease on each press until 200 is reached.
When I press the "power" button, the displayed value is set to 1.
But what gets strange is if I add another line below the "temperature := 1" line. Say for example lets change the "function" to this:
Now, from my understanding of how this change SHOULD work is this: I press the "power" button. This "If" statement is called. If the variable "temperature is greater
than 300, then it would set temperature to 1, then set temperature to 2, then update the displayed value to temperature.
But it doesn't. Instead, it pretty much locks up the prop. The display just shows junk and pressing any other button does not do anything (not even turn on and off the
output LED1 that is there just to show the prop called the correct function). And it doesn't matter which button I press, as soon as it goes into the "FindButton" function,
it freaks out.
I originally came across this issue when instead of
I had
which was just supposed to toggle the value from an "on" value to an "off" value. It did the same lockup thing too. I simplified things to make sure I wasn't doing
something completely stupid with the if-else condition.
So, does anyone have any idea what I am doing wrong? I THINK the problem has something to do with how the memory is being saved in the prop and extra
lines of code are pushing it into a different page or something. But I don't know how to prove it or how to resolve it. Any help would be greatly appreciated
1) proto board
2) 3 digit 7 segment display that is driven via the 7-segment driver (works). Digits on pins 0-2 and segments on pins 24-32
3) Small I/O board with 4 switches and 8 leds/resistors. Four leds are hard wired to the switchs and four are used as indicators.
Switches on pins 8-11 and leds on pins 12-15. It's all wired to a pin header so I can just plug it into an IO "bank" on the proto board (pin headers installed) and go.
Tested and works fine on many projects.
code:
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
lowDigit = 0 'Low digit cathode
digits = 3 'Number of digits to display
Segment0 = 24 'Segment start pin
TempUp = 8 ' Pin 8 is used for the increase temperature input
TempDown = 9 ' Pin 9 is used for the decrease temperature input
Power = 10 ' Pin 10 is used for the On/Off button
Pressed = %1 ' Set a constant for checking if inputs are pressed.
LED1 = 12 ' Configure pin 12 as LED1
LED2 = 13 ' Configure pin 13 as LED2
LED3 = 14 ' Configure pin 14 as LED3
LED4 = 15 ' Configure pin 15 as LED4
VAR
long stack0[noparse][[/noparse]20]
long stack1[noparse][[/noparse]20]
long counter
long temperature
OBJ
sevenseg : "SevenSegment"
PUB Start
' Configure the push buttons
dira[noparse][[/noparse]TempUp..Power]~ ' Setup our pushbutton as an input
'Configure debug LEDs
dira[noparse][[/noparse]LED1..LED4]~~
' Start the seven segment display driver on a new cog
cognew(sevenseg.start(lowDigit, digits, Segment0, true), @temperature)
'Set the initial temperature to 350
temperature := 350
sevenseg.SetValue(temperature) ' Set the initial temperature value of 250
Monitor ' Start monitoring the button
Pri Monitor ' Monitor constantly monitors the control buttons
waitcnt(clkfreq / 10 + cnt)
repeat
waitpne(%0000 << 8, %111 << 8, 0) ' Wait for any control button to be pressed
waitcnt(clkfreq / 20 + cnt) ' debounce the switches
FindButton ' Find out which button was pressed
waitpeq(%0000 << 8, %111 << 8, 0) ' Wait for all the control buttons to be released
waitcnt(clkfreq / 20 + cnt) ' debounce the switches
Pri FindButton
If InA[noparse][[/noparse]TempUp] == Pressed
outa[noparse][[/noparse]LED1] := %1
waitcnt(clkfreq / 10 + cnt)
outa[noparse][[/noparse]LED1] := %0
temperature := temperature + 5
If temperature > 400
temperature := 400
sevenseg.SetValue(temperature)
return
If InA[noparse][[/noparse]TempDown] == Pressed
outa[noparse][[/noparse]LED1] := %1
waitcnt(clkfreq / 10 + cnt)
outa[noparse][[/noparse]LED1] := %0
temperature := temperature - 5
If temperature < 200
temperature := 200
sevenseg.SetValue(temperature)
return
If InA[noparse][[/noparse]Power] == Pressed
outa[noparse][[/noparse]LED1] := %1
waitcnt(clkfreq / 10 + cnt)
outa[noparse][[/noparse]LED1] := %0
if temperature > 300
temperature := 1
sevenseg.SetValue(temperature)
return
return
The problem is very strange. If you look at the section that starts with "If InA[noparse][[/noparse]Power] == Pressed" and look down, yoiu will see a simple line "temperature := 1".
Now, as this is written, this actually works exactly as expected. The display fires up, sets the default value of 350 to it and when I hit the "up" button, the displayed
value increases on each press of the button by 5 until 400 is reached. If I press the "down" button, the displayed value will decrease on each press until 200 is reached.
When I press the "power" button, the displayed value is set to 1.
But what gets strange is if I add another line below the "temperature := 1" line. Say for example lets change the "function" to this:
If InA[noparse][[/noparse]Power] == Pressed
outa[noparse][[/noparse]LED1] := %1
waitcnt(clkfreq / 10 + cnt)
outa[noparse][[/noparse]LED1] := %0
if temperature > 300
temperature := 1
temperature := 2
sevenseg.SetValue(temperature)
return
Now, from my understanding of how this change SHOULD work is this: I press the "power" button. This "If" statement is called. If the variable "temperature is greater
than 300, then it would set temperature to 1, then set temperature to 2, then update the displayed value to temperature.
But it doesn't. Instead, it pretty much locks up the prop. The display just shows junk and pressing any other button does not do anything (not even turn on and off the
output LED1 that is there just to show the prop called the correct function). And it doesn't matter which button I press, as soon as it goes into the "FindButton" function,
it freaks out.
I originally came across this issue when instead of
if temperature > 300 temperature := 1
I had
if temperature > 0 temperature := 0 else temperature := 350
which was just supposed to toggle the value from an "on" value to an "off" value. It did the same lockup thing too. I simplified things to make sure I wasn't doing
something completely stupid with the if-else condition.
So, does anyone have any idea what I am doing wrong? I THINK the problem has something to do with how the memory is being saved in the prop and extra
lines of code are pushing it into a different page or something. But I don't know how to prove it or how to resolve it. Any help would be greatly appreciated

Comments
cognew(sevenseg.start(lowDigit, digits, Segment0, true), @temperature)
is wrong. You get do a cognew of a routine not in the local object. Move the sevenseg.start call into a local routne and do a cognew of that.
Why would I need to move the start method from the sevenseg object into the local code before I did a cognew on it? Doesn't that take away from the whole
point of being able to call stand alone spin objects?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Clint
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 9/12/2008 12:18:33 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Clint
I would add a routine
PRI segstart(p1,p2, p3, p4)
sevenseg.start(p1, p2, p3, p4)
then change cognew to
cognew(segstart(lowDigit, digits, Segment0, true), @temperature)
Then see what is happening
Also look at the same cognew, the 2nd parameter @temperature. This should be the stack for spin, temperature isn't a stack so I am not sure what you
meant here but I dont think is correct. This will also cause a memory corruption so needs to be fixed before looking further
You are correct . My first "try" at addressing this was to change "@temperature" on the cognew line to "@stack0" (defined as a stack of 10 longs).
For some reason, the seven segment code would not start like that. So, I swapped the cognew around and let the seven segment stuff run from cog 0 and
changed the call to "Monitor" to "cognew(Monitor, @stack0).
That worked correctly. So, I went back to the findbutton function and edited back to the original if..else.. statement and it kept working correctly.
I see I am going to have to pay more attention to and learn more about how the memory is used by the assorted cogs.
Thanks for the help everyone.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Clint