{"id":12734,"date":"2021-10-09T14:53:55","date_gmt":"2021-10-09T14:53:55","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/programming-the-esp32-with-micropython"},"modified":"2024-10-29T14:52:07","modified_gmt":"2024-10-29T14:52:07","slug":"programming-the-esp32-with-micropython","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython","title":{"rendered":"Programming the ESP32 with MicroPython"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this post<\/h2>\n\n<p>In my <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/micropython-switching-from-arduino\" target=\"_blank\" rel=\"noopener\">last post,<\/a> I covered the basics of MicroPython. I showed how to install uPyCraft and Thonny and how to upload programs to the ESP32. However, I have only briefly discussed how you control the many functions of the ESP32 with MicroPython. I now want to close this gap. In particular, I will highlight the differences to Arduino \/ C++.<\/p>\r\n\r\n<p>I will cover the following topics:<\/p>\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<ul>\r\n<li><a href=\"#GPIOs_schalten\">Short repetition: how to switch GPIOs<\/a><\/li>\r\n<li><a href=\"#AD_Wandler\">Reading the ADCs<\/a><\/li>\r\n<li><a href=\"#PWM\">Pulse width modulation<\/a><\/li>\r\n<li><a href=\"#AnalogPins\">Analog pins<\/a><\/li>\r\n<li><a href=\"#Zeitfunktionen\">Time functions<\/a><\/li>\r\n<li><a href=\"#ExtInterrupts\">External interrupts<\/a><\/li>\r\n<li><a href=\"#Timer\">Timer<\/a><\/li>\r\n<\/ul>\r\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<ul>\r\n<li><a href=\"#I2C\">I2C<\/a><\/li>\r\n<li><a href=\"#ExtModule\">Adding external modules<\/a><\/li>\r\n<li><a href=\"#SPI\">SPI<\/a><\/li>\r\n<li><a href=\"#UART\">UART<\/a><\/li>\r\n<li><a href=\"#DeepLightSleep\">Deep and light sleep<\/a><\/li>\r\n<li><a href=\"#TouchPins\">Touch pins<\/a><\/li>\r\n<li><a href=\"#HallSensor\">Hall sensor<\/a><\/li>\r\n<\/ul>\r\n<\/div>\n<\/div>\n\n<p>I will only very briefly discuss <a href=\"#WiFi_BT\">Wi-Fi and Bluetooth<\/a>.<\/p>\r\n\n<h2 class=\"wp-block-heading\">Pinout of the ESP32<\/h2>\n\n<p>I have explained the pins of the ESP32 and their functions in detail <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-arduino-code\" target=\"_blank\" rel=\"noopener\">here<\/a>. The pinout is:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-1024x497.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"497\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-1024x497.png\" alt=\"Pinout of the ESP32 with MicroPython\" class=\"wp-image-12530\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-1024x497.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-300x146.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-768x373.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-1536x746.png 1536w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython-1320x641.png 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/ESP32_mPython.png 1823w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Pinout of the ESP32 with MicroPython<\/figcaption><\/figure>\n\n<p>The only difference to the pin assignment in the Arduino implementation is the position of the I2C pins. <a id=\"GPIOs_schalten\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Short repetition: Switching and reading the GPIOs<\/h2>\n\n<p>Since I covered switching of GPIOs in detail in the last post, there is only a compact repetition here. A simple blink program on the ESP32 with MicroPython looks like this:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"blink.py\" data-enlighter-title=\"blink.py\">from machine import Pin\r\nfrom time import sleep\r\nled = Pin(18, Pin.OUT)\r\nwhile True:\r\n    led.value(not led.value())\r\n    sleep(0.5)<\/pre>\r\n\n<p>The big difference to C++ is that the pins are defined as objects. Whether a pin acts as input or output is determined with <code>Pin.OUT<\/code> or <code>Pin.IN<\/code>. You can read the GPIO level with <code>pinname.value()<\/code>. You can switch the pin using <code>pinname.value(0\/1)<\/code>. In addition, you can connect internal pull-up or pull-down resistors if they are available at the respective pin. You would define a pin for reading a button state like this:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">buttonPin = Pin(18, Pin.IN, Pin.PULL_DOWN) # button Pin = GPIO18<\/code>&nbsp; <a id=\"AD_Wandler\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Read the ADCs of the ESP32 with MicroPython<\/h2>\n\n<p>First of all: As powerful as the ESP32 is, as bad are its A\/D converters. They generate quite a bit of noise, and what&#8217;s worse, they are not linear. I have described this in detail <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-arduino-code#analog_pins\" target=\"_blank\" rel=\"noopener\">here<\/a>. <\/p>\r\n<p>Now for the code:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">from machine import ADC, Pin\r\nfrom time import sleep\r\n\r\nadc = ADC(Pin(32))          \r\n\r\nadc.atten(ADC.ATTN_11DB)    # ATTN_11DB, ATTN_6DB, ATTN_2_5DB, ATTN_0DB (default)\r\nadc.width(ADC.WIDTH_12BIT)  # WIDTH_12BIT (default), WITDTH_11BIT, WIDTH_10BIT, WIDTH_9BIT\r\n\r\nwhile True:\r\n    val = adc.read()\r\n    print(\"Raw ADC value:\", val)\r\n    sleep(1)<\/pre>\r\n\n<p>In order to use a pin as an A\/D converter input, you first create an object. The default resolution is 12 bits. Alternatively, you can set with <code>adc.width()<\/code> 11, 10 or 9 bits. With <code>adc.atten(ADC.ATTN_XDB)<\/code> you set the attenuation and thus determine the input voltage range:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/ADC_atten_ESP32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"919\" height=\"180\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/ADC_atten_ESP32.png\" alt=\"Parameter selection for attenuation \" class=\"wp-image-12477\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/ADC_atten_ESP32.png 919w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/ADC_atten_ESP32-300x59.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/ADC_atten_ESP32-768x150.png 768w\" sizes=\"auto, (max-width: 919px) 100vw, 919px\" \/><\/a><figcaption class=\"wp-element-caption\">Parameter selection for attenuation <\/figcaption><\/figure>\n\n<p>This data is from the MicroPython <a href=\"https:\/\/docs.micropython.org\/en\/latest\/esp32\/quickref.html\" target=\"_blank\" rel=\"noopener\">Quick Reference<\/a>. In my own measurements, the A\/D converter overflowed in the maximum range at about 3.15 volts.<a id=\"PWM\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Pulse width modulation<\/h2>\n\n<p>To produce pulse width modulation (PWM), you create a PWM object for a specific pin and pass the frequency and duty cycle. With the Arduino implementation of the ESP32 you can set the resolution (see <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-arduino-code#PWM\" target=\"_blank\" rel=\"noopener\">here<\/a>). If you program the ESP32 with MicroPython, only 10 bit resolution is available (0-1023). Here is an example:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"pwm.py\" data-enlighter-title=\"pwm.py\">from machine import Pin, PWM\r\n\r\npwm16 = PWM(Pin(16))     # create PWM object from GPIO 16\r\npwm16.freq(1000)         # 1 kHz\r\npwm16.duty(256)          # duty cycle = 256\/1024 * 100 = 25%\r\n\r\n# pwm16 = PWM(Pin(16), freq=1000, duty=256) # short Version<\/pre>\r\n\n<p>Other functions are:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">pwm16.freq()             # get current frequency\r\npwm16.duty()             # get current duty cycle\r\npwm16.deinit()           # turn off PWM on the pin<\/pre>\r\n\n<p>The maximum PWM frequency is 40 MHz. However, due to the timer frequency of the ESP32 (80 MHz), you only get the full 10 bit resolution up to the following PWM frequency:&nbsp;<\/p>\r\n\n<p><\/p>\r\n<p><p class=\"ql-center-displayed-equation\" style=\"line-height: 39px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-fd0abfe2f4cc6b377d2aec37832c6cf6_l3.png\" height=\"39\" width=\"302\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#91; &#102;&#95;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#109;&#97;&#120;&#44;&#32;&#102;&#117;&#108;&#108;&#32;&#114;&#101;&#115;&#125;&#125;&#61;&#92;&#102;&#114;&#97;&#99;&#123;&#56;&#48;&#48;&#48;&#48;&#48;&#48;&#48;&#125;&#123;&#50;&#94;&#123;&#49;&#48;&#125;&#125;&#61;&#55;&#56;&#49;&#50;&#53;&#92;&#59;&#92;&#116;&#101;&#120;&#116;&#123;&#91;&#72;&#122;&#93;&#125; &#92;&#93;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p><\/p>\r\n\n<p>For larger frequencies, you can calculate the actual resolution as follows:<\/p>\r\n\n<p><p class=\"ql-center-displayed-equation\" style=\"line-height: 43px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-463e7e41ce62932c68909f324b85b306_l3.png\" height=\"43\" width=\"126\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#91; &#92;&#116;&#101;&#120;&#116;&#123;&#114;&#101;&#115;&#125;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#56;&#48;&#48;&#48;&#48;&#48;&#48;&#48;&#125;&#123;&#102;&#125; &#92;&#93;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p><\/p>\r\n\n<p>For example, if you choose 20 MHz as frequency, you only have a resolution of 4, i.e. you can set the duty cycles 0, 25, 50 and 75% by passing values in the ranges 0-255, 256-511, 512-767 or 768-1023 to <code>pwm.duty()<\/code>.<a id=\"AnalogPins\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Analog Pins <\/h2>\n\n<p>You can pick off a real analog signal between 0 and 3.3 V at pins 25 and 26. The resolution is 8 bits. Here&#8217;s how it works:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"dac.py\" data-enlighter-title=\"dac.py\">from machine import Pin, DAC\r\ndac = DAC(Pin(25)) \r\ndac.write(128)       # voltage = 3.3 * 128\/256<\/pre>\r\n\n<p>The drawback: the output voltage is linear to the value passed to dac.write(), but the slope of the straight line is not quite right. In my measurements, the range was 0.086 to 3.18 volts instead of 0 to 3.3 volts (see <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-arduino-code#analog_pins\" target=\"_blank\" rel=\"noopener\">here<\/a>).<a id=\"Zeitfunktionen\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Time functions<\/h2>\n\n<p>The equivalents to <code>delay()<\/code> and <code>delayMicroseconds()<\/code> when using ESP32 with MicroPython are <code>sleep_ms()<\/code> or <code>sleep_us()<\/code>. In addition, you can use <code>sleep()<\/code> which takes seconds as parameter.<\/p>\r\n<p><code>millis()<\/code> and <code>micros()<\/code> are called <code>ticks_ms()<\/code> and <code>ticks_us()<\/code> in MicroPython. With <code>ticks_diff()<\/code> you can determine time spans. Here is a small example:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import time\r\n\r\nstart_ms = time.ticks_ms() \r\nstart_us = time.ticks_us()\r\nprint(\"Millisecs: \", start_ms)\r\nprint(\"Microsecs: \", start_us)\r\ntime.sleep(3)\r\ndelta = time.ticks_diff(time.ticks_ms(), start_ms)\r\nprint(\"Delta =\", delta)<\/pre>\r\n\n<h3 class=\"wp-block-heading\">The time module<\/h3>\n\n<p>With the time module, you can query the current time and the seconds since 01\/01\/2000, 00:00 o&#8217;clock. You can calculate the frequently used <a href=\"https:\/\/www.unixtimestamp.com\/\" target=\"_blank\" rel=\"noopener\">Unix time<\/a> from this.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"local_and_unixtime.py\" data-enlighter-title=\"local_and_unixtime.py\">import time\r\n\r\nnow = time.localtime()           # query local time as tuple\r\nprint(now)\r\nprint(now[0])                    # print element 0\r\nnow_secs = time.time()           # secs since 01\/01\/2000, 00:00\r\nnow_unix = now_secs + 946681200  # unixtime: secs since 01\/01\/1970, 00:00 \r\nprint(now_unix)<\/pre>\r\n\n<p>&#8220;localtime&#8221; is used as a tuple in the format:<\/p>\r\n<p>(year, month, day of the month, hours, minutes, seconds, day of the week, day of the year)<\/p>\r\n<p>The elements are integers. Here&#8217;s what the output looks like:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"645\" height=\"83\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/localtime.png\" alt=\"\" class=\"wp-image-12485\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/localtime.png 645w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/localtime-300x39.png 300w\" sizes=\"auto, (max-width: 645px) 100vw, 645px\" \/><figcaption class=\"wp-element-caption\">Output of local_and_unixtime.py<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\">The RTC class<\/h3>\n\n<p>If you want to set the date and time of the ESP32, then you have to use the RTC class. The time tuple is structured a little differently:<\/p>\r\n<p>(year, month, day of the month, day of the week, hours, minutes, seconds, microseconds).<\/p>\r\n<p>On the day of the week, it should be noted that Monday is 0 and Sunday is 6. When setting the time, the day of the week is irrelevant. MicroPython will correct the day of the week if it is wrong.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">from machine import RTC\r\n\r\nrtc = RTC()\r\na = rtc.datetime()\r\nprint(a)\r\nnew_time= (2030, 12, 24, 0, 20, 35, 0, 0)\r\nrtc.init(new_time)\r\na = rtc.datetime()\r\nprint(a)<\/pre>\r\n\n<p>We learn: December 24th, 2030 is a Tuesday:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"97\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/rtc.png\" alt=\"\" class=\"wp-image-12494\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/rtc.png 720w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/08\/rtc-300x40.png 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/figure>\n\n<p>In addition, we learn: the time is set according to the system time of the computer when booting the ESP32.<\/p>\r\n<p>Actually, the RTC class can do much more, e.g. alarm interrupts. However, this does not seem to have been implemented (yet) for the ESP32.<a id=\"ExtInterrupts\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">External interrupts<\/h2>\n\n<p>External (pin change) interrupts can be set up for each GPIO. This works similarly to the Arduino. The following program triggers an interrupt when a button attached to GPIO 23 is pressed. An LED on the GPIO 18 then lights up:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"interrupt.py\" data-enlighter-title=\"interrupt.py\">from machine import Pin\r\nfrom time import sleep\r\n\r\nled = Pin(18, Pin.OUT)\r\nbtn = Pin(23, Pin.IN, Pin.PULL_DOWN)\r\n\r\nbtn_pressed = False\r\n\r\ndef btn_handler(btn):\r\n    global btn_pressed\r\n    btn_pressed = True\r\n    \r\nbtn.irq(trigger=Pin.IRQ_RISING, handler=btn_handler)\r\n    \r\nwhile True:\r\n    if btn_pressed:\r\n        led.value(1)\r\n        sleep(1)\r\n        led.value(0)\r\n        btn_pressed = False<\/pre>\r\n\n<p>A few explanations:<\/p>\r\n\n<ul>\r\n<li>With <code>btn.irq()<\/code> the pin &#8220;btn&#8221; gets an interrupt function.\r\n<ul>\r\n<li><code>trigger=Pin.IRQ_RISING<\/code> causes the interrupt to be triggered by the rising edge.\r\n<ul>\r\n<li>In addition, there is &#8211; surprise! &#8211; &nbsp; also <code>IRQ_FALLING<\/code>.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><code>handler=btn_handler<\/code> defines the interrupt handler, i.e. the function that is called when the interrupt is triggered (without parentheses).<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li>You must pass the pin object to the interrupt handler.<\/li>\r\n<li>In the handler function, btn_pressed must be set as global, otherwise Python considers the variable to be local.<a id=\"Timer\"><\/a><\/li>\r\n<\/ul>\r\n\n<h2 class=\"wp-block-heading\">Programming the timers of the ESP32 with MicroPython<\/h2>\n\n<p>Timers trigger internal interrupts. The ESP32 has 4 hardware timers with the ID 0 to 3, and they are easy to program. No comparison to the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/timer-and-pwm-part-1-8-bit-timer0-2\" target=\"_blank\" rel=\"noopener\">timers of the ATmega328P<\/a>! Here is an example program that flashes 2 LEDs in asynchronously:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"timer.py\" data-enlighter-title=\"timer.py\">from machine import Pin, Timer\r\n\r\nled0 = Pin(18, Pin.OUT)\r\nled1 = Pin(19, Pin.OUT)\r\n\r\ndef handler_0(tim0):\r\n    led0.value(not led0.value())\r\n    \r\ndef handler_1(tim1):\r\n    led1.value(not led1.value())\r\n\r\ntim0 = Timer(0)\r\ntim0.init(period=973, mode=Timer.PERIODIC, callback=handler_0)\r\n\r\ntim1 = Timer(1)\r\ntim1.init(period=359, mode=Timer.PERIODIC, callback=handler_1)\r\n<\/pre>\r\n\n<p>I think the code is almost self-explanatory:<\/p>\r\n<ul>\r\n<li>Timer is a class of the machine module.<\/li>\r\n<li>First you create a timer object and pass the timer ID (0 to 3).<\/li>\r\n<li><code>init()<\/code> expects three arguments:\r\n<ul>\r\n<li><code>period<\/code> is the timespan in milliseconds until the timer interrupt is triggered.<\/li>\r\n<li><code>mode<\/code> is either <code>PERIODIC<\/code> or <code>ONE_SHOT<\/code>.<\/li>\r\n<li><code>callback<\/code> defines the function (interrupt handler) that will be called when the timer interrupt is triggered.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li>As with external interrupts, you must pass the causing object to the handlers (tim0 and tim1 in this case).<\/li>\r\n<\/ul>\r\n<p>Isn&#8217;t that wonderfully easy?<\/p>\r\n<p>As an alternative to periods, you can also pass the frequency in Hertz, e.g.: <code>freq = 20000<\/code>.<\/p>\r\n\n<h3 class=\"wp-block-heading\">Watchdog timer<\/h3>\n\n<p>The watchdog timer of the ESP32 is not particularly convenient, but easy to program. You create a WDT object and pass the timeout in milliseconds. Once started, it can no longer be stopped. It&#8217;s a bit unusual that you can only prevent the reset by a wdt.feed(). Other MCUs extend the timeout with any statement.<\/p>\r\n<p>Here is an example:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"wdt.py\" data-enlighter-title=\"wdt.py\">from machine import WDT\r\nfrom time import sleep\r\n\r\nwdt = WDT(timeout=5000)\r\n\r\nprint(\"Hi, I have just booted\")\r\n    \r\nwhile True:\r\n    sleep(1)\r\n    print(\"Still there...\")\r\n    #wdt.feed()<\/pre>\r\n\n<p>You will see that the ESP32 resets after 5 seconds. If you uncomment <code>wdt.feed()<\/code>, that doesn&#8217;t happen. By the way, the minimum timeout is 1 second.<a id=\"I2C\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">I2C<\/h2>\n\n<p>The ESP32 has two I2C interfaces. I had explained this in detail <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/how-to-use-the-i2c-interfaces-of-the-esp32\" target=\"_blank\" rel=\"noopener\">here<\/a>. In MicroPython, the interfaces are distinguished by their index (0 or 1). Interface 0 is assigned to GPIOs 18 (SCL) and 19 (SDA). Interface 1 is assigned to GPIOs 25 (SCL) and 26 (SDA). You can change the assignment and optionally specify the frequency.&nbsp; You do this when you create your I2C object.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"i2c_definition.py\" data-enlighter-title=\"i2c_definition.py\">from machine import I2C, Pin # I2C is a class in machine\r\n\r\ni2c = I2C(0)   # simplest definition, SDA=GPIO19, SCL=GPIO18\r\ni2c = I2C(1)   # SDA=GPIO26, SCL=GPIO25\r\ni2c = I2C(0, scl=Pin(16), sda=Pin(17))  # new pin assignment\r\ni2c = I2C(1, scl=Pin(12), sda=Pin(14), freq=400000) # new frequency and pin assignment<\/pre>\r\n\n<p>Scanning for I2C addresses is easy with <code>scan()<\/code>. The function returns a list of I2C addresses in decimal numbers:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/i2c_scan.png\"><img loading=\"lazy\" decoding=\"async\" width=\"745\" height=\"238\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/i2c_scan.png\" alt=\"ESP32 with MicroPython - i2c.scan() \" class=\"wp-image-12565\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/i2c_scan.png 745w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/i2c_scan-300x96.png 300w\" sizes=\"auto, (max-width: 745px) 100vw, 745px\" \/><\/a><figcaption class=\"wp-element-caption\">i2c.scan() in action<\/figcaption><\/figure>\n\n<p>You write into registers via I2C with the function <code>writeto_mem()<\/code> and read them with <code>readfrom_mem()<\/code> or <code>readfrom_mem_into()<\/code>. You need to pass the I2C address and the register number to these functions. The data you write or query must be of type bytearray, even if it is only one byte. Here&#8217;s how the functions are used:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># writing to registers:\r\ndata = bytearray([128, 255]) # just an example\r\ni2c.writeto_mem(I2C_ADDR, REG_ADDR, data)\r\n\r\n# reading from registers:\r\ndata = i2c.readfrom_mem(I2C_ADDR, REG_ADDR, 2) # read two bytes\r\n# or, alternatively:\r\ndata = bytearray(2)\r\ni2c.readfrom_mem_into(I2C_ADDR, REG_ADDR, data)<\/pre>\r\n\n<p>You often need to read 16-bit values from two 8-bit registers and then combine the individual values to form an integer. This can be done as in C++ with shift operators (<code>MSB&lt;&lt;8 | LSB<\/code>). <code>int.from_bytes(data, order)<\/code> is less cryptic. Data is a bytearray that contains the bytes to be assembled, order is either &#8220;big&#8221; or &#8220;little&#8221;. &#8220;big&#8221; means that the MSB (Most Significant Byte) is first, with &#8220;little&#8221; it is at the end.<\/p>\r\n<p>Then there is a small problem: how can MicroPython know whether the read data is signed or unsigned? With C++ you can specify that. The answer is: not at all, but you can easily solve this problem. For example, if you read a 16-bit signed integer((-2<sup>15<\/sup>) to (+2<sup>15<\/sup>-1), then the biggest positive value is 32767. Larger values are misinterpreted and actually negative. Because of the <a href=\"https:\/\/www.electronics-tutorials.ws\/binary\/signed-binary-numbers.html\" target=\"_blank\" rel=\"noopener\">two&#8217;s complement representation<\/a>, you just need to subtract 65536 (i.e.2<sup>16<\/sup>). This applies at least to the current implementation of MicroPython on the ESP32. There are also Python versions in which you can pass <code>int.from_bytes()<\/code> to <code>signed=true<\/code>.<\/p>\r\n\n<h4 class=\"wp-block-heading\">I2C example: Reading the MPU6050 on ESP32 with MicroPython <\/h4>\n\n<p>The following program provides the acceleration values, temperature and gyroscope data of an MPU6050. The example shows how compact MicroPython code can be.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"i2c_MPU6050.py\" data-enlighter-title=\"i2c_MPU6050.py\">from machine import I2C\r\nfrom time import sleep\r\n\r\nMPU_ADDR = 0x68\r\ni2c = I2C(0)\r\ni2c.writeto_mem(MPU_ADDR, 0x6B, bytearray([0])) # \"wake-up call\"\r\n\r\ndef byteToInt(bytePair):\r\n    intVal = int.from_bytes(bytePair, 'big') # \"big\" = MSB at beginning\r\n    if intVal &gt; 32767:                       # intVal is negative =&gt; 2^15\r\n        intVal -= 65536\r\n    return intVal\r\n    \r\n\r\nwhile True:\r\n    regVal = i2c.readfrom_mem(MPU_ADDR, 0x3B, 14)  # Read 14 bytes   \r\n    print(\"AccX =\", byteToInt(bytearray([regVal[0],regVal[1]]))) \r\n    print(\"AccY =\", byteToInt(bytearray([regVal[2],regVal[3]])))\r\n    print(\"AccZ =\", byteToInt(bytearray([regVal[4],regVal[5]])))\r\n    print(\"Temp =\", (byteToInt(bytearray([regVal[6],regVal[7]])))\/340.00+36.53)\r\n    print(\"GyrX =\", byteToInt(bytearray([regVal[8],regVal[9]])))\r\n    print(\"GyrY =\", byteToInt(bytearray([regVal[10],regVal[11]])))\r\n    print(\"GyrZ =\", byteToInt(bytearray([regVal[12],regVal[13]])))\r\n    print(\"***************\")\r\n    sleep(2)\r\n<\/pre>\r\n\n<p>First, the MPU6050 is woken up by writing a zero to its register 0x6B (&#8220;Powermanagement 1&#8221;). The measured values are available in fourteen registers, starting from 0x3B, and they are read in one go. 2 bytes each of the bytearray regVal form one of the 7 measured values.<\/p>\r\n<p>Most of the time, however, you will probably not want to deal with registers and therefore choose external modules. I come to that now.<a id=\"ExtModule\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Adding external (I2C) modules<\/h2>\n\n<p>First of all, there is a certain confusion of names here. You will find the terms module, library and package. In first approximation, the terms mean the same thing.<\/p>\r\n<p>For many components such as sensors, displays, ADCs, etc., hard-working people have written modules. To use them, you have to install them in most cases.<\/p>\r\n<p>If you work with Thonny, then it is best to use the package manager. Go to Tools \u2192 Manage Packages. Enter the name and search for PyPI. Select the package, install it, and you can immediately use it. This is similar to the library management in the Arduino IDE. Only the handling of example programs is less well solved. To get them, you have to go to the platforms where the packages are made available.<\/p>\r\n<p>However, there may also be modules that you cannot find via the package management. Maybe you programmed them yourself. In this case, take the file to be included, right-click on it in Thonny and select &#8220;Upload to \\&#8221;. Then you can use the classes and functions. <\/p>\r\n<p>uPyCraft does not have a package management. There, you open the file to be included and select &#8220;Download&#8221;. <a id=\"SPI\"><\/a>&nbsp;<\/p>\r\n\n<h2 class=\"wp-block-heading\">SPI<\/h2>\n\n<p>The ESP32 has four SPI interfaces, of which you can use two. They are called HSPI and VSPI and they are addressed via their IDs 1 and 2 respectively. By default, the following pins are assigned to the interfaces:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/SPI_pinout_ESP32-1024x236.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"236\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/SPI_pinout_ESP32-1024x236.png\" alt=\"SPI Pins of the ESP32\" class=\"wp-image-12533\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/SPI_pinout_ESP32-1024x236.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/SPI_pinout_ESP32-300x69.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/SPI_pinout_ESP32-768x177.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/SPI_pinout_ESP32.png 1142w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">SPI Pins of the ESP32<\/figcaption><\/figure>\n\n<p>You can easily change the pin assignment. The creation of SPI objects is similar to I2C. You can pass different parameters:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">from machine import Pin, SPI\r\n\r\nhspi = SPI(1) # use default Pins\r\nhspi = SPI(1, 20000000)\r\nhspi = SPI(1, baudrate=20000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))\r\nvspi = SPI(2, baudrate=40000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(15), mosi=Pin(16), miso=Pin(17))<\/pre>\r\n\n<p>When using the standard GPIOs, the baud rate can be up to 80 MHz. If you choose other GPIOs, the baud rate is limited to 40 MHz.<\/p>\r\n<p>Reading and writing to registers is also similar. The data is passed and received as bytearrays. Here is an example of how to use the most important functions:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">spi.read(5)             # read 5 bytes \r\nspi.read(5, 0xFF)       # read 5 bytes and write 0xFF\r\n\r\nbuf = bytearray(20)    \r\nspi.readinto(buf)       # read into the given buffer \r\nspi.readinto(buf, 0xFF) # read into the buffer and write 0xFF\r\n\r\nspi.write(buf)          # write buffer\r\nspi.write_readinto(buf_1, buf_2) # write buf_1 and read into the buf_2<\/pre>\r\n<p>&nbsp;<\/p>\r\n\n<h2 class=\"wp-block-heading\">UART (Serial)<\/h2>\n\n<p>The ESP32 has the three UART interfaces UART0, UART1 and UART2. By default, these are assigned to the following GPIOs:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/UART_GPIOs_ESP32-1024x162.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"162\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/UART_GPIOs_ESP32-1024x162.png\" alt=\"Standard GPIOs of the UART interfaces\" class=\"wp-image-12538\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/UART_GPIOs_ESP32-1024x162.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/UART_GPIOs_ESP32-300x47.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/UART_GPIOs_ESP32-768x122.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/UART_GPIOs_ESP32.png 1150w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Standard GPIOs of the UART interfaces<\/figcaption><\/figure>\n\n<p>When choosing the pins, you have to be a bit careful. You should not use the standard GPIOS for UART0 and UART1 (<a href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-arduino-code#UART\" target=\"_blank\" rel=\"noopener\">see also here<\/a>).<\/p>\r\n<p>Things repeat. Again, you first create a UART object, where you can pass several parameters. At least you have to pass the UART ID. Here is an example:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">from machine import UART\r\n\r\nuart1 = UART(1, baudrate=115200, tx=18, rx=19)<\/pre>\r\n\n<p>And here are a few &#8211; I think self-explanatory &#8211; statements:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">uart1.init(9600, bits=8, parity=None, stop=1) # standard settings\r\nuart1.read(7)        # read 7 characters, returns a bytes object, not bytearray\r\nuart1.read()         # read all available characters\r\nuart1.readline()     # read a line\r\nuart1.readinto(buf)  # read and store into buf\r\nuart1.write('xyz')   # write the 3 characters\r\nuart1.any()          # returns number of bytes available <\/pre>\r\n<a id=\"DeepLightSleep\"><\/a>\r\n\n<h2 class=\"wp-block-heading\">Deep and Light Sleep<\/h2>\n\n<p>To save power, the ESP32 has a light sleep and a deep sleep function. After a light sleep, the program picks up where it left off. A deep sleep causes a reset. The setting is very easy on the ESP32 with MicroPython. You can try the following program:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-group=\"light_deep_sleep.py\" data-enlighter-title=\"light_deep_sleep.py\">import machine, time \r\n\r\nif machine.reset_cause() == machine.DEEPSLEEP_RESET:\r\n    print(\"woke up from a deep sleep\")\r\n\r\nwhile True:\r\n    #machine.deepsleep(3000)\r\n    machine.lightsleep(3000)\r\n    print(\"woke up from a light sleep\")\r\n    time.sleep(0.1)<\/pre>\r\n\n<p>Without the small <code>time.sleep()<\/code> delay, <code>print()<\/code> did not work properly for me. Apparently, the ESP32 goes to sleep before the <code>print()<\/code> instruction is completely processed.<a id=\"TouchPins\"><\/a><\/p>\r\n\n<h2 class=\"wp-block-heading\">Touch Pins<\/h2>\n\n<p>The touch pins register capacities. Since the human body also has a certain capacity, the touch pins serve as touch sensors. Here&#8217;s how it works:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"touch.py\" data-enlighter-title=\"touch.py\">from machine import TouchPad, Pin\r\nfrom time import sleep\r\n\r\nt = TouchPad(Pin(32))\r\n\r\nwhile True:\r\n    t_val=t.read()\r\n    print(\"Touch value:\", t_val)\r\n    sleep(0.5)<\/pre>\r\n\n<p>The initial values (ESP32 used on a breadboard) were around 800 for me. When I touched the touch pin via a jumper cable, the values dropped below 100. <\/p>\r\n<p>A touch event can wake the ESP32 from both light and deep sleep. Here&#8217;s how it works:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import machine\r\nfrom machine import TouchPad, Pin\r\nimport esp32\r\nfrom time import sleep\r\n\r\nt = TouchPad(Pin(32))\r\nt.config(300)               # configure the threshold at which the pin is considered touched\r\nesp32.wake_on_touch(True)\r\n\r\nwhile True:\r\n    machine.lightsleep()    # put the MCU to sleep until a touchpad is touched\r\n    print(\"Woke up from light sleep\")\r\n    sleep(1)\r\n    print(\"Falling asleep again\")\r\n    sleep(0.1)              # you can try without this<\/pre>\r\n<a id=\"HallSensor\"><\/a>\r\n\n<h2 class=\"wp-block-heading\">Hall Sensor<\/h2>\n\n<p>The ESP32 has a <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/hall-sensors-and-reed-switches\" target=\"_blank\" rel=\"noopener\">Hall sensor<\/a> that detects magnetic fields. It is easy to read:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import esp32, time\r\n\r\nwhile True:\r\n    m = esp32.hall_sensor()\r\n    print(m)\r\n    time.sleep(2)<\/pre>\r\n<a id=\"WiFi_BT\"><\/a>\r\n\n<h2 class=\"wp-block-heading\">Wi-Fi<\/h2>\n\n<p>One of the great advantages of the ESP32 is the integrated WLAN. However, the topic is quite extensive and would go beyond the scope of this post. Maybe I&#8217;ll cover it in a later article.<\/p>\r\n<p>If you want to deal with the topic in more detail, then I recommend <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-micropython-web-server\/\" target=\"_blank\" rel=\"noopener\">this tutorial<\/a> as a starting point. There it is shown how to set up a web server with the ESP32 and how to then switch an LED via browser. The instructions worked wonderfully for me right away.<\/p>\r\n\n<h2 class=\"wp-block-heading\">Bluetooth<\/h2>\n\n<p>With Bluetooth, a distinction is made &#8211; among many other things &#8211; between Bluetooth Classic and BLE (Bluetooth Low Energy). You may know the classic version from the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/hc-05-and-hc-06-bluetooth-modules\" target=\"_blank\" rel=\"noopener\">HC-05 and HC-06 modules<\/a> or from my article about programming the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-arduino-code\" target=\"_blank\" rel=\"noopener\">ESP32 with Arduino code.<\/a> The advantage is the simple programming.<\/p>\r\n<p>The BLE variant, as its name suggests, is more energy-saving. More about the differences between Classic and BLE can be found <a href=\"https:\/\/electronicsinnovation.com\/bluetooth-low-energy-versus-classic-bluetooth\/\" target=\"_blank\" rel=\"noopener\">here<\/a>. Unfortunately, Classic Bluetooth is not (yet?) implemented in MicroPython. On the other hand, BLE is a somewhat more complex topic that would go beyond the scope here. And honestly, I have some learning to do on this topic as well.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\/D converters, I2C, timers, RTC, touch pins, etc.<\/p>\n","protected":false},"author":1,"featured_media":12574,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[543,575],"tags":[1241,1506,1044,1567,666,1566,1508,1542,1565,1503,973,1505,1502,1050],"class_list":["post-12734","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-boards-and-microcontrollers","category-software-and-tools","tag-a-d-converter","tag-deep-sleep-en","tag-esp32-en","tag-hall-sensor-en-2","tag-i2c-en","tag-interrupts-en","tag-light-sleep-en","tag-micropython-en","tag-rtc-en","tag-spi-en","tag-timer-en","tag-touch-en","tag-uart-en","tag-watchdog-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Programming the ESP32 with MicroPython &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\/D converters, I2C, timers, RTC, touch pins, etc.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Programming the ESP32 with MicroPython &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\/D converters, I2C, timers, RTC, touch pins, etc.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2021-10-09T14:53:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-29T14:52:07+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/Beitragsbild_ESP_MP.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1340\" \/>\n\t<meta property=\"og:image:height\" content=\"1339\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"Programming the ESP32 with MicroPython\",\"datePublished\":\"2021-10-09T14:53:55+00:00\",\"dateModified\":\"2024-10-29T14:52:07+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython\"},\"wordCount\":2372,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/Beitragsbild_ESP_MP.png\",\"keywords\":[\"A\\\/D converter\",\"deep sleep\",\"ESP32\",\"Hall Sensor\",\"I2C\",\"interrupts\",\"light sleep\",\"MicroPython\",\"RTC\",\"SPI\",\"timer\",\"Touch\",\"UART\",\"watchdog\"],\"articleSection\":[\"Boards and Microcontrollers\",\"Software and tools\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython\",\"name\":\"Programming the ESP32 with MicroPython &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/Beitragsbild_ESP_MP.png\",\"datePublished\":\"2021-10-09T14:53:55+00:00\",\"dateModified\":\"2024-10-29T14:52:07+00:00\",\"description\":\"In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\\\/D converters, I2C, timers, RTC, touch pins, etc.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/Beitragsbild_ESP_MP.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/Beitragsbild_ESP_MP.png\",\"width\":1340,\"height\":1339},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/programming-the-esp32-with-micropython#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming the ESP32 with MicroPython\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Programming the ESP32 with MicroPython &#8226; Wolles Elektronikkiste","description":"In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\/D converters, I2C, timers, RTC, touch pins, etc.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython","og_locale":"en_US","og_type":"article","og_title":"Programming the ESP32 with MicroPython &#8226; Wolles Elektronikkiste","og_description":"In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\/D converters, I2C, timers, RTC, touch pins, etc.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython","og_site_name":"Wolles Elektronikkiste","article_published_time":"2021-10-09T14:53:55+00:00","article_modified_time":"2024-10-29T14:52:07+00:00","og_image":[{"width":1340,"height":1339,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/Beitragsbild_ESP_MP.png","type":"image\/png"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"Programming the ESP32 with MicroPython","datePublished":"2021-10-09T14:53:55+00:00","dateModified":"2024-10-29T14:52:07+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython"},"wordCount":2372,"commentCount":1,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/Beitragsbild_ESP_MP.png","keywords":["A\/D converter","deep sleep","ESP32","Hall Sensor","I2C","interrupts","light sleep","MicroPython","RTC","SPI","timer","Touch","UART","watchdog"],"articleSection":["Boards and Microcontrollers","Software and tools"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython","url":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython","name":"Programming the ESP32 with MicroPython &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/Beitragsbild_ESP_MP.png","datePublished":"2021-10-09T14:53:55+00:00","dateModified":"2024-10-29T14:52:07+00:00","description":"In this post, I show you how to program the ESP32 with MicroPython. I go into detail about the A\/D converters, I2C, timers, RTC, touch pins, etc.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/Beitragsbild_ESP_MP.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/09\/Beitragsbild_ESP_MP.png","width":1340,"height":1339},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/programming-the-esp32-with-micropython#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"Programming the ESP32 with MicroPython"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/12734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=12734"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/12734\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/12574"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=12734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=12734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=12734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}