Peltierelemente und MicroPython - Teil 1: Ein 8A-Netzteil als Stromlieferant

Autumn is here and although it's not hot this time of year, it's still nice to have a chilled drink handy at work. So the goal is a transportable beverage cooler. As a "cooling unit" for this I have peltier elements. With small 4 x 4 cm surfice and 3.7mm thin, the parts can be used both for cooling, but also for heating (for something hot in the cold season). The little elements have only one small disadvantage: they need to be supplied with some ampers to work properly. Of course, the amperage should also be measured, autonomously, by the device. For this we use a Hall-effect current sensor and for the display we make a decent sized OLED display from a Windows character set. Measuring and displaying is done by an ESP8266 based on MicroPython. This is exactly where we start in the first part of the new series. And so welcome to this blog with the topic: A power source for the cold makers

Figure 1: Buck converter from the front

Figure 1: Buck converter from the front

Before we get started, I want to give you a preview of what you expect overall.

The first part is about a power supply that brings enough power for several thermocouples. We recycle an old computer power supply and pair it with a very efficient regulator circuit that can deliver up to 8 amps. The DC-DC converter, controllable by a potentiometer, needs active cooling with so much power, which we build from a 4 x 4 - cm fan and a temperature control. The control ensures that the fan is not constantly whirring.

In the next episode we will deal with the Peltier element as a thermosensor. But we will not measure temperatures with it, but heat flows. With it, we can determine the amount of heat coming in through window panes or walls, or leaving the room through the same. The measuring servant will be an ESP8266, which we will program in MicroPython. Such a part is useful for energy optimization of rooms, heating and cooling devices.

Finally, we will use the same type of Peltier elements as cooling units. The beverage cooler can be powered from the PC power supply, as well as from the car power supply with our regulator circuit. The power supply will be monitored by an ESP32, which will also monitor the temperature in the cooler and control it via a relay unit.

So let's start. These parts are required for the first sequence.

Power supply


XH-M401 DC-DC Step Down Buck Converter XL4016E1,


0.28 inch Mini Digital Voltmeter Voltage Meter with 7-Segment Display 2,5V-30V


KY-013 Thermistor Temperature Sensor Module


0.91 inch OLED I2C display 128 x 32 pixels


NodeMCU Lua Amica Module V2 ESP8266 ESP-12F

for optional current measurement


ACS712 20A Ampere Current Sensor Range Module Current Sensor


Active Miniventilator Cooling-Axial-Fan for Raspberry Pi

or processor fan 4 x 4 cm

Two-point temperature controller


PCB Board Set Hole Board

or own PCBs with manufacture by print template




LM78L05, if an Amica is to be included


BC337 NPN transistor with Ic= 500mA to circuit the fan


LM358 Operational Amplifier


IC-version DIL8


Resistance 1kΩ


Resistance 1,5kΩ


Resistance 3,3kΩ


Resistance 3,9kΩ


Resistance 15kΩ


Resistance 82kΩ


Resistance 100kΩ


Trimmpoti 10-Gang 10kΩ *


Ceramic capacitor 0,1 µ F


Electrolytic capacitor 470 µ F/16V


Electrolytic capacitor 1000 µ F/6,3V, if an Amica is to be entered into the race


Diode 1N4148


Pin bar 10-pin


Sheet metal, plastic or wood panels for a housing


4mm jacks for input and output (2 x red, 2 x blue, 1 x yellow)


insulated stranded wire for compounds (>=1.5mm²)

* These parts need you for the optional current measurement

The Buck Converter XL4016E1

Figure 2: Buck Converter

Figure 2: Buck Converter

According to the manufacturer's data sheet, the converter chip can digest input voltages of up to 32V and spit out up to 12A. Our own measurements showed a maximum efficiency of the circuit of up to 88% at higher currents. This is good for us, because we want to use the part in this range. Also the low dropout of 0.4V between input and output voltage is ideal. There is very little to consider when connecting the circuit. The input terminals for Vcc and GND are at the top left in the figure, and the positive connection is at the input and output to the front to the viewer.

