Différences entre versions de « Mydin-classes-diagram »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
(Page créée avec « {{MyDin-NAV}} {{traduction}} »)
 
 
(46 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
 
{{MyDin-NAV}}
 
{{MyDin-NAV}}
  
{{traduction}}
+
== About this section ==
 +
 
 +
Before reading the classes documentation, it may be opportune to understand how the MyDin core is designed.
 +
 
 +
That will help to understand how the code works and where are located the key items when programming your MyDin project with MicroPython.
 +
 
 +
== Class diagram ==
 +
 
 +
[[Fichier:MyDin-Class-diagram.jpg]]
 +
 
 +
Here a short description of the main classes and their responsibilities:
 +
 
 +
* '''DinControler''' : Base class responsible for starting the asynchronous execution. It puts every mechanism in place to initiate the setup then start asynchronous tasks including the user_loop task. A this level, the DinCOntroler doesn't know anything about the underlaying microcontroler used. DinControler also takes care of the process termination.
 +
* '''PicoControler''' : Base class for myDin solution based on Raspberry-Pi Pico microcontroler. PicoControler inherits of DinControler (and all its behavior). At the PicoContoler level, we can create object related to microcontroler hardware that will be shared accross all the descendant classes. At the PicoControler level we can define the common I2C bus, RTC clock, internal temperature sensor, watchdog and other common ressources.
 +
* '''Pico3Mod''' : Specialized implementation of the PicoControler for a 3 modules size DIN. As the microcontroler is now placed on a PCB with fixed dimensions and obvious placement constraints (due to the 3 modules Din) then the specific hardware design like buttons, LEDs, interface connectors can be defined by this class. This class also defines the interface between the controler and the 3 modules backplane.
 +
* '''Pico6Mod''' : Another specialized implementation of the PicoControler for a 6 modules size DIN. Thanks to additional place available, it is also possible to add a LCD/OLED display, mini-joystick aside the usual interface.
 +
* '''TwoRelay3Mod''' is a specialized Backplane implementation for a 3 modules DIN. Backplane 3 modules shares a common interface with the 3 modules Controler (Pico3Mod and any 3 modules Controler will use exactly the same interface).
 +
 
 +
{{dbox-orange| Backplane class '''must implements''' the {{fname|attach( controler )}} method.<br />The {{fname|attach( controler )}} method is called by [[Mydin-async-or-not#Step_2:_create_instances|configure()]] to expose the backplane properties into the controler object. }}
 +
 
 +
== DinControler ==
 +
=== Header ===
 +
 
 +
{{prop|Ancestor| None}}
 +
{{prop|Class | '''DinControler'''}}
 +
{{prop|Module | controler }}
 +
{{prop|DIN Size | Any size }}
 +
{{prop|Descr | Base class responsible for starting the asynchronous execution. It puts every mechanism in place to initiate the setup then start asynchronous tasks including the userloop task. A this level, the DinControler doesn't know anything about the underlaying microcontroler used. DinControler also takes care of the process termination. }}
 +
 
 +
Details about '''DinControler''' class are available at [[Mydin-async-or-not#Step_5_:_asynchronous_tasks|"asynchronous tasks" details]]. Here is the process behind the {{fname|run()}} method.
 +
 
 +
[[fichier:Mydin-DinControler-run.jpg|960px]]
 +
 
 +
=== Attributes ===
 +
==== backplane : object ====
 +
 
 +
Reference to the backplane instance created by the {{fname|configure()}} function. The backplane is an instance of type BackplaneClass.
 +
 
 +
==== is_async : boolean ====
 +
 
 +
True when the DinControler is running asyncio code otherwise, the DinControler is running "procedural" code.
 +
 
 +
This property is set to True by the {{fname|run()}} method.
 +
 
 +
==== loop_exception : object ====
 +
 
 +
If an exception is raised by the userloop during asynchronous execution then the {{fname|run()}} exits and loop_exception contains a reference to the catched exception.
 +
 
 +
When the userloop exits for another reason (eg: APP_RUN=STOP) then the loop_exception should still be None.
 +
 
 +
Remark: loop_exception is set to None when {{fname|run()}} starts.
 +
 
 +
==== loop_time_ms : int ====
 +
Being configured to 20 milliseconds, this {{fname|async.sleep_ms()}} time is inserted after each ''userloop'' iteration. It allows other tasks to get execution time.
 +
 
 +
The value of {{fname|loop_time_ms}} can be ajusted to provide more time to other tasks.
 +
 
 +
=== Methods ===
 +
==== __init__() ====
 +
 
 +
Constructor of the {{fname|DinControler}} class. This constructor is not called directly, the DinControler class is used as a based call for a given MCU category class (RP2040, ESP32, ...).
 +
 
 +
<syntaxhighlight lang="python">
 +
def __init__( self, BackplaneClass, RunApp_pin ):
 +
</syntaxhighlight>
 +
 
 +
* '''BackplaneClass''' : Class of the backplane to be associated with the controler (eg: TwoRelay3Mod).
 +
* '''RunApp_pin''' : identification of the input pin to be used as RUN_APP swich. It will be configured with Internal Pullup. Software will not start (or will stop) when the pin is tied to ground.
 +
 
 +
==== setup() ====
 +
 
 +
Setup the ''userloop'' and other key parameter for an asynchronous code execution with {{fname|run()}}. The ''userloop'' is the main user code repetitively executed by the asynchronous execution.
 +
 
 +
<syntaxhighlight lang="python">
 +
def setup( self, setup=None, loop=None, on_tasks_create=None ):
 +
</syntaxhighlight>
 +
 
 +
* '''setup''' : function setting-up the hardware of your DIN project. Called function receives ''din'' object is as parameter.
 +
* '''loop''' : async function executing the ''userloop'' code. The ''din'' object is received as parameter. Called function receives the ''din'' object as parameter.
 +
* '''on_task_create''' : callback event allowing the user code to insert its own project tasks.
 +
 
 +
The example here below shows how to create the ''userloop'' and the ''setup'' function.
 +
 
 +
<syntaxhighlight lang="python">
 +
from mydin import configure
 +
from mydin.pico import Pico3Mod
 +
from mydin.backplane.relays import TwoRelay3Mod
 +
import time, sys
 +
 
 +
from serlcd import SerLCD
 +
 
 +
# Which Controler + Backplane to use
 +
din = configure( Pico3Mod, TwoRelay3Mod )
 +
 
 +
def setup( din ):
 +
  # Add a new attribute to "din" instance
 +
  din.lcd = SerLCD( din.i2c, cols=16, rows=4 )
 +
  din.lcd.backlight( (0,0,255) ) # Blue
 +
  din.lcd.set_cursor( (7,1) ) # column,line (0 à N-1)
 +
  din.lcd.print( "MyDin" )
 +
  din.lcd.set_cursor( (3,2) ) # column,line (0 à N-1)
 +
  din.lcd.print( "by MCHobby.be")
 +
  din.lcd_last_update = time.ticks_ms()
 +
 
 +
async def loop( din ):
 +
  """ called again and again (like Arduino) """
 +
 
 +
  # Update LCD once every 5 seconds
 +
  if time.ticks_diff( time.ticks_ms(), din.lcd_last_update )>5000:
 +
    din.lcd.clear()
 +
    din.lcd.print("Internal Temp:" )
 +
    din.lcd.set_cursor( (3,1) )
 +
    din.lcd.print( "%2.2f C" % din.internal_temperature )
 +
    din.lcd_last_update = time.ticks_ms()
 +
 
 +
 
 +
din.setup( setup=setup, loop=loop )
 +
din.run()
 +
</syntaxhighlight>
 +
 
 +
Example with tasks creation is available on the [https://github.com/mchobby/micropython-mydin micropython-mydin] repository.
 +
 
 +
==== setup_watchdog() ====
 +
 
 +
{{dbox-orange| Abstract method that must be overrided in descendant class}}
 +
 
 +
The {{fname|setup_watchdog()}} method activates the hardware Watchdog of the microcontroler. 2 seconds (2000 ms) may represent a good timing.
 +
 
 +
Once activated, the feed_watchdog() must be called before the timeout occurs otherwise the microcontroler will reset.
 +
 
 +
Remarks:
 +
* the watchdog is automatically feeded at every iteration of the ''userloop''.
 +
* do not block the ''userloop'' execution because it may timeout the watchdog
 +
* take care of the timing when using blocking function (like Ethernet request) because it may timeout the watchdog.
 +
 
 +
<syntaxhighlight lang="python">
 +
def setup_watchdog( self, time_ms ):
 +
</syntaxhighlight>
 +
 
 +
* '''time_ms''' : timeout of the watchdog before resetting occurs.
 +
 
 +
==== feed_watchdog() ====
 +
 
 +
{{dbox-orange| Abstract method that must be overrided in descendant class}}
 +
 
 +
The {{fname|feed_watchdog()}} method just reset the watchdog timeout.
 +
 
 +
Remarks:
 +
* the feed_watchdog() is automatically called every iteration of the ''userloop''.
 +
 
 +
<syntaxhighlight lang="python">
 +
def feed_watchdog( self ):
 +
</syntaxhighlight>
 +
 
 +
==== task_setup() ====
 +
 
 +
{{dbox-orange| Overridable method}}
 +
 
 +
This method setup the ''userloop'' then calls the {{fname|on_task_create}} event (when provided to the {{fname|setup()}} method.
 +
 
 +
That method is usually overrided in descendant class to append Controler specific tasks (eg: the PicoControler append monitoring and ds18b20 tasks).
 +
 
 +
<syntaxhighlight lang="python">
 +
def tasks_setup( self, async_evloop ):
 +
</syntaxhighlight>
 +
 
 +
{{Ambox
 +
| type      = delete
 +
| image      = [[File:StopHand.png|40px|alt=Stop]]
 +
| textstyle  = color: red; font-weight: bold; font-style: italic;
 +
| text      = Do not confuse the override operation used by subclasses to create their tasks with the {{fname|on_task_create}} event allowing the user code to create their own tasks. }}
 +
 
 +
==== before_run() ====
 +
{{dbox-orange| Overridable method}}
 +
 
 +
This method is called before starting the ''userloop''. The execution is aborted when the {{fname|before_run()}} returns False.
 +
 
 +
Overriding it allows the descendant class to checks specific condition before allowing the user code to run (EG: Pico3Mod checks the internal temperature before allowing the ''userloop'' to starts).
 +
 
 +
<syntaxhighlight lang="python">
 +
def before_run( self ):
 +
</syntaxhighlight>
 +
 
 +
==== after_run() ====
 +
{{dbox-orange| Overridable method}}
 +
 
 +
This method is called when the ''userloop'' ends for any reason (RUN_APP or ''userloop'' exception).
 +
 
 +
No return value is expected from this method.
 +
 
 +
<syntaxhighlight lang="python">
 +
def after_run( self ):
 +
</syntaxhighlight>
 +
 
 +
==== run() ====
 +
Start the execution of the ''userloop'' execution. See the [[Mydin-classes-diagram#DinControler|diagram at the begin of this class description]].
 +
 
 +
The {{fname|setup()}} must be called prior to any {{fname|run()}} attempt.
 +
 
 +
<syntaxhighlight lang="python">
 +
def run( self ):
 +
</syntaxhighlight>
 +
 
 +
== PicoControler ==
 +
 
 +
=== Header ===
 +
 
 +
{{prop|Ancestor| [[Mydin-classes-diagram#DinControler|DinControler]] }}
 +
{{prop|Class | '''PicoControler'''}}
 +
{{prop|Module | pico }}
 +
{{prop|DIN Size | Any size }}
 +
{{prop|Descr | Base class for myDin solution based on Raspberry-Pi Pico microcontroler. }}
 +
 
 +
 
 +
PicoControler inherits of the DinControler behaviors.
 +
 
 +
At the PicoContoler level, the class createse objects related to microcontroler hardware, objects that will be shared among all the PicoControler descendant.
 +
 
 +
PicoControler creates:
 +
* the common I2C bus,
 +
* the MCU RTC clock,
 +
* the status Pin,
 +
* access to internal temperature sensor,
 +
* implementation for the watchdog.
 +
 
 +
=== Attributes ===
 +
==== status : Pin ====
 +
Allow to control the status pin. The status pin is usually connected to a status LED. It's status can be modified by the user code.
 +
 
 +
==== i2c : I2C ====
 +
Instance of the internal I2C bus connected to the RTC clock and other I2C components of the future controler implementations.
 +
 
 +
The internal I2C bus will also be exposed on the interfaces connectors. This way, the user code doesn't needs to create an instance of I2C bus and can reuse this existing instance.
 +
 
 +
==== mcu_rtc : RTC ====
 +
Internal MCU hardware clock. Access to its date information reliable and bus access pretty fast. Unfortunately, clock is reset to zero at each power cycle.
 +
 
 +
When the software starts, the myDin code copy time & date from and external RTC to the internal MCU RTC.
 +
 
 +
Remarks: the external RTC clock is not used for software operation because the I2C bus is quite slower compared to the internal MCU buses accessing the MCU RTC.
 +
 
 +
==== adc4 : ADC ====
 +
Access to the internal ADC (the 4th one) wired to the MCU temperature sensor. That instance doesn't need to be directly accessed (see the {{fname|internal_temperature}} property).
 +
 
 +
==== internal_temperature : float ====
 +
This property uses the {{fname|adc4}} connected to an analog temperature sensor place inside the die of the Pico MCU.
 +
 
 +
Even if not precise, this sensor can provide a rough idea of the temperature inside the DIN case. A high temperature may indicates a malfunctioning situation.
 +
 
 +
==== wdt: Watchdog ====
 +
Reference to the watchdog instance or None.
 +
 
 +
The instance of the watchdog is created only when the watchdog is configured ( with {{fname|setup_watchdog()}} ).
 +
 
 +
=== Methods ===
 +
==== __init__() ====
 +
 
 +
Constructor of the {{fname|PicoControler}} class. This constructor is not called directly, the PicoControler class is used as a based for the various size of DIN modules.
 +
 
 +
The PicoControler creator is aware of the various Pin used for the I2C bus, Status pin, RUN_APP pin, etc. Le PicoControler can create the various instance accordingly.
 +
 
 +
<syntaxhighlight lang="python">
 +
def __init__( self, BackplaneClass ):
 +
</syntaxhighlight>
 +
 
 +
* '''BackplaneClass''' : Class of the backplane to be associated with the controler (eg: TwoRelay3Mod).
 +
 
 +
==== setup_watchdog() ====
 +
 
 +
Override the {{fname|setup_watchdog()}} method and implements hardware Watchdog of the Pico.
 +
 
 +
This initialize the {{fname|wdt}} attribute.
 +
 
 +
Remarks: read more about the watchdog implementation on [[Mydin-classes-diagram#setup_watchdog.28.29|DinControler watchdog]].
 +
 
 +
==== feed_watchdog() ====
 +
 
 +
Override the {{fname|feed_watchdog()}} method and implements hardware Watchdog feeding for the Pico.
 +
 
 +
This implementation is called after each ''userloop'' iteration do reset the watchdog timeout. User code do not need to call this method except when ''userloop'' contains some blocking code.
 +
 
 +
<syntaxhighlight lang="python">
 +
def feed_watchdog( self ):
 +
</syntaxhighlight>
 +
 
 +
== Pico3Mod ==
 +
The {{fname|Pico3Mod}} is the specialized class designed for 3 modules DIN case.
 +
 
 +
The {{fname|Pico3Mod}} is described into a [[Mydin-Class-Pico3Mod|dedicated page]].

Version actuelle datée du 29 avril 2025 à 11:17

About this section

Before reading the classes documentation, it may be opportune to understand how the MyDin core is designed.

That will help to understand how the code works and where are located the key items when programming your MyDin project with MicroPython.

Class diagram

MyDin-Class-diagram.jpg

Here a short description of the main classes and their responsibilities:

  • DinControler : Base class responsible for starting the asynchronous execution. It puts every mechanism in place to initiate the setup then start asynchronous tasks including the user_loop task. A this level, the DinCOntroler doesn't know anything about the underlaying microcontroler used. DinControler also takes care of the process termination.
  • PicoControler : Base class for myDin solution based on Raspberry-Pi Pico microcontroler. PicoControler inherits of DinControler (and all its behavior). At the PicoContoler level, we can create object related to microcontroler hardware that will be shared accross all the descendant classes. At the PicoControler level we can define the common I2C bus, RTC clock, internal temperature sensor, watchdog and other common ressources.
  • Pico3Mod : Specialized implementation of the PicoControler for a 3 modules size DIN. As the microcontroler is now placed on a PCB with fixed dimensions and obvious placement constraints (due to the 3 modules Din) then the specific hardware design like buttons, LEDs, interface connectors can be defined by this class. This class also defines the interface between the controler and the 3 modules backplane.
  • Pico6Mod : Another specialized implementation of the PicoControler for a 6 modules size DIN. Thanks to additional place available, it is also possible to add a LCD/OLED display, mini-joystick aside the usual interface.
  • TwoRelay3Mod is a specialized Backplane implementation for a 3 modules DIN. Backplane 3 modules shares a common interface with the 3 modules Controler (Pico3Mod and any 3 modules Controler will use exactly the same interface).
Backplane class must implements the attach( controler ) method.
The attach( controler ) method is called by configure() to expose the backplane properties into the controler object.

DinControler

Header

Ancestor None
Class DinControler
Module controler
DIN Size Any size
Descr Base class responsible for starting the asynchronous execution. It puts every mechanism in place to initiate the setup then start asynchronous tasks including the userloop task. A this level, the DinControler doesn't know anything about the underlaying microcontroler used. DinControler also takes care of the process termination.

Details about DinControler class are available at "asynchronous tasks" details. Here is the process behind the run() method.

Mydin-DinControler-run.jpg

Attributes

backplane : object

Reference to the backplane instance created by the configure() function. The backplane is an instance of type BackplaneClass.

is_async : boolean

True when the DinControler is running asyncio code otherwise, the DinControler is running "procedural" code.

This property is set to True by the run() method.

loop_exception : object

If an exception is raised by the userloop during asynchronous execution then the run() exits and loop_exception contains a reference to the catched exception.

When the userloop exits for another reason (eg: APP_RUN=STOP) then the loop_exception should still be None.

Remark: loop_exception is set to None when run() starts.

loop_time_ms : int

Being configured to 20 milliseconds, this async.sleep_ms() time is inserted after each userloop iteration. It allows other tasks to get execution time.

The value of loop_time_ms can be ajusted to provide more time to other tasks.

Methods

__init__()

Constructor of the DinControler class. This constructor is not called directly, the DinControler class is used as a based call for a given MCU category class (RP2040, ESP32, ...).

def __init__( self, BackplaneClass, RunApp_pin ):
  • BackplaneClass : Class of the backplane to be associated with the controler (eg: TwoRelay3Mod).
  • RunApp_pin : identification of the input pin to be used as RUN_APP swich. It will be configured with Internal Pullup. Software will not start (or will stop) when the pin is tied to ground.

setup()

Setup the userloop and other key parameter for an asynchronous code execution with run(). The userloop is the main user code repetitively executed by the asynchronous execution.

def setup( self, setup=None, loop=None, on_tasks_create=None ):
  • setup : function setting-up the hardware of your DIN project. Called function receives din object is as parameter.
  • loop : async function executing the userloop code. The din object is received as parameter. Called function receives the din object as parameter.
  • on_task_create : callback event allowing the user code to insert its own project tasks.

The example here below shows how to create the userloop and the setup function.

from mydin import configure
from mydin.pico import Pico3Mod
from mydin.backplane.relays import TwoRelay3Mod 
import time, sys

from serlcd import SerLCD

# Which Controler + Backplane to use
din = configure( Pico3Mod, TwoRelay3Mod )

def setup( din ):
  # Add a new attribute to "din" instance
  din.lcd = SerLCD( din.i2c, cols=16, rows=4 )
  din.lcd.backlight( (0,0,255) ) # Blue
  din.lcd.set_cursor( (7,1) ) # column,line (0 à N-1)
  din.lcd.print( "MyDin" )
  din.lcd.set_cursor( (3,2) ) # column,line (0 à N-1)
  din.lcd.print( "by MCHobby.be")
  din.lcd_last_update = time.ticks_ms()

async def loop( din ):
  """ called again and again (like Arduino) """

  # Update LCD once every 5 seconds
  if time.ticks_diff( time.ticks_ms(), din.lcd_last_update )>5000:
    din.lcd.clear()
    din.lcd.print("Internal Temp:" )
    din.lcd.set_cursor( (3,1) )
    din.lcd.print( "%2.2f C" % din.internal_temperature )
    din.lcd_last_update = time.ticks_ms()


din.setup( setup=setup, loop=loop )
din.run()

Example with tasks creation is available on the micropython-mydin repository.

setup_watchdog()

Abstract method that must be overrided in descendant class

The setup_watchdog() method activates the hardware Watchdog of the microcontroler. 2 seconds (2000 ms) may represent a good timing.

Once activated, the feed_watchdog() must be called before the timeout occurs otherwise the microcontroler will reset.

Remarks:

  • the watchdog is automatically feeded at every iteration of the userloop.
  • do not block the userloop execution because it may timeout the watchdog
  • take care of the timing when using blocking function (like Ethernet request) because it may timeout the watchdog.
def setup_watchdog( self, time_ms ):
  • time_ms : timeout of the watchdog before resetting occurs.

feed_watchdog()

Abstract method that must be overrided in descendant class

The feed_watchdog() method just reset the watchdog timeout.

Remarks:

  • the feed_watchdog() is automatically called every iteration of the userloop.
def feed_watchdog( self ):

task_setup()

Overridable method

This method setup the userloop then calls the on_task_create event (when provided to the setup() method.

That method is usually overrided in descendant class to append Controler specific tasks (eg: the PicoControler append monitoring and ds18b20 tasks).

def tasks_setup( self, async_evloop ):

before_run()

Overridable method

This method is called before starting the userloop. The execution is aborted when the before_run() returns False.

Overriding it allows the descendant class to checks specific condition before allowing the user code to run (EG: Pico3Mod checks the internal temperature before allowing the userloop to starts).

def before_run( self ):

after_run()

Overridable method

This method is called when the userloop ends for any reason (RUN_APP or userloop exception).

No return value is expected from this method.

def after_run( self ):

run()

Start the execution of the userloop execution. See the diagram at the begin of this class description.

The setup() must be called prior to any run() attempt.

def run( self ):

PicoControler

Header

Ancestor DinControler
Class PicoControler
Module pico
DIN Size Any size
Descr Base class for myDin solution based on Raspberry-Pi Pico microcontroler.


PicoControler inherits of the DinControler behaviors.

At the PicoContoler level, the class createse objects related to microcontroler hardware, objects that will be shared among all the PicoControler descendant.

PicoControler creates:

  • the common I2C bus,
  • the MCU RTC clock,
  • the status Pin,
  • access to internal temperature sensor,
  • implementation for the watchdog.

Attributes

status : Pin

Allow to control the status pin. The status pin is usually connected to a status LED. It's status can be modified by the user code.

i2c : I2C

Instance of the internal I2C bus connected to the RTC clock and other I2C components of the future controler implementations.

The internal I2C bus will also be exposed on the interfaces connectors. This way, the user code doesn't needs to create an instance of I2C bus and can reuse this existing instance.

mcu_rtc : RTC

Internal MCU hardware clock. Access to its date information reliable and bus access pretty fast. Unfortunately, clock is reset to zero at each power cycle.

When the software starts, the myDin code copy time & date from and external RTC to the internal MCU RTC.

Remarks: the external RTC clock is not used for software operation because the I2C bus is quite slower compared to the internal MCU buses accessing the MCU RTC.

adc4 : ADC

Access to the internal ADC (the 4th one) wired to the MCU temperature sensor. That instance doesn't need to be directly accessed (see the internal_temperature property).

internal_temperature : float

This property uses the adc4 connected to an analog temperature sensor place inside the die of the Pico MCU.

Even if not precise, this sensor can provide a rough idea of the temperature inside the DIN case. A high temperature may indicates a malfunctioning situation.

wdt: Watchdog

Reference to the watchdog instance or None.

The instance of the watchdog is created only when the watchdog is configured ( with setup_watchdog() ).

Methods

__init__()

Constructor of the PicoControler class. This constructor is not called directly, the PicoControler class is used as a based for the various size of DIN modules.

The PicoControler creator is aware of the various Pin used for the I2C bus, Status pin, RUN_APP pin, etc. Le PicoControler can create the various instance accordingly.

def __init__( self, BackplaneClass ):
  • BackplaneClass : Class of the backplane to be associated with the controler (eg: TwoRelay3Mod).

setup_watchdog()

Override the setup_watchdog() method and implements hardware Watchdog of the Pico.

This initialize the wdt attribute.

Remarks: read more about the watchdog implementation on DinControler watchdog.

feed_watchdog()

Override the feed_watchdog() method and implements hardware Watchdog feeding for the Pico.

This implementation is called after each userloop iteration do reset the watchdog timeout. User code do not need to call this method except when userloop contains some blocking code.

def feed_watchdog( self ):

Pico3Mod

The Pico3Mod is the specialized class designed for 3 modules DIN case.

The Pico3Mod is described into a dedicated page.