Compile Error of TimedAction Library

In the code below, I’m getting a compiling error

apc_21_timekeeper:15: error: ‘clockUpdate’ was not declared in this scope

TimedAction timer = TimedAction(1000,clockUpdate);

^

exit status 1
‘clockUpdate’ was not declared in this scope

I declared it later on in the code. Thanks for helping! New to coding and Arduino.

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include <TimedAction.h>
#include "SystemFont5x7.h"
#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

String minsTens, minsUnits, secsTens, secsUnits;
int mins10, mins1, secs10, secs1;
int minutes, seconds;
int clockRunning = 0;

TimedAction timer = TimedAction(1000,clockUpdate);

void setup() {
 
 timer.disable();
 minutes = 0; seconds = 0;
 pinMode(2, OUTPUT);
 pinMode(A5, INPUT_PULLUP);
 pinMode(A4, INPUT_PULLUP);
 pinMode(A3, INPUT_PULLUP);
 
 Timer1.initialize( 4000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
 Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
 dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)

 dmd.selectFont(SystemFont5x7);
 dmd.drawString(2,0,"TIME:",5,GRAPHICS_NORMAL);
 dmd.drawString(8,8,"SET",5,GRAPHICS_NORMAL);
 beep();
}

void loop() {

 if (clockRunning == 0) {
   if (digitalRead(A3) == 0) {
     mins10++; 
     delay(200); 
     if (mins10 > 9) mins10 = 0;
     minutes = mins10 * 10 + mins1;
     displayUpdate();
   }
   if (digitalRead(A4) == 0) {
     mins1++; 
     delay(200);
     if (mins1 > 9) mins1 = 0;
     minutes = mins10 * 10 + mins1;
     displayUpdate();
   }
 }
 if (digitalRead(A5) == 0) {
   beep();
   delay(200);
   if (clockRunning == 0) {
     timer.enable();
     clockRunning = 1;
   } else {
     clockRunning = 0;
     timer.disable();
     dmd.drawString(2,8," OFF ",5,GRAPHICS_NORMAL);
     delay(3000);
     displayUpdate();
   }
 }

 if (clockRunning == 1) timer.check();  
}

void ScanDMD() { 
 dmd.scanDisplayBySPI();
}

void clockUpdate() {
 seconds--;
 if (seconds < 0) { 
   seconds = 59;
   minutes--;
 }
 secs10 = seconds / 10;
 secs1 = seconds % 10;
 mins10 = minutes / 10;
 mins1 = minutes % 10;
 displayUpdate();

 if (minutes == 0 && seconds == 0) {
   dmd.clearScreen(true);
   dmd.drawString(5,0,"FULL",4,GRAPHICS_NORMAL);
   dmd.drawString(5,8,"TIME",4,GRAPHICS_NORMAL);
   timer.disable();
   digitalWrite(2, HIGH);
 }
}

void displayUpdate() {
 minsTens = (String)mins10;
 minsUnits = (String)mins1;
 secsTens = (String)secs10;
 secsUnits = (String)secs1;
 
 dmd.drawString(2,8,minsTens.c_str(),1,GRAPHICS_NORMAL);
 dmd.drawString(8,8,minsUnits.c_str(),1,GRAPHICS_NORMAL);
 dmd.drawString(14,8,":",1,GRAPHICS_NORMAL);
 dmd.drawString(19,8,secsTens.c_str(),1,GRAPHICS_NORMAL);
 dmd.drawString(25,8,secsUnits.c_str(),1,GRAPHICS_NORMAL);
}

void beep() {
 digitalWrite(2, HIGH);
 delay(30);
 digitalWrite(2, LOW);
}

Hello and welcome,

At the time this line is compiled

TimedAction timer = TimedAction(1000,clockUpdate);

clockUpdate isn't yet defined. Like any variables or functions, in C/C++ you have to define it before using it. See forward declaration.

guix:
Hello and welcome,

At the time this line is compiled

TimedAction timer = TimedAction(1000,clockUpdate);

clockUpdate isn’t yet defined. Like any variables or functions, in C/C++ you have to define it before using it. See forward declaration.

Awesome, thanks for the quick reply. I thought I defined it in the following no?

void clockUpdate() {
  seconds--;
  if (seconds < 0) { 
    seconds = 59;
    minutes--;
  }
  secs10 = seconds / 10;
  secs1 = seconds % 10;
  mins10 = minutes / 10;
  mins1 = minutes % 10;
  displayUpdate();

  if (minutes == 0 && seconds == 0) {
    dmd.clearScreen(true);
    dmd.drawString(5,0,"FULL",4,GRAPHICS_NORMAL);
    dmd.drawString(5,8,"TIME",4,GRAPHICS_NORMAL);
    timer.disable();
    digitalWrite(2, HIGH);
  }
}

Appreciate your patience.

Another, better link for learning :wink:

http://www.learncpp.com/cpp-tutorial/17-forward-declarations/

Edit: I've just remembered that the Arduino IDE automatically add forward declarations if they are missing. So how do you compile your sketch?

guix:
Edit: I’ve just remembered that the Arduino IDE automatically add forward declarations if they are missing. So how do you compile your sketch?

In this case it adds them too late. A short example:

typedef void (*void_func_void_ptr)(void);

// void foo(void);

void_func_void_ptr f = foo;

void setup() { }

void loop() { }
  
void foo(void) { }

Preprocessed version:

#include <Arduino.h>
#line 1
#line 1 "/var/folders/sl/3x4zr7v14j5d_8xznyys7tjc0000gn/T/arduino_db16d530010cbdbdd452b1b8b4c58aa1/sketch_dec03a.ino"
typedef void (*void_func_void_ptr)(void);

// void foo(void);

void_func_void_ptr f = foo;  // <<< need it here

void setup();
void loop();
void foo(void);              // <<< too late!
#line 7
void setup() { }

void loop() { }
  
void foo(void) { }

With the prototype added:

#include <Arduino.h>
#line 1
#line 1 "/var/folders/sl/3x4zr7v14j5d_8xznyys7tjc0000gn/T/arduino_db16d530010cbdbdd452b1b8b4c58aa1/sketch_dec03a.ino"
typedef void (*void_func_void_ptr)(void);

void foo(void);

void_func_void_ptr f = foo;

void setup();
void loop();
#line 7
void setup() { }

void loop() { }
  
void foo(void) { }

guix:
Another, better link for learning :wink:

http://www.learncpp.com/cpp-tutorial/17-forward-declarations/

Edit: I’ve just remembered that the Arduino IDE automatically add forward declarations if they are missing. So how do you compile your sketch?

oqibidipo:
In this case it adds them too late. A short example:

typedef void (*void_func_void_ptr)(void);

// void foo(void);

void_func_void_ptr f = foo;

void setup() { }

void loop() { }
 
void foo(void) { }




Preprocessed version:


#include <Arduino.h>
#line 1
#line 1 “/var/folders/sl/3x4zr7v14j5d_8xznyys7tjc0000gn/T/arduino_db16d530010cbdbdd452b1b8b4c58aa1/sketch_dec03a.ino”
typedef void (*void_func_void_ptr)(void);

// void foo(void);

void_func_void_ptr f = foo;  // <<< need it here

void setup();
void loop();
void foo(void);              // <<< too late!
#line 7
void setup() { }

void loop() { }
 
void foo(void) { }





With the prototype added:


#include <Arduino.h>
#line 1
#line 1 “/var/folders/sl/3x4zr7v14j5d_8xznyys7tjc0000gn/T/arduino_db16d530010cbdbdd452b1b8b4c58aa1/sketch_dec03a.ino”
typedef void (*void_func_void_ptr)(void);

void foo(void);

void_func_void_ptr f = foo;

void setup();
void loop();
#line 7
void setup() { }

void loop() { }
 
void foo(void) { }

I’ve attempted to place it about the void setup() and void loop()

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include <TimedAction.h>
#include "SystemFont5x7.h"
#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

String minsTens, minsUnits, secsTens, secsUnits;
int mins10, mins1, secs10, secs1;
int minutes, seconds;
int clockRunning = 0;

void clockUpdate() {
  seconds--;
  if (seconds < 0) { 
    seconds = 59;
    minutes--;
  }
  secs10 = seconds / 10;
  secs1 = seconds % 10;
  mins10 = minutes / 10;
  mins1 = minutes % 10;
  displayUpdate();

  if (minutes == 0 && seconds == 0) {
    dmd.clearScreen(true);
    dmd.drawString(5,0,"FULL",4,GRAPHICS_NORMAL);
    dmd.drawString(5,8,"TIME",4,GRAPHICS_NORMAL);
    timer.disable();
    digitalWrite(2, HIGH);
  }
}

TimedAction timer = TimedAction(1000,clockUpdate);

