ESP32 timerISR in separate header but can't delare variable

Hi,

I wanted to treat the timer ISR from my ESP32 as a separate module. So I wanted to put the ISR declaration in a header file. Now I want to increase the variable count every time the timer gives an interrupt. But when building the project the compiler gives the error count not declared in this scope. I already tried declaring it with "extern" but the error remains.
Can someone help me get on the right track?

Here is the code:

timersettings.h

/*-----------------------------------------------------------------------------------------------
timersettings.h
-----------------------------------------------------------------------------------------------*/

#ifndef timersettings_h
#define timersettings_h
#endif

#include <Arduino.h>

#define HALF_SEC    (count*50)
extern int count;

// --------------- Setup Timer1:
hw_timer_t *timer1 = NULL;
hw_timer_t *timer2 = NULL;

void IRAM_ATTR onTimer1ISR();

void IRAM_ATTR onTimer2ISR();

timersettings.c

#include <timersettings.h>

unsigned int timer1Flag, timer2Flag;

void IRAM_ATTR onTimer1ISR()
{
  // What to do when the timer ticks out.
  timer1Flag = 1;
  count++;
}

void IRAM_ATTR onTimer2ISR()
{
  // What to do when the timer ticks out.
  timer2Flag = 1;
}

and the main.c

#include <Arduino.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <Wire.h>
#include <SPI.h>
#include "Adafruit_PWMServoDriver.h"
#include <joysticks.h>
#include <timersettings.h>

unsigned long buttonTime = 0, prevButtonTime = 0, startTime = 0;
unsigned int prevState, curState = 0;
unsigned int buttonFlag = 0;
unsigned int freq = 0;
unsigned int buttonState;
extern int count = 0;



// --------------- Setup Button Interrupt
void IRAM_ATTR isrButton() 
{
  buttonTime = millis();
  if (buttonTime - prevButtonTime > 50)
  {
    prevButtonTime = buttonTime;
    curState = 1;
  }
  
}

void setup() 
{
  //startTime = millis();
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Serial Port Initialised");

  freq = getCpuFrequencyMhz();
  Serial.printf("CPU FREQ: %dMHz \n",freq);
  freq = getApbFrequency();
  Serial.printf("APB FREQ: %dMHz \n",(freq/1000000));
  

  // hardware interrupt init
  pinMode(JOY_LEFT_BUT, INPUT_PULLDOWN);
  attachInterrupt(JOY_LEFT_BUT, isrButton, ONHIGH);
  

  // timer1 init
  timer1 = timerBegin(0, 80, true);    // timer0 (from 0 to 3), 80 prescaler(80MHZ/PRESCALER), counting up (true, down=false)
  timerAttachInterrupt(timer1, &onTimer1ISR, false);   // attach ISR to timer  (true edge triggered, false level triggered)
  timerAlarmWrite(timer1, 10000, true);    // Set countvalue to 10 milliseconds autoreload(true)
  timerAlarmEnable(timer1);   // Enable timer
  
}

void loop() 
{
  // put your main code here, to run repeatedly:


  joystick joystickL;
  joystickL.curButState = false;
  joystickL.prevButState = false;

  // button state logic
  if( (curState == 1) && (prevState == 0) )     // button is pressed
  {

    if( (curState == 1) && (count >= 50 ) )    // button is held for at least 0.5 seconds
    {
      buttonState = HELD;
    }
    
  }
  else if( (curState ==1) && (count < 0) )    // button is pushed but not held
    {
      buttonState = PRESSED;
    }
  else if( (curState == 0) && (prevState == 1) )// button is released
  {
    buttonState = RELEASED;
  }
  else
  {
    buttonState = INITIAL;
  }
  // end button state logic

  switch (buttonState)
  {
  case PRESSED:
    Serial.printf("Button: %s\n",buttonState);
    prevState = curState;
    break;

  case RELEASED:
    Serial.printf("Button: %s\n",buttonState);
    prevState = curState;
    break;

  case HELD:
    Serial.printf("Button: %s\n",buttonState);

    break;
  
  default:
    curState = 0;
    prevState = 0;
    break;
  }

}

I'm still debugging the rest of the program so don't mind the buttons etc. I just need to know how to solve this:

Processing esp32doit-devkit-v1 (platform: espressif32; board: esp32doit-devkit-v1; framework: arduino)
----------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32doit-devkit-v1.html
PLATFORM: Espressif 32 (6.6.0) > DOIT ESP32 DEVKIT V1
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 @ 3.20014.231204 (2.0.14)
 - tool-esptoolpy @ 1.40501.0 (4.5.1)
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 36 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Adafruit PWM Servo Driver Library @ 3.0.2
|-- SPI @ 2.0.0
|-- Wire @ 2.0.0
Building in release mode
Compiling .pio\build\esp32doit-devkit-v1\src\main.cpp.o
Compiling .pio\build\esp32doit-devkit-v1\src\timersettings.c.o
src/main.cpp:20:12: warning: 'count' initialized and declared 'extern'
 extern int count = 0;
            ^~~~~
Linking .pio\build\esp32doit-devkit-v1\firmware.elf
c:/users/td/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\esp32doit-devkit-v1\src\timersettings.c.o:C:\Users\TD\Documents\PlatformIO\Projects\Remote/include/timersettings.h:16: multiple definition of `timer2'; .pio\build\esp32doit-devkit-v1\src\main.cpp.o:C:\Users\TD\Documents\PlatformIO\Projects\Remote/include/timersettings.h:16: first defined here
c:/users/td/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\esp32doit-devkit-v1\src\timersettings.c.o:C:\Users\TD\Documents\PlatformIO\Projects\Remote/include/timersettings.h:15: multiple definition of `timer1'; .pio\build\esp32doit-devkit-v1\src\main.cpp.o:C:\Users\TD\Documents\PlatformIO\Projects\Remote/include/timersettings.h:15: first defined here
c:/users/td/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\esp32doit-devkit-v1\src\main.cpp.o:(.literal._Z5setupv+0x2c): undefined reference to `onTimer1ISR()'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\esp32doit-devkit-v1\firmware.elf] Error 1
========================================= [FAILED] Took 20.44 seconds =========================================

you appear to have declared

extern int count;

in timersettings.h and main.c but where do you define count? e.g.

int count=0;

should be in timersettings.c ???

extern declarations only declare a variable exists somewhere - but you have define it (create it) somewhere

also you cannot initialize in an declaration

extern int count = 0;

only in a definition

I had tried a few different notations of it. It seems that this way made most of the error go away.

But it still won't let me build the project. Can i split up the declaration and definition of the ISR this way? Because when I put all of it in the main.c file it does let me build it.

Post your latest, complete code with the "different notations" that you tried. Post the complete error messages.

note if the header files are in the directory with the .ino file use "" not <> which is for system header files)
if I compile and run multi_file_1.ino

#include <Arduino.h>
#include "timersettings.h"

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println(count);
  onTimer1ISR();
  Serial.println(count);
  }

void loop() {}

timersettings.cpp

#include "timersettings.h"

unsigned int timer1Flag, timer2Flag;

int count=0;   // define count

void IRAM_ATTR onTimer1ISR()
{
  // What to do when the timer ticks out.
  timer1Flag = 1;
  count++;
}

timersettings.h

#ifndef timersettings_h
#define timersettings_h

#include <Arduino.h>

#define HALF_SEC    (count*50)
extern int count;    // declare count

void IRAM_ATTR onTimer1ISR();

void IRAM_ATTR onTimer2ISR();

#endif

a run displays

0
1

the directory contains

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.