Firmware Release v1.20.1

  • Hello everyone, we have release a new Firmware release v1.20.1

    sources can be found on Github Here

    Release Notes:

    • SmartConfig (Smart provisioning of Wifi Credentials)
      • To disable Smart Provisioning use pybytes.smart_config(False)
    • IDF V3.2
    • Micropython V1.11
    • Secure BLE (Server side )
    • Pybytes v1.1.2
    • LittleFS v2.0
    • Light sleep support
    • RTC memory support
    • Wifi promiscuous mode
    • CoAp module
    • Esp32 touchpad functionality exposed to micropy
    • uasyncio module
    • Uzlib module
    • Add support for LoRa regions CN470 and IN865
    • Added support for LoRa Class C multicast
    • Increase App partition Size For FIPy, GPy and LoPy4 to 1980K
    • Updated Build ENV for detecting Flash Size
    • Update Make Environment for IDF version check and checkout
    • Support OTA from older v1.18 Firmwares through intermediate firmware v1.18.3
    • Updates / Bug fixes to Pycom module
    • Updates / bug fixes to UART module
    • Updates to machrmt module
    • Updates / bug fixes to machrtc module
    • Updates / Bug fixes to modlora
    • Updates / Bug Fixes to Bluetooth module
    • Updates / Bug fixes to WLAN module
    • Updates / Bug fixes to LTE module
    • Updates / Bug fixes to machine module
    • Updates / bug fixing for OS module
    • Updates / Bug fixing for modusocket module
    • General fixes and improvements to the LoRaWAN stack
    • General Makefile Updates
    • General Bug Fixing

    Here is the summary of changes which can cause compatibility issues updating from 1.18 FW along with new APIs added


    • "pulses_send()" API can be configured as non-blocking
      "wait_tx_done" parameter is added


    • ntp_sync() API has new parameter: "backup_server" -> not mandatory
      memory() API is added


    • RX Buffer length can be maximum of 512 byte on all boards
      • Previously it was 4096 bytes on FIPY and GPY
    • New parameter of UART constructor:
      • rx_buffer_size
      • New Exception is dropped if "rx_buffer_size" is bigger than 512 bytes


    • New API: LoRa.reset() to reset sx1272 chip on LoPy1 Boards


    • Bluetooth's constructor has new parameter: "modem_sleep”, “mtu”
      • Exception is dropped if sleep failed
    • New API of characteristic class: read_descriptor()
    • Bluetooth.deinit() closes all connections
    • Bluetooth.connect() from now drops TimeoutError and not OSError when timeout happens
    • New parameter of Bluetooth.connect()
      • Has a "timeout" parameter defining timeout for establishing connection
      • Previously it was set to 5ms
    • New API: Bluetooth.set_advertisement_params()
    • New API: Bluetooth.set_advertisement_raw()
    • New API: Bluetooth.modem_sleep()
    • New API: Bluetooth.gatts_mtu() to get mtu of the client connection to Pycom device
    • New API: Bluetooth.tx_power()


    New module


    • set_color() has new parameter: "wait_tx"
      • Can be used to make underlying RMT operation block


    • lte_iccid() API drops new OSError exception if SIM is not detected
    • send_at_cmd() API's "delay" parameter is removed
    • send_at_cmd() raises new TypeError exception if "cmd" is not passed
    • New Callback registering API for registering a callback function to be called when LTE coverage is Lost (Note: Depending on the Sequans modem FW it might be supported or not , if not the callback will not be triggered - an update on Sequans FW supporting this Feature will be announced later )


    • deepsleep_wakeup() API is renamed to sleep_wakeup
    • sleep() API is implemented for light sleep (it was an empty function)


    • New API: bootmgr()
    • New API: get_free_heap()
    • New APIs: related to Pybytes
    • New APIs for setting/getting stored Wifi Credentials for STA and AP mode
    • heartbeat() API drops new OSError excpetion if RGB_LED is disabled (can be disabled during build)
    • rgb_led() API drops new OSError excpetion if RGB_LED is disabled (can be disabled during build)
    • nvs_get() API returns user defined "NoExistValue" if the object does not exist in NVS. Otherwise it raises a ValueError!.
      * To maintain previous behaviour, use pycom.nvs_get('<item>', None)


    • New file system type is added: Little FS
    • Virtual File System concept is used
      • The /flash can be LittleFS or FatFS, the SD Card can be FatFS
      • Files System related functions are replaced, they are used via VFS
    • mkfs() API is removed and is replaced by fsformat()


    • queue_put() releases the GIL during operation -> REPL will work
    • queue_get() releases the GIL during operation -> REPL will work


    • readall() API is removed
      • read() without parameters does the same
    • connect() API can be set as Non-BLocking
      • Only if timeout is defined: new OSError exception is dropped if settimeout operation of lwip fails
      • Only if timeout is defined: new TimeoutError exception is dropped if connection times out
      • Only if timeout is defined: new OsError exception may dropped if SSL is configured and underlying ssl operation fails
    • recv() API drops TimeoutError exception if underlying lwip returns with SSL_TIMEOUT
      • Before it only dropped this exception if MP_EAGAIN is returned
    • recvfrom() API drops TimeoutError exception if underlying lwip returns with SSL_TIMEOUT
      • Before it only dropped this exception if MP_EAGAIN is returned
    • New API: sendto()


    • Parameters of ticks_diff() API are swapped
      • Was: start_in, end_in
      • New: end_in, start_in


    • New API: bandwidth()
    • New API: hostname()
    • New API: ap_sta_list()
    • New API: max_tx_power()
    • New API: country()
    • New API: joined_ap_info()
    • New API: wifi_protocol()
    • New API: send_raw()
    • New API: promiscuous()
    • New API: callback()
    • New API: events()
    • New API: smartConfig()
    • New API: Connected_ap_pwd
    • New API: wifi_packet()
    • New API: ctrl_pkt_filter()
    • WLAN's contructor/init():
      • New optional parameter: bandwidth
      • New optional parameter: max_tx_pwr
      • New optional parameter: country -> if not given as tuple TypeError is dropped
    • API scan() has new optional parameters:
      • ssid, bssid, channel, show_hidden, type, scantime -> drops exception if given incorrectly
    • API mac() may drop new exceptions depends on number of arguments and it returns Mac of both AP and STA
    • New Triggers for Wlan Callback

    MQTT aws lib

    • Removed from frozen code but can be found on Github Here

    Please Note Documentation for v1.20 FW is still being updated and can be found Here

    Issue submission and Collaboration:

    For better experience and support for Pycom community, we have restructured our GitHub public Repo to have a separate branches for 1.18 and 1.20 FWs (under Release) - Daily development will be done on a new default branch (Dev) (previously we used to do the main Dev privately and do weekly/monthly releases to public repo).
    This will make it easier for people to Contribute to Our Firmware plus better traceability of opened Issues.
    we recommend you open any pull request on that Branch (Dev).

    OTA to 1.20 FW from 1.18

    Between version 1.18.2 and 1.20 the partition table is changed, the OTA_0 partition, among several others, is relocated because the size of the firmware has been increased due to the extended functionality of the 1.20 version. Due to this reason when updating from version 1.18.2 to 1.20 via OTA, an update to an intermediate version, numbered as 1.18.3, must be performed.
    The intermediate version makes sure that when OTA update to 1.20 is requested, the partition table contains correct entries and the new image will be flashed to the proper location.

    The intermediate version, 1.18.3, contains the following EXTRA steps when OTA update is requested:

    • Updates bootloader
    • Moves the content of the "ota data" partition to its new location
    • Updates the partition table

    Note: Please note that if bootloader or partition table update fails (e.g.: due to a power-loss), the device will not boot and recover and a new image must be flashed via a cable.

    When the device is being updated to the 1.18.3 intermediate version it may be flashed onto "OTA_0" partition depending on the where current active image is loaded from. In this case on next boot it automatically copies itself from "OTA_0" to "Factory" partition as a preparation for being able to receive the 1.20 image in the future. Without this step when the 1.20 image is being flashed on the "Factory" partition due to its increased size it would overwrite the first segments of the curently running firmware (which is the 1.18.3 and located on "OTA_0" partition).

    Therefore the correct update chain from 1.18 to 1.20 via OTA looks like: 1.18.2 -> 1.18.3 -> 1.20

    Downgarding from 1.20 back to 1.18 is possible, however the target version must be 1.18.3. The 1.18.3 image able to detect whether a downgrade happened and in this case it will not perform the steps explained above, it behaves as the 1.18.2r7 image just with updated partition table and bootloader. Updating back again to 1.20 is possible and allowed.

    Note: Updating devices with encrypted flash is not supported.

    Note: Downgrading via OTA from 1.18.3 to 1.18.2.xx is not allowed as this might casuse further OTA operations to fail.

    Note: Before doing OTA to 1.20 firmware make sure that the Scripts on device are updated (if necessary) to be compatible with 1.20 FW to avoid exceptions once device is updated to 1.20 which might lead to loosing connection to the remote device.

    You can find firmware images for 1.18.3 here:


    Note: This new Release has support for LittleFS filesystem if you updated from 1.18 FW your Filesystem is set to FatFS and if you choose to switch to LittleFS this will cause the filesystem to be formatted .

    Note: previous stable and development firmware can now be found as “legacy” in the firmware updater, so the new firmware updater has the 3 firmware types pybytes, legacy and pybytes-legacy

    Note: Upgrading from legacy (1.18) FW also downgrading from 1.20 to 1.18 will cause Nvs data to be erased as formatting under new FW is updated

    Note: There is an issue regarding BLE connection from Pycom Device (client) to a mobile phone (tested on Iphone) acting as Server, where connection always times out - connection from Pycom Device to another does not have that issue - will keep you updated with the fix for that problem.

  • @benc You have to go to this lib and get: uasyncio/uasyncio/ and uasyncio.core/uasyncio/ Copy it to the board, best under lib/uasyncio. Then you should have the files:


    You may also copy the files and from If you install these on your board (e.g. to lib), you can use that via REPL to install modules from or with the commands:

    import upip
    upip.install("micropython-uasyncio", "lib")

    The status of micropython-lib is somewhat unclear. Not all modules from that lib work with any micropython board. But it is always a good source of inspiration.

  • Hi, the release notes mention that uasyncio is included in this release, but I can't find it when I run help('modules').
    Any tips of how to import it?

  • @rcolistete said in Firmware Release v1.20.1:

    Please update the links for all Pycom devices in :
    to include the version 1.20.1 for manual firmware download.

    Repeating my request.

  • Wlan connection has turned to really unreliable in 1.20 version. In 1.18 connection was instant and never disconnected but in the 1.20 version wlan.connect(...) timeout most of the time and if connection is made it disconnects randomly.
    If connection get broken wlan.ifconfig() show (,,,

    Pycom MicroPython 1.20.1.r1 [v1.11-3138a13] on 2019-10-08; LoPy4 with ESP32
    Pybytes Version: 1.1.3
    Smart config auto-start is disabled.

    Sometimes during FTP transfer there is an unhandled exception and flash memory is formatted:

    Memory dump at 0x4020234c: bad00bad bad00bad bad00bad
    Guru Meditation Error: Core  0 panic'ed (IllegalInstruction). Exception was unhandled.

    From my file:

    if useWlan == True:
    	print('Configure WLAN')
    	from network import WLAN
    	wlan = WLAN(mode=WLAN.STA, power_save=True)
    	wlan.connect(AP_name, auth=(WLAN.WPA2, AP_password), timeout=30000)
    	del AP_name
    	del AP_password

  • Hi there,

    @berni said in Firmware Release v1.20.1:

    I have disabled the pybytes in the pybytes_config.json file by adding {"pybytes_autostart": false} and that fixed the issue.

    We are able to confirm the new firmware obtained from [0] and bundled and flashed to a FiPy device through the process outlined on [1] works flawlessly. Before adding the pybytes_config.json file, we also experienced Guru Meditation errors like outlined above (bad00bad bad00bad bad00bad). We didn't even use LoRa, just WiFi.

    @crumble said in Firmware Release v1.20.1:

    Running 1.20.1r1 I am impressed of the boot performance.

    We are running the Terkin Datalogger [2] and are also very happy about the performance improvements through the efficiency gains of the new mpy file format shipped with MicroPython 1.11 [3] when loading the py/mpy files into memory. On MicroPython 1.9.4, this took about 30(!) seconds and now we are down to 5 seconds [4].

    Thanks to all people involved in this release, turtles all the way down to the MicroPython core maintainers - you know who you are!

    With kind regards,


  • Running 1.20.1r1 I am impressed of the boot performance.

    But in combination with a pytrack there are a lot of i2c errors. I am not amused to figure out new timings which may result in less errors, but will never remove them all.

    Additionally I run now into i2c that can only be resolved by cutting the power suply. Would be great, if the PIC has a watchpig function. So I can track down with less efford, if this is caused by the LoPy or the Pytrack.

  • @robert-hh

    from network import WLAN
    import time
    wlan=WLAN(mode=WLAN.STA_AP, ssid="teste", auth=(WLAN.WPA2, 'passpass'))

    If I put a delay >= 3 seconds, works as espected, strange.

  • @robert-hh This sequence works too, after setting the password to a length of 8 min.:

    from network import WLAN
    wlan=WLAN(mode=WLAN.STA_AP, ssid="teste", auth=(WLAN.WPA2, 'passpass'))

    Pycom MicroPython 1.20.1.r1 [d4b4717] on 2019-10-09; LoPy4 with ESP32
    Type "help()" for more information.

    I do not expect that the GPY is different with respect to WiFi.

  • @robert-hh but I need to set a custom ssid and password.

  • @serafimsaudade The following sequence works for me:

    from network import WLAN
    wlan = WLAN(WLAN.STA_AP)

  • Hi again,
    I'm trying to connect gpy to wireless, but when I do wlan.scan() get this error:

    wlan = WLAN(mode=WLAN.STA_AP,ssid="teste", auth=(WLAN.WPA2, 'pass'))
    nets = wlan.scan()
    OSError: Scan operation Failed!

    This work on others fw version.

  • @robert-hh Tks for the tip.

    That was the idf submodules.
    problem solve. :)

  • @serafimsaudade IOt may be a problem with the pycom esp-idf.
    in the folder pycom-esp-idf, execute the command:

    git checkout idf_v3.2
    git submodule sync
    git submodule update --init

    Also, in you pycom esp32 source directory, issue the commands:

    git checkout Dev
    git submodule sync
    git submodule update --init

    Then, a

    make BOARD=WIPY clean
    make BOARD=WIPY

  • pycom_.png

    I'm getting this error when compiling.
    I clone the repo and try to compile.

  • @cmisztur It's not that or are executed, it's what is frozen into the image as or

  • @robert-hh said in Firmware Release v1.20.1:

    I build the image myself



  • Thank you @oligauc!

    This fixed the issue with lora.nvram_erase(). Also, I was having troubles deleting the flash from the pycom firmware upgrade software (it will time out if I select that option, working fine if I just upgrade the FW).

    I have observed that having pybytes active and doing my own LoRa OTTA (saving on nvram after joining the network) caused that the join flag was deleted and never connected again. I have disabled the pybytes in the pybytes_config.jsonfile adding {"pybytes_autostart": false} and that fixed the issue.

    I have been running the program on v1.20.1.r1 without pybytes and haven't had any Guru Meditation errors for a while. I'll keep trying...

  • @oligauc I tried another device, a LoPy now, and that one was completely messy. After setting a Lora parameter wrong, I could not change that any more. Only erasing flash and re-installing the firmware made it working again. Besides that, below is a nice picture showing how a message with DR=0 looks in the waterfall diagram.

  • @oligauc I just verified that, after a clean erase & upload. Then only one frequency is used. There may have been a modified set-up. I purchased a SDR recently, which allows to see the frequencies used. It's interesting to see all the different activities in the 868 band.

Log in to reply

Pycom on Twitter