Saturday, 1 February 2014

PVCu Mount Assay Part I

As promised, here is the first part of the mount assembly. It has actually been a very straight forward assembly process so far. This excludes the axle shafts (including counterweight) which will be M8 studding and covered in a separate (Part II) post when I get to it. These are the components and tools you will need for this part:

Disclaimer: Please don't blindly copy this. I am just documenting the progress of building something, I will undoubtedly miss things out. If you choose to follow my documentation  to make something similar and as a result you trash your telescope, yourself or others around you, I will hold no responsibility, whatsoever - I may even allow myself a little chortle depending on the grade of your idiocy. I do however hope that the following will help others make educated decisions on how to make their own mounts in the future.

Tools:

Dremel / Rotary Tool with a a drum sanding attachment (shown left).


120 grit sandpaper.

Toggle press or decent vice (I sold my toggle press a few years back but my vice work just as well).

PVCu Solvent Cement .



Materials;

Now you should be able to scale this mount up by using different pipe diameters, I have personally been looking at making one with 3" pipe, floor mounted into a concrete screed for a remote observatory idea with a large home-made Dobsonian, but not yet! 

This mount will be fitted with a small 70mm refractor, so I am using 1 1/4" fittings:
PN16 Flange

2 no. 1 1/4" PN 16 flanges.
2 no. 1 1/4" Tee Pieces.
1 no. 1 1/4" 45 Degree Elbow.
6 no. 1 1/4" > 1" Reducing Bushes.
6 no. 1" > 1/2" Reducing Bushes.
A short length of 1 1/4" PVCu Pipe.
8 no. ABEC 7 skateboard / scooter bearings.

Here is a catalogue of PVCu pipe fitting with a guide on gluing etc as well detailed info on many parts.
45 Degree Eblow
Tee Piece
Reducing Bushes




Standard Skateboard bearings











Now, depending on your bearings you will need different reducers, there is lots of information on-line about their dimensions but I have put a pipe diameter table on my previous post Here and a link to some standard bearing housing dimensions, too - I am sure will be able to find a bearing and reducer that closely match each other to suit your own requirements.





Assembly of the mount base.

I chose to use a PN16 flange as the base because I could then bolt it to a wooden tripod easily. You could equally use reducers down to a 3/8" BSP female thread, then thread to your existing tripod. If you have an odd thread size you could reduce down with plain fittings (1/4" is the smallest), drill out and tap to the thread you have on your tripod.

The idea is to use the 45 Degree elbow for the latitude of the polar axis, I live in southern England so this is close enough to be corrected with my tripod's trailing edge. For those of you further or closer to the equator than this is practical to use, you can still use the PVCu pipe method. However, use 2 no. 90 degrees to create a composite angle equal to your latitude - you could even leave the connection between the two elbows unglued and fit thumb screws to give you the ability to change the latitude. Seeing I am never going to take my telescope more than a few degrees north or south I didn't see the point, but the option is there if you wish.


  • Measure the depth of the fitting recess and cut 2 no. pieces of pipe twice the length of the recess, for 1 1/4" pipe this was 50mm for mine.

  • Paste the recesses of one of the PN16 flanges and one end of the 45 degree elbow. 

  • Push one of the pre-cut lengths of pipe in to the flange connection and push the 45 degree elbow on top. Rotate the fittings until tight against the recess stops then align the 45 so it is centrally perpendicular.

  • Next up, glue the other 50mm (or whatever length yours turns out to be) pieces of pipe in to the 45 degree elbow.

  • Finally, glue one of the Tee pieces to the pipe stub glued in to the 45 degree elbow. You should glue the central stub of the Tee piece. the longest part of the Tee should be aligned perpendicular to the 45 elbow.
Warning; PVC solvents melt the plastics they are bonding, quickly. Locate and align your pipe work quickly and firmly, once located and not moved for a few seconds the bond will become so strong will not be able to change any angles. Be diligent but quick and of course, careful.

