Monday, August 3, 2020

Power Supplies for ESP32 Arduino Based Projects

You’ll be surprised to learn that not all power supplies are created equal ;) Or if you’ve bought more than 1 or 2 online you’ll not be surprised by that at all. There are some that are so wonderfully cheap and seductive that you purchase them only to have them fail on day 3 or do something even worse. I have fallen prey to that in the past, but not anymore. This post is nothing about any of that, but just the well documented differences between name brand (not rip off!) imported power supplies. There are still issues you need to be aware of when selecting a power supply for your Arduino or IOT based project and evidently, specifically for your ESP32 based projects. 

Here you’ll see 2 name brand, Mean Well Din rail mounted power supplies of similar ratings.

The one on the left is a MeanWell model: HDR-15-12 with a slightly blurry sticker on the top which I apologize for. It accepts line voltage input and outputs 12v at 1.25 amps. It is also very nicely tiny and uses only a very small amount of your din rail space. It’s also cheaper than any other Mean Well supply I’ve seen of similar output. It also did not work reliably with an ESP32 based IOT device. The one on the right is also a Mean Well supply model DR-15-12. It also outputs 12v at 1.25 amps but it has the “DC OK” indicator on it.

The cheaper one on the left caused my ESP32 based device to reliably startup in firmware upload mode if you waited long enough between re-powering for the internal capacitors to be discharged. If the power was disconnected for more than a minute or so the device would not properly restart when power was applied again! This is obviously not acceptable as you need to be able to plug in a device and have it actually start up. The DR-15 model on the right starts up the device every single time without any care for how long it’s been disconnected and is only slightly more expensive and only slightly wider than the cheaper one.

So whats the difference? The only thing I can find is that the “Rise Time” on the spec sheet for the 2 is significantly different. It is listed in the “output” section of the sheet and along with the “setup” time. The setup time is the amount of time between when power is applied before the output actually turns on. If you’ve used many switching power supplies you’ll have noticed that there is a delay between applying power and any voltage coming out of them. This is not generally an issue, just the housekeeping and charging up of everything that the power supply must do before it is ready to supply regulated output. It’s the “Rise Time” that seems to be important. 

In the case of the cheaper HDR-15 model the rise time is 80ms. Which doesn’t sound like a lot. The slightly more expensive one is only 30ms. I have measured these on the scope and it does indeed seem like they are the problem. In my case they are running a secondary 3.3v switching supply on the board, so your exact requirements and the point at which is causes you trouble will be different based on that.  

It does seem that a longer Rise Time can cause the ESP32 (and possibly ESP8266) based designs to startup in firmware upload mode, as if you were holding gpio0 to ground even when you are most definitely not, rather than starting up normally.  There is some allusion to this in the ESP32 documentation about making sure that if you’re running from batteries that you have a power controller that will not apply power to the ESP32 until it is above a certain level. Or as I’ve learned if it is going to within 30 or 40ms but not as long as 80ms. Keep in mind while testing that if I unplugged and replugged the supply within say 10 or 20 seconds it would come up fine. It was only with power outages that lasted long enough for it to discharge all it’s internal caps that it would fail.

While the exact timing that causes your design problems will be different based on the 3.3v regulator design if you have this specific issue then I would first recommend testing with a power supply with a faster rise time. In my case the chip just did nothing when powering up. Re-applying the programming cable revealed the “waiting for download” message from the ESP32 making it clear that it thought I was grounding the gpio0 pin even though I wasn’t. With a faster rise time it starts up reliably every single time. 

Friday, July 3, 2020

1-wire Temperature Sensors and Lightning (and other sources of interference)

I use a lot of 1-wire temp sensors around the house for various purposes. One of which was a sort of hack to know when the hot water heater was in use. I placed one on the inlet side and one on the output side of the tank and when the 2 temperatures diverge by enough I know that the hot water is actually flowing. Within a few minutes of someone turning the tap off the temperature has equalized enough that it can tell the hot water is no longer in use. 

The main reason I set this up initially is that I wanted to have my bathroom lights go off after there was no motion in the bathroom for a while, but I didn’t want them to go off while I was in the shower nor did I want to set the timeout to be so long that they would stay on unnecessarily at other times. So now if the hot water is in use the logic of the master bathroom will not turn off the lights on you, but will keep checking back to see if the water is now off or if there has been more motion.

My day job is home automation software so all the logic for that is running in XTension.

Here is the graph of the output from last night:

The blue and red lines are the inlet and outlet temps of the water heater. Physically they are just a standard 1-wire temp sensor taped to the pipes a few inches up from the water heater. The yellow highlight is when the hot water is considered to be in use. The light green line is another 1-wire sensor just hanging in the attic showing the ambient temp in the attic. You can see 2 spikes to 185 degrees between 5:30 and 6pm last evening and one identical spike on the inlet sensor. 

Those were all caused by very sharp close by lightning hits. These particular sensors are connected to a Barix Barionet device which is a fantastic remote host for 1-wire sensors as well as digital inputs and relay outputs. Very handy for home automation and fully supported by my plugin for it in XTension. I have another device that is just basically an arduino that has a similar sensor that is glued to the side of a power supply so that I can make sure it is not overheating as it is in an electrical box with no ventilation. When those lights are on that sensor reads the same 185f or 85c repeatedly until the load decreases. These 1-wire sensors are just prone to interference and when that happens they return a reading of 85c. 

The reading of 185c is within the range of temperatures the device can actually read so it isn’t good to just filter that out in the driver or plugin or hardware. I am considering for a future firmware build of the 1-wire to wifi kit that if I get an 85c reading I will attempt another reading a few seconds later and only report it if the reading is the same twice. For the moment though the solution to filter them is easy enough inside the XTension ON script for the Unit. In the case of the above graph I am not going to filter it as it is interesting and happens rarely and does not throw off any other calculations or anything. For the sensor on the power supply it happens so frequently that it is frustrating to look at the graph. In that case I use the Change Future Value verb to change the value back to the previous reading if it is exactly equal to 85c. That does potentially ignore some valid measurements, but it does let anything through that is 84.9 or below or 85.1 and above and so I’m not terribly worried about that. The script is very simple and just looks like this:

if (future value) is equal to 185 then

change future value to (value of (thisUnit))

write log "ignored bogus 185 value for porch temp sensors"

end if


futureValue tells you the value that the unit will be set to when the script is finished running. The (value of (thisUnit)) portion returns the current value of the unit. This is sometimes initially confusing to people new to working with XTension but it allows you to do things like this or anything where you need to compare the current value with the new value and potentially override or change it. It also lets you do very specific smoothing of readings or throwing out ones that are out of range such as this. The call to ThisUnit just returns the name of the unit that you would normally have to pass to the value of verb so that if you renamed the unit you wouldn’t have to remember to edit the script and if you had many of the devices you want to do this to you could either cut and paste the code, or create a single script that you could call for all of them.

This 185/85 reading is actually a known issue with some 1-wire temp sensors. I don’t see a difference between powered or parasitically powered networks. The sensors in the above graph are parasitically powered but the one that is on the power supply is powered. The parasitically powered ones are on an absolutely horrible network of wires flying through the attic and to say that it is not a single bus or a standard star configuration would be a dramatic understatement. There is no shielding though they are on a single twisted pair of bell wire. Anyplace I wanted to add more sensors I just spliced into it and extended it. That attic network is my test of the absolute worst case I can imagine for testing 1-wire reading devices. The barix does exceptionally well under almost all circumstances except for these lighting storms.

That network now has 10 sensors on it all over the attic and it does sometimes drop a reading for one of them entirely. It also reads the intake and output temperatures from 3 different AC units so that I can verify the temp differential and know if the units are leaking gas and will need a recharge (or in one of the older ones a replacement is coming up I’m afraid) before they actually stop working and we have to make an emergency call to the HVAC folks. That reading also lets me run the fan after an AC or Heat cycle the best length of time to get all the cold or hot out of the unit. I turn the fan to On when a cycle completes and then start watching the temp sensors. As soon as the 2 temperatures are within a few degrees of each other I turn the fan back to Auto. 

I am also going to update the hardware in the next revision of the wifi temp sensor to use the better interface that is outlined in the 1-wire best practices documentation to see if that will help with bad values or interference.  In any case, overall 1-wire sensors work great, are inexpensive and there are a lot of options for getting them into your home automation system. 

Friday, January 3, 2020

Python Motion Detection on a Raspberry Pi Zero

I have been working non-stop the last few months to make my main project software compatible with Apple’s latest OS version. I finally realized how badly this was depressing me and how much I didn’t want to be doing this and how much it was making me hate Apple. I was spending literally man months of time to rebuild from scratch things that weren’t broken before Catalina and it was making me miserable. My rants about the absolute stupidity of everything that Apple chose to do to this alleged OS update will have to wait as I can’t afford the dental bills to fix the damage that gritting my teeth that hard will cause.

So in the interest of sanity and preserving the small quantity of it with which I have been granted  I took a short vacation from everything MacOS. I have been fighting with the horrible firmware of even the best available IP security cams for some time as I struggle to write software that can connect to them and insert their video streams into the web and other interfaces of XTension. I believed that there should be software for the Raspberry Pi that could leverage that camera for a much more reasonable price that would be terrific. Sadly even the best software out there for it just wasn’t doing the things that I wanted or at least with the quality of image and recording that I wanted.

The idea of controlling everything about a security camera is compelling! Not having to setup a firewall to keep it from contacting it’s own “cloud” and making sure it isn’t setting up a UPnP passthrough even when you told it not to have revealed to me several times that even commercial products don’t really do what you think they are. I wanted one based on software that I have written myself and so knew exactly what it’s doing.

It should also run well on a Pi Zero W so that you can make something small, though if it runs better on the latest multi-core Pi4’s thats OK too. Those little machines are worth every penny and very very nice!

The built in “motion” system is really interesting, but it’s remarkably difficult to get it to run at a high framerate and a larger frame size. Who wants a non-HD security cam now days anyway? The separate OS versions available may be spectacular but I want a software package for the stock Pi. After fighting with trying to get openCV to compile on a Pi Zero for the last week I wanted something that didn’t need that either. (Which I suspect is why they went with a totally separate image for their security cam OS as getting that stuff to install properly is almost hilarious)

The python camera support for the Pi is absolutely awesome. I can stream 1080p video and I can record it to disk and then post process it to standard MP4 files in almost real time. Those were not insignificant accomplishments ;) But the real sticking point was going to be the video motion detection. Using the pycamera code as a starting point and the hardware H264 encoders ability to output it’s changes from one frame to another makes it absolutely possible to do this at least as well as any commercial product. I’ll eventually open source this project but for the moment I’m working on it just myself. Here’s the 720p stream, part of the web interface and also a stream of just the motion sensing. This works as high as 1080p but at lower framerates though I’m sure I can optimize the calculations a bit more for that.

The image on the right is a live stream of the motion content and I’m just really enjoying playing with this at the moment.

I am currently building the web interface to the ability to mask out portions of the video for motion detection. The math for that is working great and adds very little if any overhead. Lots of work yet to do of course before something that is download/install ready but it will come before long. This is making me happy! Apple is making me mad.

Lest anyone think I’ll abandon developing software for Apple products over how much they drive me crazy sometimes really needs to spend some time using any of the other truly commercial desktop OS’s available out there. Don’t worry. XTension is undergoing a lot of changes because of this, but it’s not going away and unless I sell enough of it to hire a support team in another time zone I wont even consider doing a windows version. Sorry but if Apple frustrates me then Microsoft would kill me outright.

.code { background:#f5f8fa; background-repeat:no-repeat; border: solid #5C7B90; border-width: 1px 1px 1px 20px; color: #000000; font: 13px 'Courier New', Courier, monospace; line-height: 16px; margin: 10px 0 10px 10px; max-height: 200px; min-height: 16px; overflow: auto; padding: 28px 10px 10px; width: 90%; } .code:hover { background-repeat:no-repeat; }