Notifications
Clear all

using timebased interrupts with ESP32

15 Posts
2 Users
2 Likes
407 Views
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

Good evening all,

I'm trying to make my ESP32 sensing the speed my motors are running. I have watched the video from Bill where he explains using speed sensors with interrupts. His example is with a Arudino Uno and I'm working with an ESP32-Whroom. In his sketch he is using a library TimerOne.h for making accurate time stamps. Unfortunately the ESP32 doesn't accept this library. Therefore I got a bit stuck on how to get this working with interrupts. My code that I have at the moment looks as follows:

 

#include <CommandHandler.h>

#define PWM_A 14
#define PWM_A_Chan 0
#define AI_1 12
#define AI_2 13
#define PWM_B 25
#define PWM_B_Chan 1
#define BI_1 26
#define BI_2 27
#define PWM_Res 8
#define PWM_Freq 1000

int PWM_DutyCycle = 100;
float diskslots = 20.00;                                //Total slots on motor disk
const byte RightMotorSpeedSens = 18;                    //Right motor Interrupt pin for speed sensing 
unsigned int RightSpeedCount = 0;                       //Pulse counter for right motor

CommandHandler<> SerialCmds;

void IRAM_ATTR isr()
{
  RightSpeedCount++;
}

void setup() {
 
  Serial.begin(115200);
  Serial.println(F("Program starts....."));
  
  SerialCmds.AddCommand(F("MotorSpeed"), Cmd_DriveForwards);          //Command to communicate with Megunolink
  pinMode(AI_1, OUTPUT);                                              //A motor setup input channels
  pinMode(AI_2, OUTPUT);
  pinMode(BI_1, OUTPUT);                                              //B motor setup input channels
  pinMode(BI_2, OUTPUT);
  pinMode(RightMotorSpeedSens, INPUT_PULLUP);

  ledcAttachPin(PWM_A, PWM_A_Chan);                                   //Setup A motor PWM channel
  ledcAttachPin(PWM_B, PWM_B_Chan);                                   //Setup B motor PWM channel
  ledcSetup(PWM_A_Chan, PWM_Freq, PWM_Res);
  ledcSetup(PWM_B_Chan, PWM_Freq, PWM_Res);

  attachInterrupt(RightMotorSpeedSens, isr, RISING);
}

void loop() 
{
  SerialCmds.Process();                                             //Monitor serial commands
}


void Cmd_DriveForwards(CommandParameter& p)                         //Function for driving forward
{
  int DutyCycle = p.NextParameterAsInteger();  
  digitalWrite(AI_1, LOW);
  digitalWrite(AI_2, HIGH);
  digitalWrite(BI_1, LOW);
  digitalWrite(BI_2, HIGH);
  ledcWrite(PWM_A_Chan, DutyCycle);
  ledcWrite(PWM_B_Chan, DutyCycle);
  Serial.println(DutyCycle);
}

I think I'm pretty far to make this working but I only need a function which uses timestamps or a certain amount of time passed. So then I could use the amount of pulses during that passed time to calculate the RPM or even the speed in m/s.

Could anybody help me a bit?

 

Thanks in advance

Grtz,
Ray


   
Quote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

 @electricray1981 RightSpeedCount has to be volatile

Check the doc'n, re interrupt pin https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

@zander 

Thanks s there is no difference between Arudino or ESP32 in this case?

I found allready an error in my previous code so I fixed that. But now I need to measure time on some kind of way, because the TimerOne.h lib is not available for the ESP32 and Bill wa using that in his code.

Grtz,
Ray


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 What was the library doing for you

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

he usses it as a timer. So in his program it counts all the pulses during a time of one second. I have 20 pulses in one rotation so I could compute the RPM value.

In fact a better way wouldl be to compute the time durration of one slot I did that before with my Mega but I can't apply that trick now the same way.

I would like to record the current time at a rising edge than record the current time at the following rising edge so I know the duration between two rising edges and by that I can compute the rpm and speed a well.
But I think that's not possible with an interrupt because it are void functions.

Grtz,
Ray


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 I have experimented with timers and interrupts and did not have the best results. the esp32 has the primitives, but you will need to find an equivalent library as the TimerOne library is only for arduino. This will keep you busy for a while!

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 Have a look at THIS , same functionality I think.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

@zander 

Yes TimeOne.h is only for Arduino so indeed I would need something with the same capabilities, I'll check you link and see if I can add that lib and make use of it. 
If it works fine I could even measure the time between two pulses this would give me very fast and accurate speed readings, thanks!

Grtz,
Ray


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 That isn't a library, it's the esp32 docs for timers. You will see a lot of similarity in the function names.

BTW, I am not a fan of constantly attaching and detaching interrupts, there are functions to stop, pause, start etc.

Also, I will look for the other level of timers for esp boards, I think it's at the OS level. Give me a few.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 Here are a few more references. It can be confusing and daunting, I never felt I got it right.

First

Best?

High Res

General Purpose

 

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

@zander 

Cool thanks for all the information. Yes when I read the article I noticed it whas information about the timer of the esp32 itself. 

With the MEGA I did what I wanted by reading the status of the digtal pin. and stored the current time I did that everytime a pulse was detected placed it in an array and computed the time difference. This was verry accurate and fast. 
If I do it the way I saw in Bill's video you have only an update of the speed every 1 second. I prefer to have this faster (in one second the rover could have moved a meter easily). So I'm not sure if using the interrupt is the way I should go.
Maybe its better by redaing the digital input on rising edges with timestamps , but on the other hand (I thought ....I'm not a specialist) this is all blocking code. If it takes a "long time" to compute the speed and therefore the object detection is not working it could result in dissasters 🙂

Grtz,
Ray


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 The maximum timer speed is 80,000,000, this is usually normalized using what is called a scalar of 80 so now the clock is 1,000,000 available interrupts per second, but when initing the code we often use a value of 1,000,000 which means 1 interrupt per second. This is where you can make the interrupts happen more quickly, but keep in mind the processor is only so fast, and you are writing in a high level language so be careful or switch to assembler.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@electricray1981 You sound like a fellow not afraid of a challenge, so why not look into using one core for certain tasks, and the other core for other tasks. This way you may be able to get a finer resolution with to dropping data. However, be aware that the OS assigns certain functions to specific cores as well, so you might want to take all that into account. Very bleeding edge and of course assembler is really the best choice but if you aren't already trained in that then either forget it or be ready for at least many months of 12 hours a day learning unless you have another low level language that might help you get up to speed faster.

Good luck.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

@zander 

Heheh yes I like a challange but I know my limitations as well. Assembler is not the way to go for now. Maybe thinking of seperating tasks between the two CPU's is not a bad idea but I still have a lot to learn in C++. So I have to accpet that maybe I wont get immediatly what I want and to keep it fun one should make progress once in a while and decide how to go on and accept the concequences. 
So I think I go thru your last links there I found some information that might help me to get what I want. From there I can continue with my project. If the end result is not that perfect I will start with Project Rover V2.0 🤣 

Grtz,
Ray


   
Ron reacted
ReplyQuote
ElectricRay1981
(@electricray1981)
Member
Joined: 1 year ago
Posts: 119
Topic starter  

@zander 

This might also be a good option, appearantly there's a built in pulse counter in the ESP32.

PCNT

Grtz,
Ray


   
ReplyQuote