You'll often find it easier to get assistance when others understand the outcome you desire. You have code that doesn't work. Okay. Explain (in English, not non-working code) what you would love to have happen if it did work. An outside point-of-view -- once fully understanding your desired outcome -- may show you things you hadn't considered that simplifies.
Initially, you seem to be stacking a lot of things that don't need to be.
I removed documentation to size it down....Not thinking again, head is spinning....LOL
I want the top object to call the "BlinkMethod01", passing it the first two pins in the array of pins.
Expected is to call the LED1 method, which checks and stops cog if in use then returns and starts a cog passing the pin values and runs a pair of led's on the pins. Cleaning out garbage code, and now I get a return from the calling function, but no lights work if I call from the top object. BUT if I add the necessary code to make the BlinkMethod01 work stand alone, the LED's work the way I expected and desire, with that cog.
If I run serial terminal from the BlinkMethod01 proper, not thru the top object, I can see all my debug code(cleaned out for here) and the led's work
So this is the TopLED ...top obj
{{TopLed.spin
test file for making the LED prog work right
}}
OBJ
Flash1 : "BlinkMethod01" ''LED1 is call
pst : "Parallax Serial Terminal"
CON
_xinfreq = 5000000
_clkmode = xtal1+PLL16x
VAR
byte pin[15] {1,2,3,4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
''array of the pin nums, leaving 0 for no special reason
PUB Main
Flash1.LED1(pin[1],pin[2]) ''pins 1&2 sent to method BlinkMethod01, expecting 'success' back
.
Then this is the BlinkMethod01
{{ BlinkMethod01
Purpose to blink LED
}}
OBJ
pst : "Parallax Serial Terminal"
VAR
long stack[20]
byte cog
PUB LED1 (pin1,pin2): success
Stop '' stop cog if already in use
success :=(cog:=cognew(BlinkMethod01(pin1, pin2), @stack)+1)
PUB Stop
if cog '' it has a value stop it.
cogstop(cog~ -1)
PRI BlinkMethod01(pin1, pin2) | rate
rate:= clkfreq
dira[pin1]~~
outa[pin1]:=1
dira[pin2]~~
outa[pin2]:=1 {{this sets up the double flash sequence
Which changes with the 7404 setup must be correct
or it will not work right.}}
repeat
waitcnt(rate/6+cnt)
!outa[pin1]
!outa[pin2] ''for ref, on
waitcnt(rate/6+cnt)
!outa[pin1]
!outa[pin2] ''for ref, off
waitcnt(rate/6+cnt)
!outa[pin1]
!outa[pin2] ''for ref, on
waitcnt(rate/6+cnt)
!outa[pin1]
!outa[pin2] ''for ref, off
waitcnt(rate/2+cnt) ''longer wait
I am expecting the top object to call a method that starts a cog that runs a method that flashes 2 LED's, for 2 fast short flashes with a longer pause for effect, and for this to continue running while the top object goes and calls another cog and starts another LED process that is totally different.
I hope this is more clear. My family always gets on my case because they dont' understand what I am trying to say, so please ask if I confused. Thanks for the time you may take on this.
Writing a specification that others will understand is the hardest part -- I just got of the phone with a client.
BTW... you understand that you cannot pre-initialize a VAR array, correct? Change that to a DAT array if you want to specify the pins in the array without having to do that when the program is running
The cool thing is that the array in pre-initialized but still malleable.
Stepping back a bit, your original code caused me to think you want an object that can flash one or two LEDs. Here's a very simple approach (that works, I tested it) that may give you something to think about. The object object has public methods for each flash type, and corresponding private methods that are launched into a separate cog so that they can run in the background. Calling a new method kills the previous. Of course, you can use .stop to kill anything that is running.
con
{ ----------- }
{ Blinker Cog }
{ ----------- }
var
long cog
long blinkstack[32]
pub blink1(pin1, ms1)
stop
cog := cognew(run_blink1(pin1, ms1), @blinkstack) + 1
return cog
pub blink2(pin1, ms1, ms2)
stop
cog := cognew(run_blink2(pin1, ms1, ms2), @blinkstack) + 1
return cog
pub blink3(pin1, ms1, pin2, ms2)
stop
cog := cognew(run_blink3(pin1, ms1, pin2, ms2), @blinkstack) + 1
return cog
pub stop
if (cog)
cogstop(cog - 1)
cog := 0
pri run_blink1(pin1, ms1) | t
'' Blink pin1
'' -- toggles ever ms1 milliseconds
ms1 *= (clkfreq / 1000) ' convert to ticks
dira[pin1] := 1 ' output mode
t := cnt ' sync loop timing
repeat
!outa[pin1] ' toggle
waitcnt(t += ms1) ' wait
pri run_blink2(pin1, ms1, ms2) | t
'' Blink pin1
'' -- on time in ms1, off time in ms2
ms1 *= (clkfreq / 1000)
ms2 *= (clkfreq / 1000)
dira[pin1] := 1
t := cnt
repeat
outa[pin1] := 1
waitcnt(t += ms1)
outa[pin1] := 0
waitcnt(t += ms2)
pri run_blink3(pin1, ms1, pin2, ms2) | t
'' Alternate between pin1 and pin2
'' -- timing independent per pin
ms1 *= (clkfreq / 1000)
ms2 *= (clkfreq / 1000)
dira[pin1] := 1
dira[pin2] := 1
t := cnt
repeat
outa[pin1] := 1
outa[pin2] := 0
waitcnt(t += ms1)
outa[pin1] := 0
outa[pin2] := 1
waitcnt(t += ms2)
Jon,
Thanks, Nope, I misunderstood about initializing variable But, I need to study what I have to do for the data section, not learned that yet, so have questions about what you showed me. You mention "t DAT array" but I don't see a t in the example. I also don't know how to address the data. You show "Pinz" Is the 'z' like a position place? I will go read up on DAT in a few.
Your description of the blinker program sounds similar. My ultimate goal is to run multiple cogs with varying light displays that all work independently, including one method that uses radio input, splits up the length of the square wave (you gave the the code to do that). Think of an airplane....minimum of 2 each... wing lights, strobes, red flashing, landing lights....all working independently. The only one that would change would be the landing light one, so I kinda left that for last thing for cog 0 to do and to loop that part.
One cog handles 2 pins solid lights
one cog handles 2 pins with flash 1
two cogs handle 4 pins with flash 2
one cog handles the radio input/get square wave
Main cog calls all the above and then loops on a method at the end that keeps calling the radio cog and then either calls another cog or just loops back to the check radio cog.(To clarify, it will use a case to determine whether to turn on, wig wag, or turn off the landing lights by starting and stopping one of two methods in one cog by using coginit.....if I ever get that far).....The big point is that I want everything to run independent of each other.
So I will go write a loop to init my array until I learn how to use the DAT structures and see if this works better, maybe try the offering above and see what I can learn.
Topping it all off, I haven't a clue, just desire to learn.
The lights that flash on an airplane are not changing at a fast rate. Cogs are precious -- save them when you can. I'll bet if I understood all of the conditions I (and others) could show you how to use a finite state machine approach to run all the lights in a single cog. Your master code would update a control variable that affects lighting behavior.
Ok, well just learning here. You guys are pros, I am neonatal here........Going to work on that data statement. I really want to write this myself. I don't want others to do it for me, tho I am not beyond copy and paste to speed things up IF I UNDERSTAND the code. Won't use code I haven't been able to understand yet, that is cheating and not learning. I will get there. Back to plugging along.
Your call. You learned to walk by watching someone else do it -- you can learn to code that way, too. Unless this is the only program you ever plan on working with...
As this is a thread on airplane lights, can you explain the behavior(s) of the various lights. I love programming, and would love to prove to myself that I can do it in one cog. I won't post that code unless you ask for it.
Sure Jon,
I thought I posted this once, but it wasn't here when I came to ask new question.
First, sure, I would like to see it, go for it...
4 LED's on solid, one in each wing tip and sometimes 2 so there needs to be 4 on.
2 LED's at wing tips, with 1/10 second double flash, with one second pause after On, 1/10 off, On, 1 sec off, repeat
2 LED's Usually rudder and belly with flash 1/2 second on and 1/2 off, alternating which is on and which is off to save power input for LED's
2 LED's Landing lights, with 3 options, off, on always, or wigwag between the two 1/2 sec in the on/off.
The last required the code you gave me to digest the square wave for a case statement for the 3 options, with OFF the default case
Jon,
With hours of testing and modifying, I can get 3/4 (not gone further yet, one bug at a time). I used your DAT statement, called it pinz, and when I called methods, I used @ pinz[x]. The first time it ran, it ran on the correct pins. Things worked okay through the first two method calls. Then I added the third method call and things went bizarre, The program from that point on shifted all the pin locations up by 5 pins. Even removing power from the board did not clear this problem. I could not get pins 1..4 to do anything until I commented out the data statement, and then by hard code, initialized the pins to their place in the array. That resolved all of the problems I had been chasing around getting nowhere.
This way the code works. I left in the comment out code
VAR
byte pin[15]
long PulseWidth
byte index
PUB Main
{{index :=1
repeat until index == 16 This doesn't work either
pin[index] := index++ }}
{{so I hard code it to make program work here}}
pin[1]:=1
pin[2]:=2
pin[3]:=3
pin[4]:=4
pin[5]:=5
pin[6]:=6
pin[7]:=7
pin[8]:=8
''Flash1.LED1(@pinz[1],@pinz[2]) Slow flash
Flash1.LED1(pin[1],pin[2])
waitcnt(clkfreq/2+cnt) ''gives a gap on start so everything isn't starting at same tine
''reducing load on 5V side
''Flash2.LED2(@pinz[3], @pinz[4]) ''all on the same cycle fast flash
Flash2.LED2(pin[3], pin[4])
waitcnt(clkfreq/2+cnt)
Solid3.Solids(pin[5], pin[6], pin[7], pin[8]) 'all solid on
''Solid3.Solids(@pinz[5], @pinz[6], @pinz[7], @pinz[8])
waitcnt(clkfreq/2+cnt)
*****************************
DAT
pinz byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
If you need more information ask me and I will be happy to try to clear things up....try. LOL
You can remove a bit of redundancy with an inner repeat loop. I tend not to toggle pins when a specific pattern is required -- I also tend to go for the most obvious coding so I don't use the ~~ or ~ post operators. While it's not important for this app, I like to use synchronized delays. In this case, the delay times are pre-calculated which simplifies the loop code.
There's a really good explanation of synchronized delays in the manual, starting on page 219. Timing for what happens in the loop synchronized to a singular point, just before entering the loop. Using this style removes the overhead of accessing the cnt register in the middle of the loop, allowing very precise timing of the loop. The only caveat is that anything happening inside the loop, must consume less time than the loop delay.
Comments
Initially, you seem to be stacking a lot of things that don't need to be.
I want the top object to call the "BlinkMethod01", passing it the first two pins in the array of pins.
Expected is to call the LED1 method, which checks and stops cog if in use then returns and starts a cog passing the pin values and runs a pair of led's on the pins. Cleaning out garbage code, and now I get a return from the calling function, but no lights work if I call from the top object. BUT if I add the necessary code to make the BlinkMethod01 work stand alone, the LED's work the way I expected and desire, with that cog.
If I run serial terminal from the BlinkMethod01 proper, not thru the top object, I can see all my debug code(cleaned out for here) and the led's work
So this is the TopLED ...top obj .
Then this is the BlinkMethod01
I am expecting the top object to call a method that starts a cog that runs a method that flashes 2 LED's, for 2 fast short flashes with a longer pause for effect, and for this to continue running while the top object goes and calls another cog and starts another LED process that is totally different.
I hope this is more clear. My family always gets on my case because they dont' understand what I am trying to say, so please ask if I confused. Thanks for the time you may take on this.
BTW... you understand that you cannot pre-initialize a VAR array, correct? Change that to a DAT array if you want to specify the pins in the array without having to do that when the program is running
The cool thing is that the array in pre-initialized but still malleable.
Stepping back a bit, your original code caused me to think you want an object that can flash one or two LEDs. Here's a very simple approach (that works, I tested it) that may give you something to think about. The object object has public methods for each flash type, and corresponding private methods that are launched into a separate cog so that they can run in the background. Calling a new method kills the previous. Of course, you can use .stop to kill anything that is running.
Thanks, Nope, I misunderstood about initializing variable But, I need to study what I have to do for the data section, not learned that yet, so have questions about what you showed me. You mention "t DAT array" but I don't see a t in the example. I also don't know how to address the data. You show "Pinz" Is the 'z' like a position place? I will go read up on DAT in a few.
Your description of the blinker program sounds similar. My ultimate goal is to run multiple cogs with varying light displays that all work independently, including one method that uses radio input, splits up the length of the square wave (you gave the the code to do that). Think of an airplane....minimum of 2 each... wing lights, strobes, red flashing, landing lights....all working independently. The only one that would change would be the landing light one, so I kinda left that for last thing for cog 0 to do and to loop that part.
One cog handles 2 pins solid lights
one cog handles 2 pins with flash 1
two cogs handle 4 pins with flash 2
one cog handles the radio input/get square wave
Main cog calls all the above and then loops on a method at the end that keeps calling the radio cog and then either calls another cog or just loops back to the check radio cog.(To clarify, it will use a case to determine whether to turn on, wig wag, or turn off the landing lights by starting and stopping one of two methods in one cog by using coginit.....if I ever get that far).....The big point is that I want everything to run independent of each other.
So I will go write a loop to init my array until I learn how to use the DAT structures and see if this works better, maybe try the offering above and see what I can learn.
Topping it all off, I haven't a clue, just desire to learn.
The lights that flash on an airplane are not changing at a fast rate. Cogs are precious -- save them when you can. I'll bet if I understood all of the conditions I (and others) could show you how to use a finite state machine approach to run all the lights in a single cog. Your master code would update a control variable that affects lighting behavior.
I thought I posted this once, but it wasn't here when I came to ask new question.
First, sure, I would like to see it, go for it...
4 LED's on solid, one in each wing tip and sometimes 2 so there needs to be 4 on.
2 LED's at wing tips, with 1/10 second double flash, with one second pause after On, 1/10 off, On, 1 sec off, repeat
2 LED's Usually rudder and belly with flash 1/2 second on and 1/2 off, alternating which is on and which is off to save power input for LED's
2 LED's Landing lights, with 3 options, off, on always, or wigwag between the two 1/2 sec in the on/off.
The last required the code you gave me to digest the square wave for a case statement for the 3 options, with OFF the default case
Ok, I think that describes the idea....now.
Still working on my question, .....later
With hours of testing and modifying, I can get 3/4 (not gone further yet, one bug at a time). I used your DAT statement, called it pinz, and when I called methods, I used @ pinz[x]. The first time it ran, it ran on the correct pins. Things worked okay through the first two method calls. Then I added the third method call and things went bizarre, The program from that point on shifted all the pin locations up by 5 pins. Even removing power from the board did not clear this problem. I could not get pins 1..4 to do anything until I commented out the data statement, and then by hard code, initialized the pins to their place in the array. That resolved all of the problems I had been chasing around getting nowhere.
This way the code works. I left in the comment out code If you need more information ask me and I will be happy to try to clear things up....try. LOL
Here's an alternative to a method you posted above.
You can remove a bit of redundancy with an inner repeat loop. I tend not to toggle pins when a specific pattern is required -- I also tend to go for the most obvious coding so I don't use the ~~ or ~ post operators. While it's not important for this app, I like to use synchronized delays. In this case, the delay times are pre-calculated which simplifies the loop code.
Good I get confused with those Dang ~ operators, do not like them. Like 1's and 0's a whole bunch.... or -1 and 0, whichever, I can grasp that one.
Can you explain what you mean with the term synchronized delays. Varying output times?