Shop OBEX P1 Docs P2 Docs Learn Events
Running a complete Spin program in a separate COG — Parallax Forums

Running a complete Spin program in a separate COG

Sabre00Sabre00 Posts: 30
edited 2009-09-01 14:38 in Propeller 1
I am trying to create a device that communicates with a PC, Stores data to an EEPROM and checks a GPS.

I broke down each section into different spin code programs and now I want them to run together it seems as though I can only get PUB or PRI to run in the CogNew or CogInit Command. When I Try to put the initialize procedure in a PUB in the main program eg.

Main Cog

obj

PC :"PC"
EEPROM :"EEPROM"
GPS : "GPS"

var

PUB start
Cognew(Tip,@stack0)
Cognew(PC.Start,@stack)
Cognew(EEPROM.start,@stack2)
Cognew(GPS.start,@stack3)

where there is a PUB start in each of the spin programs and Tip is a PUB within the main program. The above method didn't work except for the Tip PUB.

So I tried to be smart and put the PC.Start into a separate PUB eg PUB PC and put the PC.Start in there is works but it seems to stall.

My question is do I have to write one big program including all of the PUBs from the three spin codes or is there a way I can get a complete spin code to run in a separate cog keeping a nice clean structure to the program.

Sabre00

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-08-19 18:13
    You can't do COGNEW(<object>.<method>,...)

    The method called in the COGNEW must be in the same object that does the COGNEW. If you look at all the objects in the Object Exchange that use separate cogs, the COGNEW is actually done in the Start method. Typically, you'd have something like:
    VAR
       long stack[noparse][[/noparse] ??? ]
       byte cog
    
    PUB start( ... some parameters ...)
    ... first time initialization ...
       result := cog := COGNEW( routine( ... parameters ...), @stack) + 1
    
    PUB stop
       if cog
          cogstop(cog~ - 1)
    
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-08-19 20:25
    every cognew starts a NEW cog as its name says already

    so coding something like

    Cognew(Tip,@stack0)
    Cognew(PC@stack)
    Cognew(EEPROM@stack2)
    Cognew(GPS@stack3)

    starts 4 DIFFERENT cogs each running the specified part of the code

    as you said you want to run ALL the code in ONE cog
    you define your code in different *.SPIN-files = objects
    and then call the methods WITHOUT using cognew-commands

    if parts of your code have to run independ and permant from other parts of your code
    you have to use cognew to run this part of your code in a different cog

    to give further advice you have to post here how the program should work

    if your GPS sends information at unpredictable times the datareceiving-method has to run in its own cog
    to be ready to receive the data all the time
    if your GPS is connected via a standard serial connection the serialdriver like FullDuplexSerial-object is already running in its own cog

    if it is enough to POLL for data or the state of IO-PINs and it doesn't matter if some data is read or written some time eralier or later
    you can call all your methods within one great loop that calls all the methods sequentially

    the code is in different *.SPIN-files
    you have one main.spin-file where all needed objects are listet
    and call them by their objectname

    OBJ
      PC     :"PC"
      EEPROM :"EEPROM"
      GPS    : "GPS"
    
    
    PUB Main
    
      PC.Connect
      EEPROM.Read(...some parameters..)
      GPS.GetPos(...some parameters..)
    
      if X == 57
        PC.SendAlert
        EEPROM.StoreAlertLogEntry
    
      PC.SendDeviceStatus
      etc. etc. etc
    
    



    so it is up to you to provide more detailed information what you want to do in the end

    best regards

    Stefan
  • Sabre00Sabre00 Posts: 30
    edited 2009-08-19 23:42
    Ok I am measuring the GPS and stripping the it of the time and if the time is right I want to check the number of times an input line has been pulled low (tips PUB ) and then store the value in EEPROM. That is the general workings of the program then I want to when requested, to communicate with a PC to download the EEPROM.

    The problem I have to work around is when the PC is communicating with the EEPROM that the main operations don't try to save to the EEPROM when it is being read. Having said that I do not want any readings to be lost in the event that the device is communicating with the PC, that is why I was going the parallel processing route.

    I believe I may have over looked the PC.spin object aspect as I am using the fullSerialDuplex object so there may be no need to call that in a new Cog anyhow.

    I will give it another shot tomorrow but if anyone can help me out with this it would be great.

    If push comes to shove I will put all the relevant code in one object and assign the relevant PUBS to a Cog.

    Thanks again guys...

    Sabre00...
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-08-20 13:31
    I guess your understanding of PUBs, objects and cogs or how they work is not right in all details

    you can have ONE *.spin-file and ONE and the same PUB method running in 8 different cogs if you want to

    the other way: you can have 100 objects (=*.spin-files) with 1000 PUB or PRI methods running in ONE SINGLE cog
    and everything in between. It just depends on what you are coding.

    You can use
    one *.SPIN-fie with all your GPS-code
    one *.SPIN-fie with all your EEPROM-code
    one *.SPIN-fie with all your PC-code
    one *.SPIN-fie with all your tip-code

    With the code disributed in five *.files you can run ALL this code in ONE cog or almost every combination of parts of the code in 1-8 cogs
    just depending on how you programmed it.

    This means you can keep your code well sorted in different *.spin-files with almost no restrictions on how the code is distributed between cogs.

    OK I have more information now so I can make a suggestion:

    the checking of the GPS time has to be done alle the time. What precision do you need in the time ?
    mircoseconds I guess not, 2 milliseconds ?, seconds ?

    if the precisision needed is 2,0 seconds you can code something like that

    you have a main-loop that is checking every 0,8 seconds for the time matching certain time-margins
    if time is matching store amount of low-pulls to EEPROM
    after doing that there is some time checking is there a PC request do read-out the EEPROM
    if so do read SOME EEPROM-bytes and send them to the PC
    this is done sequentually after each other so the writing to EEPROM and reading-from EEPROM can't collide with each other

    if you just send one byte per loop the time needed to send to the PC is short.

    the amount pof time passed by since your last chekcing for time to match is shorter then your needed precisision so you don't miss
    any time-matches. Then after the next check for ti´me-matching the next part of EEPROM-values is send to the PC until all values are send

    If the needed precisision is MUCH higher it depends on how fast everything runs through

    the counting of the low-pulls can be done in its own cog (as you can't predict when the low-pull will come)
    another solution might be to use a counter which counts independ from executing code

    another idea is to use a buffer. Depending on the timings you could store the low-pulled-counts in a arraybuffer as long as
    a PC-request reads out the EEPROM and after finishing the PC-request the values are transferred from the array-buffer to the EEPROM

    but anyway to find a solution that is easy to realise and still suits we need information about the minimum time between two time-matches
    your used baudrate in the PC-connection and the minimum-time the IO-PIN is pulled low (lowtime of the pulse and the maximum frequency
    with wich the low-pulling occurs

    best regards

    Stefan
  • Sabre00Sabre00 Posts: 30
    edited 2009-08-31 13:40
    Just an update so I dont leave the thread open.

    I managed to get the relevant cogs working how I wanted. However, I put all the code into one spin program but when I did that initially it was not working I got the same result, ie the programme stalled when I called the PC interface and the GPS interface. Since I was usingthe "FullDuplexSerial" object I did not start the two of them in new Cogs using the Cognew command. I found that he programme worked when they were started individually but not together which I thought was strange.

    The PC interface the initialization was PC.start(31,30,0,9600) and the GPS was GPS.start(0,-1,0,4800). having looked through the initialization of my programme now I decided to fiddle with the parameter of the objects and low and behold when I changed the GPS to GPS.start(0,9,0,9600) (I used 9 because it was the next available i/o pin) the programme worked.

    I am not sure if it is a problem with the object itself but when I tried the GPS by itself in a separate spin programme it worked with the -1, since I won't be transmitting any information to it.

    Technically what I was doing before should work, but I am so pressed for time I haven't had a chance to go back to see if I can write three separate spin objects and tie them together in one object file.

    Until then, happy "propellering"...

    Sabre00...
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-31 15:56
    FullDuplexserial doesn't support -1 for a pin that is not being used. Simple_serial does as well as the 4port full duplex serial.
  • Sabre00Sabre00 Posts: 30
    edited 2009-09-01 10:47
    Thanks Timmoore,

    Its always the little things. I initially has the SimpleSerial object communicating with the GPS but then I realised I needed a dedicated Cog to handle the communication and parsing of the GPS string. I changes over and just assumed. Once again an Assumption has......

    Sabre00...
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-09-01 14:24
    What happens when you use -1? I've been using it for quite some time without any problems (well, any problems I could determine came from fullduplexserial)?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-01 14:38
    FullDuplexSerial sort of supports the use of an "invalid" pin number. For transmitting, it works ... the code goes through the motions, but no I/O pins are affected. For receiving, the code behaves as if the input line is stuck at zero (a break condition). The code will treat the zero as a start bit, then 8 zero data bits and an invalid stop bit (which the code doesn't check for).
Sign In or Register to comment.