stepper record and playback
Owen
Posts: 100
I'm currently trying to write an object that will record the propeller controlled movement of a stepper motor to an SD card and then be able to play it back again. My setup is an encoder that is used for an input device which is programed on the propeller to step a stepper motor for every pulse of the encoder. I'm having trouble with how to approach this problem, all my attempts I'm sure have been far too complicated. Anyone have any simple ideas?
Owen
Owen
Comments
The second solution (encoder) would generate a lot denser information stream (ie bigger) with less useful data and possibly more noise.
the encoder is connected to a handwheel as a user interface to the motor and is not used as motor feedback. the faster or slower the handwheel is turned the faster or slower the motor moves. ultimately I am controlling the way a camera moves, one handwheel is the panning motion and another is the tilting motion. the idea is to playback the camera motion exactly how it was recorded. I was hoping to track the motors steps over a given amount of time, like a record of of Xaxis and Yaxis every millisecond. Recording the location of the motor is not hard for me it's how to smoothly playback the information that I'm having difficulties with. Anyone done anything similar?
I expect data of this type will be highly compressible. However, it may not be worth the effort to compress it if there is no need to conserve storage space.
- Sparks
· I have done extensive work with decoding data from a gps and found that by slowing down the info to a more managable level it is easier to decode and use. Once it is working you can optimize for speed.
·What program are you using to interperet the data? If the program cannot prosses fast enough you will lose data when trying to decode.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mosquito: An animal which buzzes in your ear and never stops. He may byte you, he may nibble you, but you will know you were bit.
Technologically challenged individual, Please have pity.
Did you already test a program?
what does the steppermotor do if you playback the recorded pulses?
could you post your code here? (with a lot of comments !)
do you have an oscilloscope for displaying the created stream of steppermotorpulses?
what are you recording exactly?
Is it an incremental encoder?
If so - if you manage to record every millisecond the amount of encoder pulses counted
these amount of pulses is directly proportional to the speed of the stepper-motor
if you have an absolute encoder you have to calculate the value-differencies.
In this case you have to take care of turning around the zero-position of the encoder.
you have to calculate from encoderpulses to motorsteps per second (=stepperfrequency) and then set a
stepperpulse-routine to that stepperfrequency. Direction could be inside the sign of the value.
this stepperpulse-routine creates pulses on an IO-Pin endlessly with the frequency READ from
a variable (or in Assembler from a certain RAM-adress)
Lets call this variable "StepFreq"
another routine is reading out the recorded encoderpulses every millisecond, calculating the stepperfrequency
and STORES the stepperfrequency in the same variable "StepFreq"
So the stepperfrequency "0" stops the stepperpulseroutine
And here milliseconds might be a problem:
If you use a steppermotor in fullstep or halfstep-mode (in microstep-mode it could be higher)
The frequency for starting the steppermotor in halfstep-mode from zero is around or lower than 1000 Hz (= 1 pulse per millisecond)
Here it might be better to have a greater timebase f.e. 10 milliseconds
So this would give a minimum of 2 to 10 pulses per time"frame" for the stepperpulse-routine to "send out"
to the IO-PIN
Steppermotors don't like it if you change the frequency too fast. Then you will loose control and the rotor of the steppermotor
is only vibrating instead of turning around.
The limit of this frequencyCHANGE depends on the type of the steppermotor
explaining with extreme (and unrealsitic) values just to make it clear:
let's say your steppermotor is running at a speed of 1000 stepperpulses per second. (=1000 Hz)
If you would CHANGE the frequency within 1 step to another from 1000 Hz to 100.000 Hz
how should the mechanical rotor accelerate within 1/100.000 = 10 microseconds to a speed thats a 100times higher?
That's not possible.
So
It might be possible to do all this inside 1 mainloop
but i suggest for the beginning have one cog for the stepperpulseroutine
and another cog for the SD-Card-reading
give in more concrete information then the forum could help you much better
greetings
Stefan
thanks,
Owen
that's a quick answer (just heard my mobilephone buzz (SMS-email notification)
are you using the function "PUB FREQOUT(Pin,Duration, Frequency)?"
it uses the waitcnt-command which stops the COG COMPLETELY !
use the function "PUB FREQOUT_Set(Pin, Frequency)" instead.
It uses the hardwarecounters to create the frequency.
The hardwarecounters are independend from codeexecutiontime
This one creates the frequency INDEFINATELY.
Initialize with Frequency zero (=no Pulses sended out
FREQOUT_Set(Pin, 0)
once you have startet Playback every 1/100 Secs comes an updated value
that chances the frequency in the right way
For stopping just call FREQOUT_Set(Pin, 0) again
Did you understand how it is working?
if your SD-Card-reading has runtime differencies you can avoid them
by taking a snapshot of the cnt-value right on top of your reading-loop BEFORE start reading
With this snapshot-value you can correct the waitcnt-delay-time
if runtime-differencies have occurred reading the SD-card.
and you have to make sure that the reading is done in less than 1/100 Sec
or whatever your timeframe is
greetings
Stefan
You could use the counters, use one the measure the frequency which is then stored at a regular time interval and then use the counter again to reproduce it.
You can forget all about positions if you do this, it just works out.
Graham
here is the recording and playback code I'm trying to get working...
i didn't include the code that drives the stepper motor during recording but there is another cog that moves the stepper motor and ubdates the memory location @coordinateX which is what the recording code stores on the sd card.
I seem to have trouble with:
sync := cnt
repeat
waitcnt(sync += ((clkfreq / 1_000) * 100))
thanks,
Owen
you have to put the line
sync := cnt
INSIDE the repeat loop
this does what i called a snapshot of the systemcounter right on the beginning of your mainloop
now all the SD-Card-reading can take different times. It doesn't matter anymore
because you refer to a countervalue that comes from a time BEFORE the SD-Card reading starts
to make it really sure you have to implement a timeout inside the sd-card-reading
in your way you are waiting 100ms and then the sd-card-reading take ADDITIONAL time
one example with easy values
sync := cnt let's say the 32bit cnt-value is the same as 1200ms (for easier understanding)
now SD-Card-reading starts and takes different times in the first, the second, th third loop: 10 ms, 80ms, 5ms,
my code does
1200ms take cnt-snapshot
do sd-card-reading (takes 10ms)
waitcnt starts at 1210ms and waits until 1300ms
first loop waitcnt(1200ms + 100ms)
1300ms take cnt-snapshot
do sd-card-reading (takes 80ms)
waitcnt starts at 1380ms and waits until 1400ms
second loop waitcnt (1300ms + 100ms)
1400ms take cnt-snapshot
do sd-card-reading (takes 5ms)
waitcnt starts at 1405ms and waits until 1500ms
third loop waitcnt(1400ms + 100ms)
with this code you have to make sure that the sdcard-reading does take less than 100ms, becouse otherwise
the value sync + 100ms is already through and then the waitcnt waits for almost a minute until the systemcounter
wrappes around to zero and reaches again the value sync + 100ms
your code does
first loop
do sd-card-reading (takes 10ms)
waitcnt(1210ms + 100ms)
waitcnt starts at 1210ms and waits until 1310ms
second loop
do sd-card-reading (takes 80ms)
waitcnt(1390ms + 100ms)
waitcnt starts at 1390ms and waits until 1490ms
third loop
do sd-card-reading (takes 5ms)
waitcnt(1495ms + 100ms)
waitcnt starts at 1495ms and waits until 1595ms
etc.
greetings
Stefan
Post Edited (StefanL38) : 1/9/2008 10:45:38 AM GMT
If you use the counters then you leave your program free to do other things nearly all of the 1ms sampling period can be used for any processing you like. CNT would be used to set the length of the loop as Stefan shows.
This is how I did my stepper motor code in essence, I had a fixed length (in time) loop in which most of the time was spent working out what frequency to send to the motor next.
Graham
thanks,
owen
When done in SPIN you will be around 40 kBit/sec, so 5000 bytes should be feasible (=10x of what you observe)
(b) Buffering of 400 bytes is no problem in COG
This is somewhat similiar to what I am doing, except I am recording remote control inputs to an SD Card. I think this can be related to what you are doing.
In my program, I have a table that stores my keycodes sent from a remote control to the propeller, then an enumerated list that interacts with the previous table to form a lookup table. On the SD Card, I simply write the "KeyNum"(the enumerated number that cooresponds to the code sent), a "comma and space", then the KeyCode(the actual code) written in Hex, then a new line. Basically, the file format looks like this:
0, $00001B14
3, $00001E14
2, $00001C14
14, $00002314
and so on...
What I end up with, is an easily parseable file that I can then manipulate into a record in memory. It's also easy to go in and make slight changes manually to the file. What I suggest you do, is have two components to each line: Step Direction and Delay until next instruction. Like this:
0, 10
0, 10
0, 10
0, 10
0, 10
0, 1000
1, 1
1, 1
1, 1
1, 1
1, 1
1, 1
This simple instruction set translates into: Move LEFT 5 times with 10ms in between steps, then wait 1 second, move RIGHT 5 times with 1ms in between steps.
Like I said, this format is easy to code a translator for. Hey, I could even give you some of my code I'm working on. It's very similiar. Each command is 1 line, and you can add as many variables as you want, like in the a.m. example, it has two. PM me if you want to colaborate.