New v1.20.0 Release candidate v1.20.0.rc7

  • Re: New Firmware Release Candidate v1.20.0

    Hello everyone, There is a new Firmware release candidate v1.20.0.rc7 released today the new release includes the following:

    New Features


    • Adding do_handshake for non-blocking sockets
    • Gracefully handle EAGAIN return of Socket.write in AwsMQTT lib
    • make openthread over lora a build-time configuration option (Author: @martijnthe)
    • Added factory LTE modem reset option and method to check UE coverage
    • New API in modusocket to get/set DNS servers
    • Updated frozen Sequans modem upgrade scripts
    • Improved PPP session suspend/resume mechanism with LTE modem
    • Wifi AP mode on boot now is using only Default AP and SSID -> Initially the onboot wifi mode was using the ssid/pwd configured in pycom-config saved in flash which caused
      inconvenience for some users when switching between Pybytes FW and other Base FWs since the AP would be brought up with same ssid/pwd. This is now removed and in next releases wifi config saved in flash will be improved for more efficiency and relaiability.
    • Updated Pybytes lib

    Bug Fixes

    • Fix an issue in cleaning up user threads during of soft-reset
    • Fix issue causing Device crash when safe booting (CTRL-F) while BLE/Wlan enabled
    • LTE module bug fixes
    • Fix Makefile bug where SIPY FIPY and LOPY4 excluded secure boot
    • Fixed crashinf Issue when LoRa/sigfox are initialized before LTE or Wlan
    • Fixed Issue in SecureBoot mechanism that caused compilation error when Secure Boot is enabled

    co-authored by: @xykon and @martijnthe

    You can download the source code here
    or you can flash it directly via the Firmware Updater tool as the latest development firmware.

  • @reidfo The connection was between P23 and Reset (what else). And yes, it did reset the board and the board booted in a normal fashion. The board should have an RC lowpass at Reset to suppress bouncing of the push button.

  • @robert-hh What pin did you connect P23 to? Did it successfully reset your board?

  • @reidfo SO I tried that. The only Pin that worked for that purpose was P23. All other Pins caused a freeze or constant reset loop. And P23 is used for the SD card. The command sequence was like:

    >>> from machine import Pin
    >>> p=Pin("P23", Pin.IN)
    >>> p(1)
    >>> p=Pin("P23", Pin.OUT)
    >>> p(0)

    Setting the Pin to IN first and then p(1) ensures, that when switched to OUT mode the value is high.

  • @reidfo According to the data sheet, the reset line has to be low at least 50 µs. If you connect reset to a GPIO pin, that cannot be guaranteed, or even the reset may not be released. Different to others, the ESP32 chip does not have a separate reset input. The pin used for that is CHIP_PU, which powers the chip or at least most of it up/down. So you would anyhow need something like a pulse extender to ensure a proper reset signal. And that must be more than a RC circuit.
    Edit: Looking at typical devices, there is a RC circuit at the reset with a time constant of 1 ms (10k & 100nF). So using that might work.

  • @robert-hh Just thinking out loud, and I haven't really looked into it yet, but could you use an output pin to trigger the reset input? If so, it would prevent having to have a separate watchdog chip (though I can also see why that would be useful).

  • @tlanier I agree that machine.reset() is different from pushing the reset button, and pushing the reset button is different to a power cycle. There are obviously states which are not reset by the code running after machine.reset(). I do not know whether this can be fixed. In any case I would use an external watchdog if long term unsupported operation is needed. There are error states where the internal watchdog also fails.

  • @robert-hh
    My bigger concern was that the machine.reset() is not equivalent to pressing the reset button as the manual suggest. There are definite differences. One difference is the utime.ticks_ms() is not zero'ed. Another difference I discovered by accident. In our design we were having trouble with an occasional I2C bus error which was later resolved by adjusting the pull-up resistor values on the I2C bus. What was more concerning is that after the I2C bus error occurred, there seemed to be nothing I could do in software, including doing a machine.reset(), that would resolve the problem. Only a press of the reset button would allow the I2C bus to function normally again.

    The question now is what else is different between a machine.reset() and a reset button press? Is there reason to believe that we should have an external watchdog that pulses the reset line of the processor to be assured that everything is properly reset after a problem occurs?

    Incidentally, there are valid reasons to want the ticks_ms timer to be zero'ed after reset. If you know the program will be restarted before the timer overflows and if the timer is zero'ed after reset as you would expect, a simple subtraction would work for measuring time differences.

  • @tlanier said in New v1.20.0 Release candidate v1.20.0.rc7:

    machine.reset() does not zero the utime.ticks_ms() counter.

    That does not really matter, since utime.ticks_ms(), utime.tick_us() and utime.ticks_cpu() are not intended as absolute time stamps, but only intended as to be used for time differences in combination with utime.ticks_diff(). These counters overflow anyhow after a while.

  • This post is deleted!

  • Bug Report

    machine.reset() does not zero the utime.ticks_ms() counter.

    An actual button press reset does.

  • @protean
    In my production code the object instantiation lte = LTE() line is executed once at startup. The following code is executed whenever an error occurs that may require reinitializing the modem.


    That's what I have found to work with experimentation.

    The problem I have discovered are many of the python commands are blocking other tasks from running for relatively long periods of time. For instance the lte.reset() command seems to block tasks for up to 5 secs. Unless Pycom provides some way to execute code when a timer interrupt occurs, I believe that all python commands should be rewritten to have some maximum time of execution (maybe 1-2 msecs) before they return to allow multitasking to run smoothly. For instance instead of lte.reset(), we would need lte.reset_start() and lte.reset_iscompleted() commands.

    I would love for someone with more knowledge of this subject to jump in and explain how Pycom expects programmers to do any type of real-time code in the existing environment. Is work being done to solve this problem? Is there something I am missing which currently solves the problem?

    One possibility is to rebuild the software from source as described on Github and to add new python commands to implement a true interrupt service routine using the Espressif ESP32 IDF to do the work required. A second possibility is to add another micro-controller to the design to do the real-time work. Neither option is appealing.

  • @tlanier said in New v1.20.0 Release candidate v1.20.0.rc7:

    lte = LTE()

    Why init twice?

    Either way, there is a method in the C source for the LTE code called: lte_check_init(). Seems like it would be trivial to expose that to the public class and then you can call it lte.is_init() and use it just like is_connected or is_attached

  • Is there any way in Pycom's MicroPython to get some sort of low latency periodic interrupt service routine that can do an I2C transfer?

    What I have found is if I use the Timer.Alarm (set to 200 msec periodic interrupt), I get wide variations in the execution of the scheduled callback handler. Some of the code that causes large latency issues include: (1) calling the modem reset method which kills servicing the interrupt routine for seconds, (2) calling the modem initialization method, (3) calling modem AT commands for instance to read signal strength and SMS messages, and (4) calling flash disk i/o methods such as open, read, write, and close.

    The idea to schedule the callback on a new thread which can run any Python code without restriction is nice, but it seems that the long latency issues make that technique prohibitive in some cases. Some of the Python commands block the interrupt handlers from being able to run for long periods. For instance in my case I need to sample an analog signal periodically at a rate of 200 msec. I can't afford to have the sample be 200 msec plus or minus 50-5000 msecs. I could live with plus or minus maybe 20-30 msecs.

    Would it be possible to have two types of timers? Type #1 timers would schedule the handler to run in the future as it does now. Type #2 timers would allow executing restricted code immediately at the time of the interrupt.

    Here's documentation from the MicroPython site:

    Writing Interrupt Handlers

    Any ideas on how this problem can be accomplished with Pycom's implementation of MicroPython without adding another micro-controller to the design just to do the analog sampling?

  • @eric-waai said in New v1.20.0 Release candidate v1.20.0.rc7:

    If clearly stated i have no problem with adding a manual delay.
    there are plenty of case where this time can be used to initialize other stuf. if that already takes 750 ms. there are a 750 ms wasted.

    There is another way to program this. Start each init in an own thread and wait until each one died.

    Yes, it shall be optional, 'cause ensure order of execution will not be easy ans overhead maybe too slow. But there are at least two ways to deal with this problem.

    If we have to implement the wait time, the min time shall be in the documentation and not in the forum ;)

  • @tlanier
    If clearly stated i have no problem with adding a manual delay.
    there are plenty of case where this time can be used to initialize other stuf. if that already takes 750 ms. there are a 750 ms wasted.

  • At least a 750 msec delay is needed after lte.init(). Would it not make better sense for the init() method to do the delay internally?


    lte = LTE()
    r = lte.iccid()    # delays less than about 750 msec will return None

  • @catalin Thanks , I'll lookout for code updates.



  • hi @thinginnovations, in the development release the method network.LoRa.Mesh.border_router is here, in the code:

    As for roadmap, I am waiting for suggestions :) Of course, meanwhile, working on stability, quicker joining Pymesh, power management...

    Meanwhile, by the end of the week I am targeting:

    1. example with Border Router (maybe add list and remove method)
    2. multi-socket and bind on a specific ipv6 (not for :: as today) for socket

  • @catalin There seems to be differences in the documentation and what is actually implemented in the code, for example makes reference to the border_router function. This is not present.

    Do you have a roadmap for when the rest of the loramesh implementation is to be completed and available?



Log in to reply

Pycom on Twitter