It should like this (minus the bearings, we'll get to them next);

Tripod mount, 45 Degrees latitude + Right Ascension axis.


Reducers and Bearings;

I chose to use bearings on all the axis to reduce the friction and therefore load requirements of my stepper motors. The right ascension axis, shown above shows the axis runs through 2 no. ends of the tee piece. Each end must contain a set of reducers and a bearing this will contain the axle which will bolt to the declination-axis-tee-piece.

This design gives an approximately 100mm of space between bearings for the main axis which I feel is sufficient to support even a fairly weighty telescope given that heavy duty MTB hubs are generally no more 75-80mm apart.

The 1/2" Reducing bushes mic'd up with an ID of 21.25mm and the bearings were 21.98mm, I want a press fit, but pressing into that would risk either splitting the reducers or deforming the bearing housing. I used a Dremel and sanding drum to remove a small amount of the material until the ID measured about 21.60mm.


Rusty vice pressing bearings into reducing bushes.


Stub axis hubs; the receiving hub to the declination axis and the top mount that will take the telescope (the actual declination hub) are both on stub axis i.e. they only have a bearing and support at one end. This is the only simple way to assemble the mount. However, it does put more strain on the bearing and puts a higher emphasis on on the bearing seat being complete concentric, In order to help reduce stresses and to help with seating accuracy I chose to use double bearings in these locations, this will:


  • Increase distance between bolting faces; reducing the affect of inconsistencies.


  • Put the clamping nuts on two different bearing faces; if one face is not perfectly square the problem is not passed to the axis - if clamped on a single bearing the axis would rotate around the uneven bearing rather than the actual axis.

Double bearings pressed in to declination hub.
5 no. Axis bearings and the declination hub, RA hub not assembled yet.




Right, so that is as far as I got today, I dummied up the RA axis with some M8 rod and it is super smooth! I am really looking forward to getting it all assembled and ready for testing the stepper motors and working out the best mounting options for them - I have a few tricks up my sleeve, Hopefully I can check whether they will work soon enough and update the assembly with Part 2 soon, probably next weekend, I seem to have no time at the moment!!

Right is a quick annotation of what has been assembled so far.








Thursday, 30 January 2014

First Working Draft Program R/A Only

I had some time last night to fiddle about with getting the "stepdegrees" variable to work within the Hour Angle calculations. I had tried a number of different methods but the first method that work is the one below.


A quick photo of the RA stepper motor and
CW / CCW buttons being tested.

Like I have said before, I really don't know much about this C++ malarkey, so I am sure someone will be poking holes in it, please feel free to improve on it if you wish - My end game is to have a downloadable Arduino library and build plan so others can make a cheap motorised telescope mount, any assistance would be welcomed.


/*-----( Import needed libraries )-----*/
#include <Stepper.h>
#include <Wire.h> 
#include <Button.h>

unsigned long start, finished, elapsed; // Unsigned long for Sidereal day calculation

/*-----( Declare Constants, Pin Numbers )-----*/
//---( Number of steps per revolution of INTERNAL motor in 4-step mode )---
#define STEPS_PER_MOTOR_REVOLUTION 32   

//---( Steps per OUTPUT SHAFT of gear reduction )---
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 64  //2048  

/*-----( Declare objects )-----*/
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to

//The pin connections need to be 4 pins connected
// to Motor Driver In1, In2, In3, In4  and then the pins entered
// here in the sequence 1-3-2-4 for proper sequencing

Stepper RA_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);

Stepper DEC_stepper(STEPS_PER_MOTOR_REVOLUTION, 12, 14, 13, 15);

Stepper FOC_stepper(STEPS_PER_MOTOR_REVOLUTION, 16, 18, 17, 19);

/*
Create Button Objects
 */
Button RAscCW = Button(A0,PULLUP); //create a Button object for the Right Ascension Clockwise switch @ pin A0
Button RAscCCW = Button(A1,PULLUP); //create a Button object for Right Ascension Anti-Clockwise switch @ pin A1

Button DECCW = Button(A2,PULLUP); //create a Button object for the Declination Clockwise switch @ pin A2
Button DECCCW = Button(A3,PULLUP); //create a Button object for the Declination Anti-Clockwise switch @ pin A3

