Jump to content

Banner.jpg.b83b14cd4142fe10848741bb2a14c66b.jpg

DIY Moon Phase Dial


Gina

Recommended Posts

I've ordered one of these - Japanese sinano 2 phase 4 wire stepper motor 0.5A Step Angle 0.9 STH-36C1018.  Has the advantage of half the step angle of the NEMA 17.  I may have a NEMA17 spare - I'll have a look but its a 40mm deep one or maybe more.  I know I have a driver module.

I am thinking that I'm just continually metaphoretically banking my head against a brick wall with the 28BYJ-48 stepper motor :BangHead:  The odd ratio gearbox shouldn't be a problem but it just doesn't want to "play ball".  I get the impression that I could go on indefinitely trying to get sensible timing.  And wasting a lot of time when I could be doing something useful.

Link to comment
Share on other sites

  • Replies 1.1k
  • Created
  • Last Reply
31 minutes ago, hughgilhespie said:

Hi Gina,

These are nice motors and available in the UK. A bit pricey but decent quality.

http://uk.stepperonline.com/geared-stepper-motors-c-4.html

Regards, Hugh

Thanks Hugh :)  Yes, I have one of those with a 100:1 gearbox that I bought for a 3D printer.  I didn't use it for the Titan in the end but plan to use it for the Z drive for my Giant printer.  A clock doesn't need anything that powerful.

Link to comment
Share on other sites

6 hours ago, Gina said:

I am thinking that I'm just continually metaphoretically banking my head against a brick wall with the 28BYJ-48 stepper motor :BangHead:  The odd ratio gearbox shouldn't be a problem but it just doesn't want to "play ball".  I get the impression that I could go on indefinitely trying to get sensible timing.  And wasting a lot of time when I could be doing something useful.

I have two of these steppers, unused. They are so tiny, I can't help wondering how useful they really are. Very interested to see if you get consistent results from a larger stepper.

Link to comment
Share on other sites

These little stepper motors work fine for remote focussing but I haven't used them for much else until this clock.  Nothing else needed accuracy.  Focussing control is a feedback system so accuracy isn't important.

ATM I'm still running the clock and logging the results - what for, I really don't know but if anyone would like to see the results I can post them.  Actually, I've just left it running while I've been getting on with other things.  I'll continue to look for a spare NEMA17 - I'm sure I should have one or two ready for extra 3D printer extruders.

Link to comment
Share on other sites

Hi Gina,

This project has certainly given you a lot to think about.

Having followed your progress for a while now, albeit in the background, it crossed my mind that I had not seen any mention of the execution times of the various sub routines and/or interrupt routines being mentioned.

Normally these would not be of much concern for a focuser programme or such, however, they can be a very big issue when it comes to real time operations such as this one.

I don't remember seeing any mention of these in any of your timing calculations, but I may have missed it, it's been a long post and I have only skimmed through a lot of the coding etc.

It crossed my mind that perhaps this could account for ,at least some of, the ghosts you appear to be chasing if you had not factored them in to your timing calcs.

I am not that familiar with C++, being an assembler man myself, but I can follow the major jist of it, however,  I am not sure quite how you could assess such execution times accurately since the actual code seen by the processor is generated by the compliler... and they vary a lot in the way they compile... unlike assembler where you can easily assess the instruction times and calculate such things pretty accurately.

Just thoughts really Gina so please forgive me if I have got this wrong.

I hope you can find the problem/s and resolve them soon.

Best regards.

Sandy.:icon_biggrin:

 

Link to comment
Share on other sites

14 hours ago, Gina said:

These little stepper motors work fine for remote focussing but I haven't used them for much else until this clock.  Nothing else needed accuracy.  Focussing control is a feedback system so accuracy isn't important.

ATM I'm still running the clock and logging the results - what for, I really don't know but if anyone would like to see the results I can post them.  Actually, I've just left it running while I've been getting on with other things.  I'll continue to look for a spare NEMA17 - I'm sure I should have one or two ready for extra 3D printer extruders.

Funnily enough that's what I was thinking of using mine for.

Link to comment
Share on other sites

They're good for focussing because they're small and light, have 5mm shaft so getting pulleys to fit is no problem, have a built-in gearbox so you don't have to resort to microstepping to get enough resolution.  Available in 5v and 12v versions and easy to drive using ULN2003A driver chips from an Arduino.  And they are cheap :)

Link to comment
Share on other sites

11 hours ago, Lonestar70 said:

Hi Gina,

This project has certainly given you a lot to think about.

Having followed your progress for a while now, albeit in the background, it crossed my mind that I had not seen any mention of the execution times of the various sub routines and/or interrupt routines being mentioned.

Normally these would not be of much concern for a focuser programme or such, however, they can be a very big issue when it comes to real time operations such as this one.

I don't remember seeing any mention of these in any of your timing calculations, but I may have missed it, it's been a long post and I have only skimmed through a lot of the coding etc.

It crossed my mind that perhaps this could account for ,at least some of, the ghosts you appear to be chasing if you had not factored them in to your timing calcs.

I am not that familiar with C++, being an assembler man myself, but I can follow the major jist of it, however,  I am not sure quite how you could assess such execution times accurately since the actual code seen by the processor is generated by the compliler... and they vary a lot in the way they compile... unlike assembler where you can easily assess the instruction times and calculate such things pretty accurately.

Just thoughts really Gina so please forgive me if I have got this wrong.

I hope you can find the problem/s and resolve them soon.

Best regards.

Sandy.:icon_biggrin:

 

Thank you for taking the trouble to read through this rather long thread Sandy :)  Funnily enough, Arduino coding was my first time with C++ having used mainly assembler in my carreer plus a few other languages.  The only significant difference in C++ from other high level languages is the syntax - the structure is much the same.  I was pleased to see that the Arduino IDE used a compiler rather than an interpreter thereby reducing processing time vastly (depending on the efficiency of the compiler).  And yes, most of my applications were time critical so I was used to calculating processing times.

Coming now to the Arduino and this clock application, I haven't attempted to calculate processing times because I have assumed that this is insignificant compared with the time interval of one second used to drive the clock.  As long as all processing and motor driving is completed within well within the second, the timing shouldn't matter.  In fact the clock is gaining rather than losing as would occur if input pulses were missed.  If the input was from a mechanical device I would suspect contact bounce causing extra input pulses, but it isn't - it's a square wave logic signal from the RTC.

Link to comment
Share on other sites

That last point in my last post has given me a thought - clutching at straws, of course, but that's all that left.  Could the Arduino be picking up stray pulses on D2.  A simple test is to measure the time interval between "ticks".   Taking the dual edge transition, this should be 500ms.  A simple test can measure this time using millis().  The Arduino web page example can simply be modified to suit.

unsigned long time;

void setup(){
  Serial.begin(9600);
}
void loop(){
  Serial.print("Time: ");
  time = millis();
  //prints time since program started
  Serial.println(time);
  // wait a second so as not to send massive amounts of data
  delay(1000);
}

Here's the simple test sketch and the result

// Filename :- Moon_Clock_RTC_Input_Test 2016-03-008_1224
// Arduino test sketch for noise on RTC square wave input.
// Software timing from RTC on pin 2 using polling
//
#include <DS3232RTC.h>    //http://github.com/JChristensen/DS3232RTC
#include <Time.h>         //http://www.arduino.cc/playground/Code/Time  
#include <Wire.h>         //http://arduino.cc/en/Reference/Wire (included with Arduino IDE)
//
int lastSqWave = 0; //  Save logic state of square wave
unsigned long time, lastTime = 0;

//
void setup() {
  Serial.begin (9600);     // Enable Serial Monitor via USB
  pinMode(2,INPUT_PULLUP);   //  One sec timing pin
  setSyncProvider(RTC.get);  // the function to get the time from the RTC
  if(timeStatus() != timeSet) 
      Serial.println(" Unable to sync with the RTC");
  else
      Serial.println(" RTC has set the system time");
  RTC.squareWave(SQWAVE_1_HZ);    // 1 Hz square wave            
}
//
//
void loop(){
  int val = digitalRead(2);  // read logic level of 1Hz square wave
  if (val != lastSqWave) { lastSqWave = val;
    Serial.print(" Time: ");
    time = millis();
    //print time since last "tick"
    Serial.println(time - lastTime);
    lastTime = time;

  ;}  }
//  
// End

56dec968240a5_RTCInputTestLog01.thumb.JP

So no problem there :)  BUT this is not running the stepper motor and there is the possibility that this is causing interference - very unlikely but...

Link to comment
Share on other sites

I've now added the millis() check to the full sketch that runs everything including power from the mains 12v PSU.  The check is after the motor run and shows the time taken advancing the clock.  So far it all looks correct.  The motor run takes about 20ms on the up stroke of the square followed by the millis showing correction for this on the down stroke.  Then every 5 intervals the motor run is skipped and that shows as 500ms plus or minus one.  I can see no sign of any interference.  So that's another ghost exorcised!!

56ded31eb3465_RTCInputTestLog02.thumb.JP

This is the relevant extra code

void loop(){
  if (timeIsSet) { 
    int val = digitalRead(2);  // read logic level of 1Hz square wave
    if (val != lastSqWave) { lastSqWave = val; if (val) {runClock();} 
      Serial.print(" Time: ");
      time = millis();
      //print time since last "tick"
      Serial.println(time - lastTime);
      lastTime = time;
  }

 

Link to comment
Share on other sites

I think the above results prove that the timing errors are not due to software or interference.  The errors are of the order of 1 in 100 or so, so would show up in 500ms.  I think the problem has to be mechanical unless someone has something else to suggest.  It looks as it the motor is running on in spite of having current in the coils all the time.  And it's not the pinion slipping on the motor shaft as that has flats on it with matching flats in the pinion.                                                                        

Link to comment
Share on other sites

Let's see - 8 half-steps in each interval.  8 x 50 = 400ms.  Much less than 1s so no problem.  In fact 100ms per step would be no problem and would make the motion a lot smoother than an 80ms burst followed by 920ms hold time.  it would do 8 steps in 800ms and 100ms pause.  Except when it dropped a burst when the pause would be 1100ms.

 I think that's a good idea - I'll try it - thank you Neil :) 

Link to comment
Share on other sites

Thinking more about this I would prefer the motion to be as smooth as possible and therefore using individual half-steps would be better than groups of 8.  I can implement this if I hold the pattern table position between steps (or rather half-steps).

Here is the current stepForward, moving forward by 8 half-steps.

void stepForward(void)  // Normal clock advance of 8 half-steps per call
{
  for(int i = 7; i >= 0; i--)
  {
    digitalWrite(motorPin1, bitRead(lookup[i], 3));
    digitalWrite(motorPin2, bitRead(lookup[i], 2));
    digitalWrite(motorPin3, bitRead(lookup[i], 1));
    digitalWrite(motorPin4, bitRead(lookup[i], 0));
    delayMicroseconds(100000);
  }
}

If a global variable is used for the phase pattern array, the half-steps can be separated into individual ones.  Let's call this patternPointer.

int patternPointer = 0;  //  Pointer for pattern array
...
...
...
void stepForward(void) { // Normal clock advance of 8 half-steps per call
  digitalWrite(motorPin1, bitRead(lookup[patternPointer], 0));
  digitalWrite(motorPin2, bitRead(lookup[patternPointer], 1));
  digitalWrite(motorPin3, bitRead(lookup[patternPointer], 2));
  digitalWrite(motorPin4, bitRead(lookup[patternPointer], 3));
  delayMicroseconds(100000);
  patternPointer ++;  //  Increment pointer ready for next half-step phase
}

Now when we call stepForward the clock will advance by just one half-step. 

Link to comment
Share on other sites

Now to a new calculation for half-stepping.  A new calculation means  I won't be influenced by previous ones :D  There are 128 half steps at the stepper mechanism which is then geared down to the ooutput shaft.  The clock gear ratio from motor to minutes is 8:45 so the 3600s revolution time becomes 3600x8/45 secs at the motor shaft that's 640s.  Gearbox ratio is 63.68395:1 so a revolution of the ouput shaft is 128 x 63.68395 half-steps.  Required half-steps per second is therefore 128 x 63.68395 / 640 = 12.73679.

The magic number is thus 12.73679 half-steps per second.  Nearest whole number = 13 so we send 13 half-steps every second but drop this to 12 every so often as the first correction level.  13 - 12.73679 = 0.26321.  Converting this to seconds gives 3.799.  Nearest whole number is then 4 so I reckon we want to sent 12 steps instead of 13 every 4 seconds

Link to comment
Share on other sites

1 hour ago, fireshipjohn said:

Hi Gina,

One that caught me out before, delayMicroseconds() only works up to 16384.  See here: https://www.arduino.cc/en/Reference/DelayMicroseconds

 

John

Aha... Thank you John - very good point :) I didn't pick up on that.  Means the latest sketch isn't going to show any improvement as the 100ms won't be implemented :(   I'll sort it out tomorrow.

Link to comment
Share on other sites

Now I'm not using interrupts I can use delay() for delay in ms.  If I go for the 13 half-steps per sec, the delay wants to be 76ms to get 13 into the second. 

Link to comment
Share on other sites

I made a mistake in the calculation and had twice the stepping rate wanted - DOH :(  Anyway, I've fixed that by using a 2s timing period and changing the delay to 140ms.  Now the clock seems to be losing a bit instead of gaining so that's different.  The correction is only at the first level so far though so I'm not expecting high accuracy.

Link to comment
Share on other sites

Here is the log from this last code change.

 12:59:41
 13:59:55 14
 15:00:15 20

16 hours ago, Gina said:

The magic number is thus 12.73679 half-steps per second.  Nearest whole number = 13 so we send 13 half-steps every second but drop this to 12 every so often as the first correction level.  13 - 12.73679 = 0.26321.  Converting this to seconds gives 3.799.  Nearest whole number is then 4 so I reckon we want to sent 12 steps instead of 13 every 4 seconds

The last correction is 1 in 4 ie. 0.25 and we want 0.26321 so next correction is 0.26321 - 0.25 = 0.01321 or 1 in 75.70.  Nearest whole number is 76 and this time we want to gain a half-step.

The current code is

void runClock() {  // subroutine called on every rising edge of the RTC squawre wave
  gbCount ++; // Increment gearbox count
  if (gbCount >= 13) { gbCount = 0; stepForward(12); } // half-step less
    else if ((gbCount % 4) == 0) { stepForward(12); }  // half-step less every 4 secs
    else { stepForward(13); }                          // normal call to stepForward
 }

And amended code for next correction will be

void runClock() {  // subroutine called on every rising edge of the RTC square wave
  gbCount ++; // Increment gearbox count
  if (gbCount >= 76) { gbCount = 0; stepForward(14); } // half-step more
    else if ((gbCount % 13) == 0) { stepForward(12); }  // half-step less every 13 periods
    else if ((gbCount % 4) == 0) { stepForward(12); }  // half-step less every 4 periods
    else { stepForward(13); }                          // normal call to stepForward
 }

 

Link to comment
Share on other sites

Holding up well :)  Here is the latest log with the time error in seconds.  So far the error has been less than 10s - fingers crossed :)

   Time      Diff   Total
 16:00:02 
 16:59:58   - 4     - 4
 17:59:58     0     - 4
 19:00:04   +6     +2
 20:00:00   - 4     - 2

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.