Help needed with 4-digit display behaving badly

I am new to the Arduino. I am trying to get a 4-digit display to count out the time in a 24 hour day by minutes. So from 00:01 to 23:59. The actual timing is not important at the moment so there is no real time clock involved.

The 4-digit display uses (4) wires. Vcc, Gnd, and (2) digital pins.

The sketch I have runs perfectly on the 4-digit display when the values are also being serial printed to the PC screen.

But if the values are not printed to the PC screen, the same sketch will bomb out at 00:33, 01:40, 02:16, or 07:36 (approximately). Bombing out means the count will start over again at 00:00.

I can extend the range that the sketch will count before bombing out by inserting delays, but I cannot get past 07:36, unless the values are being printed to the PC screen.

The current sketch follows:

// fourth attempt to count time in minutes
// limited to hours, 1-24
// works perfectly when printing out to serial printer on screen
// when not printing to the screen, it stops in unusual places
// e.g. 36 or 141, or 133
// setting delays extends the range that it will count
// but it will never get past about 7:50 unless printing to screen

// 4-digit, 7-segment display with (2) data wires, Vcc, and Gnd
// (4) wires total

//15 dec 16

#include "TM1637.h"

//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//the range of numbers handled by TM1637
//0~9,A,b,C,d,E,F
//the output of TM1737 for the corresponding numbers

#define CLK 6
#define DIO 5
TM1637 tm1637(CLK,DIO);

//the four digits of the display defined
int digitone = 0;
int digittwo = 0;
int digitthree = 0;
int digitfour = 0;

int minute = 0;
int hour = 0;

void setup() 
{
tm1637.init();
tm1637.set(BRIGHT_TYPICAL);
//BRIGHT_TYPICAL = 2, BRIGHT_DARKEST = 0, BRIGHTEST = 7

Serial.begin( 9600);

}

void loop() 
{
if (minute == 60)
 {
 minute = 0;
 hour++;
 }

//delay(3);

if (minute >= 10) // check if minute is a double digit
 {
 digitthree = (minute/10);
 digitfour = minute - (digitthree*10);
 }
 else
 {
 digitthree = 0;
 digitfour= minute;
 }

//delay(3);

Serial.print("Minute: ");
Serial.print(minute);
Serial.print(" ");
Serial.print("digitone: ");
Serial.print(digitone);
Serial.print(" ");
Serial.print("digittwo: ");
Serial.print(digittwo);
Serial.print(" ");
Serial.print("digitthree: ");
Serial.print(digitthree);
Serial.print(" ");
Serial.print("digitfour: ");
Serial.print(digitfour);
Serial.print("\n");

IncrementHour();

//delay(3);
 
tm1637.display(0,digitone);
//delay(3);
tm1637.display(1,digittwo);
//delay(3);
tm1637.display(2,digitthree);
//delay(3);
tm1637.display(3,digitfour);
//delay(3);
 
minute++;
delay (300);

}

void IncrementHour()
{
 if (hour == 24) //check if more than 24 hours
   {
   hour = 0;     // reset clock if more than 24 hours
   }
   
if (hour >= 10) // check if hours is a double digit
   {
   digitone = (hour/10);
   digittwo = hour - (digitone*10);
   }
else
   {
   digitone = 0;
   digittwo = hour;
   }
}

Any help will be appreciated. Thanks. djgeenen

lncrementHour() is getting too big for an integer. Your test for it equaling 24 is being skipped because it is called during each loop iteration. IncrementHour should be called only when minute equals 60. Edit Why is hour++ separate from IncrementHour() ?

Further to my post at the top, when everything (Arduino and 4-digit display) is run on battery power the sketch again works perfectly. It is only when the USB cable is connected between the PC and the Arduino that the sketch bombs out and starts re-counting prematurely.

So my problem is fixed although I don't understand what has been happening. But my device will run on battery power and under battery power the sketch works. So all is good from a practical stand point.

IncrementHour is not a good name for the subroutine. IncrementHour is preparing the value of the hour for display by creating two separate digits from the hour value. This is done every time a new value for minute is posted. As you say it could be improved and stream-lined.

And again as you say, the hour is only incremented after the "if" statement has determined minute has reached 60.

Thanks for taking the time to go through the sketch and make your comments.

Hi, Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Your PC USB powering having problems yet when on battery ok.

How are you powering with the battery?

Tom... :)

This seems to indicate that you have a power pb when on USB

