Arduino Wall Clock

I am making a 12 hour analog style wall clock using a DC geared motor to drive the hands, and potentiometers to read their positions. I only have the hour hand functioning so far. It works perfectly, except that anywhere from 2 hours to as long as 30 hours after powered on, it freezes, and wont move or tick off second on its LED until it is restarted. I am not sure if it is a hardware or software issue. I am relatively new to arduino, so any help would greatly be appreciated. Just to give all the info, it freezes with the led on pin 13 either high or low randomly, but the led on pin 11 always seems to be in the on state. Here is the sketch…

// A 12 hour clock based on a DC Geared motor, ~4rpm, and a potentiometer for measuring the
// position of the clock hand. The clock must be powered on at 12:00, or the targetPosition
// variable must be initialised to the time in miliseconds it will be powered on.

const int positionSignalPin = 0; //Potentiometer to pin A0 for rotation measurement
const int positionSamples = 8; //number of samples to be averaged for each reading

const int high1Pin = 2; //H-Bridge high side to pin D2
const int high2Pin = 3; //other H-Bridge high side to pin D3
const int low1Pin = 4; //H-Bridge low side to pin D4
const int low2Pin = 5; //other H-Bridge low side to pin D5
const int greenLedPin = 11; //LED indicator, lit when at correct position, to pin D11
const int ledPin = 13; //LED indicator, lit for one second, off for one second, to pin D13

unsigned int targetPosition = 0; //ranges between 0 for 12:00, and 43199 for 11:59

int ledState = LOW; //toggles on and off to indicate seconds ticking
long previousMillis = 0;

long interval = 1000; //1000 miliseconds = 1 second

void setup()
{
pinMode(high1Pin, OUTPUT);
digitalWrite(high1Pin, HIGH);
pinMode(low1Pin, OUTPUT);
digitalWrite(low1Pin, LOW);
pinMode(high2Pin, OUTPUT);
digitalWrite(high2Pin, HIGH);
pinMode(low2Pin, OUTPUT);
digitalWrite(low2Pin, LOW);

pinMode(greenLedPin, OUTPUT);
digitalWrite(greenLedPin, LOW);
pinMode(ledPin, OUTPUT);
}

void loop()
{
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval)
{
previousMillis = currentMillis;
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);

targetPosition++;
int goToPosition = map(targetPosition, 0, 43199, 1, 600); //convert the time in miliseconds to the
//desired range of analog values
if (targetPosition > 43199) // sweeps the clock hand back to the start position when 12hrs has elapsed
{
targetPosition = 0;
goToPosition = map(targetPosition, 0, 43199, 1, 600);
int currentPosition = positionRead();
while (currentPosition > goToPosition)
{
hBridge(3);
currentPosition = positionRead();
}
hBridge(0);
}
int positionNow = positionRead();
while (positionNow < goToPosition)
{
hBridge(2);
positionNow = positionRead();
}
hBridge(0);
}
blinkGreenLed(2);
}

void blinkGreenLed(int cycles)
{
for(int i = 0; i < cycles; i++)
{
digitalWrite(greenLedPin, HIGH);
delay(10);
digitalWrite(greenLedPin, LOW);
delay(10);
}
}

void hBridge(int x)
{
if(x == 0) // COAST
{
digitalWrite(high1Pin, HIGH);
digitalWrite(low1Pin, LOW);
digitalWrite(high2Pin, HIGH);
digitalWrite(low2Pin, LOW);
}
if(x == 1) // STOP
{
digitalWrite(high1Pin, HIGH); //puts the H-Bridge into the coast state for safety between each state change
digitalWrite(low1Pin, LOW); // ----
digitalWrite(high2Pin, HIGH); // ----
digitalWrite(low2Pin, LOW); // ----
digitalWrite(high1Pin, HIGH); //now puts the H-Bridge into the “locked” state
digitalWrite(low1Pin, HIGH);
digitalWrite(high2Pin, HIGH);
digitalWrite(low2Pin, HIGH);
}
if(x == 2) // FORWARD
{
digitalWrite(high1Pin, HIGH);
digitalWrite(low1Pin, LOW);
digitalWrite(high2Pin, HIGH);
digitalWrite(low2Pin, LOW);
digitalWrite(high1Pin, LOW);
digitalWrite(low1Pin, HIGH);
digitalWrite(high2Pin, HIGH);
digitalWrite(low2Pin, LOW);
}
if(x == 3) // BACKWARD
{
digitalWrite(high1Pin, HIGH);
digitalWrite(low1Pin, LOW);
digitalWrite(high2Pin, HIGH);
digitalWrite(low2Pin, LOW);
digitalWrite(high1Pin, HIGH);
digitalWrite(low1Pin, LOW);
digitalWrite(high2Pin, LOW);
digitalWrite(low2Pin, HIGH);
}
}

int positionRead(void)
{
long positionMeasurement = 0;
for(int i = 0; i<positionSamples; i++)
{
positionMeasurement += analogRead(positionSignalPin);
delay(1);
}
positionMeasurement = positionMeasurement / positionSamples;
return(positionMeasurement);
}

long previousMillis = 0; 

long interval = 1000;  //1000 miliseconds = 1 second

  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval)

Is interval signed to allow for negative durations? The previousMillis variable should be unsigned.

What do you expect to have happen if currentMillis - previousMillis is equal to interval? Forget it, and wait for the next pass?

    if (targetPosition > 43199)  // sweeps the clock hand back to the start position when 12hrs has elapsed
    {
      targetPosition = 0;
      goToPosition = map(targetPosition, 0, 43199, 1, 600);

If targetPosition is 0, do you really need the map function to determine goToPosition?

  long positionMeasurement = 0;
  for(int i = 0; i<positionSamples; i++)
  {
    positionMeasurement += analogRead(positionSignalPin);
    delay(1);
  }
  positionMeasurement = positionMeasurement / positionSamples;

If you need to read the position of the potentiometer more than once, you need a better quality potentiometer.

I’d add some Serial.print() and Serial.println() statements to the sketch (and Serial.begin()), to see where the sketch is hanging up. If the time until the sketch hangs were consistent, the time would give a clue. But, with different times, its harder to know where there are issues. Other than those mentioned above.

Thanks so much for the suggestions, and sorry for the silly signed/unsigned and map mistakes. I only used the multiple analogReads because of earlier projects with load cell measurements always needed it, but I am sure your right that it is overkill here. I will try those fixes, and see what happens. Thanks again!!!

I FOUND THE PROBLEM. I have had a similar problems of the arduino randomly freezing / iradic behaviour, it was my power supply. I was using a wall-wart style switch mode. Once I switched over to a transformer style no more problems. :slight_smile: