I just cant win with these timers.

annoying prick
Posts: 2
Joined: Sat Jun 22, 2024 11:02 am

I just cant win with these timers.

Postby annoying prick » Sat Jun 22, 2024 11:12 am

G'day guys.
Basically, I have no business trying to write code, but yet, i give it a crack anyway.

Having trouble with timers however i try to do it though.
Keep in mind though, that i have no external hardware attached at this point, so if that's the reason for the errors I'm asking about, please allow me to apologize in advance.

Anyhow, on with the show. (also please forgive my impending code pasting errors. First time here)

My current code;

Code: Select all

#define TIMER_BASE_CLK 80000000  // Add this line at the top of your code

#include <dummy.h>
#include <ESP32TimerInterrupt.h>  // Include the ESP32TimerInterrupt library
#include "BluetoothSerial.h"

// Define sensor and ignition pins
#define SENSOR_PIN1 18
#define SENSOR_PIN2 19
#define SENSOR_PIN3 22
#define SENSOR_PIN4 23
#define IGNITION_PIN1 25
#define IGNITION_PIN2 26

// Define timing constants
#define TIMING_AT_LOW_RPM 8.0
#define TIMING_AT_HIGH_RPM 25.0
#define LOW_RPM 1000.0
#define HIGH_RPM 5000.0
#define COIL_CHARGE_TIME 3000  // Coil charge time in microseconds

// Declare volatile variables for interrupt tracking
volatile unsigned long lastInterruptTime1 = 0;
volatile unsigned long lastInterruptTime2 = 0;
volatile unsigned long lastInterruptTime3 = 0;
volatile unsigned long lastInterruptTime4 = 0;
volatile float rpm2 = 0;
volatile float rpm4 = 0;

// Declare other necessary variables
unsigned long ignitionStartTime = 0;
bool ignitionStarted = false;
volatile bool interruptOccurred = false;  // Flag for interrupt occurrence

BluetoothSerial SerialBT;

// Declare timer objects
ESP32Timer ITimer0(0);
ESP32Timer ITimer1(1);

// Function prototypes
float getTiming(float rpm);
void controlIgnition1(float rpm);
void controlIgnition2(float rpm);
void handleBluetoothMessage(String message);
bool IRAM_ATTR onTimer0(void*);  // Modify the function signature
bool IRAM_ATTR onTimer1(void*);  // Modify the function signature

void setup() {
  Serial.begin(9600);  // Initialize serial communication
  // Initialize sensor and ignition pins
  pinMode(SENSOR_PIN1, INPUT);
  pinMode(SENSOR_PIN2, INPUT);
  pinMode(SENSOR_PIN3, INPUT);
  pinMode(SENSOR_PIN4, INPUT);
  pinMode(IGNITION_PIN1, OUTPUT);
  pinMode(IGNITION_PIN2, OUTPUT);

  // Attach interrupts to sensor pins
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN1), calculateRPM1, FALLING);
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN2), calculateRPM2, FALLING);
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN3), calculateRPM3, FALLING);
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN4), calculateRPM4, FALLING);

  // Initialize timers
  ITimer0.attachInterruptInterval(10000, onTimer0);  // Timer 0, interval 10000us
  ITimer1.attachInterruptInterval(10000, onTimer1);  // Timer 1, interval 10000us

  SerialBT.begin("ESP32test");  // Initialize Bluetooth Serial
}

void loop() {
  while (!interruptOccurred) {
    // Waiting for interruptOccurred to become true
    if (SerialBT.available()) {
      String message = SerialBT.readString();
      handleBluetoothMessage(message);
    }
  }

  // Once interruptOccurred is true, the following code will execute
  float avgRpm = (rpm2 + rpm4) / 2.0;  // Average RPM from sensors 2 and 4
  float timing = getTiming(avgRpm);
  controlIgnition1(timing);
  controlIgnition2(timing);

  SerialBT.println("RPM: " + String(avgRpm) + ", Timing: " + String(timing));

  // Reset interruptOccurred to false for the next cycle
  interruptOccurred = false;
}

void calculateRPM1() {
  lastInterruptTime1 = micros();
  interruptOccurred = true;  // Add this line
}

void calculateRPM2() {
  unsigned long currentTime = micros();
  unsigned long timeDifference2 = currentTime - lastInterruptTime2;

  if (timeDifference2 < 1000 || timeDifference2 == 0) { // Debounce, ignore if interrupt fires within 1ms or if timeDifference is zero
    return;
  }

  SerialBT.println("timeDifference2: " + String(timeDifference2));  // Add this line
  rpm2 = 60000000.0 / timeDifference2;  // 1 edges per revolution
  lastInterruptTime2 = currentTime;
}

void calculateRPM3() {
  lastInterruptTime3 = micros();
  interruptOccurred = true;  // Add this line
}