Figure 3: Efficiency at 8A Output

Figure 3: Efficiency at 8A Output

The minimum adjustable voltage is 1.25V, due to the reference voltage of the switching regulator. Our voltage display starts at approx. 3.5V. It is small, but works very accurately. To get as much power as possible to the consumer, the leads should not be too thin and too long. The potentiometer has an additional switch, with which the output can be switched voltage-free.

The output DC voltage is overlaid by a slight high frequency noise signal, but this is irrelevant for our application. Only for the direct supply of controller applications an additional filter stage is helpful.

The energy supplier for the controller

Now the module is only a converter for DC voltage, but not a real current source. So we need a source, which should be able to supply a voltage of 12V upwards as well as full currents of up to 12A. Without major changes to the device, a car battery or an old computer power supply can be used. The former has only limited resources, except when the engine is running, while the latter is supplied from the mains. Since we need voltages up to approx. 12V (15V maximum) to operate our thermocouples, both versions are sufficient.

If you want to process higher voltages, up to 32V, on the input side, you need appropriate transformers, a rectifier and a saturated filter capacitor. So much only as a view on possible extensions and the applicability of the controller module for other purposes. Real transformers for halogen lighting are a good tip for this. To increase the voltage to 24V AC, you can connect 2 identical transformers in series and achieve output DC voltages of up to about 33V. Also transformers from old overhead projectors deliver 24V/10A. But be careful that the secondary coil is really galvanically separated from the mains winding. This should be checked and confirmed by an electrician. If the two windings are conductively connected (autotransformer), there is a danger to life if they are touched!

The active cooling of the controller

The maximum converted power for our planned applications is 12V - 8A = 96W. That is 88% of the supplied power, of which 12% has to be dissipated as heat, and that is about 13 watts. It is obvious that the small heatsinks on the board cannot manage this, . Therefore we need active cooling by virtual airflow. This is generated by the fan for the Raspi or simply a small PC fan from a "stone-age" PC from the time when these parts were only 4 by 4 cm (the fan of course, not the PC).

However, constantly running fans cause unrest, acoustically and with the air masses at the work desk. Therefore, a temperature control was needed. Of the three solutions, I'll present the two most practical ones today.


An AT-Tiny13A serves as a controller. The sleepers can be pre-set by program.


A Schmitt trigger with the dual operational amplifier LM358 switches the motor temperature-dependent.


The NobellSolution with an Amica V2 supplies the value of the current intensity at the output of the controller circuit and optionally takes over the digital signal of the solution B.

Solution A I discarded for the blog because simply too many requirements would have to be met to implement it. ATMEL software, programming in AVR assembler, burning the ATTiny13 differs from the Arduino method, different SPI connector and a suitable USB converter would be necessary and alone already topic for some blogs. Those who nevertheless have an interest in the solution A should be this address , from which the approach B was derived in terms of circuitry.

So solution B as a solid basic function expandable by an ESP8266 in any version as a noble version C. Because this has only one analog input, we still need the LM358 as a temperature worker, which provides a ready digital signal. Of course, an alternative for both together would be the ESP32 or an analog multiplexer connected via I2C to the ESP8266. This could then measure voltage, current, power, energy and temperature... - OK, that's it - let's stay on the patch with solutions B and C.

The temperature sensor

We have just ruled out an ESP32 for use as a measuring servant as excessive. The same applies to the sensor. A DS18B20 from Dallas would be manageable even by the Amica V2, but we do not want to measure temperatures, but only determine when a motor must be switched on and off again. A simple NTC resistor is sufficient for this. Negative Temperature Coefficient means that the resistance value decreases with increasing temperature, and it decreases exponentially. In series with a fixed resistor R1 of 100 kΩ, this voltage divider circuit provides us with a temperature dependent voltage at point A. You can find the point in the circuit diagram of the controller a bit further down in the text. A following Schmitt trigger, which we built up from one half of the operational amplifier LM358, compares this voltage with a reference voltage, which the other half together with the trimmer potentiometer provides us at point B.