void setup() {............

However timer needs definition within clockUpdate.

Sorry this is really simplistic.

Just add the prototype before the timer definition, actual definition of the function can be later.

void clockUpdate();

TimedAction timer = TimedAction(1000,clockUpdate);

// later ...

void clockUpdate() { 
... 
}

oqibidipo:
Just add the prototype before the timer definition, actual definition of the function can be later.

void clockUpdate();

TimedAction timer = TimedAction(1000,clockUpdate);

// later …

void clockUpdate() {

}

Thanks tons! I have done the following but I’m getting many more errors. Still issues with the position.

void clockUpdate();

TimedAction timer = TimedAction(1000,clockUpdate);

void setup() {
  
  timer.disable();
  minutes = 0; seconds = 0;
  pinMode(2, OUTPUT);
  pinMode(A5, INPUT_PULLUP);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  
  Timer1.initialize( 4000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
  Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
  dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)

  dmd.selectFont(SystemFont5x7);
  dmd.drawString(2,0,"TIME:",5,GRAPHICS_NORMAL);
  dmd.drawString(8,8,"SET",5,GRAPHICS_NORMAL);
  beep();
}

void loop() {

  if (clockRunning == 0) {
    if (digitalRead(A3) == 0) {
      mins10++; 
      delay(200); 
      if (mins10 > 9) mins10 = 0;
      minutes = mins10 * 10 + mins1;
      displayUpdate();
    }
    if (digitalRead(A4) == 0) {
      mins1++; 
      delay(200);
      if (mins1 > 9) mins1 = 0;
      minutes = mins10 * 10 + mins1;
      displayUpdate();
    }
  }
  if (digitalRead(A5) == 0) {
    beep();
    delay(200);
    if (clockRunning == 0) {
      timer.enable();
      clockRunning = 1;
    } else {
      clockRunning = 0;
      timer.disable();
      dmd.drawString(2,8," OFF ",5,GRAPHICS_NORMAL);
      delay(3000);
      displayUpdate();
    }
  }

  if (clockRunning == 1) timer.check();  
}

void ScanDMD() { 
  dmd.scanDisplayBySPI();
}

void clockUpdate() {
  seconds--;
  if (seconds < 0) { 
    seconds = 59;
    minutes--;
  }
  secs10 = seconds / 10;
  secs1 = seconds % 10;
  mins10 = minutes / 10;
  mins1 = minutes % 10;
  displayUpdate();

  if (minutes == 0 && seconds == 0) {
    dmd.clearScreen(true);
    dmd.drawString(5,0,"FULL",4,GRAPHICS_NORMAL);
    dmd.drawString(5,8,"TIME",4,GRAPHICS_NORMAL);
    timer.disable();
    digitalWrite(2, HIGH);
  }
}

void displayUpdate() {
  minsTens = (String)mins10;
  minsUnits = (String)mins1;
  secsTens = (String)secs10;
  secsUnits = (String)secs1;
  
  dmd.drawString(2,8,minsTens.c_str(),1,GRAPHICS_NORMAL);
  dmd.drawString(8,8,minsUnits.c_str(),1,GRAPHICS_NORMAL);
  dmd.drawString(14,8,":",1,GRAPHICS_NORMAL);
  dmd.drawString(19,8,secsTens.c_str(),1,GRAPHICS_NORMAL);
  dmd.drawString(25,8,secsUnits.c_str(),1,GRAPHICS_NORMAL);
}

void beep() {
  digitalWrite(2, HIGH);
  delay(30);
  digitalWrite(2, LOW);
}

but I'm getting many more errors.

But I'm not going to show them to you, or tell you where I got the TimedAction library...

Well, good luck.

PaulS:
But I’m not going to show them to you, or tell you where I got the TimedAction library…

Well, good luck.

Sorry Paul, I should know better about Forum etiquette.

I’m using the code provided in a project found here:

and you can download the files under Project 21 here:

I’m now able to compile the code from what oqibidipo above mentioned. I thank him for his help!

I just need to assign the pins for my buttons and work out some kinks like why the board seems to reset randomly every few seconds when I run the program. Is there anything in the program that points to a reset?

The working code is currently:

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include <TimedAction.h>
#include "SystemFont5x7.h"
#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

String minsTens, minsUnits, secsTens, secsUnits;
int mins10, mins1, secs10, secs1;
int minutes, seconds;
int clockRunning = 0;

void clockUpdate();

TimedAction timer = TimedAction(1000,clockUpdate);

void setup() {
  
  timer.disable();
  minutes = 0; seconds = 0;
  pinMode(2, OUTPUT);
  pinMode(A5, INPUT_PULLUP);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  
  Timer1.initialize( 4000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
  Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
  dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)

  dmd.selectFont(SystemFont5x7);
  dmd.drawString(2,0,"TIME:",5,GRAPHICS_NORMAL);
  dmd.drawString(8,8,"SET",5,GRAPHICS_NORMAL);
  beep();
}

void loop() {

  if (clockRunning == 0) {
    if (digitalRead(A3) == 0) {
      mins10++; 
      delay(200); 
      if (mins10 > 9) mins10 = 0;
      minutes = mins10 * 10 + mins1;
      displayUpdate();
    }
    if (digitalRead(A4) == 0) {
      mins1++; 
      delay(200);
      if (mins1 > 9) mins1 = 0;
      minutes = mins10 * 10 + mins1;
      displayUpdate();
    }
  }
  if (digitalRead(A5) == 0) {
    beep();
    delay(200);
    if (clockRunning == 0) {
      timer.enable();
      clockRunning = 1;
    } else {
      clockRunning = 0;
      timer.disable();
      dmd.drawString(2,8," OFF ",5,GRAPHICS_NORMAL);
      delay(3000);
      displayUpdate();
    }
  }

  if (clockRunning == 1) timer.check();  
}

void ScanDMD() { 
  dmd.scanDisplayBySPI();
}

void clockUpdate() {
  seconds--;
  if (seconds < 0) { 
    seconds = 59;
    minutes--;
  }
  secs10 = seconds / 10;
  secs1 = seconds % 10;
  mins10 = minutes / 10;
  mins1 = minutes % 10;
  displayUpdate();

  if (minutes == 0 && seconds == 0) {
    dmd.clearScreen(true);
    dmd.drawString(5,0,"FULL",4,GRAPHICS_NORMAL);
    dmd.drawString(5,8,"TIME",4,GRAPHICS_NORMAL);
    timer.disable();
    digitalWrite(2, HIGH);
  }
}

void displayUpdate() {
  minsTens = (String)mins10;
  minsUnits = (String)mins1;
  secsTens = (String)secs10;
  secsUnits = (String)secs1;
  
  dmd.drawString(2,8,minsTens.c_str(),1,GRAPHICS_NORMAL);
  dmd.drawString(8,8,minsUnits.c_str(),1,GRAPHICS_NORMAL);
  dmd.drawString(14,8,":",1,GRAPHICS_NORMAL);
  dmd.drawString(19,8,secsTens.c_str(),1,GRAPHICS_NORMAL);
  dmd.drawString(25,8,secsUnits.c_str(),1,GRAPHICS_NORMAL);
}

void beep() {
  digitalWrite(2, HIGH);
  delay(30);
  digitalWrite(2, LOW);
}

Thanks for all your help and the hard work!

Is there anything in the program that points to a reset?

Yes.

String minsTens, minsUnits, secsTens, secsUnits;

This is a waste of resources. Use char arrays.

  minutes = 0; seconds = 0;

ONE statement per line.

  minsTens = (String)mins10;
  minsUnits = (String)mins1;
  secsTens = (String)secs10;
  secsUnits = (String)secs1;

You can't cast an int to a String!

PaulS:
Yes.

String minsTens, minsUnits, secsTens, secsUnits;

This is a waste of resources. Use char arrays.

  minutes = 0; seconds = 0;

ONE statement per line.

  minsTens = (String)mins10;

minsUnits = (String)mins1;
  secsTens = (String)secs10;
  secsUnits = (String)secs1;



You can't cast an int to a String!

Ok great! Let me sort that out!

PaulS:
Yes.

String minsTens, minsUnits, secsTens, secsUnits;

This is a waste of resources. Use char arrays.

  minutes = 0; seconds = 0;

ONE statement per line.

  minsTens = (String)mins10;

minsUnits = (String)mins1;
  secsTens = (String)secs10;
  secsUnits = (String)secs1;



You can't cast an int to a String!

Sorry mate, I'm trying to sort out the char array and I'm finding the structure a little complex. I'm just not sure where to start. Is there any reading that you've come across that will get me started in the right direction.

Thanks again for the help.

I find it difficult to believe that that library doesn't have a drawADamnedInt() method.

Since it appears not to, create your own. Converting an int to a string is trivial, using itoa().

I've been having this same issue with the TimedAction library, throwing me declaration issues. I've found that however I write the code, wherever the declarations are, and whatever I call the interrupt routine, I simply cannot get my TimedAction sketches to work on any IDE later than 1.6.5.
Consequently I've rolled all my machines back to 1.6.5 and had no compile issues since, using exactly the same code.