methods/cogs access to global variables...
gio_rome
Posts: 48
(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
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
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
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.
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
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:
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