I forgot to post last week. If you read this regularly, I am sorry.
Espressif has released a Version 2.0 of it’s SDK. I am not quite ready to upgrade to that yet, I will wait until after I get my basic functionality tested. Also, this is a major release, they might have added a few bugs, I can wait till some are fixed.
Voltage Control loop:
I decided to work on the voltage control loop. First step, get a better understanding of the ADC. I needed to know if the system calls to read the ADC are blocking or nonblocking. An ADC takes time to finish. If it returns the sample from the previous call, I will have to take a second reading to get the correct value. If it is blocking, I don’t want to call it from within the interrupt service routine (ISR).
Note: When you call a blocking function, it finishes it’s job before coming back. Non blocking starts the job and then comes back.
The SDK API is not specific as whether the system_adc_read() is blocking or not. So I set up a test. Pin 10 of the programming connector connects back to GPIO14. If I set GPIO14 high before calling system_adc_read() and set it low before calling it again, I can tell how long the call takes. I created a system timer event in events.c and used it to read the adc. The system timer just calls an os task so it isn’t like an ISR. I created a function called adc_read. I initialized a variable, set GPIO14 high, call system_adc_read() and set GPIO14 low. I then set up the function to enable the timer task, I called it init_adc_timer(). I called this from user_init(). The code built. I uploaded it. I hooked up my scope to Pin 10 of the target header.
I got nothing, I didn’t hook up Vtarget. I decided it was easier to probe GPIO14 directly on the ESP-12F. The pin was always high. I checked the pin configuration in user_main.c. Nothing wrong there. I found a copy/paste error in events.c I had copied the line to change GPIO13 to low and changed it to GPIO14 to set it high but didn’t change the one to set it low. I fixed this and tried again. I got the pulses I was looking for on the Oscilloscope. The high pulse width measured 96.2 μS. This is much longer than I would put into an ISR. If i polled this read regularly, It would cause a significant loss in performance.
The Next Step:
I decided to see if I could access the ADC directly through hardware registers. I couldn’t find any clear documentation on the ADC registers. In the API, there is also a function call system_adc_read_fast(). This one requires wifi to be turned off when called. I decided to try it turning Wifi off and back on after around each read. I modified the code to try this change. Now the pulse width is 21.8 μS. Unfortunately, the wifi disconnects when I disable it. This is a problem. I tried leaving the wifi enabled and it works. 21.8 μS is longer than I would want in an ISR so I will call it from the os_timer function and use it to make adjustments. If I call this every 5 mS, it will tie up the processor for about 1/2 of 1% of the time. This doesn’t seem like a lot, but I want to get as much performance as I can when I am programming a target. And this control loop will have to be running while programming a target.
The results of my testing are not as good as I had hoped. Maybe Espressif will come out with a non-blocking way to use the ADC in the future. Ideally, I would call a function to start the conversion, and the system would call back to my function with the result. As a final step I display the menu with the adc reading once every 200 cycles (1 second). I have uploaded these changes to github click the link in the right column to go check it out.
Do you have any experience with the ESP8266 adc? Have you found a work around for the blocking call?