Trouble passing variable (address) values between objects
squidx
Posts: 33
Hi,
I've looked at a few examples, and thought I could do this, but frustratingly, I seem to be missing the point.
I'm trying to pass the address of the Quad Encoder's output to a display routine that I will be running in its own cog. At this point, I can't even get it to run in a different object, so I haven't even started on making it its own cog.
I would do it all in one object, but I want to be able to access the encoder output (Loc[noparse][[/noparse]0]) from both objects.
The following is what I'm basing things on: (note that \[noparse][[/noparse]\ seems to allow showing the square bracket in the posting)
Main File (works great, tv output shows updated Pos. "encoder" is the quad encoder, "tv" is TV_Terminal)
Now here's the one that doesn't work:
Main file
Video output file and object
So although the technique works as a single file, when I try to pass the Pos address into Loc, it doesn't work.
Any thoughts anyone? Do I need to use @@?
Thanks,
Alex
Post Edited (squidx) : 2/19/2007 1:05:51 AM GMT
I've looked at a few examples, and thought I could do this, but frustratingly, I seem to be missing the point.
I'm trying to pass the address of the Quad Encoder's output to a display routine that I will be running in its own cog. At this point, I can't even get it to run in a different object, so I haven't even started on making it its own cog.
I would do it all in one object, but I want to be able to access the encoder output (Loc[noparse][[/noparse]0]) from both objects.
The following is what I'm basing things on: (note that \[noparse][[/noparse]\ seems to allow showing the square bracket in the posting)
Main File (works great, tv output shows updated Pos. "encoder" is the quad encoder, "tv" is TV_Terminal)
VAR long Pos\[noparse][[/noparse]3\] 'Create buffer for two encoders (plus room for delta position support of 1st encoder) PUB main Init CheckForInput PUB init Encoder.Start(2, 1, 1, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) '(StartPin, NumEnc, NumDelta, PosAddr) PUB CheckForInput repeat reading := Pos\[noparse][[/noparse]0\] 'starts at zero waitcnt(1_000_000+cnt) TV.out(0) 'clears screen TV.str(String("New Reading: ")) TV.dec(Pos[noparse][[/noparse]0])
Now here's the one that doesn't work:
Main file
VAR long Loc\[noparse][[/noparse]3\] PUB main Init video_out.start(@Pos) PUB Init 'ultimately want to run this in new cog Encoder.Start(2, 1, 1, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) '(StartPin, NumEnc, NumDelta, PosAddr)
Video output file and object
VAR Long Loc\[noparse][[/noparse]3\] ' do I need this or can I just use Pos if if I pass it? PUB start(Pos) Loc := long\[noparse][[/noparse]Pos\] ' since this is constantly changing, I want to use the address, not a one-off value pass TV.Start(12) 'Start TV Terminal for output repeat waitcnt(1_000_000+cnt) 'prevents excessive flicker TV.out(0) ' clears screen TV.str(string("Test")) TV.out(13) 'new line TV.str(string("Pos[noparse][[/noparse]0]: ")) TV.dec(Loc[noparse][[/noparse]0])
So although the technique works as a single file, when I try to pass the Pos address into Loc, it doesn't work.
Any thoughts anyone? Do I need to use @@?
Thanks,
Alex
Post Edited (squidx) : 2/19/2007 1:05:51 AM GMT
Comments
1) You don't need "Loc" declared in the video output file. In fact, that's why it doesn't do what you want.
2) The "Loc := long[noparse][[/noparse] Pos]" only copies the value once, at the start of the routine. Use "long[noparse][[/noparse] Pos]" in the "TV.dec()" call.
3) Your start routine for the video stuff won't ever return. That may be what you want.
4) You don't need "@@". It's used in assembly or when tables are statically created in a DAT section since the compiler doesn't know where things will be placed in memory at compile time. Data addresses are known to the compiler as relative to the start of the object's storage. When you use "@" in Spin, the compiler adds the starting address of the object's data storage at run-time. If you make a table containing addresses, you need to use "@@" to tell the compiler to add the starting address of the data storage. (I hope this helps rather than confuses further).
Thanks so much! That advice is right on. I now have 2 new questions!
1) The encoder code allows for many encoders to be read, as well as delta, a parameter which I don't use. You get at the first encoder through Pos[noparse][[/noparse]0], and I have been under the impression you get at the second through Pos, but I've only been using one encoder while I try to get this subroutine going.
Since my call is TV.dec(long[noparse]/noparse]Pos]), and it won't accept parameters like TV.dec(long[noparse][[/noparse]Pos[size=2), how do I read the other encoder(s)? Thoughts?
2) I would like this to be running in its own cog so that I can just call it, start seeing the feedback, but get back to my calling routine and not have to worry about it again. When I try to call a cog, strange things start happening, like maybe I'm overwriting memory: the screen starts flickering and buzzing, the motors, which are on a serial board start to run (!) and it just seems crazy.
I'll put in my new code here for the calling file and for the quad display file, in a state that is currently working, just not in a cog.
Thank you so much for your help. You must be able to tell I'm new at this, particularly addressing multiple processors!
Alex
[/size]
I found the motor minder object, and was very excited, but it isn't designed for quadrature (boo!), so it's really no good for me (it's also designed for 1 pulse per revolution, ew). does anyone else have a quadrature encoder object that they could lend me?
the values that i'm reading out of encoder (which are held in a long array in motortest) are doing strange things. they're flipping around in the case of the left motor and not returning valid responses, it's receiving an incorrect number of pulses per revolution (documented as 360 but is recognized at more like 600 but this varies too). most visibly, in the code i have an IF statement that isn't functioning correctly at all. when i state:
it won't ever perform the if, but will visibly pass the setpoint when displaying values. i watch it go from 3200 to 3644 to 3800... and nothing happens.
BUT... if i do this:
it trips immediately, no questions asked. then proceeds to display values that start at around 12...
i'm outta my league right now with this, time to bring the cavalry back in on the problem.
also, if we get it working can you give me some pointers on integrating it into the setmotor object?
~~Brian
How about you? Any new results? I have a couple suggestions, based on what I ran into:
* Encoders were giving sketchy results until I started using pullup resistors (I didn't figure this out myself - I'm using the TRD-S2500BD encoders, and I called them... )
* I have been able to successfully compare position with a target like what is frustrating you... I'm not sure how it's different from yours, except that I use more parentheses. I also wait a moment (between 1/10 and 1/2 sec usually) before checking (this is more of a motor board issue):
This code is for moving the motor quickly. I stop it, wait for the motor board to gather its thoughts, then start moving slowly until I am within 5 encoder units of the target, which is well under 1mm.
* For what it's worth, I also had a problem coming back to stopping at zero... -1 or 1 works much better, and there's no appreciable difference.
Hope this helps. I can send you the complete files if you like, including the video output in a cog bit. It's not working perfectly yet, but the encoders aren't a problem right now.
Alex
just a matter of trial and error calibrating. i've got it going fairly straight, and have asked mike green to look into a way to add feedback to the speed loop (i'm using a home-brew h-bridge after my MD23 motor controller crapped out without working once [noparse]:([/noparse] ). and i've got it making good 90deg turns from a standstill... later i'm going to try to calibrate high-speed turns. gonna be quite interesting.
but i'm working on integrating my Rangefinders and other sensors, when i was powering them them from the 5V line on the protoboard something started buzzing (prob the 5V reg) and am wiring up a new one with a standard sized heat sink, not the chopped off one mounted on the board. hopefully the dedicated device can put out the required power... oh well i'll find out in 10 min.
glad that you have your project working... i've got 5 cogs dedicated to my motors, instead of the one or two i would have needed with the serial board... so i'm jealous. it's getting tight, but right now is really holding together nicely.
congrats on your project, what' it for anyway?
~~Brian
The project has a lot of components, but I'm pretty close on the x-y axes. I have been planning to use some backup optical interference sensors just to calibrate better at various locations by adding an offset to my encoder info, but the encoders have been so good I don't think I'll be doing that. I think I'd rather have a hard 'home' location where I jam the motors up against some fixed points (gently!) and then restart my encoder cog. This way I'll still reduce my accumulated errors regularly without having to do very careful sensor positioning.
In a sense, this is much more of an automation exercise than a robot exercise, but I call it a robot anyway! I've written some fun sound routines, so it does seem to have a bit of a personality!
I did try working on my own stepper drivers, but the serial board is really good for my needs. If I needed immediate responses, though, I wouldn't have done it. There is some latency in the communications.
What's your project?
Alex
Graham
I'm not sure why this happens. It may well be because I haven't hooked things up right, or because my load is too massive for the steppers, but I don't think so -- my original tests were on small steppers, no load.
Using the encoders is really great, and for my particular purposes it would be just unwise to run open-loop anyway. I have 4mm targets to hit on a run of 36"x14" (sorry to mix units!). The encoders can get me within 1mm.
Alex