-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Read from PWM #19
Comments
Thank you. I've taken a look into your FastAccelStepper, I may need to use it some day. Bojan |
Quite good documentation is here from page 45: (https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf) Eventually it is even easier:
|
The respective macro for setting FUN_IE seems to be: |
I'm still having difficulties getting it to work with Arduino. If I PIN_INPUT_ENABLE weather in setup () or in loop () the result is the same - ESP32 reboots with: Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. The code I used for testing: #include <WiFi.h>
#include <soc/gpio_sig_map.h>
void setup () {
Serial.begin (115200);
#define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE)
PIN_INPUT_ENABLE (2);
// start PWM on built-in LED
ledcSetup (0, 1000, 10);
ledcAttachPin (2, 0); // built-in LED
ledcWrite (0, 307); // 1/3 duty cycle
}
void loop () {
delay (1000);
Serial.printf ("%i\n", digitalRead (2)); // expected: 1/3 of 1 and 2/3 of 0 on built-in LED
} Do you have any ideas? |
Try this:
|
Two more comments:
|
Indeed. There are some combinations that just don't work well. For example 1000 Hz PWM and 10 ms sampling. On the other hand oscilloscope normally does not use "delay" but rather "delayMicroseconds" at higher frequencies which I believe is not RTOS but an Arduino function so it doesn't have to do much with interrupters and everything works just fine. I'll include your solution to the Oscilloscope. Thank you. |
"For example 1000 Hz PWM and 10 ms sampling." "It is strange though why 1200 Hz with 12 ms sampling works." |
Hi gin66. I'm sorry to bother you again with the same topic. PIN_INPUT_ENABLE (GPIO_PIN_MUX_REG[...]) worked very well with IDF 4.x. After the upgrade to IDF 5.x I've been struggling for days to get it working, with no success. Although the code compiles without any problems, digitalRead only returns 0 if GPIO is not configured in INPUT mode (if it is configured as OUTPUT or PWM for example). Can you help me with this, please? |
Sorry, but the IDF5 gives me headaches, too, so I only can give you link to migration guide. My lib is absolutely broken with IDF5 and porting mcpwm/pcnt/rmt drivers is close to a new development….for the EXACT same hardware. And your experience tells me, that there is chance, that this is not even possible anymore….on the EXACT same hardware. |
Thank you for your information. I hope we'll find something out. |
This is just a partial success: Using gpio_get_level (gpio_pin) instead of digitalRead (gpio_pin) helps reading pins configured as OUTPUT, but doesn't help with PWM signals at all. I tried writing a modified version of gpio_get_level function that basically returns (_gpio_hal.dev->out >> gpio_num) & 0x1, instead original one that returns (_gpio_hal.dev->in>> gpio_num) & 0x1, but this didn't help either. I guess I'll go with this for now, until a better solution is found. |
This seems to be a full solution. Basically, instead of using PIN_INPUT_ENABLE (GPIO_PIN_MUX_REG[... we can now use gpio_hal_input_enable (... Here is a whole test script: #include "driver/gpio.h"
#include "hal/gpio_hal.h"
void setup () {
Serial.begin (115200);
#define PWM_PIN 16
// generate PWM signal on PWM_PIN ...
ledcAttach (PWM_PIN, 1000, 10);
ledcWrite (PWM_PIN, 307); // 307 out of 1024 (10 bit resolution) = 1/3
// ... or just set the output value of PWM_PIN
// pinMode (PWM_PIN, OUTPUT);
// digitalWrite (PWM_PIN, HIGH);
// enable input on PWM_PIN
static gpio_hal_context_t _gpio_hal = {
.dev = GPIO_HAL_GET_HW (GPIO_PORT_0)
};
gpio_hal_input_enable (&_gpio_hal, PWM_PIN);
// test reading PWM_PIN
for (int i = 0; i < 100; i ++) {
delayMicroseconds (111);
Serial.println (gpio_get_level ((gpio_num_t) PWM_PIN));
}
}
void loop () {
} |
great News! Thanks for figuring out and sharing the solution. So I can make use of this in my lib, too. |
Nice project and thanks for sharing. In regard to this comment of yours:
I do not know how to digitalRead PWM signals directly from GPIOs that output them. Any useful idea would be greatly appreciated.
In my project FastAccelStepper, the mcpwm are used to output stepper signals. Those pulses are read back from the pin and fed into the pcnt modules. Perhaps similar approach works for your issue. The relevant code is:
The key is
gpio_iomux_in()
. Via github search could not see, that you use this function. Perhaps new to you and a direction towards a solution. even though, no turn-key solution.The text was updated successfully, but these errors were encountered: