Developing a new controller, Papywizard compatible  

Everything you need to motorize your head
User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

Developing a new controller, Papywizard compatible

by panoguy » Mon Jan 25, 2010 5:16 am

Hi all,
first of all thank you all for sharing all this technical details how to build and make your own pano head. I have read most of the topics and also had a close view on the Papywizard development Wiki. Great work and many thanks to Frederic for publishing so much details.
I want to program my own controller and got a few questions for Frederic regarding the interface.
My controller is based on Atmel atmega 128 and should drive stepper motors.

1. 0E62D3 is the number of encoder counts
1.1 Is this number taken into account by Papywizard? Ie. if I use a different gear the number would be different, so the receiving software, in that case Papywizard must use the number and adjust any following calculations
1.2 Is it possible to have different encoder counts per axis? As guess the tilt gear would use a different gear ratio compared to the pan gear. From the init sequence I see it does send the parameter for both axis, but again the question is what happens if the number is different than 0E62D3? Does Papywizard use the number?

2. What is the rationale to send Low byte first and use Hex numbers? This additional conversion takes additional process time and usually you won't loose the time to convert dec to hex and shift once more. I understand that this is a given due to Merlin protocol, but if you would have a 'universal' plugin in Papywizard, would it not be easier to use the plain decimal count of the encoder position?

3. There are still a few open questions on the parameters and commands
3.1 axis status, there is only mentioned: 3 ascii digits - Second digit is 0 when axis is stopped; What are the other digits used for and what is the return code when axis is moving? I guess 1?

3.2 What is the G command used for? Are there other options as the two mentioned?
G<axis>3<dir>
G<axis>00

3.3 What is the J command used for?

3.3 Drive to position seems to be a straight forward function, to drive to encoder position X, but how is the head moving manually using the function start moving? Do you send that command over and over and the head is moving as long it receives the command?

3.4 Is it possible to increase the port speed of 9600?

I did program already a few lines of code but with my current approach I see a few issues:
The receiver must run in background as interrupt routine to receive and answer commands from Papywizard. Due to the additional steps I need to convert the motor position into the merlin format I loose too much time in the interrupt routine and the processor performs unpredictable operations...
So my question is if I should continue to optimize the code or would it make more sense to implement a simpler 'universal' plugin into Papywizard?

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Mon Jan 25, 2010 8:03 am

Don't bother with the Merin/Orion protocole if you think it is not the best one (and it is not!); I can easily write a dedicated plugin to fit your needs.

I already described the mandatory low levels function Papywizard needs to work; the main thing to keep in mind is that all commands should return immediatly (telling if it was understood or not). Then, there should be a 'get status' command to know if the previous command (mainly the 'goto') is over. You also need to implement 'start moving in a dir', 'stop', and 'read'.

About the encoder values, use whatever base you want (hex, octal...). However, I suggest you use a ascii-based protocole: it is much easier to debug without any dedicated program. But if you really want a binary-based protocole, no problem for me. You can also use more than 9600bauds, but remember that increasing the speed also increases the errors.
Frédéric

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Mon Jan 25, 2010 10:21 am

Hi Frederic,
thank you for the quick reply. This is very good news.
As I saw there are plans anyway for a controller to replace the current Merlin electronics, it would make sense to define a new simple protocol and use this for further development.
Few ideas:
During initialization phase the master (papywizard) should ask the slave what capabilities it has implemented and based on the implemented features it can control the slave. Similar to what Merlin does, but we may need additional features, like a third axis or additional sensors.
1. The minimum is the plain encoder 360° value (or total steps needed to turn the head 360°) and the reference point of the head in 0° position. Everyone may use different gear type or encoders, so the master must use the value to be able to control the head with absolute precision.
For example if I use a gear ratio of 20:1, have a motor with 200 steps, and use a controller with micro steeping of 16, I would end up with 20x200x16 = 64000 steps.
2. The same flexibility should be given for the reference (calibrated position) point. If I decide to use dec 0 as reference and not something like 800000 the master should take care about this fact.
But I agree it is easier to use a high value and avoid sending negative values.

3. ASCII transmission even in HEX is fine but I don't see a reason for shifting the LSB and MSB.
Typically the encoder value is counted in a interrupt routine as a plain decimal number, the same as every single step send to the motor.
4. Sure we need a status to know if the head is still moving or ready to accept new commands.
5. Acknowledging every command in the interrupt routine and even sending back the position or status is fine, as long I don't have to compute to many numbers.

I'm sure you know how AVR type micro controller works, you have very limited multitasking capabilities and a simple task like listening to the port and confirm every command while at the same time driving a stepper motor can get challenging. As far I saw the Merlin head is using 2 or even 3 micro controllers? This may be one reason...

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Mon Jan 25, 2010 11:15 am

