Jump to content

Banner.jpg.b89429c566825f6ab32bcafbada449c9.jpg

Arduino controlled focussing


Gina

Recommended Posts

Alternative controls. Both stepper motors are off unless one or other button is pressed - which button determines which focuser to control. Neither button pressed gives 0v, one button gives 5v and the other 2.5v. The pot determines speed and direction as before.

post-13131-0-81299000-1361917868_thumb.p

Link to comment
Share on other sites

  • Replies 180
  • Created
  • Last Reply

Another alternative is to determine which focuser to control at the scope end with a toggle switch. Or, of course, it could be controlled from the computer. Lots of possibilities :D

Link to comment
Share on other sites

Cheers Gina and Neil - watching with interest as I wait for my stepper motors and nanos to come, then I will join the party! Though my own programming skills are limited and pretty rusty I do have an office full of geeks to bounce things off. My primary interest is arduino focuser, but also looking at dew heater and filter wheel control. Probably following Gina's lead on separate arduino's for each function, but sharing a single project box/dc supply. Looking to do this with direct display and push button control (at the box), then look at the usb and ascom side in more detail.

If I get the chance tomorrow at work I'll try and get a logical circuit diagram uploaded as a start point.

Link to comment
Share on other sites

... The Arduino code was designed so that all instructions follow the same syntax over serial comms as i thought it would allow anyone to build their own front end...but no-one has. :(

But i know it's helped a couple of people who have no programming ability so i'll keep plugging away....

And very grateful we are too, Neil. I wouldn't have a clue where to start with the programming and I'm very happily using the standard code that you provided on the user group, now controlling two scopes equipped with DIY steppers.

I used 400 step motors and a 1:3 reduction belt drive, to avoid any backlash problems in a gearbox. Works a treat - thank you.

Adrian

focuser_MN190.jpg

focuser_pentax_sm.jpg

Link to comment
Share on other sites

OK -- I think I can help here but I need your co-operation.

So -- I have done the following:

LAN devices.

Test software for SOHO spacecraft.

CCD camera fo BADR-B satellite

Main Imaging system for William Herschel Telescope

Autoguider for the William Herschel Telescope

Autoguider for JetX Xray telescope

Embedded firmware for Cassini Huygens Surface Science Package.

Encryption devices for financial transactions.

ADSL routers.

Networked sound systems for Beijing Olympics, Wembley Stadium, Washington Senate ...

So I am willing to answer specific questions about how to interface to hardware and how to write embedded code.

However if you don't like what I say that is fine I am not going to argue.

I know this sounds arrogant but I am willing to give advice but I haven't got the time or inclination to argue the toss.

Link to comment
Share on other sites

No quibbles from me gkec, any advice always welcome and I'll watch in as the conversation develops - I recall your welcome post to SGL re Cassini Huygens, not so long back - touching the surface of Titan was incredible enough, but that's one hell of a cv. I'll have to get my code peer reviewed before posting ;)

Link to comment
Share on other sites

I have had a look at JAS's code -- nice circuit board BTW. I can't solder so I now have PCBs made for my projects.

I feel an explanation of the volatile keyword would be in order as this is very useful in these types of projects.

here is some code

int tx = 0 ;

tx = 1 ;

tx = 2 ;

tx = 3 ;

Now most compilers will see that and remove tx=1 and tx=2 and just leave tx=3

Now if we have this:

int *uart_tx_reg = <address of UART register>

*uart_tx_reg = CMD_CODE ;

*uart_tx_reg = parameter1 ;

*uart_tx_reg = parameter2 ;

we don't want the compiler to strip out the first two write to the tx register because it won't work for us.

So we declare uart_tx_reg as volatile

volatile int *uart_tx_reg ;

The compiler will then ensure that all three write occur.

The same goes for reading e.g

int *uart_status_reg = <address of UART status register>;

while( *uart_status_reg == 0 ){

delay(10);

}

If uart_status_reg is not declared volatile then the compiler may compile code that reads the value once into a register and then never reads it again. Declaring it volatile forces the compiler to compile code to always read the value.

With memory mapped devices I find it useful to define structure that map directly onto the devices. For example if I had a UART with three consecutive registers I would do the following:

typedef struct {

volatile int tx_reg ;

volatile int rx_reg ;

volatile int status ;

} uart_regs_t ;

Then I declare a pointer :

uart_reg_t *uart = <address of UART in memory>

I can the access the UART without worrying about what the compiler does.

int val ;

while( uart->status==0){

delay(10);

}

val = uart->rx ;

This only work for memory mapped devices but it has the added advantage that you can access the device from a debugger by just examining the uart structure.

If it is only your code that accesses the memory and you are not running several tasks at once that access the same memory then you do not need the volatile keyword.

Link to comment
Share on other sites

I've been giving my focus control further thought and I think I shall just put a toggle switch in the scope end box to select which motor to control. I shall only be using one focuser or the other in an imaging session (for the immediate future) and it's a good idea to reduce controls at the warm room end as much as possible to avoid confusion (I do sometimes get confused :D ) This system could be good for the ASCOM driven version too.

Link to comment
Share on other sites

I have had a look at JAS's code -- nice circuit board BTW. I can't solder so I now have PCBs made for my projects.

I feel an explanation of the volatile keyword would be in order as this is very useful in these types of projects.

here is some code

int tx = 0 ;

tx = 1 ;

tx = 2 ;

tx = 3 ;

Now most compilers will see that and remove tx=1 and tx=2 and just leave tx=3

Now if we have this:

int *uart_tx_reg = <address of UART register>

*uart_tx_reg = CMD_CODE ;

*uart_tx_reg = parameter1 ;

*uart_tx_reg = parameter2 ;

we don't want the compiler to strip out the first two write to the tx register because it won't work for us.

So we declare uart_tx_reg as volatile

volatile int *uart_tx_reg ;

The compiler will then ensure that all three write occur.

The same goes for reading e.g

int *uart_status_reg = <address of UART status register>;

while( *uart_status_reg == 0 ){

delay(10);

}

If uart_status_reg is not declared volatile then the compiler may compile code that reads the value once into a register and then never reads it again. Declaring it volatile forces the compiler to compile code to always read the value.

With memory mapped devices I find it useful to define structure that map directly onto the devices. For example if I had a UART with three consecutive registers I would do the following:

typedef struct {

volatile int tx_reg ;

volatile int rx_reg ;

volatile int status ;

} uart_regs_t ;

Then I declare a pointer :

uart_reg_t *uart = <address of UART in memory>

I can the access the UART without worrying about what the compiler does.

int val ;

while( uart->status==0){

delay(10);

}

val = uart->rx ;

This only work for memory mapped devices but it has the added advantage that you can access the device from a debugger by just examining the uart structure.

If it is only your code that accesses the memory and you are not running several tasks at once that access the same memory then you do not need the volatile keyword.

Thank you for that :) I hadn't seen the "volatile" keyword before and wondered what it did. I was going to look it up when I got round to it :D I think I understand your explanation :)
Link to comment
Share on other sites