I have attached a circuit diagram of my 4-digit time counter. The completed device includes an H-bridge shield for two motors and a joystick, so I am running out of pins. That is why I am interested in the 4-digit display with only four wires.

The circuit diagram only deals with the wiring for the 4-digit display.

I don’t know what a “power pb when on USB” means. I’m guessing “pb” means problem.

But when I couldn’t get the sketch to work I went out and bought a Genuine Arduino Uno and tried it. But there was no difference.

Right now the sketch is running well on a 12 volt battery.

Hi,
OPs circuit.
ab0fb818611afcd117b286b935250b6e493e16ff.jpg
You need to include your motors in the diagram, how are you powering them.
The USB can only provide a limited amount of current, your 12V battery will be able to supply much more.

What current rating are your motors and where do you get the power for them.
What sort of 12V battery are you using and do you have a fuse in the positive line to prevent damage due to short circuits.

If you disconnect the motors and try the USB port power does the problem still occur?
What H-Bridge do you have?

Tom… :slight_smile:

I have attached a circuit diagram of my entire device, including the LED display I was having trouble with, two motors, a motor controller, and a joystick. I have also included a parts lists with specs on the parts.

Unfortunately, I can’t figure out how to get the images into this message. “Enter the image URL” doesn’t make sense to me when the images are on my computer.

However, when I ran into trouble with the LED display starting to re-count prematurely, all the parts where assembled on the Arduino but they were not addressed or activated in any way by the sketch. The sketch was solely to get the LED display to count the minutes in a 24 hour day. After that was accomplished, I intended to integrate the display sketch into previously working sketches that ran the motors and joystick.

Just to summarize: The display sketch counts and displays the minutes and hours in a 24 hour day, the two motors are activated at scheduled times by the time function. The joystick allows for manual corrections to the motors positions if needed. The complete device is powered by a 12 volt battery.

The CountingTime-4 sketch works perfectly when the time values are serial printed to the PC screen. The sketch also works perfectly when a 12 volt battery is the power source for the Arduino and all other attached hardware. But the sketch will start re-counting prematurely when the a USB cable connected to the PC is the power source for the Arduino and all other attached hardware, although only the LED display is addressed or activated by the sketch. When the sketch starts re-counting prematurely, it is not serial printing to the PC.

The USB cable is about 1500mm long. I have had a problem in the past with an HDMI cable that was too long. But the fact that the sketch works perfectly when serial printing to the PC thru the USB cable is baffling.

This is a prototype and is small as you can see from the motors.

Thanks for your interest and comments.

Is that “The” Tesla?

If so, God bless you and may the Force be with you.

Hi,
Thanks for the circuit diagram, however why are the motors connected where I have circled.
They should be connected to the motor terminals on the shield.
I think you had better read how to use the shield before going any further.
ArduinoMotorJoystickDisplay_SchematicCCCC.jpg
If you completely removed the shield, does your project perform properly on USB as well as battery?

Tom… :slight_smile:

Your comment on the motors is noted. The wiring I'm showing to the motors is data cabling that controls the direction of the motors' rotation, forward or backward. Perhaps, I have not diagrammed it correctly. The two motors are getting their power from the motor terminals on the shield. The motor power wiring is not shown in my circuit diagram. I agree this is a large omission.

At sometime in the near future I will take it all apart and see if I have the display problem without the motor shield.

Hi, I'm surprised you didn't just mount the shield on the UNO and use the top of the shield to add the extra wires for joystick and display.

Tom.... :)

The motor controller shield I have used does not have pass-thru headers so there is no option to plug a pin into the top of the shield. I was told to de-solder it and put in my own headers.

Doesn’t seem to me to be a very thoughtful design.

It eliminates any possibility of adding another shield on top of the motor controller.

I found it easier to cut notches in the motor controller shield where I needed a pin to pass thru to the UNO below.

For whatever value it may have

A working sketch

Timer control of two bi-directional DC motors, with time display and joystick.

//Working sketch
//
// This sketch combines bi-directional motor control
// with a 24 hour timer, time display, and joystick
// 16 Dec 16
//
// One example application
// If a robot can move in the X and Y directions
// This sketch can program the robot to trace out a square,
// Or some other shape, at a scheduled time or times
// In a 24 hour day
// The joystick can be used to move the robot
// To a new location for the next square
//
// Adjustable parameters
// seconds - determines the accuracy of the time clock
//           set low to speed up 24 hour cycle for debugging
// motor direction and speed - depends on motor controller library
// motor running duration
// operation schedule - insert subroutines for required 
//                      operation times
//
// Note
// Sketch works as intended when hardware is powered by battery
// Sketch works as intended when hardware is powered by USB
// cable and is serial printing to PC screen
// Timer will restart 24 hour cycle prematurely when hardware is 
// powered by USB cable and not serial printing to PC screen
// This is an unresolved mystery
//
// Hardware
// Genuine Arduino UNO
// Duinotech motor controller shield XC-4472
// Duinotech 4-wire Joystick XC-4422
// TM1637 4-wire 4-digit LED display
//
//
// Outer motor = motorY
// Inner motor = motorX

