Programming Question
Cenlasoft
Posts: 265
Hello,
I found some Spin Objects that I want to use; ADC0831_demo.spin and SquareWave.spin. This is what I want to do.
1. Send a square wave to a spin at a specified frequency.
2. keep that squarewave going.
3. use the 0831 adc ic to read the output voltage from a prop pin
4. use the the fullduplexserial.spin object to send it to hyperterminal
I have the circuit working and I can do each object separately.
I wrote this to produce the squarewave:
{{SquareWaveLC.spin
Use SquareWave.spin to excite coil.
LC Circuit SCHEMATIC
──────────────────────
100 Ω 560 pF 2.14 mH
P5 ────||────────────── GND
Resonance Frequency is 203.3 KHz
}}
CON
_clkmode = xtal1 + pll16x ' Crystal and PLL settings
_xinfreq = 5_000_000 ' 5 MHz crystal
OBJ
sqw : "SquareWave" ' Declare Square wave object
PUB go
'clkgen.Freq(I/O pin, module=0 or 1, frequency in Hz)
sqw.Freq(5, 0, 200_300) ' P5, channel 0, 203 KHz
'Cog moves on to other jobs and lets counter modules send a wave to the scope.
waitcnt(clkfreq*7+cnt) ' Blink for 10 seconds
I am new to prop and I would appreciate any help.
Cenlasoft
I found some Spin Objects that I want to use; ADC0831_demo.spin and SquareWave.spin. This is what I want to do.
1. Send a square wave to a spin at a specified frequency.
2. keep that squarewave going.
3. use the 0831 adc ic to read the output voltage from a prop pin
4. use the the fullduplexserial.spin object to send it to hyperterminal
I have the circuit working and I can do each object separately.
I wrote this to produce the squarewave:
{{SquareWaveLC.spin
Use SquareWave.spin to excite coil.
LC Circuit SCHEMATIC
──────────────────────
100 Ω 560 pF 2.14 mH
P5 ────||────────────── GND
Resonance Frequency is 203.3 KHz
}}
CON
_clkmode = xtal1 + pll16x ' Crystal and PLL settings
_xinfreq = 5_000_000 ' 5 MHz crystal
OBJ
sqw : "SquareWave" ' Declare Square wave object
PUB go
'clkgen.Freq(I/O pin, module=0 or 1, frequency in Hz)
sqw.Freq(5, 0, 200_300) ' P5, channel 0, 203 KHz
'Cog moves on to other jobs and lets counter modules send a wave to the scope.
waitcnt(clkfreq*7+cnt) ' Blink for 10 seconds
I am new to prop and I would appreciate any help.
Cenlasoft
Comments
Can you describe in more detail what you need help with?
Are you saying that you have only gotten as far as #1 on your list, and now need to ove on to #3?
I have 1, 3, and 4 done as stand alone. Do I start a new cog for each step? How do I call all the objects from a main program? Number 3 and 4 are in the same spin code and it works. I just want to learn how to make a program to call the other objects I guess. How do I make number 2 work and then do everything else?
Thanks,
Cenlasoft
Yes, you start a new cog for each step in this general situation (Steps 1,3,4), but you can use the main cog to handle one of those steps, or just let it supervise (drive terminal say).
Most of the library code I have seen, has been designed to at least be able to run in a cog, so it should be easier to make this work than polling. You are looking for the function called Start or Init in general.
In a general sense, you assign an object to a cog, and so you can call object methods for a library that has been started on a cog (from other cogs), to affect its behaviour if it has been designed this way. And most seem to be designed this way. This is a simplification...
The propeller chip is basically 8 cpus in one chip, there are no interrupts (although you can sleep until a pin(s) change), the architecture is designed to assign a cog (cpu) to each task that requires *real time* response.
The propeller manual describes the process fairly well, the library object should have something like "Start" or maybe "Init" that starts the library software on a new cog.
The manual can be downloaded here: www.parallax.com/Portals/0/Downloads/docs/prod/prop/WebPM-v1.1.pdf
Page 117 is where they describe running a function on a cog, but you should probably start earlier so you understand things better. (I would go through the manual, it makes things quite straightforward for beginning.)
But basically you assign a cog to run a function, when (if) it returns, that cog goes to sleep and becomes available for other purposes.
Keep in mind that once the function running on a cog returns, the cog goes to sleep (and you lose any output interaction settings), this can happen to your main cog, If you need it to keep running for some reason, you need to make sure the last thing you do is some sort of infinite loop (use it for your polling loop rather than another cog, so you are not wasting electrical current).
If you are running out of cogs, then it is time to decide what functions can be polled rather than requiring real time processing. However, it seems unlikely that you will run out of cogs easily.
To me, the Propeller chip is like an 8 way SMP computer on a chip.
Propeller programming can very easily be parallel programming, with the pitfalls thereof.
When you are designing your own code, if you are only dealing with long variables, you do not need to worry about memory contention (the hub hardware handles everything). If you are working with the cog ram, then of course your cog owns its own ram. However, if you are dealing with global memory, and whatever set of values that go together needs to be accessed as something other than a long, you need to use the locking instructions. They are quite straightforward and explained in the manual.
What you want to do (so far) sounds like system integration, with a small bit of work, and a bit of looking around in the object exchange, you should be well on your way in a short time.
The propeller OBEX seems to have all the typical tasks handled quite well.
I think that you can be productive with a propeller in way less time than other embedded processors because of the architecture and the OBEX, if it seems difficult, ask yourself if you are doing something the wrong way.
If you need more information, just ask [noparse]:)[/noparse].
(Is SquareWave written by yourself? I suppose it's using a counter to produce a constant square wave?! Or do you frequently update the frqa? My guess here is that you don't need a COG for that, because cntra will do the whole job of running the square-wave.)
In the main program you assemble your system. You have an OBJ section which defines all needed objects (Serial, ADC). Then you start the drivers (Serial,ADC again ;o) by calling their init or start function. Drivers will very likely start a COG, which waits for commands. The commands are usually given by calling other methods of the object. For example Serial.str() will do everything needed to let the serial COG output the given string.
ADC is presumably started with giving it a memory adress where it has to write the result of analog to digital conversion to.
Your main program can simply take the value from there and do whatever it wants to do with it - send it via serial interface in this case.
So, this is a rough sketch of the program
1. initialize serial interface
2. initialize adc
3. initialize counter
4. repeat
4a. read adc value - maybe you have to sync here?
4b. send adc value to serial interface
For generating a square wave and keeping that square wave going, check out the FrequencySynth object that's part of the Propeller "Library" where you installed the Propeller IDE.
This object does not use an additional cog, but rather uses the counters within the cog it was originally called from.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
The object is easy. My eddy current analyzer is almost done. The only problem I have is getting the voltage divider to bring down the voltage. I can bring it down to 4 volts rms, but the 0831 does not respond well to this. My new digital two channel scope has solved the problems I have been having before. Is it the rms volts or the peak to peak used in the voltage divider formula? My voltages are: across the coil = 244 V AC RMS, 254 V DC after diode.
Thanks,
Cenlasoft
{{ECA.spin
Exciting an LC circuit to measure eddy currents.
Resonance Frequency is 828.000 KHz
}}
CON
_clkmode = xtal1 + pll16x ' Crystal and PLL settings
_xinfreq = 5_000_000 ' 5 MHz crystal
FPin = 0
LFreq = 828_000
OBJ
sqw : "Synth" ' Declare Synth object
PUB go
sqw.Synth("A", FPin, LFreq)
Thanks,
Cenlasoft
You need to use peak-to-peak IMO, RMS is the equivalent DC power if I remember correctly. So the peak AC voltage will be higher than the RMS voltage, and if your divider is not bringing down the voltage enough, and you are using RMS, that may be why.
As well, only the top object in your compile can set the crystal frequency, I assume you ran that as the main object?
The code you posted provides 828kHz on this end, however I would place a repeat command at the end of your program to keep the COG alive. ...But your getting 40kHz? hmmm, the DEMO code has a default value of 40 kHz are you sure that your version is getting uploaded to the Propeller?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I was thinking the same thing so I tried my other code (Squarewave) and it worked. How do I know if the code is in the prop?
Cenlasoft
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·······
······· "What do you mean, it doesn't have any tubes?"
······· "No such thing as a dumb question" unless it's on the internet
········