I've been giving my focus control further thought and I think I shall just put a toggle switch in the scope end box to select which motor to control. I shall only be using one focuser or the other in an imaging session (for the immediate future) and it's a good idea to reduce controls at the warm room end as much as possible to avoid confusion (I do sometimes get confused :D ) This system could be good for the ASCOM driven version too.

Gina, I know you're not planning to use the EasyDriver motor controller board, but just a warning for anyone using one who is thinking about a toggle switch like you describe .... beware! The EasyDriver board is very susceptible to failure if the motor is disconnected hot, i.e. with power still applied to the board. Momentary disconnection whilst toggling could cause this.

One other consideration: if you don't maintain power to the stepper motor, you lose the holding-torque. Probably not a problem with the braking effect of a 1:64 gearbox on the motor, but with a more direct drive there is little natural braking and loss of holding torque could easily cause the focuser to slip back.

Adrian

Link to comment
Share on other sites

Gina, I know you're not planning to use the EasyDriver motor controller board, but just a warning for anyone using one who is thinking about a toggle switch like you describe .... beware! The EasyDriver board is very susceptible to failure if the motor is disconnected hot, i.e. with power still applied to the board. Momentary disconnection whilst toggling could cause this.

Useful warning to others who may use the EasyDriver board - thanks :) I'm simply using the ULN2003A driver chip to provide the extra drive current to the stepper motor. It simply goes between the Arduino digital (output) pins and the stepper motor. 4 of the 7 drivers in the chip are used to drive the stepper coils. Also, the switch simply inputs to the Arduino - it doesn't switch the power.
One other consideration: if you don't maintain power to the stepper motor, you lose the holding-torque. Probably not a problem with the braking effect of a 1:64 gearbox on the motor, but with a more direct drive there is little natural braking and loss of holding torque could easily cause the focuser to slip back.

Adrian

With my sketch, if the focuser select switch is operated while the power is on it will leave power on one stepper coil of the focuser de-selected. If however, the appropriate focuser is selected before power-on (or Arduino reset) power will only be applied to the selected focuser motor. So this system will work with direct drive stepper motors as well as the 64:1 reduction gearing type I'm using.
Link to comment
Share on other sites

Here's my current sketch. This uses a simple toggle switch connected to a digital pin set as input with internal pullup resistor. viz. pinMode (wfPin, INPUT_PULLUP); It goes from pin to ground and provides a LOW state when ON.


/* Stepper Unipolar Advanced
* -------------------------
*
* Program to drive a stepper motor
* Unipolar stepper motor with 5 wires:
*
* @author: David Cuartielles
* @date: 20 Oct. 2005
* Modified 2013-02-27 by Gina Davis
* to control one of two stepper motors selected by toggle switch
*/
int motorPins_a[] = {2, 3, 4, 5};
int motorPins_b[] = {6, 7, 8, 9};
int wfPin = 10; // Widefield focuser select switch
boolean wf; // Widefield focuser true/false
int count = 0;
int count2 = 0;
int delayTime = 500;
int val = 0;
void setup() {
pinMode (wfPin, INPUT_PULLUP);
for (count = 0; count < 4; count++) {
pinMode(motorPins_a[count], OUTPUT);
pinMode(motorPins_b[count], OUTPUT);
}
}
void moveForward() {
if ((count2 == 0) || (count2 == 1)) {
count2 = 16;
}
count2>>=1;
for (count = 3; count >= 0; count--) {
if (wf) {
digitalWrite(motorPins_a[count], count2>>count&0x01);
} else {
digitalWrite(motorPins_b[count], count2>>count&0x01);
}
}
delay(delayTime);
}
void moveBackward() {
if ((count2 == 0) || (count2 == 1)) {
count2 = 16;
}
count2>>=1;
for (count = 3; count >= 0; count--) {
if (wf) {
digitalWrite(motorPins_a[3 - count], count2>>count&0x01);
} else {
digitalWrite(motorPins_b[3 - count], count2>>count&0x01);
}
}
delay(delayTime);
}
void loop() {
wf = (digitalRead(wfPin) == LOW);
val = analogRead(0);
if (val > 540) {
// move faster the higher the value from the potentiometer
delayTime = 2048 - 1024 * val / 512 + 1;
moveForward();
} else if (val < 480) {
// move faster the lower the value from the potentiometer
delayTime = 1024 * val / 512 + 1;
moveBackward();
} else {
delayTime = 1024;
}
}

Link to comment
Share on other sites

.... With my sketch, if the focuser select switch is operated while the power is on it will leave power on one stepper coil of the focuser de-selected. If however, the appropriate focuser is selected before power-on (or Arduino reset) power will only be applied to the selected focuser motor. So this system will work with direct drive stepper motors as well as the 64:1 reduction gearing type I'm using.

Sounds like you've got it covered, Gina!

These economical little geared motors look great for this kind of application. How much backlash do you find you get at the output shaft - I presume you need to program in a few extra steps to take up slack when you change direction?

Adrian

Link to comment
Share on other sites

I haven't measured the backlash yet but it seems to be of the order of 3-4 full steps. This sketch I'm using does full steps rather than half steps though I could change to a half stepper if wanted. I have about a 2:1 reduction with the pulley drive to the Baader SteelTrack fine focuser so I think full steps will be fine but proof of the pudding and all that :D I've yet to decide the gearing for the widefield lens focussing. I expect to provide a computer display of a step count later so that I can see what's going on.

Link to comment
Share on other sites

Yes, that was what I had in mind. If I get a step count I can gradually move through the focus watching the FWHM and the step count and noting the step count for best focus. Then zoom back and gradually approach the focus point again from the same direction. Just need to add the serial stuff to the sketch - not a problem :)

ATM I'm working on the hardware.

Link to comment
Share on other sites

I'll see how I get on with what I've got. I have a feeling I'll have a very fine focussing on my SteelTrack. I'm driving the "Fine" knob (which has a timing pulley on it as supplied) with something like 2.5:1 reduction pulleys and then there's a 64:1 reduction in the stepper motor. With manual focussing I estimate that I get down to about 10 degrees. So that's 25 degrees at the stepper and 25x64=1600 degrees or 4 revolutions of the stepper itself. Hmmmm... I think I shall want a different stepper motor without a 64:1 reduction gearbox in it :D

For the widefield lenses I have a 64:1 plastic gearbox plus 64:1 stepper gearbox then about a 5:1 pulley ratio. That might be too fine but I think we're looking at something like a tenth of a degree rotation of the lens sleeve as desired resolution. Half a degree at the second gearbox, about 32 at the motor o/p, 2048 at the stepper... Oh... also too fine. I can easily reduce that by 16:1 by removing a gear pair.

Oh well - I've probably got my arithmetic way out - time will tell :D

Link to comment
Share on other sites

