Secondary Cog will not start
CountMurphy
Posts: 19
I'm not sure what I'm doing wrong here. My main function looks like this:
The cog code in question looks like this:
When ShowVideoCog is called from main, nothing happens on the screen, and the gps turns on. Nothing else happens after this. If I comment out gps.ProcessLocalDateTime(DST), the code should play the animation on the screen, turn the gps on, wait, turn the screen off and kill the GPS. What actually happens is the GPS turns on. Thats it. I tried running my video code without starting a new cog and it works just fine. I even tried to simply turn an LED off and on with the new cog and I get the same results. The entire program seems to stall and the led never blinks. I have tried both coginit and cog new with the same results.What am I doing wrong? I am compeltly out of ideas
SC.Clear 'clears OLED Screen SC.ShowVideoCog 'supposed to launch new cog to animate screen gps.init 'turns on GPS gps.ProcessLocalDateTime(DST) 'parses GPS data waitcnt(clkfreq+cnt) SC.FadeOut 'turn screen off gps.kill 'turns off GPS
The cog code in question looks like this:
var long stack[20] pub Init serial.init(5,4,9600) pub ShowVideo MediaInit serial.tx($FF) serial.tx($BB) serial.tx($00) serial.tx($00) serial.tx($00) serial.tx($00) WaitForComplete pub ShowVideoCog coginit(7,newCogSetup,@stack) pub MediaInit serial.tx($FF) serial.tx($B1) WaitForComplete pri newCogSetup ShowVideo
When ShowVideoCog is called from main, nothing happens on the screen, and the gps turns on. Nothing else happens after this. If I comment out gps.ProcessLocalDateTime(DST), the code should play the animation on the screen, turn the gps on, wait, turn the screen off and kill the GPS. What actually happens is the GPS turns on. Thats it. I tried running my video code without starting a new cog and it works just fine. I even tried to simply turn an LED off and on with the new cog and I get the same results. The entire program seems to stall and the led never blinks. I have tried both coginit and cog new with the same results.What am I doing wrong? I am compeltly out of ideas
Comments
-Phil
Another thing is that each cog has its own set of I/O registers. One cog may have initialized DIRA so that a pin is an output, but another cog may have left it as the default (input). Even though the 2nd cog is sending data to OUTA, it doesn't make it out to the I/O pins.
I don't understand why your program is so convoluted, but I'd suggest you simplify the use of multiple cogs first. Let library objects first be the only ones to start up new cogs, then think carefully about why you'd want or need to move a section of code into another cog. When you do that, you can first think about all the ramifications in terms of I/O usage, shared memory access, etc.
Originally, I was using cognew. When that didn't work I tried coginit. When that didnt work I posted here. Currently my program only uses 2 cogs (The main, one for the gps library and hopefully 3 if I can get this one working. I doubt cog 7 was being used).
I did also try to reinialize the pins using the serial.init in the new cog (tried it before posting the original post). Again, nothing really happened.
How is the program convoluted? The way its setup now when I make any call to the screen functions, I need to wait for the complete signal from the OLED before I can continue. since my animation is about 10 seconds,there would be 10 seconds without the prop doing any acutal work with the GPS while the code waited on the OLED. I do of know a way around that, but why not just spin up an extra cog to play the animation while the other cogs do the real work? Or did I misunderstand your quote? Either way I will need to figure out how to start cogs properly for another task I have down the road.
What would you do to make my code unconvoluted?
You've only posted part of your program, so it's hard to figure out for sure which parts are being executed by one cog and which parts are being executed by the other cog. It may be that the animation needs to be done by a 2nd cog and that's the cog that needs to "own" the serial I/O routines. Alternatively, the serial.tx and serial.rx routines may need to be modified so they can be called by either of the two cogs without getting confused. It depends partly on what WaitForComplete does.
That makes perfect sense, thank you. I am going to need to rethink this. Does spin have built in semaphore support, or is that something I will have to code by hand / get from a library?
As Mike Green suggests, I think your serial object is causing the problem. Call "Init" from the same cog as the cog which will use the serial object. If it's something like SimpleSerial, you can't use if from multiple cogs. Many of the other serial driver can be used from multiple cogs but it's still a bad idea to do so.
I generally try to have one cog take care of all the serial tasks. If more than one cog can use the serial driver they end up stepping on each other's output. If you do want to use if from multiple cogs, I know I have an example of using locks to keep the cogs from using the driver at the same time. If you'd like, I'll try to find an example.
What objects are you using for you GPS stuff. When I started a GPS project about a year ago I was dismayed by the way serial objects were used within the GPS code I had found in the OBEX. Hopefully you found a better start place than I had.
Enjoy!
Mike
I too wasn't thrilled with most of the gps objects I found. I Ended up using gps_io_mini and it works really well. The only link I could find for it was here: https://code.google.com/p/robot-chopper/source/browse/trunk/Analysis/Communications/RF+DAQ/Propeller+Program/GPS_IO_mini.spin?r=218
If you have that example on locking I would love to read it.
@Mike Green
I will definetly read up on LOCKxxx. Thanks for your help!
@msrobots, SC.Init is one of the first lines I call, though I didn't post any code that high up. Thanks anyway though