Welcome to theFrankes.com. This blog contains years of posts covering a wide range of topics and interests, including information and resources for our RepRaps for Education project, woodworking projects, German naval history collections, and more.

For visitors interested in getting open-hardware 3D printing technology into public schools, please visit the RepRaps for Education landing page:

RepRaps4Edu

Other popular content:

tl;dr

The ESP-12F ADC pin appears to consistently read higher values at times when the processor is not as busy. I worked around this by taking the average of multiple reads, and discarding any averages where the number of samples varied dramatically from expectations.

My Application

I’m using an ESP-12F and a TEMT6000 module to measure brightness in an area that also has PWM-modulated LED lighting. I have an AMS1117 providing pretty consistent 3.3V to the circuit and it draws about 41mA. The ESP doesn’t have hardware PWM, so I’m suing the software version with analogWrite(), and I have the PWM frequency set down to about 200Hz because that seems to resolve some flickering issues.

I’m using MQTT (PubSubClient) and the AutoConnect library in my project. I take a brightness measurement every 5 seconds, and, if the resulting value has changed since the previous measurement, I publish the result to a related MQTT topic.

I’m using a 10k/4.7k voltage divider to step down the output of the TEMT6000 module to 1.055V. This circuit switches a separate 12V source that drives the LEDs, and that switching is optically isolated.

ADC analogRead() averaging with PWM LEDs

Because the LEDs turn on and off repeatedly to give the effect of dimming, I sample the ADC pin repeatedly for two PWM wavelengths (100Hz) and average the results. This seems to work out pretty well and is reasonably consistent. I get typically about 45 samples during that time in production. I’ll refer to this average in this post as “the value” or “the brightness” — it’s not an instantaneous value, but an average of several samples. This value is scaled to 0-1000 to approximate the number of mV read. I yield() inside of the sample loop as well.

Stability Techniques Already Employed

I have a 0.1uF tantallum across the ADC pin and GND, and when I sample the ADC pin, I do it twice in a row, ignoring the first sample, because I read somewhere that the first sample can be a bit inconsistent sometimes.

The Problem

From time to time I observed pretty erratic ADC fluctuations, notably right after start-up, and then periodically throughout the day. I haven’t taken the time to figure out if there’s a larger pattern here, but while I was debugging this I started writing out the number of samples actually taken when calculating the brightness value. That’s when I discovered a positive correlation between samples taken and brightness value.

Brightness value on the left, and sample count on the right

The PWM duty cycle is consistent, as is the length of time I take samples for each reading. In this graph, I was doing some extra serial communication, so the number of samples per 100Hz period is lower than the ~45 or so I consistently get in production.

I used my KORAD KA3005P to feed 0.05V to the ADC pin for this test. Note that a value of 61 is usually read when the number of samples is lower than 40, but that value goes up to 68 when the number of samples if over 70. I ruled out a math error — each individual reading does in fact average 68 when more samples are taken.

The Diagnosis

Although I wasn’t able to correlate things like WiFi status with this variation, my guess is that the power used for wireless communication is affecting the ADC readings — when the ESP12F isn’t very busy and can take more samples in the allotted time, then the voltage it reads is a tiny bit higher (~7mV). It’s not a lot, but when you values you expect to see only range 1-60 or so, then it’s significant.

The Work-around

I still haven’t nailed down the exact problem, and I’m not sure I even want to spend the time doing that if this work-around works out, but here’s how I chose to resolve this:

  • I’ve added some code that compares the number of samples actually taken to the number of samples I expect (those that provide a more consistent result).
  • If this “expected sample count” value is zero, then I’ll let the circuit operate normally, and report out the number of samples taken with each reading. This will allow me to figure out how many samples to expect in production.
  • When the “expected sample count” value is greater than zero, I basically just ignore the reading and pretend it hasn’t changed from the previous reading.

This seems to do a great job of smoothing out these erratic ADC fluctuations and providing more consistent brightness readings for my application. I hope others will find this helpful, too, and I’ll update here if I decide to look into it further.

I picked up a $9 Comidox logic analyzer for some ESP8266 work I’m doing, and so far it works great. You really can’t beat the price. Plus, it’s not just for Linux. Here’s how I got it up and running on Windows 10.

  1. Install PulseView software (it’s free). You can find it at sigrok.org. Navigate to Downloads, scroll down to Windows, and select the appropriate PulseView nightly build installer. (I used 64 bit.) Then install the software. This also installs the Zadig USB driver installation tool.
  2. Plug in the logic analyzer — it’ll probably show up as an unrecognized device.
  3. From the Start menu, type Zadig to run the driver installer, select the unrecognized device. Click Edit to change the name to something you recognize like Comidox Logic Analyzer. Be sure WinUSB is selected and click Install. This part can take a few minutes.
  4. From the Start menu, type PulseView. At the top, click where it says Demo Device, change the driver to fx2lafw, choose USB, and then Scan for devices. Select Saleae Logic with 8 Channels and click OK.
  5. Hook up the wires — don’t forget GND — and click Run in the software to start capturing.

I’m rolling my own home security system for pennies on the dollar (and lots and lots of time, but this kind of stuff is fun to me). Here’s what I ended up with for the kitchen. It controls three distinct lighting zones and three entry points (two doors and one window). It has its own captive portal for network/LED/sensor configuration (using Autoconnect) and it’s fully connected. So far it’s testing out pretty well. Here are the notable parts:

  1. ESP-12F ($1.09 from Aliexpress). This is the brain — the venerable ESP8266 module, with some custom code to control the lights, sensors, and communications. I used pins 5, 4, and 15 (with a 10K to ground) as PWM outputs, and pins 12, 13, and 14 as inputs. I broke out pins EN and 0, as well as VCC and GND and soldered up the wires so I could re-insert it into the programmer in case the OTA updates failed.
  1. Cat-5E network cable (free, on hand). I use this stuff a lot. I used all eight wires in the cable, plus a couple more for VCC and GND.
  2. Resistor Header (a couple cents). I broke out EN and pin 0 so I could place 10K resistors and remove them again if necessary to program.
  3. Dual MOSFET Trigger ($0.84 at Aliexpress). This triggers with 3.3V and drives up to 36V, 400W — plenty for each of my three 12V LED lighting zones. There’s one of these per output channel. The one on pin 15 also contains a 10K resister to ground, which is necessary for normal operation.
  4. Mini DC Step-down Buck Converter, 3A ($0.50 on eBay). This takes the power from the 12V LED power supply and efficiently converts it down to the ~3.3V operating voltage of the ESP-12F. I originally planned on using a linear regulator thinking that this might cause some interference with the ESP, but that turned out to not be a problem. (The AMS 1117 regulator would have probably run hot, but not too hot.)
  5. Power (free, on hand). This connects to the 12V power supply. I used green for 12V because that’s what I had on hand.
  6. Input Sensor Header (free, on hand). This breaks out the three input pins in a 2×3 header, once side of which is all GND.
  7. Output Header (free, on hand). This breaks out the three output pins in a 2×3 header, once side of which is all GND.
  8. Removable 10K resistor (pennies). The third output channel MOSFET driver has this resistor soldered on, but it basically takes pin 15 low, which is required for normal operation.

Here’s how I planned out the wiring and headers:

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 8 letters in 33 images. 

March 1, 1917

March 4, 1917

March 8, 1917

March 11, 1917

March 17, 1917

March 20, 1917

March 22, 1917

March 29, 1917

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 7 letters in 29 images. 

February 1, 1917

February 4, 1917

February 8, 1917

February 15, 1917

February 20, 1917

February 22, 1917

February 28, 1917

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 7 letters in 23 images. 

January 3, 1917

January 7, 1917

January 11, 1917

January 15, 1917

January 18, 1917

January 22, 1917

January 29, 1917

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 8 letters in 28 images. 

December 7, 1916

December 14, 1916

December 18, 1916

December 21, 1916

December 22, 1916

December 25, 1916

December 28, 1916

December 29, 1916

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 8 letters in 26 images. 

November 3, 1916

November 6, 1916

November 8, 1916

November 13, 1916

November 16, 1916

November 21, 1916

November 23, 1916

November 29, 1916

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 7 letters in 24 images. 

October 1, 1916

October 5, 1916

October 10, 1916

October 15, 1916

October 19, 1916

October 22, 1916

October 26, 1916

This is a single month of a large collection of letters from Lotte, who lived in northern Germany, to her boyfriend Ernst, who served on the SMS Gneisenau before WWI (though these letters start after that ship had already been sunk). For details and links to other months in this collection, visit the index page for this collection. This month includes 9 letters in 30 images. 

September 3, 1916

September 7, 1916

September 11, 1916

September 12, 1916

September 18, 1916

September 21, 1916

September 24, 1916

September 28, 1916, Letter 1

September 28, 1916, Letter 2

« Older entries