I'm trying to send a ~10µs pulse every MY_DELAY microseconds.
The obvious way to do this would be
void loop(){
digitalWrite(PIN_NO, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_NO, LOW);
delayMicroseconds(MY_DELAY);
}
However, such an approach is blocking and I can't do much else. Is there anyway I can spawn something to do this asynchronously? Ideally, this would look like:
start_pulse_loop(MY_DELAY) // Start loop sending pulse every MY_DELAY µs
run_something_else() // Blocks for, say, 5 seconds
start_pulse_loop(800) // Updates loop to pulse every 800µs
// etc...
I'd imagine this is possible with timers, but I'm unfamiliar with them. I'm using an ESP32, if that changes things. Thanks for the help!
LarryD
January 30, 2024, 9:32pm
2
1 Like
horace
January 30, 2024, 9:42pm
3
have a look at ESP32TimerInterrupt
you could
set output high - start 10uSec timer
10uSec later on timer interrupt set output low
if you have an oscilloscope put the test in a loop to check it is correct
1 Like
This is th most important information at all.
This is the same timing pattern as for creating RC-servo-pulses.
Which are 1000 to 2000 µsec long pulses once every 20 millisconds.
Your pulss are shorter and occur faster.
I haven't looked into the ESP32-servo library. It might be that simply reducing the timing-constants and adding a set-pulse-pause-time function is sufficient.
THough a RC-Servo-Signal has 50 Hz and you are asking for a signal in the 100 kHz range
best regards Stefan
Add a function to void loop() to do this.
Use delayMicroseconds(10) between the pin changes because 10 micros is so short it's a bump not a block.
But if (MY_DELAY) can be > 10, use a no-block timer for that.
Just FYI, micros() adds 4 every 4 usecs, not add 1 every 1 usec so 10 means 12. You want closest, you stack NOP's, 16 per usec.
Also, use direct port manipulation (write to a PINx register) to flip the pin quicker than Arduino digitalWrite().
1 Like
JCA34F
January 31, 2024, 4:09am
7
A hint, compiles, not tested.
const byte pulsePin = 2;
void setup()
{
pinMode(pulsePin,OUTPUT);
}
void loop()
{
static uint32_t
timer = micros(),
myDelay = 1000000, // 1 sec
pulseLen = 12;
if(micros() - timer >= myDelay)
{
timer += myDelay;
}
digitalWrite(pulsePin,micros() - timer < pulseLen);
}
1 Like
horace
January 31, 2024, 9:44am
8
example code using ESP32 timers every 100uSec generate a 10uSec pulse
// example code using ESP32 every 100uSec generate a 10uSec pulse
// from https://github.com/khoih-prog/ESP32TimerInterrupt
#define _TIMERINTERRUPT_LOGLEVEL_ 0
#include "ESP32TimerInterrupt.h"
#define PIN_D19 19 // Pin D19 mapped to pin GPIO19 of ESP32 10uSec pulse
#define PIN_D18 18 // Pin D18 mapped to pin GPIO18 of ESP32 100uSec period square wave
// timer0 generates a 10usec pulse on GPIO19
#define TIMER0_INTERVAL_US 8 // alow 2uSec for execution of instructions
ESP32Timer ITimer0(0);
bool IRAM_ATTR TimerHandler0(void* timerNo) {
digitalWrite(PIN_D19, LOW); // level LOW
ITimer0.stopTimer(); // end of 10uSec pulse
return true;
}
// Timer1 generates 200uSec period square wave
#define TIMER1_INTERVAL_US 100
ESP32Timer ITimer1(1);
bool IRAM_ATTR TimerHandler1(void* timerNo) {
digitalWrite(PIN_D18, !digitalRead(PIN_D18)); // 100uSec period square wave
ITimer0.restartTimer(); // start 10uSec pulse
digitalWrite(PIN_D19, HIGH); // HIGH
return true;
}
void setup() {
pinMode(PIN_D19, OUTPUT);
pinMode(PIN_D18, OUTPUT);
digitalWrite(PIN_D19, LOW);
Serial.begin(115200);
while (!Serial && millis() < 5000)
;
delay(500);
Serial.print(F("\nESP32 every 100uSec generate a 10uSec pulse - board "));
Serial.println(ARDUINO_BOARD);
// Interval in microsecs
if (!ITimer0.attachInterruptInterval(TIMER0_INTERVAL_US, TimerHandler0))
Serial.println(F("Can't set ITimer0. Select another freq. or timer"));
else
Serial.println(F("Timer0 started OK generate a 10uSec pulse "));
ITimer0.stopTimer();
// Interval in microsecs
if (!ITimer1.attachInterruptInterval(TIMER1_INTERVAL_US, TimerHandler1))
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
else
Serial.println(F("Timer1 started OK generate a 100uSec period square wave "));
Serial.flush();
}
void loop() {
}
generates a square wave 200uSec period
with a 10uSec pulse
system
Closed
July 29, 2024, 9:45am
9
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.