Button HNudgeBut = Button(A4,PULLUP); //create a Button object for the Hour Plus Nudge switch @ pin A4
Button MNudgeBut = Button(A5,PULLUP); //create a Button object for the Minute Plus Nudge Anti-Clockwise switch @ pin A5

Button FOCUSin = Button(A6,PULLUP); //create a Button object for the Telescope Focus IN switch @ pin A6
Button FOCUSout = Button(A7,PULLUP); //create a Button object for the Telescope Focus OUT switch @ pin A7


int Stepcount = 0; // creates a zero value for the stepcounter

int Hnudge = 0; // Nudge Hour + 1
int Mnudge = 0; // Nudge Minute + 1


float D,LSTH,LSTM,LSTS,ms; // sidereal count millis

float ihr;  // create float for output of initial convertion

float stepdegrees; // output from stepper motor in degrees


void setup()   /*----( SETUP: RUNS ONCE )----*/
{
Serial.begin(9600); // will have LCD here on final version.
}
void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{

          if(HNudgeBut.isPressed()) // Hour Nudge Button + 1
          {
            Hnudge++;
          } 
          if(MNudgeBut.isPressed()) // Hour Nudge Button + 1
          {
            Mnudge++;
          } 
          if(RAscCCW.isPressed()) // Right Ascension Clockwise Slew
          {
            RA_stepper.setSpeed(900);   // speed
            RA_stepper.step(-50);       // step value per cycle - too high == lack of sensitivity / too low == poor slew rate/stutter
            Stepcount -=50;                // stepcount must equal step value per cycle.
          }
          if(RAscCW.isPressed())
          {
            RA_stepper.setSpeed(900);   // speed
            RA_stepper.step(50);        // step value per cycle - too high == lack of sensitivity / too low == poor slew rate/stutter
            Stepcount +=50;                // stepcount must equal step value per cycle.
          }
          else
          {
            RA_stepper.setSpeed(300);  // Adjust to equal 0.2507 Degrees of Right Ascension per minute 
            RA_stepper.step(1);        // step value per cycle, 1 is OK for low speeds, may need to change once fitted to mount and tested
            Stepcount ++;                 // stepcount must equal step value per cycle.
          }
  
 int Hnudge; // Nudge Hour + 1
 int Mnudge; // Nudge Minute + 1
 float ihr;  // create float for output of initial convertion
 float stepdegrees; // output from stepper motor in degrees
 

 stepdegrees = ((Stepcount/5.68)/10)+37.954; // when the Arduino is "reset" @ polar alignment the count will start at pos; 37.954541 degrees *location of polaris*

 Hnudge = 0;                  // Sidereal clock set Hour nudge
 Mnudge = 0;                  // Sidereal clock set Minute nudge
 ihr = ((stepdegrees/15));   // divides total degrees into number of hours in an sidereal day (15 degrees per hour)

 float D,LSTH,LSTM,LSTS,ms;   // Local Sidereal time calculator, with nudge control for setting the clock.
 unsigned long over;
 elapsed=(((ihr*3600000)+(Hnudge*3600000)+(Mnudge*60000))+start); // elapsed is the ajustable hour angle in milliseconds = Right Ascension + Hour set + Minute Set + Elapsed Time 
 D=int(elapsed/86164091);                                         // = 23 hrs 56 mins 4 seconds = Sidereal day
 over=elapsed%86164091;                                           // +1 Sidereal day
 LSTH=int(elapsed/3600000);                                       // = 60 minutes
 over=elapsed%3600000;                                            // + 1 hour
 LSTM=int(over/60000);                                            // = 60 seconds
 over=over%60000;                                                 // + 1 Minute
 LSTS=int(over/1000);                                             // = 1000 ms
 ms=over%1000;  

 Serial.print("H = " );                       
 Serial.print(LSTH);      
 Serial.print("\t M= ");      
 Serial.print(LSTM); 
 Serial.print("\t S= ");      
 Serial.print(LSTS); 

}


/* --(end main loop )-- */

/* ( THE END ) */