void calculateRPM4() {
  unsigned long currentTime = micros();
  unsigned long timeDifference4 = currentTime - lastInterruptTime4;

  if (timeDifference4 < 1000 || timeDifference4 == 0) { // Debounce, ignore if interrupt fires within 1ms or if timeDifference is zero
    return;
  }

  SerialBT.println("timeDifference4: " + String(timeDifference4));  // Add this line
  rpm4 = 30000000.0 / timeDifference4;  // 2 edges per revolution
  lastInterruptTime4 = currentTime;
}

float getTiming(float rpm) {
  float slope;
  if (HIGH_RPM == LOW_RPM) {
    // Handle error: HIGH_RPM and LOW_RPM should not be equal
    Serial.println("Error: HIGH_RPM and LOW_RPM should not be equal");
    slope = 1.0;  // Set a default slope value
  } else {
    slope = (TIMING_AT_HIGH_RPM - TIMING_AT_LOW_RPM) / (HIGH_RPM - LOW_RPM);
  }
  
  float intercept = TIMING_AT_LOW_RPM - slope * LOW_RPM;
  return slope * rpm + intercept;
}

void controlIgnition1(float timing) {
  float delay = timing - COIL_CHARGE_TIME;  // calculate delay for coil 1
  if (delay > 0) {
    ITimer0.attachInterruptInterval(delay, onTimer0);
  }
}

void controlIgnition2(float timing) {
  float delay = timing - COIL_CHARGE_TIME;  // calculate delay for coil 2
  if (delay > 0) {
    ITimer1.attachInterruptInterval(delay, onTimer1);
  }
}

bool IRAM_ATTR onTimer0(void*) {  // Modify the function signature
  digitalWrite(IGNITION_PIN1, HIGH);
  delayMicroseconds(COIL_CHARGE_TIME);
  digitalWrite(IGNITION_PIN1, LOW);
  return true;
}

bool IRAM_ATTR onTimer1(void*) {  // Modify the function signature
  digitalWrite(IGNITION_PIN2, HIGH);
  delayMicroseconds(COIL_CHARGE_TIME);
  digitalWrite(IGNITION_PIN2, LOW);
  return true;
}

void handleBluetoothMessage(String message) {
  if (message.startsWith("RPM:")) {
    rpm2 = rpm4 = message.substring(4).toFloat();
  }
  // Add more conditions here to handle other settings
}
And the output from the serial monitor;

Code: Select all

Y�4]q�5�p�2�y���%`�E (15) timer_group: timer_init(301): only support Level Interrupt
E (15) timer_group: timer_set_counter_value(92): HW TIMER NEVER INIT ERROR
E (31) timer_group: timer_set_alarm_value(165): HW TIMER NEVER INIT ERROR
E (109) timer_group: timer_enable_intr(230): HW TIMER NEVER INIT ERROR
E (184) timer_group: timer_isr_callback_add(266): HW TIMER NEVER INIT ERROR
E (264) timer_group: timer_start(103): HW TIMER NEVER INIT ERROR
E (333) timer_group: timer_init(301): only support Level Interrupt
E (403) timer_group: timer_set_counter_value(92): HW TIMER NEVER INIT ERROR
E (484) timer_group: timer_set_alarm_value(165): HW TIMER NEVER INIT ERROR
E (563) timer_group: timer_enable_intr(230): HW TIMER NEVER INIT ERROR
E (638) timer_group: timer_isr_callback_add(266): HW TIMER NEVER INIT ERROR
E (718) timer_group: timer_start(103): HW TIMER NEVER INIT ERROR
Now, could anybody spare the time to tell me what i'm doing wrong?
Thanks in advance.

lbernstone
Posts: 829
Joined: Mon Jul 22, 2019 3:20 pm

Re: I just cant win with these timers.

Postby lbernstone » Sun Jun 23, 2024 5:00 am

The timer API has changed significantly between v2.X and v3.0. Make sure you are compiling on v2.0 (.17 is the latest patch ATM).
If you really want/need to use 3.0, your use case is simple enough that the Timer example should be adequate for your two timers.

annoying prick
Posts: 2
Joined: Sat Jun 22, 2024 11:02 am

Re: I just cant win with these timers.

Postby annoying prick » Sun Jun 30, 2024 3:11 am

G'day, and thank you.

sorry to be a pain but, could you dumb that down 1 more level for me?
version 2.0 of what? or should i mention that i am using arduino IDE 2.3.2?

Sorry, quite new to all this.

lbernstone
Posts: 829
Joined: Mon Jul 22, 2019 3:20 pm

Re: I just cant win with these timers.

Postby lbernstone » Mon Jul 01, 2024 4:44 pm

You can see what version of arduino-esp32 you are using in the IDE Boards Manager.
https://docs.espressif.com/projects/ard ... rduino-ide
Perhaps you don't actually need timer groups here? If you just want a simple timer that fires on a period (or one-time), take a look at the Ticker library

Who is online

Users browsing this forum: brebisson and 82 guests