Strange problem with my test code
clcorbin
Posts: 14
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