Trouble getting a cog to work
AGCB
Posts: 327
in Propeller 1
I'm still playing with the LED&KEY module and making headway. I'm now trying to put the display part of the code in a separate cog to run continuously, displaying whatever the main cog has to display. The display part works great when part of the main cog but does not when put in its own cog.
This works
This does not. I've used cogs before many times but this must be something unique. They are the same in every other respect.
The TV shows the cog as number 3
Thanks
Aaron
This works
CON '4th try. Displays value without zeros to left of significant digits. _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 DIO_PIN = 24 CLK_PIN = 25 STB_PIN = 26 OBJ tv : "tv_text" VAR byte DIN[4],counter 'not used in this iteration long myStack[50] long displayValue long myValue,digpos,divisor PUB main tv.start(0) dira[DIO_PIN] := 1 dira[CLK_PIN] := 1 dira[STB_PIN] := 1 outa[STB_PIN] := 1 outa[CLK_PIN] := 1 DisplayValue:=83 'value to display divisor:=1 tv.move(3,3) tv.str(string("divisor = ")) 'show current divisor tv.dec(divisor) clear 'start with clean registers repeat digPos from 0 to 7 'right to left digit display tv.move(1,1) tv.str(string("digpos ")) 'show current digit position if wait is long enough to see tv.dec(digpos) start send_byte($8f) 'turn on bright end start send_byte($40) end start send_byte(digSel[0 + digPos]) 'enable the next digit send_byte(Digits[0 + DisplayValue / divisor // 10]) 'display the digit tv.move(2,2) tv.str(string("digit ")) tv.hex(Digits[0 + DisplayValue / divisor // 10],2) 'show hex value of digit waitcnt (clkfreq /100000+ cnt) 'time between repeat loops. Normally 1/100,000. Slow to 2 seconds to read TV end IF divisor * 10 > displayValue 'No zeros left of msd quit divisor *= 10 'to display next ms digit tv.move(3,3) tv.str(string("divisor = ")) tv.dec(divisor) DAT ' 0 1 2 3 4 5 6 7 digits BYTE %00111111, %00000110, %01011011, %01001111, %01100110, %01101101, %01111101, %00000111,{ $3F $06 $5B $4F $66 $6D $7D $07 ' 8 9 }%01111111, %01101111 ' $7F $6F digsel byte $CE, $CC, $CA, $C8, $C6, $C4, $C2, $C0
This does not. I've used cogs before many times but this must be something unique. They are the same in every other respect.
The TV shows the cog as number 3
OBJ tv : "tv_text" VAR byte DIN[4],counter 'not used in this iteration long myStack[50] long myValue, runningCogID PUB main tv.start(0) dira[DIO_PIN] := 1 dira[CLK_PIN] := 1 dira[STB_PIN] := 1 outa[STB_PIN] := 1 outa[CLK_PIN] := 1 runningCogID := cognew(ShowValue, @myStack) + 1 wait1 tv.str(string("cog = ")) tv.dec(runningCogID) wait1 repeat myValue:=46890 'value to display PUB ShowValue | divisor, digpos, displayValue clear 'clear display Repeat displayValue:=myValue divisor:=1 repeat digPos from 0 to 7 'right to left digit display start send_byte($8f) 'turn on bright end start send_byte($40) end start send_byte(digSel[0 + digPos]) 'enable the next digit send_byte(Digits[0 + DisplayValue / divisor // 10]) 'display the digit waitcnt (clkfreq + cnt) 'time between repeat loops. Normally 1/100,000. Slow to 2 seconds to read TV end IF divisor * 10 > displayValue 'No zeros left of msd quit divisor *= 10 'to display next ms digit
Thanks
Aaron
Comments
To the code for the new cog...
I had tried that but left it in both cogs thinking that the send_byte and other methods needed it also in the main cog. I guess not!
Aaron
Just like the TV driver does, the main spin file passes the pin numbers needed to that file...
So do you mean a separate object in the library to be called by top object. I've made a few simple ones of those and saved them in the library.
Aaron
Normally, I put a "Start" function in the sub-objects that receives the pin numbers and starts up any cogs needed.
That really shouldn't be a problem. I frequently do this with a background cog that spits out continuous debugging information to a terminal. It seems like the code you've submitted here is not complete, because the IO pins in your listing are never used.
I'm with Ray on these points:
-- Define your project pin numbers at the top of the program code. I put { I }, { O }, or { IO } comments on each pin definition line.
-- Generic objects should go into a separate file so they can be shared.
Specialty objects can be embedded, so long as you follow the rules that have been outlined about pin use. The advantage of an embedded Spin object is that it can access the objects defined by the application, so long as you don't have a conflict with the top-level code (e.g., you don't want to your main code and background code sending values to the TV object).
There is another case for embedded Spin cogs: When the project has specific hardware that makes that code specific -- not useful to other projects by placing in an external file. I have attached my template file for the EFX-TEK HC-8+ controller. I designed the HC-8+ circuit for EFX-TEK. In the main code you'll see there is a background Spin cog that refreshes a bunch of inputs (through shift registers), manages a red/green LED so that it can be red, green, yellow, or off, and flash between any two colors. Finally, it keeps track of a 1m-resolution timer that can be used for long events. This background Spin code is often modified for specific projects. Most don't use the RG LED. I have a few that need simple, monotonic music, so there is a version that can do that.
Finally, in the case for generic objects... last week I went through the exercise of removing numeric formatting routines built into display objects (like FullDuplexSerial, serial LCDs, I2C LCDs) that have a .str() (string output) method. Any device that wants to display formatted numbers can use an object called jm_format.spin (which originated at Parallax; I have made heavy updates). In fact, if i ever decide to use TV_Text, I will update it to use the jm_format.spin. You could either add this to TV_Text, or you could add it to your main app and then remove the formatting code from your background cog. That might look like this.
Final note: You'll see that I define by embedded Spin cogs as private methods. In the top level object, there really is no such thing as a private method -- this just serves to remind me not to call that code like a standard method.
I've admired your coding for a long time but lots of it is beyond my skill level.
Aaron