Although there would be a complete module already equipped with a comparator (comparator) LM393, but it has a significant disadvantage. This is the LM393, which works as a sensitive comparator without hysteresis. This would lead to the fan being switched off and on in quick succession for even the smallest temperature fluctuations here. A proper cooling effect could not be achieved with this. Figures 4 and 5 demonstrate this.

Figure 4: Switching behavior Comparator

Figure 4: Switching behavior Comparator

Figure 5: Switching behavior Comparator Zoom

Figure 5: Switching behavior Comparator Zoom

Because the voltage change at A takes place only slowly, the flutter around the switching point would be a permanent state. We can't use something like that.

I therefore have the KY-013 Thermistor Temperature Sensor Module which lives on its little board without a comparator. Nevertheless, we have to be tricky with the connection, because there is a fixed resistor of 10kΩ on this board, which we have to bypass, at least circuit-wise.

You can see the complete circuit here. The original parts and their connections are shown. We then come to the temperature controller. As always, there is a more readable plan than PDF-File for download.

Figure 6: Circuit Converter

Figure 6: Circuit Converter

Our thermostat also draws its energy from the connection of the external voltage source. In addition to the temperature signal to E, the circuit also supplies +12V for the supply of external fan motors and the +5V for an optional ESP8266. Of course, it also switches the fan motor. The very accurate digital voltmeter shows the output voltage of the build-up.

Here is also the wiring diagram for the thermostat. On my PCB Design the points E and F are still connected by the jumper J. As a result, the switching transistor BC337 is directly driven. If J is opened, then the signal at E can be fed to the ESP8266. The switching signal of the controller is then fed in at point F, as in the above general view. The ESP8266 then decides when the fan should (re)run and for how long. The LM358 is also supplied with Vcc = 12V. The LM78L05 can deliver 100 mA.

Figure 7: Thermostat with LM358

Figure 7: Thermostat with LM358

The NTC resistor has a value of around 100kΩ at 25 °C. With a fixed resistance of also 100kΩ, we set the voltage at A to this temperature. In order to bypass the useless fixed resistance of 10kΩ on the NTC board, we use only the terminals S and GND from the NTC board, between them is the NTC. Our fixed resistance of 100kΩ is on the controller board. There are also help and tips on how to make the circuit. How the whole thing works let's discuss it afterwards.

Making the temperature controller circuit

The circuit can be produced on a perforated grid board. The conductor tracks are made by solder bridges between the pins, or by short wires.

However, the construction is simpler if you produce a printed circuit. This can be done, for example, with the help of a laser printout of the Template, which you then place on a board laminated on one side and transfer to the copper layer with an iron at the highest level.

Figure 8: Therm Switch for Fan Motor-PrintTemplate

Figure 8: Thermal switch for fan motor - Print template

How to do this exactly, I have described here. After that, the board is etched, drilled, cut to size and cleaned with a solvent (for example, acetone). Finally, the assembly follows according to the following plan.

Figure 9: Thermoswitch for fan motor equipping

Figure 9: Thermal switch for fan motor assembly

How does the circuit work?

With the trim potentiometer on our board, the operating point of the thermostat is set. The 82kΩ resistor provides a hysteresis by coupling the output level to the positive input of the operational amplifier. This means that at a lower threshold voltage at point A (BY=4.72V, yellow curve), the output (blue curve) jumps to a value around 10V and at a higher input value (AY=6.74V) back to 0V. The following graph shows this. For the demonstration, an a sinusoidal voltage is applied to the point A instead of the NTC voltage divider in order to obtain a periodic signal for the display. The positive feedback leads not only to a shifted switching behavior, but also to clear, sharp switching edges. The comparison with Figures 4 and 5 clearly shows this (curve colors are reversed!)