Yes, I know that µ-controllers programming is not easy, due to limited resources. The Merlin uses one chip per axis; they both implement the same program, receive the same datas at the same time; they just react at a different address (the # of the axis). It is a very simple and powerfull solution. and in fact, Papywizard is build on this model: both axis are totally independant, so it is possible to use a different plugin for each one. Keep this in mind when writing your protocole: a command should not request or send values for both axis at the same time...
Frédéric

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Mon Jan 25, 2010 12:20 pm

Yes, it is implemented already ...
But I got stuck due to the additional calculations I have to make to 'emulate' a Merlin head...
Due to the different encoder value and different offset value I loose too much time in the interrupt and get off synch.
It probably would help if Papywizard would use the encoder value it receives from the slave. Can you confirm if you use it or is it hard coded by now?
What do you think, when could you compile a simple plugin with this few requirements? I would also try to do it myself, but I have no clue with that programming environment.

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Mon Jan 25, 2010 1:03 pm

No problem to use encoder values, in whatever format you want. Again, you don't need to follow Merlin/Orion protocole if you need something different, for an easier implementation.

If you use the same architecture in your commands (a goto is non-blocking, a read command can occur at any time...), I can write the plugin very quiclky, and I'm sure you will be able to modify it yourself to fit your needs. Just describe me your exact protocole...
Frédéric

no avatar
hankkarl
Member
 
Posts: 1284
Likes: 0 post
Liked in: 0 post
Joined: Tue Feb 21, 2006 5:32 pm
Location: Connecticut, USA
Info

by hankkarl » Mon Jan 25, 2010 4:06 pm

The Merlin/Orion may have a new program, see http://www.skywatcherusa.com/multifunction-mount-s21300.html

User avatar
claudevh
Moderator
 
Posts: 1349
Likes: 0 post
Liked in: 0 post
Joined: Sun Nov 25, 2007 11:12 pm
Location: Mont-Saint-André (Belgium)
Info

by claudevh » Mon Jan 25, 2010 5:52 pm

The Merlin/Orion may have a new program

What do-you mean by that ?
:cool: Claude :cool:
Merlin + Papywizard on Windows 7 & Nokia 770 § N810 & Acer (Netbook) + PanoramaApp Androïd + Deltawave PapyMerlin BT + Autopano
Spherical Pano (180 x 360) with Canon 40D + Canon EF-S 10-22mm f/3.5-4.5 Zoom & Pôle Pano with Canon 5D MK2 and shaved Tokina 10-17 3.5-4.5 AF DX Fisheye
Gigapixel photography with Nikon D200 + Sigma 70-200 F 2.8 EX DG APO HSM

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Tue Jan 26, 2010 6:27 am

Hi,
I did continue to test the program but seems I'm not on the right track.
If I try to catch and answer all commands received on the serial input in a interrupt function this slows down my motor speed to an unacceptable speed.
The reason for that is that the MC can handle only one interrupt at a time. As I'm using an interrupt function to generate the code for the stepper motor and now the additional interrupt function to handle the serial communication I'm getting into this conflict.
How often per second, does papywizard send a request to the slave if the slave is immediately answering the request? After what time does papywizard run into timeout and resend the request if the slave is answering with a delay?

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Tue Jan 26, 2010 7:53 am

I refresh the GUI 5 times per second, so 'read' commands occur at this rate. And the com. timeout is set to a high value (~1s). But there are some OS/driver which don't support the settimeout function; this is the case under Windows with the bluetooth driver (I think it is much longer). I resend the command 3 times before raising an exception.
Frédéric

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Wed Jan 27, 2010 12:39 am

Id did further optimize the code and it looks promising, the only thing I would still need is a higher timeout value when the motors are turning.
Another option would be to repeat sending the status and position commands until the head responds again. Means if papywizard does not receive the answer within 1 sec, it repeats the command until user aborts.

Could you implement a plugin like described below, mainly a simplified version of the Merlin protocol but with some additional features.
All values are transmitted as plain ASCII, Hex, no rotation of LSB/MSB

1. Axis to control 1 to 9,
1=Pan, 2=Tilt, 3=Focus, 4=Zoom, 5 to 9 reserved for any additional sensors

2. Encoder Position, 6 ASCII digits, hex, when switched on initial value is set at Hex 800000 (dec 8388608)

3. Axis direction, 0 or 1, 0=increments (up/right), 1=decrements (down/left)

4. Axis status, 0 or 1, 0=Ready, 1=Busy

5. Set axis state, 0 or 1, 0 opens the contact, 1 closes the contact, this can apply to any axis 1-9 to switch additional external functions.
When set on axis 1 the shutter is closed, when set on axis 2 the AF is switched on.

Commands: All commands need to include the axis number
j = position
f = status
L = stop

Start moving (speed parameter is not needed, the head starts to move slowly and increases the speed as long the the command is send)
L<axis>
G<axis><dir>
J<axis>

Drive to position
L<axis>
G<axis><dir> (this parameter could be omitted as the direction depends on the given position compared to the current head position
S<axis><pos>
J<axis>

Set shutter, AF, Flash, or other external switches (can apply to any axis 1-9 to switch some external device)
When set on axis 1 the shutter is closed, when set on axis 2 the AF is switched on.
O<axis><state>

Initialize head
F<axis>
e<axis> firmware version (max 6 char)
a<axis> encoder value per 360° turn, when using a stepper motor this value also corresponds the number of steps needed to turn the head one turn (360°)
As an example
for axis a1 Hex 012C00 (dec 76800)
and for axis a2 Hex 027100 (dec 160000)
Papywizard need to use this encoder value to calculate the head position and the steps to move the head.

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Wed Jan 27, 2010 8:22 am

Ok, I'll write the plugin ASAP.
Frédéric

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Wed Jan 27, 2010 10:03 am

Are you still using \r as end of line? How do you manage errors? Merlin returns '!' followed by a a single digit number as error code (I don't know the meaning of these codes, so choose yours!).
Frédéric

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Wed Jan 27, 2010 10:22 am

And what is the 'get status' (f) returned format and meaning?
Frédéric

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Wed Jan 27, 2010 10:26 am

Hi,
this is great news! I'm sure this plugin could be used later for any further enhancements with own implementations.
We only need to document the Wiki page ;-)
yes I still use \r (CR) to identify EOL. and also sending back the same codes as Merlin does.
I did not implement any error handling by now, let's use the same as Merlin is using.
Means if papywizard is requesting a command for example to move the head out of range, the head would answer with an error code instead of the normal acknowledge.

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Wed Jan 27, 2010 11:52 am

fma38 wrote:And what is the 'get status' (f) returned format and meaning?

Status return would be one character, 0 or 1, 0=Ready, 1=Busy
Or do you think we need more?

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Wed Jan 27, 2010 1:01 pm

No, it is enough to start.
Frédéric

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Wed Jan 27, 2010 1:07 pm

In the status command, could you return 1 as long as the head moves? I mean, when I request stop to the Merlin, its stops motors, but because of inertia, it continues to move: I have to poll the position.

So, after a stop (itself after a start moving), you should return immediatly to acknowledge the command, then stop the motors, and refresh the status: 1 if the head moves (busy), 0 when it is really stopped.

Is it OK for you?
Frédéric

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Wed Jan 27, 2010 5:22 pm

fma38 wrote:In the status command, could you return 1 as long as the head moves? I mean, when I request stop to the Merlin, its stops motors, but because of inertia, it continues to move: I have to poll the position.

So, after a stop (itself after a start moving), you should return immediatly to acknowledge the command, then stop the motors, and refresh the status: 1 if the head moves (busy), 0 when it is really stopped.

Is it OK for you?

My problem is not to be able to respond during the time the head is moving. Sure I can set the status to 1 right before starting the motor and back to 0 as soon the motor stops.
It may even be possible to send the status bit as the motor is turning, but I need to prove this first if it still slows down the motor. Sending serial data within a interrupt is terribly slow and must be avoided.
As long the motors are not moving I can respond in realtime.

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Thu Jan 28, 2010 12:58 pm

Hi,
currently this command does only trigger the camera and does not trigger AF.
O<axis><state>
When set on axis 1 the shutter is closed
I would like to have AF triggered as a separate command and enabled before the actual shutter is closed.
When set on axis 2 the AF is closed.
This command needs to be send right after the motor stops (during the delay time before the shutter is closed.
Both commands are disabled later at the same time.
Why is this useful? You can use the camera in AF mode and the camera can auto focus during the time the head is stabilized and is ready to take the picture when it receives the shutter closed command.
If camera is used in manual AF mode it does not have any influence.

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Thu Jan 28, 2010 1:03 pm

Well, why not? But the problem is that you don't have any feedback about the focus. If it fails, the picture won't be taken at all...
Frédéric

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Thu Jan 28, 2010 1:09 pm

fma38 wrote:Well, why not? But the problem is that you don't have any feedback about the focus. If it fails, the picture won't be taken at all...

Yes I know, but there are occasions where this works fine and I use 2 opto couplers anyway to trigger the camera.

no avatar
Greg Nuspel
Member
 
Posts: 169
Likes: 0 post
Liked in: 0 post
Joined: Tue Oct 06, 2009 6:50 pm
Location: Calgary, Alberta, Canada
Info

by Greg Nuspel » Thu Jan 28, 2010 3:11 pm

With all the panoramic I have shot I use manual focus, I was taught that focus and aperture should always remain fixed to avoid any changes in the image that would affect stitching. You will note that as you change focus the image does re-size some. Time to use the hyperfocal distance :-)
--Greg Nuspel

User avatar
panoguy
Member
 
Topic author
Posts: 106
Likes: 1 post
Liked in: 0 post
Joined: Mon Jan 25, 2010 3:55 am
Location: Bavaria
Info

by panoguy » Thu Jan 28, 2010 4:18 pm

I agree, but I also shoot some gigapixel panoramas using autofocus ...
And this would not have been possible with manual AF, except you stop the head after each image and refocus manually.

User avatar
fma38
Moderator
 
Posts: 5850
Likes: 2 posts
Liked in: 2 posts
Joined: Wed Dec 07, 2005 6:21 pm
Location: Grenoble, France
Info

by fma38 » Thu Jan 28, 2010 4:23 pm

I think it is also while shooting gigapixel you have the highest probability to get out-of-focus, as you can shoot a uniform surface, like wall or so...
Frédéric

Next

Who is online

Users browsing this forum: No registered users and 2 guests