Can only start 5 cogs?
eagletalontim
Posts: 1,399
Did I run out of cogs or something? If I null out one of the "cognew" lines, the program continues. I am only counting 5 cogs?
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CR = 13 ' Define Pins CS = 0 'CLK = CS + 1, MISO = CS + 2, MOSI = CS + 3 -> ADC PINS ACC1 = 4 ACC2 = 5 ACC3 = 6 ACC4 = 7 WIND = 8 W_STOP = 9 E_STOP = 10 XB_IN = 15 XB_OUT = 16 XB_BAUD = 9600 ' Output UP = 11 DOWN = 12 LEFT = 13 RIGHT = 14 ' Offsets east_offset = 0 west_offset = -19 up_offset = 10 down_offset = 0 ' Define Specifics Max_Freq_Count = 4095 ' Max number counted from sensor SampleRate = 70 ' Time between E/W and U/D sample MaxSampleCount = 1000 ' Cloud Buffer Min_EW_move = 164 ' Minimum Pulse count to move East or West Min_UD_move = 164 ' Minimum Pulse count to move Up or Down UD_Park_Range = 162 EW_Park_Range = 162 ' Go to Park mode when EW pulse count equals X Park_Timer = 10000 ' Number of loops before Park is initiated Wake_Timer = 10000 max_diff = 5 ' Serial Terminal Stuff DEBUG_BAUD = 9_600 DEBUG_HEADING_X = 1 ' Output formatting data DEBUG_HEADING_Y = 1 DEBUG_DYNAMIC_X = DEBUG_HEADING_X + 8 DEBUG_DYNAMIC_Y = DEBUG_HEADING_Y + 2 VAR LONG variableStack[400] LONG moveStack[400] LONG wifiStack[400] LONG temp LONG EWArray[MaxSampleCount] LONG UDArray[MaxSampleCount] LONG register, East_Count, West_Count, Up_Count, Down_Count LONG EWdiff LONG EWdiffavg LONG UDdiff LONG UDdiffavg BYTE EastSwitch BYTE WestSwitch BYTE shutdown BYTE Park_Flag BYTE threshold_flag BYTE moving_flag BYTE buffer[200] BYTE cog OBJ adc : "ADC_MCP3204_SE_SPI" Pst : "Parallax Serial Terminal" xb : "FullDuplexSerial" PUB go | index, char, EWarray_pointer, UDarray_pointer, aloopcount, arraysum, threshold_count shutdown := 0 moving_flag := 0 aloopcount := 0 threshold_count := 0 threshold_flag := 0 dira[E_STOP]~ dira[W_STOP]~ Pst.Start(DEBUG_BAUD) '1 Cog pause(300) adc.start(CS, 0, @East_Count, @West_Count, @Up_Count, @Down_Count) '1 Cog pause(1000) cog := cognew(controlMovement, @moveStack) '1 Cog pause(500) cog := cognew(Handle_Wifi, @wifiStack) '2 Cogs Pst.Dec(cog) 'Pst.Clear Pst.Position(DEBUG_HEADING_X, DEBUG_HEADING_Y) Pst.Str(string("Current Position", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("------------------------", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("East ................", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("West ................", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("EWdiff ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("EWavg ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("Up .................", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("Down ................", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("UDdiff ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("UDavg ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("Park ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("West SW ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("East SW ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("Thrshld ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("Moving ...............", 13)) Pst.PositionX(DEBUG_HEADING_X) Pst.Str(string("Sending data to XB...", 13)) xb.str(string("Solar Connected!")) repeat ReadSwitches Update_Debug_Window if East_Count > West_Count EWdiff := East_Count - West_Count else EWdiff := West_Count - East_Count ' if Up_Count > Down_Count UDdiff := Up_Count - Down_Count else UDdiff := Down_Count - Up_Count aloopcount++ if aloopcount => SampleRate if East_Count > Min_EW_move OR West_Count > Min_EW_move EWArray[EWarray_pointer] := EWdiff EWarray_pointer++ if EWarray_pointer == MaxSampleCount EWarray_pointer := 0 if Up_Count > Min_UD_move OR Down_Count > Min_UD_move UDArray[UDarray_pointer] := UDdiff UDarray_pointer++ if UDarray_pointer == MaxSampleCount UDarray_pointer := 0 EWdiffavg := getAverage(@EWarray) UDdiffavg := getAverage(@UDarray) aloopcount := 0 if East_Count > EW_Park_Range OR West_Count > EW_Park_Range OR Up_Count > UD_Park_Range OR Down_Count > UD_Park_Range threshold_count++ if threshold_count > 2000 threshold_flag := 1 else threshold_flag := 0 threshold_count := 0 PUB Handle_Wifi | index, char xb.Start(XB_OUT, XB_IN, %0000, 9_600) repeat index~ ' Reset the buffer pointer repeat char := xb.rxCheck ' Read port if char > 31 ' ASCII code of character must be > SPACE buffer[index++] := char ' Append it to the string buffer until char == 13 ' Received an end of line character buffer[index]~ ' Insert a null at the end of the string buffer, so it can a zstring PUB controlMovement | park_loopcount, wake_loopcount, moving_east, moving_west, moving_up, moving_down dira[LEFT]~~ dira[RIGHT]~~ dira[UP]~~ dira[DOWN]~~ moving_east := 0 moving_west := 0 moving_up := 0 moving_down := 0 repeat if EastSwitch == 1 outa[RIGHT] := 0 if WestSwitch == 1 outa[LEFT] := 0 if EWdiffavg => max_diff if East_Count > West_Count AND moving_west == 0 goEast moving_east := 1 elseif West_Count > East_Count AND moving_east == 0 goWest moving_west := 1 else EWoff moving_east := 0 moving_west := 0 if UDdiffavg => max_diff if Up_Count > Down_Count AND moving_down == 0 goUp moving_up := 1 elseif Down_Count > Up_Count AND moving_up == 0 goDown moving_down := 1 else UDoff moving_down := 0 moving_up := 0 if East_Count < EW_Park_Range AND West_Count < EW_Park_Range AND Up_Count < UD_Park_Range AND Down_Count < UD_Park_Range AND Park_Flag == 0 park_loopcount++ wake_loopcount := 0 if park_loopcount > Park_Timer Park Park_Flag := 1 else if East_Count > EW_Park_Range OR West_Count > EW_Park_Range OR Up_Count > UD_Park_Range OR Down_Count > UD_Park_Range wake_loopcount++ if Park_Flag == 1 AND moving_flag == 0 AND threshold_flag == 1 AND wake_loopcount > Wake_Timer Wake wake_loopcount := 0 park_loopcount := 0 PUB getAverage(the_array) | i, arraysum arraysum := 0 repeat i from 0 to MaxSampleCount - 1 arraysum += long[the_array][i] return arraysum / MaxSampleCount PUB goEast outa[LEFT] := 0 if EastSwitch == 0 moving_flag := 1 outa[RIGHT] := 1 else outa[RIGHT] := 0 return PUB goWest outa[RIGHT] := 0 if WestSwitch == 0 moving_flag := 1 outa[LEFT] := 1 else outa[LEFT] := 0 return PUB goUp outa[DOWN] := 0 moving_flag := 1 outa[UP] := 1 return PUB goDown outa[UP] := 0 moving_flag := 1 outa[DOWN] := 1 return PUB EWoff outa[LEFT] := 0 outa[RIGHT] := 0 pause(100) moving_flag := 0 reset_EW_avg return PUB UDoff outa[UP] := 0 outa[DOWN] := 0 pause(100) moving_flag := 0 reset_UD_avg return PUB reset_EW_avg longfill(@EWarray, 0, MaxSampleCount) EWdiffavg := 0 'pause(1000) return PUB reset_UD_avg longfill(@UDarray, 0, MaxSampleCount) UDdiffavg := 0 'pause(1000) return PUB ReadSwitches | i if ina[W_STOP] == 0 WestSwitch := 0 else WestSwitch := 1 if ina[E_STOP] == 0 EastSwitch := 0 else EastSwitch := 1 return PUB Park | i Park_Flag := 1 threshold_flag := 0 UDoff EWoff pause(100) i := 0 'goUp repeat until WestSwitch == 1 or threshold_flag == 1 goWest EWoff pause(2000) repeat until i == 1199 or threshold_flag == 1 goEast pause(10) i++ EWoff pause(2000) i := 0 repeat until i == 30000 or threshold_flag == 1 goUp 'goDown pause(10) i++ UDoff return PUB Wake | i Park_Flag := 0 UDoff EWoff pause(100) repeat until EastSwitch == 1 goEast pause(10) EWoff pause(2000) i := 0 repeat until i == 20000 or threshold_flag == 1 and i => 5000 'goUp goDown pause(10) i++ UDoff return PUB Update_Debug_Window Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y) Pst.Dec(East_Count) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 1) Pst.Dec(West_Count) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 2) Pst.Dec(EWdiff) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 3) Pst.Dec(EWdiffavg) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 4) Pst.Dec(Up_Count) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 5) Pst.Dec(Down_Count) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 6) Pst.Dec(UDdiff) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 7) Pst.Dec(UDdiffavg) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 8) Pst.Dec(Park_Flag) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 9) Pst.Dec(WestSwitch) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 10) Pst.Dec(EastSwitch) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 11) Pst.Dec(threshold_flag) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 12) Pst.Dec(moving_flag) Pst.Str(string("...")) Pst.Position(DEBUG_DYNAMIC_X, DEBUG_DYNAMIC_Y + 13) Pst.Str(@buffer) 'Pst.Str(string("...")) return PUB pause(Duration) if(Duration > 0) waitcnt((clkfreq / 1_000 * Duration) + cnt) return
Comments
COGS
0 spin
1 pst
2 adc
3 controlMovement
4 Handle_Wifi
5 xb
6 ?
7 ?
As we can see in the code posted that Handle_WiFi also starts the xb cog as well. I don't know about pst and adc if they do anything extra.
Edit. It is modified a bit from the original posted as I keep trying different things to make it work. Still no luck yet
That didn't include "Parallax Serial Terminal" but if you use the "archive" function in the File menu it will include all files.
Since the original code didn't include coginit calls I'm guessing you added them out of desperation.
What are you expecting the code to do which it's not doing?
I noticed your buffer index in "Handle_Wifi" is not checked to make sure it doesn't overflow the buffer. It's not uncommon for FDS to pick up $FF values from an idle line. There's chance your buffer is overflowing though I kind of doubt this.
I don't think you're running out of cogs. I think your problem is elsewhere (where it is I don't know).
EDIT * : The weird thing is, I can null out any of the lines that start a new cog and the program will run....just without that feature.
Why do you coginit instead of cognew? Are you saying that this program as is won't work unless you disable one of the cog start lines? Example?
EDIT: you are taking chances hoping that the "buffer" does not overflow which could easily happen with transmission errors and noise etc. Always put a limit on your buffer writes, easy to just make this buffer 256 bytes and limit the write index to a single byte.
But what is going on here!!!!!! 400 longs ---- wahhhh!!!
LONG variableStack[400]
LONG moveStack[400]
LONG wifiStack[400]
If you run the code and open the serial terminal, you will see what is happening
It's working fine with all cogs as far as I can tell. The only thing I did extra was insert a 3 second startup delay so I could switch to the terminal. As each cog starts up it draws a little more current but unless your hardware was really underpowered I can't see that being a problem. But if it is not adequately decoupled then that is probably your problem.
I tried coginit out of desperation to get this working. Did not help.
Yes, if I disable any cog start, the program will run.
I never did understand the Stack part of a cog and I usually put 100 or 200. I tried 400 out of desperation as well....
100 is already way over the top but your problem seems to be hardware decoupling.
Here is the last screen shot of my circuit board layout before I ordered them.
Is there something that was missed? Should I use a different value decoupling cap on the Prop pins?
The two caps look ok where they are but just check they are intact (or wrong value) but just to make sure just tack a known through-hole 0.1uf across 9 and 12 directly. Unplug your XBee as that may be drawing a bit of current on start-up and the Prop could have benefited from either its own regulator or at least a direct track back to the main regulator (not via a potential noise source). If your XBee is a 100mW version it could draw quite a bit of current which the regulator should handle but obviously something is happening, so unplug it and check.
Edit * : I have also unplugged the Xbee and tried to run it, but no luck
That's better. You know that regulators don't have to stay in "the power supply area", they work even better when you place them close to the load. Just a tip.
But make no assumptions here, solder a known 0.1uF cap directly to the Prop socket and also measure the supply voltages because if your 5V supply drops then this may affect your 3.3V supplies depending upon what type of regulators you are using there. If you put an LED on the EEPROM SCL line to 3.3V through a 1K resistor you will be able to see it light up when the Prop boots, or in this case, if it reboots because of a supply glitch.
I supposed do this to both decoupling caps?
To be safe for this test solder it direct to the socket pins with a cap that you know for sure is 0.1uF or thereabouts. SMD caps can get mixed up and you can't easily tell what it is in that case. For this test you really only need one but if it's easy enough to do two, then do two. If the problem still persists then try the scope but not before you put a simple diagnostic LED on the board as I mentioned. You just want to know when it reboots.
The code seems to be running Ok and the COG leds indicate 6 x cogs running.
I agree with Peter that decoupling seems to be the gremlin.
I went ahead and soldered on 2 known 0.1uF caps directly to the socket pins and noticed no difference on the O-Scope. The line is pretty flat honestly.
So... having checked all this, I feel as though I something else may be the issue. Right now, the code seems to be running just fine with all cogs fired up.
To better understand about overflowing a variable, is there any "simple" explanation of how to prevent this? Do I just set BYTE index[200] and be done with it?
If you allow for a bleed resistor across your 3.3V supply then this will help with regulation by maintaining a minimum current, and also help with discharging supply capacitance as well as "load up" leakage currents that result from external devices such as USB feeding current through I/O pins back into the supply. Try a value of 1K.
Depending upon what you are using there I doubt very much that the "O-Scope" will pick up glitches, they only have to be tens of nanoseconds long. I know that the Tektronix scopes have a "peak detect" mode to make sure you see where those glitches are.
As for writing to array variables I would always put in index limiting, either in the form of ANDing a mask, or modulus. The other way that I have already mentioned to you is to just declare a byte variable for the index and create a 256 element buffer, that way there is no need to mask as even if you progress past 255 it will just wrap to 0 etc.
I know there is a shorter way to write that, just can't seem to remember how :P I know I have seen it before.
EDIT : This is the O-scope I have : http://www.ebay.com/itm/Mini-Digital-Storage-Color-Oscilloscope-Metal-Handheld-scope-DSO-203-Nano-Black-/221079075360
because if index is 255 when you do index++ it will become zero. A byte cannot exceed 255, and 255 + 1 = 0.
In fact, will never be true.
The whole idea of declaring index as a byte is so that it can never exceed 255 so there is no need to test and reset which btw would normally test for anything in excess of 255 rather than equality (just in case). But remember to allocate 256 elements for your buffer then. I don't think you can declare a local variable as a byte in Spin but just make it a global variable (maybe rename it) like this:
BYTE index,buffer[256]
That scope is just a baby scope so don't expect any wonders from it, handy as it is, it just doesn't have the performance and features of a digital bench scope, so it is not likely that it will show or even trigger on those little glitches. One good thing about them though, as you said "The line is pretty flat honestly" so the display is nice n smooth
Just start a new thread and tell us what you do know, what we should know, and what you don't know. That way those of us in the know will be able to let you know, if you know what I mean, no?
What I am thinking is going on is I am possibly "over running" a variable somewhere in my "PUB go". Problem is...I don't know how to find which one unless I start nulling out lines.
Blah.....
EDIT *** :I have nulled out pretty much the entire PUB go and it is still not working. The Prop is not resetting and the PST is still updating properly as I can see when "East switch" is on or off.