Figure 10: Switching levels and hysteresis

Figure 10: Switching stages and hysteresis

The NTC value decreases with increasing temperature. As a result, the voltage at point A in the circuit also decreases. If the switching threshold of 4.72V is reached, the output of the operational amplifier tilts to 10V, the transistor becomes conductive and the motor starts. As a result of cooling, the temperature of the cooling plates decreases, the NTC value and the voltage at A increase. When the upper threshold voltage of 6.74V is reached, the output tilts to 0V, the transistor locks and the motor stops. Through hysteresis the heat sink is almost supercooled and thus the next active phase of the fan is postponed. Because the threshold voltages are far apart, no fluttering occurs at the switching point, which can also cause high-frequency interference.

The range of the two threshold voltages can be shifted by the reference voltage from the trim potentiometer. The temperature range is thus adjusted. One half of the operational amplifier makes this reference voltage available from the trimmer with low impedance at point B, so that it cannot be retroactively influenced by the switching processes.

The optional current display function with the ESP8266

The measurement of the output current strength happens with the Hall sensor module ACS712 whose current-sensitive chip is an ACS712T-ELC20A chip. Deviating from the data sheet, I measured a sensitivity of 60mV per ampere. The measuring range is +/-20A.

When measuring the current strength with a Hallsensor the current is not passed through the sensor, but past it. The magnetic field of the electric current passes through the sensor and causes a voltage to build up there, which is directly proportional to the current strength. By the way, the "hall" in the sensor name has nothing to do with echo, but goes back to Edwin Hall, after whom the effect is named.

In addition to the Hall sensor itself, our chip also contains an amplifier and a level adjustment, which sets the zero point of the current measurement to the value of half the supply voltage of the chip. For us, this is 3.30V : 2 = 1.65V. Per ampere, this voltage is increased by 60 Mv, or, if the current flows in the opposite direction, decreased. The MicroPython program in the ESP8266 knows this and converts the voltage difference into the current strength. Unfortunately, the linearity of the ESP8266 is not particularly good, so that despite the accuracy of the ACS712, the current strength is loaded with an error of up to 10%. With a separate converter, such as the ADS1115 type, more accurate results could be obtained. However, the question of proportionality then arises again.


Software used:

For flashing and programming the ESP32:

Thonny or



Firmware used:


Please choose a stable version

MicroPython programs

Links to the programs and modules can be found in the text.

MicroPython Language Modules and Programs

For the installation of Thonny you will find a detailed instructions. In it there is also a description such as the MicropythonFirmware on the ESP chip burn opens.

MicroPython is an interpreter language. The main difference to the Arduino IDE, where you always and exclusively flash entire programs, is that you only have to flash the MicroPython firmware to the ESP32 once at the beginning, before the controller understands MicroPython instructions. You can use Thonny, µPyCraft or use it. For Thonny I have the process here described below.

As soon as the firmware is flashed, you can chat casually with your controller in a dialogue, test individual commands and immediately see the answer without having to compile and transfer an entire program beforehand. This is exactly what bothers me about the Arduino IDE. You simply save a lot of time if you can test simple tests of the syntax and the hardware up to trying out and refining functions and entire program parts in advance via the command line before you a program of knitting from it. For this purpose, I also like to create small test programs again and again. As a kind of macro, they summarize recurring commands. From such program fragments, entire applications sometimes develop.


If you want the program to start autonomously when the controller is switched on, copy the program text into a newly created blank file. Save this file as in the workspace and upload them to the ESP chip. The next time you reset or turn on the program starts automatically.

Testing programs

Programs are started manually from the current editor window in the Thonny IDE using the F5 key. This is faster than clicking on the start button or using the menu Run. Only the modules used in the program must be in the flash of the ESP8266.

In the meantime, Arduino IDE again?

If you want to use the controller together with the Arduino IDE again later, just flash the program in the usual way. However, the ESP32/ESP8266 then forgot that he ever spoke MicroPython. Conversely, any Espressif chip that contains a compiled program from the Arduino IDE or the AT firmware or LUA or ... can be easily provided with the MicroPython firmware. The process is always like here described below.

Display in large numbers on the OLED display

The advantage of an OLED display is clearly given by the flexible display of text and graphics. We use this to implement the display of the amperage not with the poplige 10x8 pixel characters, but with neatly readable digits. For this purpose, we will port a Windows character set to an OLED character set and extract the required characters from it into a module. Both are based on CPython and MicroPython. CPython was created together with Thonny installed, because Thonny is written in Python and needs the CPython environment to make it work at all. Of course, we can also write CPython programs in Thonny (or another editor) and then start them from the PowerShell. This is exactly what we will do once our character set is converted.

Clone Windows TTF character set

To transfer a vector character set from Windows to pixel format, we use a freeware by Peter Hinch, which is subject to the MIT License. Her name is micropython-font-to-py and will be downloaded as a ZIP file from Downloaded Git hub. For the installation I created the directory _fonts in the root directory of my hard disk. By the way, this and everything else also works together with a USB flash drive.

file did I get in F:\_fonts stored and unpacked there as well. I have created the resulting directory in font2py rechristened, I like shorter pathnames. Now let's go to this directory. The two Python programs and we will use it soon. Before that, we will create a directory source to.

Figure 11: Charset 01

Figure 11: Charset 01

Now open the font folder of Windows, C:\Windows\Fonts. Look for the clearest possible written form and copy the file to the sources directory. I got here impact.ttf alternatively chosen.

Figure 12: Charset 02

Figure 12: Charset 02

The next two steps are done in a PowerShell window. We open the context menu by pressing Shift (Shift) and a Right-click click on the folder font2py and choose Open the PowerShell window here. A you show us that we are in the right directory. Then we issue the following command:

.\ F:\_fonts\font2py\quellen\impact.ttf 24 -f

Please note that the command is marked with a ".\" must be initiated so that it is executed in the desired path environment.

Figure 13: Charset 03

Figure 13: Charset 03

We have just converted the character set Impact with a character height of 24 pixels (including sublengths) into a Python file. switch -f ensures that all characters are initially brought to the same width, including those of proportional character sets. This is important, because otherwise there will be a mess of characters in the next step when dividing the strings.

We can save space if we make only the characters that we really need available from the entire character set. We specify these characters between quotation marks and direct the output to the file impact24.txt to.

.\ impact24 "0123456789,-AVW" > impact24.txt

Figure 14: Charset 04

Figure 14: Charset 04

The content of this file looks something like this:

Figure 15: Charset text

Figure 15: Charset text

On this basis, we are now finally creating a module that we can integrate into programs that use OLED displays.

Let's start Thonny and go to the working directory F:\_fonts\font2py.

Charset finishing

Figure 16: Charset finishing

We create a new program window via File - New, copy the text of the Program listings of go there and save the file under this name after the variables path, file and chars have been adjusted. chars is assigned the same string content as it is assigned when calling was used.


Please note that the "\" must be specified twice in the path specification. This cancels the special meaning of the "\" in strings.

 import sys
 def readln():
     while 1:
         if a>10 and a<126:
         elif a==10:
             for i in rank(3):
     return s
 f=open(path+file+".txt", "s")
 # Read header data and get character height and width
 for j in rank(3):
     line = readln()
 pos1=line.find("width ")
 # now read the character info
 for z in rank(height):
 for i in rank(len(chars)):
     for z in rank(height):
         if new>load:
     load=(load+2 if load < b else load)
     for z in rank(height):
     print('   ('+beaches(load)+', # Characters: '+chars[i])
     f.write('   ('+beaches(load)+', # Characters: '+chars[i]+'\n')
     for z in block:
         print(' 0b'+z+',')
         f.write(' 0b'+z+',\n')
     print('   ),')
     f.write(' ),\n')
We do not start the program in Thonny, but on the PowerShell.


Figure 16: Charset 05

Figure 17: Charset 05

The program runs on the PC, not in the ESP8266. It cuts off a piece of the set character width for each character from each line of the character definition and searches for the position of the last "#". To the maximum of these positions, 1 is added. Then all row strings are shortened to this length. This creates the original weighting of the characters for a balanced typeface.

Each "." the character definition is now next converted to a 0 and each # to a 1. By prefixing "0b", integers in binary notation are created from the pattern in the listing. Per character, they are combined into a tuple. The first value in each tuple is the character width. The tuples of all characters are displayed in the list number gathered.

The result is displayed as a file with the name saved. It is the desired module that can now be imported into any MicroPython program.

Figure 17: Charset 06

Figure 18: Charset 06

The following program shows the usage. will be added to the workspace of the project, here thermometers, copied, loaded into the flash of the ESP8266 and installed as a module in the Program imported. If you have not yet created a character set yourself, you can also download my 30s.

 from the machine import Pin, I2C, ADC, Timer
 from time import sleep, ticks_ms,sleep_ms
 from OLEDs import OLEDs
 import charset PLC cs
 # Pintranslator for ESP8266 boards
 # LUA-Pins D0 D1 D2 D3 D4 D5 D6 D7 D8
 # ESP8266 Pins 16 5 4 0 2 14 12 13 15
 # SC SD
 def putDigit(n,xpos,ypos,show=True):
     for row in rank(1,cs.height):
         for col in rank(width-1,-1,-1):
             c=cs.number[n][row] & 1<<col
     if show:
     return xpos+width+2
 def PutValue(value,unit,xpos,ypos,show=True):  
     for z in ws:
             print("unauthorized sign:",z)
         print("unauthorized unit:",unit)
     return pos
 def getRawADC():
     for i in rank(10):
     return s//10
 def calibrate():
     global UmidCnt
 def GetCurrent():
     return I
 while 1:
In addition to the module, the program for current measurement requires still and All essential actions for current recording and representation with the magnified character set are done by functions. The representation is effected by setting those pixels which correspond to a 1 in the binary representation of a pixel line. This is what makes the function putDigit (). It takes the digit and coordinates for the upper left corner of the representation, and returns the x value for the next output position. The putValue () function takes a metric and a device character. The value, integer or float, is parted. The function may then convert the decimal point into a comma, represents the digits, if possible, and also returns the next free x position.

Both functions are common to the optional show parameter. The default value True leads to immediate display. False only leads to changes in the frame buffering content, which is not displayed until the ().

The application must currentless , so that the calibration of the current measurement to zero works correctly. The function getCurrent() picks up a current strength value and converts the raw value into the unit Ampere.

Figure 18: Ampere Display

Figure 19: Ampere Display

Figure 19: Test setup for current measurement

Figure 20: Test setup for current measurement

With the photos of the test setup, where I am heating up an aluminum cuboid with a thermocouple and thus preparing to measure the specific power of the element, I say goodbye for today. We will deal with exactly this topic in the next article. Then we will deal with the rather unknown, but certainly not uninteresting side of Peltier elements in the measurement of heat flows.

Have fun building and operating the DC converter and of course programming the ESP8266.

Download contribution as PDF.

DisplaysEsp-32Basics electronicsProjects for beginners


veit burmester

veit burmester

Ich kann nur sagen SEHR GUT. Toll gemacht.
Vielleicht könnte man das Programm in micropython alternativ auch in der Arduino IDE besprechen.



Ein richtig anspruchsvolles Bastelprojekt mit vielen Hintergrundinformationen. Ich wollte mir das Thema “Platinen ätzen” sowieso schon länger einmal ansehen. Vielen Dank Herr Grzesina

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN