-
Notifications
You must be signed in to change notification settings - Fork 6
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
Some questions about carrier frequency and duty cycle #4
Comments
Yes, when I first started IR remote project, I looked for existing libraries and haven't found any decent one. IRRemoteESP8266 is direct port from Arduino and while having good library of different IR protocols, still assumes Arduino's single thread execution and thus relies on Arduino's usleep() precision. I wanted something that could reliably work on RTOS, so I created this one. To answer your first question, yes it should be much more accurate as relies on hardware counters and interrupts (so it can run in background). My tests showed pretty decent precision with both clock generation and timing larger pulses. Thanks for bringing up different frequencies. I haven't encountered different frequency protocols so this library at the moment works only with 38KHz. Yes, it relies on the same hardware pulses which occur every ~26us, so your resulting frequency might be different, although from what I have learned receivers usually have some tolerance towards frequency range and it should work fine. The frequency indeed is configured by two dividers in I2S registers (lines that you have mentioned), 62 and 2 are dividers that give frequency closest to 38KHz. Here is an example from i2s_dma library to calculate dividers based on frequency (https://github.com/SuperHouse/esp-open-rtos/blob/a8c60e096093e9e9f4a60b885676adc2cf5b790a/extras/i2s_dma/i2s_dma.c#L133-L153): #define BASE_FREQ (160000000L)
i2s_clock_div_t i2s_get_clock_div(int32_t freq)
{
i2s_clock_div_t div = {0, 0};
int32_t best_freq = 0;
for (uint32_t bclk_div = 1; bclk_div < 64; bclk_div++) {
for (uint32_t clkm_div = 1; clkm_div < 64; clkm_div++) {
int32_t curr_freq = BASE_FREQ / (bclk_div * clkm_div);
if (abs(freq - curr_freq) < abs(freq - best_freq)) {
best_freq = curr_freq;
div.clkm_div = clkm_div;
div.bclk_div = bclk_div;
}
}
}
return div;
} Can't find much info about I2S duty cycle, but Espressif ESP8266 Technical Reference mentions that their IR remote interface uses 1/3 (~30%) duty cycle. |
This library rocks! Thanks! I finally get my ESP8266 and this library is working 100% perfect. Q: I'm still confused by the i2s_dma library. I run the code with freq=38000 and FWIW, in ESP8266 Technical Reference section 13.1.1, it mentions that GPIO14 can generate standard square ware with duty ratio of 50% exactly. It also says that
|
You got me puzzled for a few days because I couldn't remember what is the rationale there. So, indeed, the frequency formula for I2S data transmission is like that 160M / clkm / bclk. But the thing is that this gives you data transmission. But this library uses WS (word switch) pin of I2S. Word switch assumes that I2S transmission is two 16bit channels and WS alternates every 16 periods of main I2S frequency (to signal left and right 16 bit word). That gives you frequency that is 32 times slower. Thus the math for frequency in this library case is 160M / 32 / clkm / bclk. In my case it is 160M / 32 / 62 / 2 = 40322Hz with 50% duty cycle. I do not remember why I picked this numbers (as there are better combinations like 10 & 13 or 3 & 44), I think I snitched it somewhere and it worked for me and I do not have enough equipment to experiment on. Also, logic analyzer shows timings pretty close to 38KHz. Let me know if you'll find other variations working better for you. |
I used to work with high level raspberry pi with LIRC. I find it sometimes unstable. Even if there's hardware 38KHz pwm support, however, the IR space delay using
usleep()
is too inaccurate under linux to guarantee a successful IR signal. (my AC fails to get my generated IR signal about 3~5% even if it's very close to the AC and with a transistor/5V support)Q1: I'm very new to esp-8266 and RTOS. I think it's possible to make this much more accurate to use NodeMCU (ESP-8266) compared to raspberry pi, right? I just ordered NodeMCU v3 so I can't test right now. I'm just trying to build esp-homekit-demo and investigate the code.
Q2: How can I adjust carrier frequency and duty cycle when sending IR signal? For example, I want to emit 36khz / 30% duty cycle or 40khz (for Sony), is it possible?
I investigate other libraries, it seems most of them generate pulse manually by using
1 / 38KHz
delay and gpio_wrtie high or low on any GPIO output. I think this is very inaccurate because the result are rounded to 26 us (from 26.315789474us). The actual generated carrier frequency is 38461Hz. It seems that your library use very different mechanism to generate the pulse. I can't figure out how to changecarrier frequency
andduty cycle
.I think this is the key part but I can't figure out why it's 62 and 2 here.
The text was updated successfully, but these errors were encountered: