I had two microSD cards ending up in trash in my Webcam Raspberry Pi in the past few months. If you think about it, the reason is quite simple: SDcards can only serve so many write cycles, for example about 10.000 cycles per cell with single level flash memory. When saving 1,5MByte of a webcam snapshot each minute, first as a temp file, then working on it to add a timestamp, then finally writing it, this leads to abot 5MBytes written - every single minute.
Even with good wear leveling algorithms you will write 7.2GByte each single day. It should be doubled because you need to erase-before-write on flash memory. On a 8 GByte SDcard, with much luck would lead to 5.000 days usage time. But reality looks different. The cheap memory cards use multilevel flash which can serve much less write cycles, about 1000. Even if the wear leveling works good, this would lead to data corruption in less than 1 1/2 years.
When the sysstat package is installed, you can see the throughput of your SDcard:
Which means nearly 34 GByte written in 17 days, which isn't as bad as initially thought; "just" 2 GBytes per day. It was way worse before, as I already have disabled the Swap File which Raspbian enables by default. On a RasPi A+ with only 128MByte of RAM this swapfile gets used intensively as it simulates RAM. For some updates, it is necessary to re-enable it as otherwise the package can't be decompressed. But this is done very easily and can be disabled immediately afterwards again.
To disable the swap service, run these commands:
#sudo swapoff -a
#sudo service dphys-swapfile stop
#sudo systemctl disable dphys-swapfile
To turn it on temporarily, then use these commands:
#sudo systemctl start dphys-swapfile
#sudo swapon -a
Don't forget to disable swapping after the task again. Another good idea is to set the memory splitting differently. On RasPi A+ with RasPi Camera 128/128MB are recommended, but it works also with setting GPU memory to 64 MByte via raspi-config or /boot/config.txt. This lessens the write-load on the SDcard significantly as well.
My webcam picture every minute - first as temp.jpg, then copied over as final .jpg - leads to severe amounts of data written. So I used a simple fix: Create a RAM disk with 10 MByte, mount it as tmp within the www directory, and use that for storing the image:
#mkdir /var/www/tmp
#sudo nano /etc/fstab
-> add the line:
tmpfs /var/www/tmp tmpfs nodev,nosuid,size=10M 0 0
#sudo mount -a
#df -h
# ln -s /var/www/tmp/snapshot.jpg /var/www/snapshot.jpg
The df-command should show the /var/www/tmp directory as tmpfs. Now I adapted the webcam.sh script to use this temp directory instead the www root; the index.html also refers to the new directory. Another fix is to give imagemagick the tmpfs directory as working directory by adding to the call:
I'm still looking where I can save some disk write accesses, as there still gets a lot of data written. But I'm down by a factor of 10 now, from 14.4GB per day (erase+write) to less than 1.4GB per day. This will lead to much longer lifetime of the SDcard.
To find out which processes write to the SDcard, you can use iotop:
I built a clock as fun and training project two years ago. There is always room for improvement - first I had a 7 segment LED which I multiplexed at 1kHz and used the time in between to sleep the µC. I tested several RTCs, from DS1302 over 1307 to the DS3231. The DS3231 is in place with a Nokia5110 display now for half a year and led to significant better time keeping and less power usage.
ATmega328 based DIY Clock.
Several further sensors are attached - the Si7021 measures temperature and humidity. Cool thing about the IC is that it does its measurement and goes to sleep immediatly, consuming less than 1µA.
Another sensor is a BH1750 which is used for only activating the display when there is enough light to read it. As soon as it is dark, the display gets disabled, further dropping the current drawn.
Today I added two further improvements to bring the power consumption down a little more. For one, I modified the Wire-library of the Arduino GUI to not activate the I2C pullup resistors. On those sensors, there are Pullups in place already.
Find your arduino-directory, go to hardware\arduino\avr\libraries\Wire\src\utility and open twi.c - there you can search for "pullup" and comment out both lines where the SDA/SCL pins are set to 1 (which enables the pullup resistor on an input pin).
Power consumption via 1R shunt on the oscilloscope.
This led to the current drop to 0µA every now and then.
So I decided that 100kHz I2C speed may be a little slow and keep the µC awake longer than necessary. So I added the line
TWBR=12
at the end of the setup()-routine.
This value fits for 16MHz µCs and results in 400kHz I2C speed. Looking at he graph it can be seen that the I2C reading is now taking only a short fragment of a second instead of nearly half of it as it did before. The values are close to 1mV for 1mA, but with such low values, this setup is distorted by noise a lot and doesn't show the precise load values. The multimeter shows peaks of ~3mA and sleep periods with real 0µA.
Before these changes, with a proper low-quiescient-current ultra-low-dropout regulator like the MCP1700, the LiIon battery with 2400mAh lasted for exactly three months. Let's see how long the new battery will last this time! I'll update the article when the battery is empty.
There are plenty of LDOs on the market - some cheap, some expensive, some with only three terminals, other with 5 or more. So how to decide upon a good LDO (Low DropOut regulator)? And why use a LDO when it literally burns energy within it's pass transistor? A switching regulator feels way more efficient as it only takes as much energy from the source as is needed on the output?
This all depends on your usecase. If you have no constraints in your power supply scheme like when using a USB power supply or a 12V switching power supply, you may use a switching regulator. It has a little ripple on the output voltage which may be disturbing in some cases, for example if you want to use an ADC. But it won't get too hot, and 12V down to 5V or 3.3V can be done quite efficient for medium loads.
Here's the point: It depends on your load. A switching regulator won't adapt as fast to changing loads, for example when a µC goes to deep sleep and suddenly wakes up. There the load will jump from a few µA p to 100mA or more. For the time when the µC is sleeping, the quiescient current of the switching regulator is usually many times higher than that of the µC. If the µC is sleeping long time and only wakes up every so often - or your wake-up load is below for example 10mA-, a LDO is the more efficient choice.
For my DIY clock and my mobile ESP8285-based sensor I wanted the most efficient LDO possible. The newest and most promising ICs are in form factors that are nearly impossible to solder by hand. So it had to be SOT23 size ICs. (N.b., old ICs like *7833 or *1117 have a high quiescient current of ~5mA, usually making then unusable with battery driven gear.)
Most efficient LDOs for DIY use.
For the 3.3V with a load of 250mAh and even more I found several ICs:
- HT73xx (7µA Iq)
- HT78xx (8µA Iq)
- XC6206 (2µA Iq)
- MCP1700 (2µA Iq)
I built up small PCBs which I could solder in front of my Clock and ESP.
They all delivered the load and voltage as expected. Differences became obvious, though.
The XC6206 is the cheapest of all those ICs. Unfortunately, it has a dropout voltage of max. 680mV at 200mA load. While this is great when your power comes from a USB supply, it means that a LiIon battery can be used only down to 4.0V! Also, the XC6206 becomes unstable very soon when driven by a LiIon battery with a voltage range of 3.0-4.2V. It is very sensible to load changes as well and starts to swing easily. I needed to provide a polarity protection as even short reverse polarization leads to a burnt chip.
Power consumption with different LDOs.
While the HT78xx (500mA max) and HT73xx (250mA max) also seemed to give stable performance, they didn't cope well with the load profile of sleeping 290s at <25 µA and then wake up for ~600ms at 70mA with short spikes of 250mA and more. Same behaviour shows with the clock which constantly switches between ~2mA and ~100µA. The datasheet has no graphs or values for the supply current with loads bigger than 40mA. The reason seems to be that the load on the battery significantly increases. The battery lost more than 15mV per day with these ICs. They're great when there is a wall plug involved or a huge battery and other big power hungry components, but for the ultra low current consumption I need they just don't cut it.
So the MCP1700 is the most stable and real economical LDO in this test field. Battery voltage drops about 5mV per day, leading to a runtime of roundabout half a year with my 900mAh LiIon battery.
My next tests are with lowering the voltage to 3.0V. The HT7330 showed the same behaviour as the HT78xx/HT73XX with 3.3V before and put a too big load on the battery. Interesting effect - after a runtime of more than one day, the HT78xx became much more stable and reduced the power consumption to values close to the MCP1700 ICs. I'm still waiting for MCP1700-302, I hope to shave off even more µAs to prolong the runtime with them.
I already optimized my NodeMCU firmware - LUA code to send data and then go to sleep after less than 10 seconds. That now takes a bit more than 1.2 seconds. That was a great leap forward to run a mbile sensor on a single 14500 LiIon cell with 900mAh for over a month.
The first improvement was done by moving the DeepSleep call from the Close Connection handler within the "http-code" to the On Receive handler. This led to deep sleep at less than 50µA after about 1.2-1.6 seconds.
Going to sleep after reiception of the data has been
acknowledged by the server.
Today I tried to directly go to sleep after calling the send-command with the buffer of my data. This led to no data being sent at all - the sending is done asynchronously and the DeepSleep command just interrupts it before even being started.
The solution is a timer call. Maybe it's possible to shave off a few more ms, but I am sataisfied with the result so far.
Directly after the send-command add:
tmr.alarm(0,150,1,function() node.dsleep(deepsleep_time*1000) end)
So the ESP is going to sleep after 150ms after the send command. It works and successfully delivers the data to the server, so now the wakeup time is down to roundabout 0.6s. This means nearly doubling the runtime on a battery cell! (Another ~100ms are saved by using a ESP-01 with black PCB instead of ESP-12E, by the way.)
When calling deepsleep with a short timer after the send
command, the wakeup time becomes significantly shorter.
Update 24.09.2016: With trial-and-error I could go down to 120ms instead 150ms for the DeepSleep-timer-call. While this doesn't seem much, it is saving 5% of power. instead of 600ms, we now have 570ms of awake-time, summing up to 45,6mA used instead of 48mA. During the real 290s DeepSleep, the power used sums up to 7.25mA. Average power consumption is down to 181,88µA instead of 190,12µA.
Also, the LDO is now a MCP1700 with 3.0V output, which should give another reduction. It helps using the full voltage range from 4.2V down to 3.0V of the LiIon battery.
While optimizing the ESP-based temperature and humidity sensors for my home I stumbled upon a weird issue: The different modules show different times to connect to Wifi and send the data. This was a real issue with tha battery driven sensor as there the data was always sent after roundabout 4 seconds. Looking with a 1R and the scope at it, it became clear that the connection/wake time is much longer, even more than 10 seconds.
ESP-12F on an adapter PCB.
A bit could be solved in software. Going to deepsleep after reiception has been confirmed (on:receive-handler) brought the wake-time down close to the self-timed values of the board. Using a static IP borught the self-measured time down to 0.3-0.4s, being really awake for about 1.2s. The timing code used on my other modules revealed something:
ESP-01 old version (512kByte flash, blue PCB): 9-61s
ESP-01 new version (1 MByte flash, black PCB): 3,1s
ESP-12E: 2.95-3.05s
ESP-12F: 4.1s
It doesn't matter at which distance the sensors are to the base station. The connection time is quite stable around those values, only the old ESP-01 boards really vary between those values, most of the times at 15s though. The modules use the same firmware and the same code (one variable differs between the sensors which is their name which gets sent).
It is clear that the first versions may have a different µC stepping and/or worse layout than the newer modules. But I would have expected the ESP-12F to outperform all other boards, which clearly isn't the case. Maybe someone knows the reason for this behaviour. Leave a comment if you do!
Adding a snippet helps re-programming a ESP with
init.lua calling deep sleep without flashing the whole
firmware again..
If you name your main program init.lua on a ESP8266 with NodeMCU firmware and it uses deep sleep, you need to flash the whole firmware again to upload a new program version. But there is a nice workaround. When using Esplorer, you can put small scripts on the buttons called "Snippets". When connecting the USB-to-serial adapter, hitting "Open", you have a short time for pressing this snippet button and the commands will be executed.
This way it's not not necessary to re-flash the whole firmware, but just upload your new version and test on.
Click on the "Snippets" tab, choose the snippet you want to add on the left side, and add these two lines:
file.remove('init.old')
file.rename('init.lua','init.old')
You can also rename the button with a text that suits the task.
Until now, the ESP based sensors were running as a tiny web server. This means they're at full power all the time, 80mA average according to the data sheet. With soldering a tiny wire to a pin on the ESP-01-modules it is possible to let the ESP sleep for some time - at less than 100µA usually. This greatly reduces power consumption and even makes battery based wifi sensors possible. The ESP is awake for collecting and sending data for a few seconds and then sleeps a long time.
For using deepsleep, ESP-01 needs a wire from Pin 8 (GPIO16)
to RESET. Magnifier glasses help with this modification.
I had to rewrite my data fetching logic for that. Instead of calling the web servers on the ESP modules, the modules now collect the data, send it to the Raspberry Pi and go to sleep for five minutes - more or less, the timer is quite inaccurate. 300 seconds tend to result in 280s, plus some seconds for connecting to Wifi, reading the sensor and connecting and sending the data to the server. Thus the rrd databases must accept the data more frequently, I had to rebuild them:
The LUA script has several optimizations already which help it running faster (creating the send string with a table and table.concat for example) and let the ESP sleep earlier again. One enhancement is to compile the needed modules (Si7021.lua to Si7021.lc, delete the .lua afterwards). The main program can be compiled as well and renamed to init.lua for faster startup. A minor glitch in that program keeps the ESP awake unneccessary long - moving the deepsleep call from the on:disconnect handler to the on:receive one helps getting the wake-time down by several seconds.
For mobile ESPs until now the MCP1700 LDO behind a LiIon battery gives the best performance. Without the power LED, but a Si7021 connected the quiescent current during deep sleep is down to ~45µA. A DHT22 worked well over weeks, but the quiescent current is way higher and it is really imprecise and slow.
Next to LDO based charging ICs and usual desktop chargers there is a class of LiIon charging ICs that don't burn up energy, but efficiently put them into the LiIon batteries. Since I charge from USB and work with prototype board, there are only very few chips available that I can handle with conventional soldering.
CN3761
TP8202
These are CN3761 and EUP8202 which you can find cheap in low quantities on aliexpress. As I wondered how they behave compared to the more popular linear chargers like TP4056, LTC4054 and so on, I built a small board with each and tested their charging curves. Due to the necessary coils and shunt resistors as well as switching transistors, they need significantly more space.
Another advantage over the LDO based chargers is the higher current which these switching ICs can provide.
The charging curve of the CN3761 looks ok and shows that the IC has no problems using higher charging rates. During constant current phase the current drops significantly already, but a switch-over to constant voltage mode is clearly visible. It stops charging at ~1/5C.
This EUP8202 curve starts off at low charging rate. The spikes are from moving USB cables and only affect the CC charging phase.
This charger has some peculiarities: The circuit according to the data sheet isn't stable. I needed to add 47µF at Vcc and at the battery so the current set via shunt resistor is met.
Also a weird thing, but this is documented in the datasheet, is that the charger switches to "near end" at about 450mA charge current (1/3-1/4 of current set via shunt; 25µA on the LED which then is very dim) and then charges all the way up to just about 5mA before completely turning charging process off. This leads to a real full cell at 4.218V (no problem with that), and after disconnecting the voltage won't drop fast as usual. So it is safe to use, it switches off, but cells can be used already when the LED is dimmed.
These switching chargers are interesting as they allow for higher charging currents even in USB mode and don't produce much heat compared to the LDO based charging ICs.
I was playing around with creating a PWM for power saving (and getting a stable light output) from a LED chain in the past; see here for an article about that.
TPS61070/MCP1640: Cheap and very efficient StepUp ICs.
When trying different step up ICs I finally ended up with the TPS61070 and MCP1640 which are remarkably similar with their specs and pin configuration. Those turned out to be the most efficient step ups available for hobbyist DIY projects.
They tend to discharge the cells below 1V which is expected according to the data sheets. While this is no problem for a short time on two serial NiMH batteries, a longer time in that range surely degrades the cells. Even if a pair of batteries lasts for around a week with my LED chain now, this led to two of my Duracell brand NiMH cells being damaged by deep discharge. I had to bring them to the recycling facility.
Duracell LSD vs Sanyo Eneloop
I decided that I need new cells. I often read good things about Sanyo Eneloop batteries but as those reports were too excited I didn't believe they're real. Anyhow, they ended in my basket.
I bought 8 peaces for about 16€ at Amazon now. They came precharged but I charged them all to be really full. And then I plugged the first pair into the battery holder to see how well they fare. Unfortunately I didn't write down when this was, but after more than a week a battery change was due. The cells were down to 0.8V and 0.4V each; still too deep discharged - but the cells charged just fine after that, taking a proper load of more than 2000mAh. With the Duracell batteries, the lower discharged cells only took a few hundred mAh of load until the gave their "fully charged" dV signal. Sometimes a refresh cycle helped, but the broken cells didn't recover their capacity anymore.
Now the second pair of Eneloops runs the LED chain for 10 days already and there's no end in sight yet! This is far longer than anything I reached before. 7 days was the usual time frame for my Duracells. They are Low SelfDischarge (LSD) type cells as well, but what a difference the Eneloop make! The Duracells claim 2400mAh capacity, the Eneloop only 1900, and still, they greatly outperform the Duracells! They also cope way better with deep discharge.
I plan two additions to the LED chain StepUp and PWM circuit to get rid of the deep discharge problem and prolong the runtime even more: Adding a Schmitt Trigger after the oscillator stage for less leakage - and placing a NCP303 1.8V as undervoltage lockout to put less stress on the batteries.
I had serious problems today flashing NodeMCU firmware on my new ESP-01 boards with my Windows XP virtual machine today. As I could communicate with the boards from Mc OS X directly, there is nothing wrong with the boards. But after spending some hours trying different USB-to-serial boards without success, I finally searched for a way to flash the firmware with Mac OS X directly as well.
ESP8266 with DHT22 as wireless remote sensor. A TD6810 buck delivers 3.3V from USB.
The solution was quite simple: esptool. Download the zip archive, unpack it, change into that directory and install it systemwide by typing in:
sudo python setup.py install
This will take care of all necessary dependencies like installing pySerial libraries and so on. After the installation finished, you can check whether the tool works correctly. Make sure to tie GPIO0 to GND and restart the board for getting into flash mode:
The power supply for example for the DHT22 sensors I'm currently using in my "Home Measurement Project" has a big influence on the accuracy of the readings. The graph was getting a bit "nervous" and unstable.
I removed the huge 1000µF electrolytic capacitors and added a few capacitors to the ESP board and the sensors: 100nF, 10µF, 100µF ceramic capacitors and one to two 100µF tantalum capacitors. This looks way better than before!
With those tantalum capacitors and 0.1+10µF ceramic capacitance the result was looking better when looked upon with the oscilloscope. But you can see bigger 10ms areas where the voltage significantly drops to below 2.9V.
Thus adding 100µF ceramic capacitor was helping a lot, looks way better already! But still the voltage drops to ~3.0V for those 10ms slots which is still not optimal.
The USB-to-serial-boards are nice for programming the ESP boards, but for permanent power supply, something more special is needed. I found a few RT9166A in my LDO drawer. They can deliver up to 500mA - but in the SOT23 case can only stand 0.25W of heat. 1W of heat on the other hand leads to a temperature rise of 250°K. With 500mA at 5V to 3.3V I was calculating with 0.85W of heat ... thus I added fat lines of solder tin so the dissipation would be improved at least. To my surprise, the RT9166A stays really cold!
The result is very satisfying. You ca see the transiants on load changes, but no sustained voltage drops on the plot! Thus it is a good idea to use a proper decoupling with capacitors for the sensors, the ESP board itself and use a proper power source!
Two sensors are running with TD6810 switching regulator and one with MCP1825S LDO. They all run stable and don't need the USB-to-serial-converter anymore.
My mobile wifi ESP8266-sensors with DHT22 (and soon even with a barometric sensor ... ) are working very well for seeing what is going on in my flat. But MRTG has been developed for monitoring internet traffic. Thus negative values are not possible to be displayed. There is no easy solution to add that. So I needed to switch to RRDtool to fetch my data and plot the graphs. This needs a bit more thinking as you need to setup databases for each of your sensors and think about how often you want to sample the data, the allowed values, how far are averages stored, and so on.
As I still want to monitor my internet traffic as well, next to the "weather sensors" I need to setup a traffic counter manually as well. My solution looks like this:
Update 24.01.2023: The traffic is measured in Byte/s. For current internet speeds, GBit/s are no unrealistic values anymore, so at least 128.000.000MByte/s are plausible. Thus, the database needs different borders, as the above limits max out occasionally with a 100MBit/s connection already – it can transfer more than 6,5 MByte/s.
Which means: sample accepted every 5 minutes (300 seconds). The bandwidth is 50MBit down and 10 MBit up, added some Bytes for the theoretical headroom. Derive means that the difference to the last sample value should be stored; with a 0 sample for example after a reboot, traffic gets counted as 0 (instead of giving a huge spike as RRDtool assumes a wrap-around of the counter otherwise). The other values create entries for the daily, weekly, monthly and yearly averages.
For the DHT22 sensors, I create a database for each sensor in place so adding new ones or removing old ones is easy.
Now I need to adopt the scripts which read out the sensors to feed the data into their database.
Bash is not quite intuitive, unfortunately. Whitespaces around "=" can take you hours to spot as error! ;)
A few hours later, everything falls into place. This is the script which gathers the data and creates the graphics. For crontab, I needed to add it with a trailing call to "/bin/bash" in the crontab-entry as it was throwing syntax errors when I directly called it.
Source here: http://pastebin.com/hMeCzweT
The graphs are embedded in a very basic HTML webpage for now:
Now I'm still finetuning all the scripts, graphs and websites. But it is doable, although a bit more complex, to plot the data with RRD instead of MRTG.
To save some space and because the old NiMH charger startet behaving strange I decided that its time for new charger. As I know what I'm doing I'm not afraid of a charger that handles LiIon and NiMH. If you don't know or care about the battery chemistry, as worst case a deep discharged LiIon could get charged (and that with a way too high current) and become unstable, so that this cell will become dangerous. Take care to not charge LiIons that are depleated below ~2.5V.
My choice was a LiitoKala Lii-500. It has four slots which can accept even 26650 LiIon batteries, and it supports NiMH batteries as well.
On AliExpress you can find it for even less than 20€, I bought mine here.
The device is quite a bit bigger than a two-cell-charger; still two independent chargers require more space.
The Lii-500 has another nice feature that might come in handy from time to time: It can act as power bank when batteries are inserted and no power is available. A USB plug on the back side offers 5V with up to 1A then. I didn't check it yet, but I think you need at least two inserted cells for that feature to work.
But more technically speaking, the charger is built solid. The contacts are great and work even with longer protected 18650 cells (70mm+).
For a switching charger, the charging current is very stable. A proper CC-CV charging is applied, the charger completely stops charging when the battery has 4.22V. At lest for 24-48 hours; if you leave batteries longer than that in the charger, they get slowly charged more. After 5 days I had a battery at 4,20V while it should have dropped to 4,15V or less. So take the batteries out the chargers the day after they're full, or better even earlier. By default, the Lii-500 wants to charge with 500mA; it offers 300, 500, 700 and 1000mA as well.
Also a fast or a normal test mode is included. There the battery gets discharged and fully loaded once to measure the capacity of the cell. This take some more hours though. Discharging is done with 250mA when 300 or 500mA are chosen as charge current, and 500mA for higher charging rates. The capacity shown by the charger is very close to that I can measure with my setup.
NiMH batteries get a trickle charge. Charge termination will be triggered by dV detection and seems to work properly and stable for all the tests I did the last few weeks.
It is possible to charge LiIon and NiMH batteries at the same time (in different slots, of course ;) ). The Lii-500 detects the cell type based upon the voltage and decides from there if the NiMH or LiIon charging scheme will be applied. Below 0.6V a cell is not detected. Deeply discharged NiMH cells must be "jump started" otherwise therefore - or just don't abuse your cells this badly!
I'm very satisfied with this charger's performance and can recommend it.
I have a Raspberry Pi A+ sitting in my kitchen window for over a year already, using it as webcam (first idea was some timelapse over a year with all seasons. Too much movement in the first time, so the whole-year overview takes a little longer.) Yesterday I remembered that I also have a few DHT22 temperature and humidity sensors flying around.
So I decided to hook one up to the RasPi and see what it would spit out. Just wired it up to GND, 3.3V and to GPIO17, modified a Python script which uses the AdaFruit DHT library which I found on the net, and it spits out what I need. Here is a guide from them for a starting point.
This data needs to be visualized somehow. I remembered using MRTG 15 years ago. Good news is that MRTG is still maintained and easily available. Setting it up and adding the sensor to /etc/mrtg.cfg:
### Global Config Options
WorkDir: /var/www/mrtg
Options[_]: growright, nobanner
EnableIPv6: no
WriteExpires: Yes
######################################################################
# System: CamPI DHT22
# Description: Temperature + Humidity in Kitchen Windows
######################################################################
Target[CamPi-dht]: `/usr/local/bin/dht22.py`
Title[CamPi-dht]: Temperature and Humidity in Kitchen Window
MaxBytes[CamPi-dht]: 1000
AbsMax[CamPi-dht]: 1000
WithPeak[CamPi-dht]: dwmy
Options[CamPi-dht]: gauge, growright, nopercent, pngdate
YTicsFactor[CamPi-dht]: 0.1
Factor[CamPi-dht]: 0.1
#kMG[CamPi-dht]: ,k
YLegend[CamPi-dht]: °C / %
ShortLegend[CamPi-dht]: °C/%
Legend1[CamPi-dht]: Temperature in °C
Legend2[CamPi-dht]: Relative Humidity in %
LegendI[CamPi-dht]: Temperature °C
LegendO[CamPi-dht]: Rel. Humidity %
PageTop[CamPi-dht]: <h1>Temperature and Humidity in Kitchen Window</h1>
To get the fractions of temperature and humidity, the YTicFactor and Factor options are important.
Start the index building, let mrtg run once, and you get the first empty graphs. It takes about 10 minutes so the grpahs get filled with valid data. Remember to put mrtg to the list of cronjobs so it runs every 5 minutes.
Today I found out about ESP8266 being able to directly read out a DHT22 and offer the data as web server. I needed to flash the latest NodeMCU firmware - a simple guide is available here. You should download the latest development build of NodeMCU and flash that. Just enter the path and the name of the downloaded file under "configuration" (by hitting the gear symbol you can browse the file system for that) of the esp8266-flash.exe tool, address 0x00000 is correct. Hint: Solder that CE_PD-pin on the ESP-01-boards directly to Vcc. For flashing, you need to connect GPIO0 to GND. In all cases, an eletrolytic capacitor of 1000µF between GND and Vcc helps keeping the board stable.
This firmware offers plenty of functions which you can use with LUA, a basic programming language. ESPlorer makes it extremely easy to write and test a program. My version of init.lua looks like this (adopt SSID and PW to your Wifi).
--start server
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive", function(client,request)
-- read DHT22 on GPIO2
pin = 4
status,temp,humi = dht.readxx(pin)
h=10*humi
t=10*temp
if( status == dht.OK ) then
buf = t.."\n"..h.."\n"
end
-- reading DHT done, now spit it out
client:send(buf)
client:close()
buf = nil
t = nil
h = nil
status = nil
temp = nil
humi = nil
pin = nil
collectgarbage()
end)
end)
The temperature and humidity are now accessable via webbrowser. On the Pi, create a bash script, for example /usr/local/bin/nodemcu1.sh (make it executable via "sudo chmod a+x /usr/local/bin/nodemcu1.sh"):
Add an entry to your /etc/mrtg.cfg like this (take the rest from the example above and adopt the device name in the brackets):
######################################################################
# System: NodeMCU1 DHT22
# Description: Temperature + Humidity in Living Room
######################################################################
Target[NodeMCU1-dht]: `/usr/local/bin/nodemcu1.sh`
Title[NodeMCU1-dht]: Temperature and Humidity in Living Room
Run the mrtg indexmaker and after that mrtg again.
Now you have a mobile temperature and humidity sensor which you can put anywhere in your Wifi range.
You only need a 3.3V power supply - either via USB and step-down, or battery and step-up. There are rumors that with connecting to pin 1 of the mcu you can enable a deep sleep mode, but as the ESP8266 is working as web server it should be always-on. My USB-Meter shows that the current drawn is always jumping around between 0-200mA. This is not bad for a web server!
Update 21.01.2016: Two more DHT-22 arrived yesterday, now I have four sensors in different rooms. I like the overview over the climate at home :)
I still need to learn a lot in electronics. Just yesterday I accidentally connected the battery wrong to my LDO XC6206 - which it seriously disliked and afterwards spat out 0.56V instead of 3.3V. No problem, I have plenty of them in the box - but this may happen more often and I don't want to always solder in a new LDO.
So I looked for ways to protect the IC from wrong polarity of the battery. Since I power a ATmega328 based 7-segment-LED watch via a LiIon battery this way which needs around 2mA current, a usual diode is no alternative. The voltage drop of ~0.7V is not usable with LiIon (3.0-4.2V) on a 3.3V LDO. A Schottky diode would be way better with only 0.3V voltage drop, but still makes quite some capacity of the LiIon unusable.
Thus I decided to use the AO3415A P-channel MOSFET. It has to be connected with Drain to the battery, Source to the Vin of the LDO. Gate connects to Ground. Since the LiIon voltage is well within the specs of the AO3415 for Vgs(max), I can even work without a Zener diode/TL431 to limit the voltage; a resistor at the Gate seems not necessary as well. This is a unusual orientation for a P-FET, the first time I soldered it in without turning it on its back ;)
The results are better than I expected. The battery has 4.171-4.172V; on Source, I measure the same value down to the millivolt.
How does this protection work? When connected correctly, the body diode is conducting from Drain to Source. The Gate gets negative compared to the Source, the FET opens fully. The resistance drops down to Rds(on) for the current voltage. The load is so little with ~2mA that there is no significant voltage drop, it should be in the nano- or micro-volt area.
The capacitance behind the FET is quite small and should pose no risk that the FET wouldn't disconnect. If the battery is connected the wrong way, no current can flow as the body diode of the P-FET will block in that direction. The XC6206 won't be destroyed anymore. With such a cheap transistor the power supply is much more reliable.
I had some spare time during my vacation so I finally built a more solid version of my shunt and voltage divider "breakout" board which I used to measure the performance of LiIon chargers with.
I soldered everything onto a small breadboard and adopted the programming a little ...
Improved Data Logger for Charger Measurements.
As you can see, the plenty of loose cables are gone. Everything is statically soldered together so that no distortions should be possible anymore.
During the first tests, some error spots are still left. The two DuPont cables that lead from the charger to the board don't make solid contact, need to solder my own ones. And when moving the plugs in the USB ports of the computer, the voltage and current delivered are changing a little as well.
The first test: The DuPont cables for connecting
the charger need to be replaced.
But the main goal was to minimize other distortions and that worked great. I now use a 10 mOhm resistor which can stand 1W of heat dissipation and has a <= 1% error. The ADC (ADS1115) is connected via 10 kOhm resistors to its ends, ensuring very little bias. The voltage divider consists of two 100 kOhm resistors, where the connection to the ADC has again a resistor of 1 kOhm. The OpAmp for fetching the amplified differential voltage from the shunt is removed, I'm now using the built-in PGA of the ADC to get a good resolution. 1mA current over the shunt equals 10 µV, while the resolution of the ADC is ~7µV. I should probably add some oversampling as this signal has true noise and can improve this way.
Update 22:00h: Soldered wires with better contact to the board. This helped the resistance of the whole circuit to drop by 10% to now ~90 mOhm (including the battery with its inner resistance).
Also used a USB hub so only one connection is used on the computer. Turns out that the plugs show similar behaviour on the hub when the computer is moved - you can clearly still see every movement test.
The charger seems to get even less disturbed looking at the charging curve. >1A until 4.20V are reached and then the current drops slowly, while the voltage rises up to 4.25V for a short time. This is all within LiIon specs and looks quite nice.
Last updated 01.01.2016
I recently ordered a small Wifi bridge/repeater dongle which I wanted to use to offload the WPA2/AES encryption from my satellite receiver and have it connected virtually by ethernet. This Vonets Mini300 can't cope with long WPA passwords though with special characters - a "+" sign gets stored as space, thus it won't connect to my WLAN. The firmware was quite outdated and the update servers have changed, so the internal update mechanism doesn't work. The black and red wires are for a serial console to access the operating system on the little box directly and to see if it is possible to fix via command line interface. Unfortunately, the system spits out the boot messages, but is locked against keystrokes.
I started to investigate alternatives: OpenWRT for the MT7620N processor should work. Or the manufacturer sends me the most recent firmware so I can flash it myself. But there we are: Like usual PCs BIOSes, Wifi routers use SPI flash rom for storing the firmware and data. You can buy special flashers and use the software the manufacturer offers for it. Or - you build your own!
It's actually quite easy. You can use an ATmega board, connect it with USB-to-serial-converter to your computer, and wire up the Flash IC directly to the ATmega SPI pins. My first attempts used exactly this setup, but with plenty of DuPont cables and thus possible spots for errors - and for noise on the lines which can (and did!) disturb proper operation.
For such a flash writer you need:
- An Arduino Pro Mini board (cheap and runs with 3.3V)
- A USB-to-serial converter like FT232RL, PL2303, CP2102, ... (I used a PL2303) with 3.3V output
- Very useful is a SOIC8/SOP8 clip for easy access to the Flash ROM IC.
Wire the USB-to-serial-converter to the Arduino Pro Mini. If you want auto-reset for easier flashing, you need to solder a wire from Pin 2 of the PL2303 to Reset or DTR on the Arduino - but through a 100nF ceramic capacitor. Look at the photo at the end to see my version of the hack.
The frser-duino Makefile contains some entries which you should adopt. I found out the hard way that the bootloader of the Arduino only talks at 57600bps. You need to tell that to avrdude via -b option, and set this in the Makefile for frser-duino. Also you can set a second bitrate below that line. I set it to 230400 and it works great; contrary to the 115200bps which the unmodified version offers. You should set the proper interface for your USB-to-serial-converter, the default /dev/ttyS0 is for Linux systems; on my MacBook Air, it is /dev/tty.usbserial.
Then you start building and flashing the firmware with:
make clean all program
This will build the firmware and upload it by issuing the correct avrdude command line:
That's it! Wire up the SPI Flash ROM to the proper SPI Pins on the Arduino or solder a board with a DIP8 connector which is correctly connected and you're good to go.
This way I can just plug the programmer into the computer and directly use it with flashrom to read or write SPI flash roms.
Now with the optimized firmware with 230400bps support the reading and writing significantly improved in terms of speed.
koepi$ time flashrom --programmer serprog:dev=/dev/tty.usbserial:460800 -r 16MB_empty.bin
flashrom v0.9.8-unknown on Darwin 15.2.0 (x86_64)
flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OK.
Warning: given baudrate 460800 rounded down to 230400.
serprog: Programmer name is "frser-duino"
serprog: requested mapping AT45CS1282 is incompatible: 0x1080000 bytes at 0x00000000fef80000.
Found Winbond flash chip "W25Q128.V" (16384 kB, SPI) on serprog.
Reading flash... done.
real12m42.328s; user0m6.428s; sys0m12.367s
I also tried the STM32F1xx based vserprog, but the USB connection wasn't returning the expected results. Flashrom couldn't initialize the programmer. The authors of the code state that minimal changes are necessary for setting the necessary pull-ups, but I didn't find the spots in the code where to add that - bummer! With 36MHz SPI frequency, direct USB support without extra dongle and, most important, DMA it is the best you can get performance-wise.
With this SPI flash programmer I can flash the newest firmware from the manufacturer - the bug is still there though. But it can access it's update server so there is still hope for a fix in the near future.
I also cut-and-copied the firmware image - the U-Boot Bootloader didn't allow any access to it's shell, so I use breed from HackPascal now. The first 192kByte are Bootloader (pad with zero bytes up to the 192kByte boundary), then there's config data in the next 128kByte (cut out from the original flash dump). After that at 327680 bytes the firmware itself is stored. MT7620N firmwares from OpenWRT don't work, unfortunately. I tried even to build a version myself, but with the same result. Using a bigger SPI flash rom works, but there is no use for it when only the original firmware for 4 MByte flash is running on the machine. Update 01.01.2016: I had to reduce the speed to 115200kbps again for reliable operation. The programmer stopped mid-reading after some time with 230400kbps.
More than 5 years ago I bought a cheap Bolun WR-601 wireless lavalier microphone for playing around with my camcorder and proper audio for example at presentations. I totally forgot about it till yesterday since I never had used it before. Short tests at home with an old netbook as recording device were promising. But then when needing it at a seminar - which was close to train rails and the mandatory radio distortions close to the power lines-, I couldn't use it as reception was limited to one or two meters. The sound captured by the Samsung HMX-H200 camera itself is still usable, but you have this usual thin, distant 'speaker in a huge room' sound.
So the receiver of the Bolun WR-601 needed a better antenna. Since it uses fm frequency, I removed the socket from a cheap, small TMC antenna for GPS navigators (these are dirt cheap on eBay and look like this.). It is more or less a wound up long wire antenna with good reception properties. I soldered one end of a small piece of silver wire to it, the other end to the antenna solder point which is used on the PCB. Fixed it with a small drop of hot glue and made the antenna hole in the other case side bigger. After closing it, it needs even more hot glue to be stable and more sturdy.
The first test showed outstanding success. I went more than 5m away into the kitchen, so the signal had to go through walls - and no distortion was added! This seems to be a must-do modification so this cheap lavalier mic works as intended. A short test capture shows success while walking through the house: Test MP3.
Last Update: 13.11.2015
Out of curiosity and fun I wanted to build a mobile speaker as do-it-yourself project which can be fed with auxiliary music via line in from an iPod or cellphone or even directly use some SDcard or USB stick with MP3s on it. This should work with a single LiIon battery. So I went along and ordered a few cheap components.
Additionally, you need some more components like capacitors, resistors, power inductors and so on.
Push-Pull / class AB amp try-out
The PAM8403 PCBs took quite long to arrive, so I started building a push-pull-transistor amplifier for first tests - it's less efficient, but at least I could test if the rest of the setup works. (In fact a friend 'forced' me to do it, for learning/education sake; thanks Andre, it worked. I now see capacitors not solely as equivalent of a battery anymore, but also as a frequency dependant resistor. Well done, sir!)
As always, clicking on the pictures will increase their size.
The layout of the DIY Class AB-amplifier circuit.
Top view - it's quite small, too! It's actually amazing how simple it is to build.
Some more photos and explanations from the build process:
The decoder board had a 78M05 low dropout regulator which I needed to desolder; I just bridged the remaining Vin/Vout terminals. The 5V supply stem from a small TD8208 step-up regulator. As it can deliver up to 2A, this will be enough for the 2 * 3W of the PAM8403 amplifier and the little supply current needed by MP3 decoder board. So the whole Boombox will run with a stable supply when using a LiIon cell.
The MP3 decoder output inspected via DSO toy oscilloscope. Vpp is bigger than 1V. And also notice: It works!
Since I lack craftmenship capabilities, I used simple cardboard for putting the stuff together so far. The output of the MP3 decoder passes through a 20kOhm stereo potentiometer so the output volume will be adjustable.
Hot glue is working very well to keep the components in place.
Since the step-up PCB and the MP3 decoder will draw small amounts of current even in off-mode, I added an on-off-switch between the positive terminal of the battery and the positive input of the TD8208 board.
Not pretty, but working. The display is running multiplexed at a quite low frequency, thus not the whole information is readable with a too short shutter time of the camera.
Then connected everything together. The best thing is it worked immediately! Well, kind of. The volume was a bit too low and the sound distorted. Reviewing everything I found that I soldered the PNP transistor the wrong way - it needs to be emitter against emitter. After that change - wow, that is loud! And the sound quality is nice, too. Except for the prominent hissing noise / white noise at low volume.
And then the PAM8403 PCBs arrived. Soldered one board in unmodified for a first fast test. Have a look at its small size compared to the AB-amp!
So the first draft version of the Boombox can be closed now. This is the front view. Need to decorate it a little, it already looks a bit like No. 5 or Wall-E :)
And this is the back view. I added some Velcro to 'the lid' so the battery can be easily accessed. But since I plugged the cell in a few days ago, its voltage just dropped by 0.2V to 3.9V even with prolonged usage (with the AB amp before as well, no recharge done since plugging it in the first time). The circuits thus are very efficient.
According to the PAM8403 datasheet, even if the Class D amplifier is working filterless, some components should be added to reduce EMI. In all cases, the power supply should have added capacitance of about 1000µF. I didn't want to add electrolytic capacitors as they tend to age, so I used two additional 100µF ceramic capacitors in parallel.
Next Diodes Inc. suggests to use ferrite beads in the lines to the loudspeakers and also 220pF capacitors to ground. This shouldn't be needed for wires less than 20cm long, but well - I don't want to disturb the neighbourhood with a 2*3W sender (the PAM amp switches with 260kHz and the harmonics of this frequency will be disturbed).
Update 25.09.2015: Now with some denoising - the signal lines to and from the potentiometer were receiving noise from other components. The MP3 decoder board isn't shielded at all, so over a layer of capton tape I added some copper foil and soldered it to GND as well, like the copper foil around the potentiometer wires. The PAM8403 PCB got 100µF and 10µF additional ceramic capacitos for proper decoupling. The GND and positive connections of the step-up-boards are done via ferrite beads. The cables for the GND and plus connections of the TD8208 stepup are thicker now. An additional step-up (BL8530) now supplies power to the MP3 board and is fed directly from the LiIon battery as well. This leads to massively less noise. Make sure to have some shielding in place and make the wires as short as possible.
Oh, and using a CD75 4,7µH power inductor instead of the 22µH for the TD8208 decreases noise quite a lot. The datasheet just has some complex formulas for calculating a suitable dimension and makes no suggestions about the proper range for the inductors.
Next step for improvement is a so-called Pi filter between the step-up boards and the periphery. This is a simple solution with ferrite beads, where I added 1µF ceramic capacitors between the + and - lines - one before and one after the ferrite. This helps filtering quite a lot of humming and noise, too.
Now I'm satisfied as the sound quality is very acceptable for a mobile MP3 speaker.
Update 03.10.2015: Finally, the improved wooden version of the PAM8403 mobile Boombox in action. Please bear in mind that the cellphone microphone doesn't have adequate frequency response and the real sound is different, it is actually really good. Depending on the location where you put the box the sound even improves as the sound body will be extended. On a closed bucket, the bass is much more pronounced, for example. The box is loud enough to fill a huge room like kitchen or living room so that the people in there need to shout in order to understand each other! :)
Update 30.09.2015: Today my new saw, some glue for wood and some wood arrived. As the proof-of-concept works, it is time to make a more solid enclosure. Now waiting for the glue to dry so I can continue. :)
Update 01.10.2015: And now nearly finished. Everything is working and the sound significantly improved.
Still no real beautiful design object, but far better than being made only out of cardboard.
Only little left on the todo-list. Fix the battery, add a USB-charger (I think I have a few ;) ). And maybe make a lid from wood to, either to slide in or to flip.
Update 02.20.2015: Done. Charger works. Cotton / wool filling for the empty space to dampen the backward reflections of the speakers massively improves the sound. Unbelievable what this little sucker spits out now. Defined bass, clear heights, very transparent sound. Only a proper lid is missing, it currently is improvised with cardboard again - which is ok, but ... :)
Update 04.10.2015: First real-life test on a big open soccer field. Training for a choreography in dog school, the DIY Boombox had to take care of the music. In 50m distance it was still nicely audible. After two hours of straight usage, the battery voltage fell to 4.04V, starting from 4.14V. That is only very few percent of the battery's capacity (you have to keep the discharging curve of a LiIon battery in mind). Amazing!
And now with a proper lid. Finished! :)
Update 13.11.2015: I'll build three boom boxes - at least, now that several speakers lie around here. This is a Boombox made with Peiying PY-1010C. allegedly RMS 60W. Fed with PAM8403 currently gives nice bass and it is really loud. Have some 2x15W PAM8610 in the reception pipeline, also a TDA7492 amp. For the TPA3116D2 I have some better Blaupunkt GTx 542 SC; that will get a blog article of its own though as the power supply will be interesting there.
Of course, a clip of this beauty at work is available, too. This is during the first test.