#include <AFMotor.h>
#include "TM1637.h"

AF_DCMotor motorY(1, MOTOR12_2KHZ); // create outer motor, 2KHZ pwm
AF_DCMotor motorX(2, MOTOR12_2KHZ); // create inner motor, 2KHZ

// for joystick
int Xvalue = 0;
int Yvalue = 0;

// joystick pin assignments
const int SW_pin = 2; // digital pin connected to switch output
const int X_pin = 0; // analog pin connected to X output
const int Y_pin = 1; // analog pin connected to Y output

// define display pins
#define CLK 6
#define DIO 5
TM1637 tm1637(CLK,DIO);

//define the four digits of the display
int digitone = 0;
int digittwo = 0;
int digitthree = 0;
int digitfour = 0;

// define timeing values
int seconds = 5; // used to time minutes
               // set low to speed up 24 hour cycle for debugging
int minute = 0;
int hour = 0;

void setup() 
{

motorY.setSpeed(150); // set the speed to 150/255
motorX.setSpeed(150);

// from joystick
pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH); 

tm1637.init();
tm1637.set(BRIGHT_TYPICAL);
//BRIGHT_TYPICAL = 2, BRIGHT_DARKEST = 0, BRIGHTEST = 7

motorX.run(RELEASE); // stop
delay(250);
motorY.run(RELEASE); // stop
delay(250);

}

void loop() 
{
if (minute == 60)
{
minute = 0;
hour++;
if (hour == 10)
  {
  PanelPosition10();
  }
 if (hour == 11)
  {
  PanelPosition11();
  }
}

if (minute >= 10) // check if minute is a double digit
{
digitthree = (minute/10);
digitfour = minute - (digitthree*10);
}
else
{
digitthree = 0;
digitfour= minute;
}

HourDisplay();

tm1637.display(0,digitone);
tm1637.display(1,digittwo);
tm1637.display(2,digitthree);
tm1637.display(3,digitfour);

minute++;
//delay(300);

// check if joystick has been used
// time interval before a minute has past
for (int i = 0; i <= (seconds*10); i++)
{
// from joystick
Xvalue = analogRead(X_pin); // read joystick X value
Yvalue = analogRead(Y_pin); // read joystick Y value

if(Yvalue > 760)
  {
  motorY.run(FORWARD); 
  delay(10);
  }
if(Yvalue < 150)
  {
  motorY.run(BACKWARD);
  delay(10);
  }
if(Xvalue > 760)
  {
  motorX.run(FORWARD);
  delay(10);
  }
if(Xvalue < 150)
  {
  motorX.run(BACKWARD);
  delay(10);
  }
  motorX.run(RELEASE); // stopped
  motorY.run(RELEASE); // stopped
  delay(10);
}

}

void HourDisplay()
// This subroutine prepares the hour value for display
// As single digits
{
if (hour == 24) //check if more than 24 hours
  {
  hour = 0;     // reset clock if more than 24 hours
  }
  
if (hour >= 10) // check if hours is a double digit
  {
  digitone = (hour/10);
  digittwo = hour - (digitone*10);
  }
else
  {
  digitone = 0;
  digittwo = hour;
  }
}

void PanelPosition10()
// This subroutine is one scheduled operation of both motors
{
motorX.run(FORWARD); // turn it on going forward
delay(250);
motorY.run(FORWARD); // turn it on going forward
delay(250);

motorX.run(RELEASE); // stop
delay(250);
motorY.run(RELEASE); // stop
delay(250);
}

void PanelPosition11()
// This subroutine is a second scheduled operation of both motors
//
// Add additional similar subroutines for additional
// Scheduled operations
//
{
motorX.run(BACKWARD); // turn it on going forward
delay(250);
motorY.run(BACKWARD); // turn it on going forward
delay(250);

motorX.run(RELEASE); // stop
delay(250);
motorY.run(RELEASE); // stop
delay(250);
}

TimerMotorControlJoystick-1.ino (4.59 KB)