So, the bulk of this has been covered in my post on calculating the Hour Angle, however this also incorporates the Right Ascension motor control, with a temporary output to a Serial.print so I can see if it is working without hooking up an LCD display.

I am using an additional library which you will need if you want to use or modify my work:

Alexander Brevig's excellent Button.h library; http://playground.arduino.cc/Code/Button makes writing button/switch etc. dependant functions really simple and clear, he also has some good additional latching features which I have recently used in other little projects I am working on.

So, as mentioned the additional code is for controlling the Right Ascension stepper motor, currently in 3 distinct ways - Following a comment on my Stargazer Lounge Thread for this project I am also looking at allowing variable speed on the slew function, but for now this is where I am:


Button RAscCW = Button(A0,PULLUP); //create a Button object for the Right Ascension Clockwise switch @ pin A0
Button RAscCCW = Button(A1,PULLUP); //create a Button object for Right Ascension Anti-Clockwise switch @ pin A1


This is creating Button functions with the names for clockwise and anti-clockwise Right Ascension Slew. It is called upon by;

 if(RAscCW.isPressed()) // Right Ascension Clockwise Slew

  {
    RA_stepper.setSpeed(900);   // speed
    RA_stepper.step(50);       // step value per cycle - too high == lack of sensitivity / too low == poor slew rate/stutter
    Stepcount +=50;                // stepcount must equal step value per cycle.
  }

Where if the clockwise Button is pressed the stepper motor will rotate clockwise at 900 steps per second (faster than previously cited, I have been fiddling). Although the rate is 900 steps per second it will only move 50 steps at a time as denoted by "RA_stepper.step (50), this means that if you let go of the button the motor will stop after 50 steps, if this is higher the motor will continue to move long after releasing the button.


if(RAscCCW.isPressed())
  {
    RA_stepper.setSpeed(900);   // speed
    RA_stepper.step(-50);        // step value per cycle - too high == lack of sensitivity / too low == poor slew rate/stutter
    Stepcount -=50;                // stepcount must equal step value per cycle.
  }

This is the next "if" function, basically the same slewing motion but anti-clockwise.



else
  {
    RA_stepper.setSpeed(300);  // Adjust to equal 0.2507 Degrees of Right Ascension per minute 
    RA_stepper.step(1);        // step value per cycle - too high == lack of sensitivity / too low == poor slew rate/stutter
    Stepcount ++;                 // stepcount must equal step value per cycle.
  }

Here we see an "else" statement, whereby if neither slew button is pressed the system will automatically track on the right ascension.

You may have noticed each of the above functions has "Stepcount xxxx" this an incrementing function which is equal to the number of steps made per function cycle. This is how the program knows the number of steps taken and therefore the position of the mount, more detail of that is explained in my first programming post. 


DIY Equatorial Tracking Mount Idea

This is a bit backward, as I should have posted this before the programming part, but hey ho!

This Christmas (2013), my most awesome wife surprised me with a Celestron Travelscope, a small refracting telescope mainly for lunar and planetary observations; which she may be starting to regret! I am now hooked on astronomy and want to see more and start photographing my views too.

The Travelscope is an excellent low powered wide field scope perfect for lunar viewing and some astrophotography.  But, the mount does let it down, something my wife had researched and warned me about.

So, I like a challenge and started looking at what mount options are out there - not knowing a single thing about any of them! 

I wanted to make the mount more sturdy, primarily and easier for AP. So, after some research it made sense to concentrate my ideas on the Equatorial Mount style as this it is much easier to track object during long exposures with an equatorial mountA little bit about mounts; I am just a beginner so don't rely on my explanations at all! If you want to know more about the two options Wikipedia actually have some pretty good information:



So you can see why I chose the Equatorial design - once set up you just need a 'simple' tracking motor to run at a fixed rate that equals the earth's rotation; 365ยบ/day. How on earth was I going to do this cheaply without effecting the quality (too much) and in a way that I could scale up simply as my new found hobby expanded? ? ? In my day job I have to overcome substantial engineering hurdles while simultaneously answering to my MD with regards to keeping costs to minimum; so I like to think I am pretty good at this - or perhaps I am just good at making people think I've spent less on development worj? Yeah, probably the latter....No, definitely the latter... anyway,  this is my money, so I'm going to be a tight fisted Scrooge!!

I had seen some "pipe" based mounts online which seemed to be in the sort of ball park I was thinking about:

Here and Here.

But I really wanted to make something I could scale simply and without access to a lathe or mill (anymore) I decided to look at PVCu plastics, I design with the them on a daily basis, so know the range of fittings well. The goo thing about PVC is that they come with a massive range of solvent weld reducing bushes, many of them coincide nicely with standard bearing housings:

Standard ABEC "609" bearings have an OD of 22mm and a 1/2" reducing bush has an ID of 21.70mm with a + only tolerance, they fit nicely! There are also larger sizes which fit too. My advice would be to get a standard bearing chart and a PVCu pipe OD chart (this is what the reducing bushes mate with and find the size you are after:

A metric bearing chart is here; http://www.bearingworks.com/bearing_sizes/index.php

A PVCu pipe diameter chart can be seen below, these are nominal as they are extrusions and generally the reducer will have a decent tolerance of up to 0-5 - 0.8mm:




So, I had established that I could use standard bearings and PVCu pipe to make the mount, but how was I going to do it and what parts should I use.

I have drawn up a quick 3D model showing my proposed idea proposed idea, they are very vague at the moment but indicative of my plan, I have chosen to use 1 1/4" fittings with 1/2" reducers running 22mm bearings (10mm bore):

The red shows the two main axis, motors are floating in mid air for the time being
counter weight not shown.
Showing the press-fit bearing idea in a bit more detail:







I will try an update this further soon, I have got the parts and have been dummy-ing it all up, I will do another page on the assembly process when I get to it.

PVCu pipe can be brought from lots of places, I have a commercial supply, but Pipestock is good in the UK for small quantities:


If you have any questions feel free to email me, or contact me on Stargazing lounge, where I have started a discussion about the idea:







Wednesday, 29 January 2014

Initial Arduino Programming for a Tracking Mount

I had been thinking about buying an Arduino for a very long time, but could never really work out what to make with one! I have never done any C++ programming before but I have had experience with CNC coding in the past when I was working in manufacturing engineering (predominantly 9 axis Fanuc and Mazatrol) so I understand the concepts in programming quite well, even if the applications are million miles apart.

I will say this early. I am NOT in any shape or form an expert in C++ language or even arduino in general I first looked at the language on Boxing day 2013 (5 weeks ago), what I have learned is pretty basic and done through experimenting and trawling the Arduino Website for hours on end - there is a lot of really useful info on there.

Also, there are definitely more accurate ways of calculating the following functions and probably simpler ways too, but this is what I decided to do and how I have decided to it is based on the following points:


  • It is accurate enough to last a whole evening (does it need to be any more accurate??)
  • It doesn't need a Real Time Clock / permanent power supply.
  • It doesn't need to be connected to a PC.
  • And, most importantly, I was able to write the program with my limited skills!!
As with all control designs, I started with a control philosophy. I tried lots of things before settling for (conceding) the following:

There will be 3 no. stepper motors controlling:

  1. Focusing (possibly, not urgent though)
  2. Right Ascension / Hour Angle (2 speeds, Slew and Tracking).
  3. Declination.
Declination and the Focusing are both quite simple in concept, so I will go into them once I have explained the Right Ascension. Basically Right Ascension  "is the angular distance measured eastward along the celestial equator from the vernal equinox to the hour circle of the point in question." 


There are some good explanations of Right Ascension on-line (Here and Here). BUT, the problem with Right Ascension is that the Earth's time is not as we now it; we all know we have leap year every 4 years, it doesn't affect us any more than an extra day once in a while so no-one really appreciates it - well for calculating a celestial co-ordinate it is a bloody pain in the ass!

  • Earth Day according to GMT/UTC is 24 hrs 00 mins 00 seconds with a 4 year synchronisation (and on occasion other smaller corrections).
  • Sidereal Day (actual time it takes for a full 360 degree rotation of Earth is 23 hours, 56 minutes, 4.0916 seconds.
So the Right Ascension of any given point in the sky changes by about 4 minutes a day, this shift is compensated and is called the Hour Angle;


LHA is the Localised Hour Angle for the Object you are trying to locate.
LST is your Local Sidereal Time.
xobject is the Right Ascension of the object you are trying to locate.

So, to the coding, in order to create a usable system for object locating we need to do a few things:
  1. Convert the polar alignment "start position" (polaris) Right Ascension into an angle (so that the stepper motor position can be used to create a "live" Right Ascension figure.
  2. Convert the Right Ascension angle into an hour angle by removing the the current sidereal time from it.
  3. Convert the final decimal into a readable "time stamp" so you can slew to a given Hour Angle and view the object you are slewing too!
This was not as simple as I had initially thought it to be, there were many ways I could have achieved this, they were either expensive (not really, but more than I wanted to spend), time consuming, not suited to my personal preference or just plain out of my range of knowledge, they included:

  • Using a RTC and coding it for LST - I didn't want the hassle.
  • Using serial time from the PC and coding a scaling factor on the Epoch for LST. - very complex for me and I didn't want to have to be connected to a laptop all the time.
  • GPS timing - too pricy for this project.

I decided on something relatively simple.

Sidereal time is complex to keep for long periods dues to the disparity between itself and UTC, however as long as you not pass 23 hours and 56 minutes it is for all intents and purposes, just UTC, shifted. People will be shouting at their keyboards. I don't care. I have spent many years in engineering and I have learnt many things, the most important thing is and always will KISS - Keep It Simple, Stupid. For my clients I call it "appropriate technology" it offends them less!

  • How long am I using the telescope for at a time? - A whole night, tops - less than 23 hours and 56 minutes.
  • Will it be accurate for that time period? Yes.

Right, so the idea is that we have the Right Ascension for polaris hardcoded into the Arduino (02h 31m 49.09s) as decimal degrees. when you polar align, you then press Hour, Minute and Second buttons to set the time to Sidereal time, this will in effect give you 23 hours and 56 minutes of accurate LHA tracking without having to actually calculate LST.

LST can be entered using a LST app or from This Sidereal Clock.

How does this translate into C++

Well this was my first attempt, it is basically a calculator, and didn't work very well, but it may help people understand the basics of right ascension and it's relationship with a real angle so I have included it with explanations.

First we need to create all the variables required to make the counting system work:

int H; // output of truncated float for Hours
int M; // output of truncated float for Minutes

int Hnudge; // Nudge Hour + 1
int Mnudge; // Nudge Minute + 1

int HAH; // Hour angle from Right Ascension minus Local Sidereal time
int HAM; // Hour angle from Right Ascension minus Local Sidereal time
float HAS; // Hour angle from Right Ascension minus Local Sidereal time

float ihr;  // create float for output of initial conversion
float imin; // create float for output of initial conversion
float S; // create float for output of Seconds, no conversion needed, decimals wanted.
float stepdegrees; // output from stepper motor in degrees

  1. int H will be used to create something called a truncated output, in this instance it gives us only the integer from a decimal time i.e. 2.51 hours would give only an hour integer of 2, which is correct - it will not round up, this is very important.
  2. int M is the same but for minutes.
  3. int Hnudge and Mnudge are variables for buttons whereby if the corresponding button is pressed the Xnudge values increases by 1 - not currently programmed.
  4. int HAH and HAM are final compensated time integers.
  5. float HAS is a float, this means it can handle decimals and will output a true reading rather than a truncated one like "int" this is used against the truncated figure to get the time in seconds.
  6. float ihr, imin and S are the initial float variables in the right ascension calculation, relating to the idea in point 5.
  7. float stepdegrees is the output from the stepper motor count in degrees i.e. where the telescope is pointing in a raw decimal degree figure.

Here is the code for the actual calculation, I'll try to explain it below with a worked example;


int Hnudge; // Nudge Hour + 1
int Mnudge; // Nudge Minute + 1
float ihr;  // create float for output of initial conversion
float imin; // create float for output of initial conversion
float RAS; // create float for output of Seconds, no conversion needed, decimals wanted.
float stepdegrees; // output from stepper motor in degrees

int RAH; // output of truncated float for Hours
int RAM; // output of truncated float for Minutes

stepdegrees = (Stepcount/5.68); // 5.68 degrees per step

Hnudge = 0;                  // Sidereal clock set Hour nudge
Mnudge = 0;                  // Sidereal clock set Minute nudge
ihr = ((stepdegrees/15));   // divides total degrees into number of hours in an 
sidereal day (15 degrees per hour)
RAH = ihr - 0.5;            // ensures that the output in hours is always rounded down to show correct value in "time form"

imin = ((ihr - RAH)*60);   // multiplies the remainder of stepdegrees minus rounded hours and multiplies by 60 to convert to minutes.
RAM = imin - 0.5;            // ensures that the output in minutes is always rounded down to show correct value in "time form"

RAS = (((imin - RAM)*60));   // multiplies the remainder of stepdegrees minutes minus rounded minutes and multiplies by 60 to convert to seconds, this is float so also includes 10ths.



This may look like complete gobbledegook, but it is basically fairly simple algebra whereby all the variables we started earlier are being used in a fixed way to create an output. I am really rubbish at explaining myself, I am told this daily, but I will try:

At the beginning of the code we have added a couple of additional variables RAH, RAM and RAS, as I mentioned earlier we are using an integer variable to create our readable output, in order to create the "truncated output" mentioned before we have to create an integer which will always give us the correct Hour, Minute or Second for a given decimal:

if, ihr = 2.516 hours then RAH = 2.516 - 0.5 = 2.016, which as an int = 2
if, ihr = 2.016 hours then RAH = 2.016 - 0.5 = 1.516, which as an int = 2

Edit: Thanks to Tom (TCWORLD) from the Stargazer's Lounge, this was creating an error and most likely the cause of my other problems further down; polaris is more than 30 minutes into an hour (>0.5) so, this code actually worked by accident while I was initially testing. Tom correctly points out that as the float to int cast is only truncating the results would be as follows for some given floats:


2.016 -> 2
2.980 -> 2
1.999 -> 1
1.516 -> 1

This would give anything with a right ascension of less than 30 minutes past the hour the incorrect hour.

This code was already redundant following my updates, but for anyone thinking they could use this elsewhere; it doe not work. Will - 31-01-2014, 13:21.

This is what is called truncating the output, it allows us to show any decimal pertaining to an hour as a single integer and the correct one regardless of rounding, to boot.

We then need to do the same for the Minutes to get a sensible reading:

the code states that; imin = (ihr - RAH)*60 this means that imin is equal to the remainder of the hour decimal minus the truncated result:

imin = 2.516 - 2 = 0.516 * 60 (to turn the figure into minutes) = 30.96 minutes

this needs to be truncated to give a minute integer

RAM = (imin - 0.5)   =  30.96 - 0.5   = 30.46 = int = 30.

RAS = (imin - RAM) * 60  =  30.96-30  = 0.96 * 60 = float = 57.60 seconds.

So that process has taken a decimal hour figure and created 2 sets of integers and a float, printed like so:

2.516 hours is equal to 2h : 30m : 57.60 s. 

I couldn't get this code any further than creating a fixed result it didn't integrate well once a clock counter (millis) was introduced. Learning curves, aye! - See edit above for why!!!




All was not lost though, I actually ended up with something much more simple using the unsigned long function and adding the decimal angle of the Right Ascension of polaris + the stepper position to the millis() count before the  unsigned long function to create the Hour Angle offset as follows:


 int Hnudge; // Nudge Hour + 1
 int Mnudge; // Nudge Minute + 1
 float ihr;  // create float for output of initial convertion
 float stepdegrees; // output from stepper motor in degrees
 

 stepdegrees = ((Stepcount/5.68)/10)+37.954; // temporary fixed angle for testing will be a "stepcount * no. degrees/step" where stepcount will have a button starting the count at 37.954541 degrees *location of polaris*

 Hnudge = 0;                  // Sidereal clock set Hour nudge
 Mnudge = 0;                  // Sidereal clock set Minute nudge
 ihr = ((stepdegrees/15));   // divides total degrees into number of hours in an sidereal day (15 degrees per hour)
 
 float D,LSTH,LSTM,LSTS,ms;   // Local Sidereal time calculator, with nudge control for setting the clock.
 unsigned long over;
 elapsed=(((ihr*3600000)+(Hnudge*3600000)+(Mnudge*60000))+start); // elapsed is the ajustable hour angle in milliseconds = Right Ascension + Hour set + Minute Set + Elapsed Time 
 D=int(elapsed/86164091);                                         // = 23 hrs 56 mins 4 seconds = Sidereal day
 over=elapsed%86164091;                                           // +1 Sidereal day
 LSTH=int(elapsed/3600000);                                       // = 60 minutes
 over=elapsed%3600000;                                            // + 1 hour
 LSTM=int(over/60000);                                            // = 60 seconds
 over=over%60000;                                                 // + 1 Minute
 LSTS=int(over/1000);                                             // = 1000 ms
 ms=over%1000;  

I'll try to explain how this is working on the back of the previous explanation of the right ascension calc above.

So in the background we have the microprocessor counting continuously in milliseconds, this count is being used to calculate all the timings in this program so everything interacting with it must be scaled to the same units:

Firstly we start with a step count from the stepper motor for argument sake 500. Each step has an angular value of 5.68 degrees and it is attached to a 10:1 drive so 500 steps is equal to:

(500/5.68)/10 =  8.803 degrees.

We then need to add the value of polaris to this, so that during polar alignment the system is "zeroed" to the celestial pole;

8.803 + 37.954. this has been designated as "stepdegrees" it will always equal the value of the step count in degrees plus polaris.

To convert this to a decimal hour we need to divide by how many degrees the earth rotates in 1 hour. this is 15 degrees;

ihr = stepdegrees/15   ==  46.757 / 15 = 3.1171 hours.

Then in order to add this value to the millisecond count we need to convert it to milliseconds

3.1171 * 3600000.

Then, we need to account for the Local Sidereal Time adjustment, as explained this is just an offset to keep the system simple. Each time the nudge buttons are pressed they increase the value by an increment of one so we need to scale each increment to the value they are supposed to represent in milliseconds, also:

+ (Hnudge * 3600000) + (Mnudge * 6000)

Plus the millisecond count;

+start

So, as the motor position changes so does the time relative to both the celestial co-ordinate AND Local Sidereal Time. Success.

Now to make the the time readable by a human and equal to the Hour Angle within something like stellarium:

unsigned long, over = a counting function which will roll over and count sets of numbers based on the value, this can be used quite simply to turn the complex mess above into a simple clock time:



 elapsed=(((ihr*3600000)+(Hnudge*3600000)+(Mnudge*60000))+start); // elapsed is the ajustable hour angle in milliseconds = Right Ascension + Hour set + Minute Set + Elapsed Time 
 D=int(elapsed/86164091);                                         // = 23 hrs 56 mins 4 seconds = Sidereal day
 over=elapsed%86164091;                                           // +1 Sidereal day


D is equal to how many times the "ihr" has gone over 86164091ms (a sidereal day)


 LSTH=int(elapsed/3600000);                                       // = 60 minutes
 over=elapsed%3600000;                                            // + 1 hour



LSTH is equal to how many times the "ihr" has gone over 3600000ms within 86164091ms (hours)


 LSTM=int(over/60000); // = 60 seconds  over=over%60000;                                                 // + 1 Minute


LSTM is equal to how many times the "ihr" has gone over 60000ms within 36000000ms (minutes)


 LSTS=int(over/1000);                                             // = 1000 ms
 ms=over%1000;  

LSTS is equal to how many times the "ihr" has gone over 1000ms within 60000ms (seconds)


I hope that has made some sense, I have since done some work on compiling this into a program with all the buttons and stepper motor controls. I will upload this in full once completed so anyone can hopefully replicate the whole build for cheap tracking telescope mount with joypad controlled driven "point to" capabilities!

If you have any questions, please feel free to email me.