Shop OBEX P1 Docs P2 Docs Learn Events
methods/cogs access to global variables... — Parallax Forums

methods/cogs access to global variables...

gio_romegio_rome Posts: 48
edited 2014-01-30 10:54 in Propeller 1
(sorry for the naiveness...)
I don't even know if I'm making enough sense....anyway I have a human input (already running on a Cogs, works perfectly), two outputs (an LCD and a serial transmission) and of course calculations on other pins' input, all to be done constantly at all time.

So for now I figured a cogsnew call on the human input, that remains vigilant at all time, and an endless repeat cycle on the main method, where I would perform calculations on the input from the ADC and proceed on the outputs. This is because the output of course changes if the calculations change, i.e. if the ADC input changes.

So it's like this.

cogsnews(BUTTON, @stack1) 'call the human input method in a new cog
repeat
....calculations on ADC readings....
....lcd outputs....
....serial transmission outputs...

Some things do not satisfy me.

For instance, to be able to see with my eyes the LCD changes, I have to waitcnt(clkfreq*1 + cnt) before erasing the date from the LCD and writing on new one. But since both lcd and serial transmission outputs are in the same cycle, I stop serial transmission too. And I would've like to use it to monitor everything at all time, not in steps of one second...

I just don't seem to be able to have it all (e.g. the LCD OR the serial transmission, seldomly even human input seems to freeze).

Then the "strangest" things happen. For instance with the Propeller Terminal I have no problems other than the fact that I cannot save the output to a text file. So I use WindowsXP Terminal instead, but when I "hang up" the program reset and the EEPROM is loaded again.

I think all of this could be avoided with a better understanding of the serial transmission protocols AND most of all the COGS. I'd like to run a Cog for each input and a Cog for each output and a Cog for calculations...but then how do I access the same data? With C I would've done it with pointers or something like that, but I'm really new to SPIN.

Thank you and sorry for the lenght


Giovanni

Comments

  • gio_romegio_rome Posts: 48
    edited 2014-01-30 02:11
    I've managed to drive the output into a textfile, so to estimate the sampling rate.

    If I just Adc.In(chnl) a variable though an ADC channel and output it to the serial communication terminal, this while handling a button panel with a method in a separate cog, I can sample ~ 20 values per wave period. Since the wave period is 50Hz (European mains electricity) I have something like 1kHz of sampling rate.

    Now, I'd like to keep this rate and eventually improve it.
    If I put in all the calculations and input/output routines, and all in the Main method, this sampling rate diminishes significantly. The same happens if I add other channels to the Main method. This leads me to think that I'd have to make everything parallel.

    And again this leads to how to share the same values in different cogs: 4 cogs handle 4 inputs on 4 channels, 2 cogs handle 2 outputs, 1 cog handle the computation...

    Any idea?


    Giovanni
  • T ChapT Chap Posts: 4,223
    edited 2014-01-30 04:48
    gio_rome

    It is much easier to glance at the actual code and make some suggestions that might point you in a direction. You are welcome to upload the spin files here and maybe someone can take a look for you.

    If you launch a new cog, you will include a pointer to a variable using the @myvariable method. You can pass this to other cogs being launched in the same way. The new cog can read the variable and/or write to it. Let's say you have launched a new cog and here is the start method in the new cog

    PUB start(pos)

    In this case, you have launched the new cog from your main program using a cognew method that includes yournewcogmethodname.start(@pos)

    Here you have passed a pointer to a LONG in your main method to the new cog using the pointer symbol @.

    The new cog can now read and write that same "address" by doing this:

    long[pos] := 1 ' make the variable become 1

    or read it:

    P := long[pos] ' read from the variable

    You can also access the NEXT LONG in your main program VAR section by doing this:

    I := (long[pos+4] 'get the next LONG ( same as +4 bytes)
    J:= (long[pos+8] 'get the next LONG ( same as +8 bytes)

    This way, you have full access to ANY long, word, or byte that was in your main program.
    Any cog can access these variables, but you have to be careful to manage how not to have train wrecks. You can use a variable as a flag to arbitrate access to the variables.
  • max72max72 Posts: 1,155
    edited 2014-01-30 05:56
    If you are looking for examples the obex is the right place.
    For instance objects that interface to ADC are doing what you describe:
    Passing commands to the object and retrieving data using the shared memory.
    There are different approaches, and it really depends on the task.
    The obex has many objects of different complexity. Some of them are written by experts and excellent coders, others maybe less so. Some are easy to understand, some are pushing the limits and are very difficult even to understand.
    Just to make some examples of precise timing you can have 4 serial ports in the same cog, or drive up to 32 servos. Not for the fainted of earth..
    Post some code and some more details...
    Massimo
  • StefanL38StefanL38 Posts: 2,292
    edited 2014-01-30 10:54
    Hi Giovanni,

    If you describe your problem in detail (which needs some "length") it is better to understand.

    I would appreciate of you would give an overview about you what want to do IN THE END.
    Sampling ADC-Values is not a selfpurpose. I'm sure you are using the ADC-values for something else.

    So please give us an overview about your project. This offers the possability to find new solutions to the main problem.

    Back to your questions:
    As long as methods are started in new cogs from the SAME SPIN-File each method of this spinfile can access any global variable.
    Here is a small democode showing this:
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    
      
    VAR
      long CogStack1[ 20]
      long CogStack2[ 20]
      
      long MyTestVar
    
    
    OBJ
      debug : "FullDuplexSerial"
    
    
    
    
    PUB Main
    'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run
      debug.start(31, 30, 0, 115200)
      
      MyTestVar := 100
      debug.str(string("Start MyTestVar="))
      debug.dec(MyTestVar)
      debug.Tx(13)
    
    
      'both cognew-commands are in the SAME file
      'in this case you can access variables simply by the variable-name
      cognew(M1,@CogStack1)
      cognew(M2,@CogStack2)
      
      repeat
        waitcnt(clkfreq + cnt)
        debug.str(string("MyTestVar="))
        debug.dec(MyTestVar)
        debug.Tx(13)
    
    
    
    
    
    
    PUB M1
      repeat
        waitcnt(ClkFreq * 3 + cnt)
        MyTestVar := 1
    
    
    
    
    PUB M2
      repeat
        waitcnt(ClkFreq * 5 + cnt)
        MyTestVar := 2
    

    This code will change the value of MyTestvar every 3 seconds to value 1 and every 5 seconds to value 2
    cogs and methods are mostly independent.

    If you use a terminalsoftware other than PST open/closing the COM-Port will force a reset of the propeller.
    To avoid this you would have to disconnect the reset-input from the serial interface. But to start transferring code from PC to prop-chip
    you have to create a reset. So the resetline would have to be switchable.

    best regards
    Stefan
Sign In or Register to comment.