Here are some photos of the widefield focuser. These show the extremes of lens sizes that I'm using. The belt is placed on whichever small pulley is appropriate and the tension adjusted by the screws on the ring. The original DC motor has been replaced by the stepper motor and the gear ratio reduced from 4096 to 64.

post-13131-0-39115900-1362003142_thumb.j post-13131-0-04762600-1362003149_thumb.j post-13131-0-00240200-1362003153_thumb.j post-13131-0-87079700-1362003155_thumb.j post-13131-0-41521100-1362003159_thumb.j

Link to comment
Share on other sites

I've been testing the widefield focuser and I think it will be alright. I might increase the maximum rotation speed though. I'll need to see how it performs on stars. The pulley for the scope focuser seems to rotate fast enough at the maximum speed too.

I now have the focuser controller in the box and working with the Arduino fed from my desktop PC and the USB supplying all the power. I'm using the pot in the box for testing.

post-13131-0-70806400-1362009474_thumb.j

Link to comment
Share on other sites

... Hmmmm... I think I shall want a different stepper motor without a 64:1 reduction gearbox in it :D

Or perhaps you could program the focuser 'ticks' to be 64 steps instead of single steps ('macro-stepping' ?)

I worked out the reduction I needed based on a calculated critical focus zone (www.astrodonimaging.com/docs/GetFocusedPreprint.pdf). That gives a figure for the desirable focus adjustment resolution at the drawtube of about 11 microns for a f/5.6 system, with the value varying as the square of the f/ratio (so it would be only about 4 microns at f/3.3 for example). Then just work out what fraction of a turn on the focuser spindle is required to move the drawtube that amount. From that you can figure out the reduction needed from the motor to give you that movement on one step.

The focuser on my refractor moves 20mm for one full turn of the spindle and my calculated required resolution is 16 microns. That works out at 1/1250 th of a turn on the spindle - hence a 400 step motor and a 1:3 belt reduction.

Adrian

Link to comment
Share on other sites

What I think I would like to do is arrange various size steps, using large steps initaially to get close to focus then changing down to ever smaller steps until no change in focus is detectable when changing by one step. A process of successive approximation. And rather than run the stepper motor continuously as at present the process would be :-

  1. Take an image and read the FWHM value
  2. Move the focus in one direction
  3. Take another image and read the FWHM again
  4. If it's worse change direction and change to smaller steps
  5. Repeat the above from 2 until there is no change.

The focuser control using a pot for manual input is finished and ready to be put onto the scope assembly this evening. Then (if we get the promised clear periods) I can see how much the focus changes and get an idea of how big the steps need to be.

In view of the above, I shall be rewriting the control sketch and designing a different human interface. One possibliity is 4 push buttons - two for direction (move in/out) and two for step size (increase/decrease step size). Control can still be via one analogue control line - the buttons can tap into a resistor ladder and the Arduino reads the voltage to determine which button was pressed. I have used this method with push button control of my DSLR Peltier TEC cooling system.

Link to comment
Share on other sites

Analysing the sketch I'm using ATM, this code turns the stepper forward by one full step :-


if ((count2 == 0) || (count2 == 1)) {
count2 = 16; // set up or reset a binary code of 10000 (becomes 1000 after the right shift)
}
count2>>=1; // Right shift one place to put the current on the next motor pin
for (count = 3; count >= 0; count--) {
if (wf) {
digitalWrite(motorPins_a[count], count2>>count&0x01);
} else {
digitalWrite(motorPins_b[count], count2>>count&0x01);
}
}

To move backwards the motor pins are sequenced in the opposite order by referring to them in the opposite order - count becomes (3-count) :-


if ((count2 == 0) || (count2 == 1)) {
count2 = 16; // set up or reset a binary code of 10000 (becomes 1000 after the right shift)
}
count2>>=1; // Right shift one place to put the current on the next motor pin
for (count = 3; count >= 0; count--) {
if (wf) {
digitalWrite(motorPins_a[3 - count], count2>>count&0x01);
} else {
digitalWrite(motorPins_b[3 - count], count2>>count&0x01);
}
}

The current sketch repeats the forward or backward setps with a variable delay to determine the frequency. For the new method we need to repeat either stepforward or stepbackward a certain number of times at a fixed frequency (or delay between steps). This number of times is the effective "step" size - the amount the motor turns for one push of the appropriate button. This number is what we change to determine the amount of focus change per "step".

The "step" size could be changed in powers of 2 ie. 1, 2, 4, 8, 16, 32, 64 etc. We can double the value by a binary shift left or halve the value by a binary shift right with limits at 1 and maybe 64 - or whatever the biggest "step" size wants to be.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.