195 AandC: ixmRPC Wio Remote Procedure Calls(195.html)

One of my previous articles (Article 193) described the ixmRPC system in general for various manufacturers' devices. But because there is very limited flash drive space on the Wio Termiinal, it will be addressed first (and solely) in this article. Hopefully, software support for the uSD card will be soon available. The uSD card might already be usable, but until the author has actually used MicroPython to access the uSD card on the Wio Terminal, he is presuming that it is NOT available to MicroPython users. Until then, he presumes that it is unavailable . . . . . and therefore all of the ixmRPC code for the Wio Terminal must fit into 1 megabyte of flash memory (for now).

My earlier article (191) introduced the eRPC system. Another significant application of the WioTerminal is for Acquisition and Control (ie Sense and Control) such as my PiR2 Temperature Logger. This article describes in detail, a new eRPC system: the ixmRPC using MicroPython (not c/c++ nor CircuitPython) on the Wio Terminal. I intend to use ixmRPC to port code between cores (computers) using only MicroPython. The ixmRPC system will hopefully simplify the interchange of various sensors and actuators, by keeping much of the software intact.

A Remote Procedure Call (RPC) is software that replaces a physical "wire" and in some cases provide text or file transfers between client cores and server cores. But this article limits itself to MicroPython code only for the Wio Terminal. For this software to function correctly, it must reside in a folder in a computer. The software makes use of data that moves (is transported) from one computer to another. Some text files (but very few) are required for the Wio Terminal because they hold the definitions of the type of data, where it comes from and where it goes to. Finally a person (or the software) must prepare the data that is sent to the other computer. In eRPC, the data must be defined in enough detail so that the eRPC system, itself, can create all of this software. In the ixmRPC system, a programmer must actually write (ie code) the shim software. The CRS table is where much of this technical information is stored. Therfore, the CRS tables will also be described and used in this article.

An internal device connected to one GPIO pin can be controlled by an electronic signal on another GPIO pin. This is usually done by connecting a wire from one pin to the other. A simple use of the ixmRPC system is to replace the physical wire by non-physical data communications implemented by the ixmRPC software on the Wio Terminal.

Keywords

"195 AandC: ixmRPC Wio Remote Procedure Calls(195.html)" A&C A&C AandC ambientLight ambLight "Acquisition and Control" "Acquisition & Control" "AandC" Acquisition amplitude API Blocking-Server "Blocking Server" c-wrapped Catch caveat CfromF CfromF() CPython CircuitPython Client codec complex Control CRS .crs D@CC datum "Digital Logic Analyzer" email eRPC "eRPC function names" eRPC-lite eRPClite "eRPC lite" "Fast Fourier Transform" FFT frequency github Grove "hash total" HDMI header I2C ICH180RR IDL .idl imaginary Internet Invert() IXcomplex "IXcomplex header" "IXcomplex preprocessor" ixmRPC ixTransport LA104 MicroPython minicom short "packet sequence" parity "passive components" PuTTY PIO PiR2 PiR2D PiR2Null PiR2P PiR2W Pix "Pix Explorer" PWM pi py Python Raspberry Reading "Remote Procedure Calls" RPi sampling "SD card issue" Sense "serial USB" Server shim "shim code" "short integers" "Signal Reading/control Request" "short Python integers" sin sine SRR SPI state-machine "state machine" TA TAR TARK TCC TCCK TCK TCR "temperature sensor" Thonny Throw Transport uJoyStick Unity unity() "very slow Throw" VT100 wave waveform WioTerminal "Wio Terminal SD card issue"

Table of Contents

Introduction to ixmRPC on the WioT
ixmRPC (eRPC lite) Remote Procedure Calls


SD card Issue Resolved as of 2021LDec17
Other Thoughts
Conclusion
Sources

Introduction to ixmRPC on the WioT

The eRPC mechanism provides a very comprehensive RPC (Remote Procedure Call) mechanism for the AandC (Acquisition and Control) world. It supports both c/c++ and Python code. But eRPC is a very powerful RPC mechanism. It is almost impossible to envisage eRPC in the Wio Terminal world, where only small amounts of RAM and Flash Memory exist.

The author decided to create ixmRPC which is a lite version of eRPC. The concepts of eRPC are maintained, but some of the powerful features of eRPC are left out. For example, ixmRPC only addresses the MicroPython Server world. The Server cores are limited to Raspberry compatible cores such as the Raspberry Pi cores, the Raspberry RP2040 cores (eg in the Pico) and Wio Terminal cores. Only the Wio Terminal cores will be addressed in this article. The eRPC system generates shim code for both the Client and the Server. In ixmRPC, Client cores include the Raspberry Pi 4 and the Windows PC cores. But the ixmRPC system does NOT generate the final code nor the shim code automatically. The user (the programmer) must develop this code.

The ixmRPC tables are very limited at first. As more sensors are included in ixmRPC, more functions will be created for ixmRPC. These tables are not automatically used by ixmRPC. They are mostly references used when writing ixmRPC code or they are text files read by the ixmRPC code. Therefore they might be more forgiving of errors than the tables in the eRPC system. These articles by D@CC, introduce the concept of storing data samples in complex variables. The "real" part of each complex variable is used to store the datum (sample value) while the "imaginary" part (of each complex variable) is used to store the timeStamp. This "marries" the time of each sample to the value of the sample. Simple math functions can be used to convert a Python "list" of complex variables into a "list" of real variables whenever necessary. Alternatively, if the samples are taken at very regular intervals, the imaginary information becomes redundant. For more information about this use of complex variables, refer to the author's articles numbered 75, 164, 165, 171, 180 and 193.

For an explanation of the terms used in this article, refer to the "ixmRPC Lexicon" Heading near the end of article 193.

This article covers the following topics that describe ixmRPC:

	Introduction to ixmRPC on the WioT
	The First Functions Coded For ixmRPC

	etc.

	SD card Issue Resolved as of 2021LDec17
	
This article (195) has been based on Article 193 (as of 2023EMay09). Some of the information will appear in both Articles, but the intent is for this Article to limit its content to the Wio Terminal.

Introduction to ixmRPC (eRPC lite) Remote Procedure Calls

The ixmRPC is a lite version of eRPC. For those new to RPC, multiple tables must be created to define the characteristics of the AandC (Acquisition & Control) sensors and actuators. In ixmRPC, various programming languages (eg MicroPython and Circuit Python) are supported. The name "ixmRPC" implies that Remote Procedure Calls are defined in a Client core (machine). The requested action is sent to a Server Core (machine) where the action occurs. An RPC system usually permits the Client and Server to be the same machine. This is especially useful during testing.

The first advantage of the ixmRPC system is that code created to deal with "one set of sensors and actuators" can be easily ported to "a different set of sensor and actuators". Code written in CircuitPython can more easily be converted to the MicroPython world if the different routines for the two Pythons are easily implemented.

Another advantage of the ixmRPC system is that a totally different sensor (or actuator) from a different manufacturer can be easily implemented with minor code changes.

Two main tables of information are used in the ixmRPC system. The first is the IDL. The second is the CRS table. They are described below. The combination of these two tables pales when compared to the powerful eRPC system. But ixmRPC is not intended for the commercial world. Our target audience, the amateur programmers and electronics buffs are expected to make use of the ixmRPC system.

One drawback of the ixmRPC system is that more calling parameters are passed than in the eRPC system. But the passing of more calling parameters contributes to making ixmRPC simpler to implement than eRPC.

The main parts of ixmRPC are:

IDL - Interface Data Library
          defines a single datum source or target: signal or pin on a device (including the calling 
	  parameters with the Client IDL). Two IDLs are needed.
CRS - Client Routing to Server
          defines a "connection to be made" between Client (source) & Server (target). One CRS is needed.
SRR - Signal Reading/control Request
          is an instance of a reading/control signal. Each is a datum (a data instance) at a specific time.
          This requires two things: a "datum" and a "time-stamp".  I would recommend the use of complex 
	  numbers including the time-stamp as the "imaginary" part, but fear that it is too "complex" a
	  concept for the general public.

The above three parts of the ixmRPC must be defined.  They are needed when the UDR action occurs.

UDR - Unique Data Request
	Each UDR corresponds to a signal being "Thrown" ie transmitted.  For a signal to be 
	transmitted, the IDL, CRS and SRR must be referenced.
Each UDR is a signal that is thrown by defining a SRR that goes from an IDL via a CRS to another IDL.

Each UDR needs 6 things to be specified:
	ID#  (unique identifier for this "signal" instance)
	SRR# time stamp
	IDL# source (ie client)
	CRS# routing
	IDL# target (ie server)
	SRR datum  (data object with units of measurement)
	
The above concepts form the heart of the ixmRPC mechanism. They must be sufficient to completely define an instance of a signal that goes from a Client machine to a Server machine. In actual practise, two "commands" (or phrases) are necessary: one to define the routing (a virtual link or wire) and the second to define each (or many) signal instance(s) that is/are sent or received. Once a routing is defined, more than one signal instance can pass through the defined "routing" although different routing instances must be defined.

Example

An example of such an instance is as simple as:
"1,,6,0,0,1"   which defines the "Routing" or "Link" (the "6" is physical pin # 6 which is tied to a LED.)

and

"1,,TC,True"   which defines the signal (a reading or control action). 
               "TC,True" means "T"hrow a "C"ontrol signal to set the LED to "True" ie On.
The omitted parameter is the "time-stamp" which can automatically be inserted by ixmRPC.

To accomplish each action, the user (or his program) can merely send a pair of phrases like those in quotes above. All of the complexity around a single signal instance along a single wire is reduced to two simple text phrases. Of course, much more must be defined somehow somewhere for this to be possible. This article hopefully explains all that a user needs in order to understand how the ixmRPC (or any RPC) mechanism is possible.

The author apologises in advance for all of the "bad untested" Python code that is found below. However, some actual code is needed to truly "show" how RPC works at a "code" level. Python (MicroPython for the Wio Terminal) was chosen because it is the most popular programming language today (in 2023).

The First Function Coded For ixmRPC

The author has chosen a simple PushButton to be the first sensor function used by ixmRPC. A PushButton sensor was chosen because it requires the "Throwing" of a Request action. It also requires a Response which contains the status of the PushButton. Most actuators do not absolutely need a response. When a Client Request is "Thrown" to a Server, the Server "Catches" the request. Then the Server performs the requested action and/or returns the status of the sensor as a Response. The Throwing of the request means that the Request is transferred from one core (one machine ie a computer) to another core. The ixmRPC system often uses a serial USB cable to transport the Requests and the Responses. The eRPC system can also use I2C, WiFi, Bluetooth etc to transport the Requests and Responses. In the cases when the Client and Server cores are the same machine, no Transport is required; the Client routines communicate directly with the Server routines in the same machine.

The first AandC system to be described is the PiR2 Control system that was built by the author some years ago.

AandC My First RPC System: PiR2

The name of the AandC System is "PiR2 Temperature Control". It is a very simple RPC system.

AandC PiR2 System Description

The "PiR2 Temperature Control" system controls the ambient temperature in a local area. It measures the ambient temperature using an electronic thermometer. The system can also control a "Heater" that increases the temperature in the local area.

(To enlarge .....Click it)
thumb: IMG_4569.jpg
The first PiR2A Prototype



At the very left edge, one can see a set of pins that are used to plug into the Raspberry Pi GPIO connector. In the top left corner, the tiny red square board is the TMP102 thermometer. Barely visible is the little "heater" resistor than can be controlled to provide heat to the thermometer. This PiR2 prototype was the first server that the author created. A few internal test points are labelled near the left: 9, 11, 13 and 15 which are physical GPIO pin numbers. A number of labelled external test points can also be seen on the right. The name of the text file containing the external labels is perhaps the first IDL that the author created.

    Essential PiR2 Functions

The five essential functions (or parameters) are:

a) ask the user to define the desired temperature for the area. e.g. 16 degrees Centigrade.
b) function to read the temperature
c) function to add heat to the area. Because the "local area" is small enough, a tiny resistor is used as a heater.
d) ask the user to set the allowable range of temperatures. e.g. plus or minus 2%.
e) the name of the local area being controlled.

Three additional primary functions in the first PiR2 are:

f) the temperature of the internal processor (procTemp). It is included because it is easy to read.
g) the Serial Number of the Client core (which is also easy to read).
h) the IP address of the local Client router (similar to a TransportID).

The "Set-Point" is usually a little higher than the average temperature. This means that the temperature of the local area will slowly be lowered by ambient conditions.

The system is given some freedom so that the heater does not need to continually be functioning. To do this, the system also asks the user to define the acceptable range of termperature for the local area. The electronic thermometer is usually a TMP102 IC that communicates using I2C communications.

    Secondary Functions on some PiR2 models

The "Setting" and the "Range" are built into the program and cannot be changed in the first release of the PiR2 system. The secondary functions are:

i)	The system will display on a monitor the status of the system and what control actions are being taken.
ii)	The system will turn ON a yellow LED whenever the heater is turned ON.
     At first, the system has very limited comunications with the user. This communication is:
iii)	The system can only "talk" to the user by turning on a red led for a variable amount of time.
iv)	The system can ask the user a simple question by printing the question on a monitor.
v)	The user can answer the question by pressing a pushbutton for a variable amount of time.

    Additional Functions on some PiR2 models

Some of the PiR2 systems have the following latent functions:

	A Green (or White) LED
	digIn and digOut
	algIn and algOut
	1 or 2 digLight and/or algLight (using CD cells)
	an additional pushButton
	adcIn01 and adcIn02 (analog to digital converters)
	buzzer

    Additional Peripherals on some PiR2 models

Some of the PiR2 systems have the following peripherals or test-points:

	audioOut (via bluetooth or an audio jack or hdmi)
	hdmiOut (television monitor)
	humidity sensor
	USB charger (for iPhones etc)
	GND
	3v3
	5v0
There are two additional (non-physical) features of the PiR2: a data log and a web-site called "MehInCharge.com". The data log usually keeps a record of a set of samples every 10 seconds. This log can be uploaded to the MehInCharge.com website where the log can be viewed and/or graphed. The uploading of the log must be initiated manually. The MehInCharge website accepts control requests, that are saved until the next log is uploaded. At that time, the current list of latent control requests is downloaded and activated. Source 10 (www) is a link to the MehInCharge.com website. The non-www link of Source 10 is an Article describing the Meh In Charge website. At the www.MehInCharge.com website (shown below), one can see the first list of parameters (log data names) that were built into the PiR2 system. This site was the second Client RPC created by the author. The PiR2 Prototype in the above image is the Server for this RPC system. The first Client of this RPC system was the keyboard and monitor of the Raspberry Pi that is the Client core of this PiR2 RPC system.

(To enlarge .....Click it)
thumb: MIC.jpg
MehInCharge Web Site


CLICK HERE TO GO TO THE WEBSITE

IDL (Information Data or Library)

The author (Webmaster D @ CC ) has created his first IDL for the ixmRPC system. It has been stored in Source 02. The first version of it appears below:

# This was changed on 2023DApr29
	Row Characteristic	Value		#Parm#  eg Value
	### #################	###########	#######	## ######

	#  Parameters Passed
	#01 deviceObject			#Parm01 eg PB22
	#02 clientCoreID                     	#Parm02 eg "abf3"
	#03 serverCoreID                   	#Parm03 eg "abf3"
	#04 RPC:		ixmRPC		#Parm04 eg "ixmRPC"
	#05 GPIOPin:				#Parm05 eg GPIO22
	#06 PhysPin:				#Parm06 eg 15
	#07 SensorMfr:		Generic		#Parm07 eg "Generic"
	#08 SignalName		C(digIn00)	#Parm08 eg "digIn00"
	#09 TimeOutMSecs:	50000		#Parm09 eg 50000

	#   Transport ("Wiring")
	10 Linkage		serialUSB	
	11 FactorA		S(digIn00)
	12 FactorB		False
	13 ReturnParm01:	Sum(FactorA,FactorB)

	#   Shim-Specific
	14 Code:		MicroPython
	15 Mfr:			RPi
	16 Board:		4
	17 SensorModel		Raspberry

	#   "Constant" Attributes
	18 Unique ID		A_PushButton_001
	19 IDLvsn		01.00
	20 IDLauthor:		D@CC
	21 Date:		2023DApr24
	22 AorC:		A
	23 SensorType:		PushButton
	24 Units		Bool
	25 InitialState:	False

	# Returned Information
	26 Returns01:		False
	27 Meaning01:		Low		#	   Voltage
	28 ReturnParm00:	intECode
	29 intECode00:		Success
	30 intECode01:		Timed Out
	31 intECode02:		Error Bad Parameter
	32 intECode03		Error na

	#/ixmRPC_PushButton_001.idl
	
The characteristics listed in the IDL above describe the sensor in fine detail. The IDL characteristics are grouped by:
	parameters passed
	transport-specific
	shim-specific
	"constant" attributes
	Returned Information

When generating the Client and Server routines (code), the IDL information is needed. Therefore it is in the .idl file (except for the passed parameters).

Note that, in the above IDL, there is no actual mention of the details of which pin the pushButton is connected to. Also the identification of the actual machine "cores" is not included. Such information could be defined in a client-specific file and in a server-specific file or in the parameters passed. To simplify the ixmRPC system, these specifics are sent as parameters when calling the client and server shim routines. Users who are familiar with sensors and actuators will be familiar with the idea of including these parameters when the devices are referenced. In the complex world of eRPC, the definition of the client and server core machines will be specified somewhere in text files. These Client and Server equipment details are also used when the shim files are modified to generate the final code from the shim routine code. The eRPC system is designed to "hide" all these details in the final code that is automatically generated.

Usually a Client sensor's value is equal to a Server sensor's value. In this case the RetunParm01 will be equal to the value of the Server's sensor. But occasionally, the Client sensor's Value is a function of two different readings. This is slightly awkward because the ReturnParm01 must be produced using a function of two values. These two values can be from a Client sensor's value and/or a Server sensor's value. These first two examples use functions of only one value. This is done by the following process:

FactorA      = S(digIn00)
FactorB      = Unity(1)
ReturnParm01 = FunctionC(FactorA,FactorB)

or

FactorA      = Unity(1)
FactorB      = Unity(1)
ReturnParm01 = S(digIn00)

In the case of a Server value, the result will be equal to S(digIn00)

Combining two readings

A case (real life example) of where two values must be combined into a single value is where either of two thermostats can call for heat. Say that 1 thermostat produces a lowTemp00 signal and the other produces lowTemp01. The formula to combine their signals is:

anyLowTemp = OR(lowTemp00,lowTemp01)
or
anyLowTemp = Sum(lowTemp00,lowTemp01)
The Sum of two boolean values is the same as the OR of the two values. The IDL to do this would be:
	Row Characteristic	Value		#Parm#  eg Value
	### #################	###########	#######	## ######

        #  Parameters Passed
        #01 deviceObject			#Parm01 eg PB22
        #02 clientCoreID                     	#Parm02 eg "abf3"
        #03 serverCoreID                   	#Parm03 eg "abf3"
	#04 RPC:		ixmRPC		#Parm04 eg "ixmRPC"
	#05 GPIOPin:				#Parm05 eg GPIO22
	#06 PhysPin:				#Parm06 eg 15
	#07 SensorMfr:		Generic		#Parm07 eg "Generic"
	#08 SignalName		anyLowTemp00	#Parm08 eg "anyLowTemp00"
	#09 TimeOutMSecs:	50000		#Parm09 eg 50000

	#   Transport (Wiring)
	10 Linkage		serialUSB	
	11 FactorA		lowTemp00
	12 FactorB		lowTemp01
	13 ReturnParm01:	OR(FactorA,FactorB)

	#   Shim-Specific
	14 Code:		MicroPython
	15 Mfr:			Honeywell
	16 Board:		na
	17 SensorModel		RTH221B1039

	#   Attributes
	18 Unique ID		A_Thermostat_001
	19 IDLvsn		01.00
	20 IDLauthor:		D@CC
	21 Date:		2023DApr25
	22 AorC:		A
	23 SensorType:		Thermostat
        24 Units		Bool
	25 InitialState:	False

	#   Returned Info
	26 ReturnsParm01:	False
	27 Meaning01:		Low		#	   Voltage
	28 ReturnParm00:	intCode
	29 intECode00:		Success
	30 intECode01:		Timed Out
	31 intECode02:		Error Bad Parameter
	32 intECode03		Error Constant Signal

	#/ixmRPC_Thermostat_001.idl
Now, returning back to the first function example: the PushButton.

The first IDL text file (before the Thermostat) defines the specifics of the many parameters that might need to be taken into consideration when the shim code is created for each sensor, actuator or conversion function. The author plans to refer to this ixmRPC_PushButton.idl definition when creating the first shim code for the "RPC client request" (and for the "RPC server response"). A similar IDL file will be generated for the LEDs that are usually driven by an eRPC system as an early example. The PushButton IDL file (named "ixmRPC_pushButton_001.idl" shown high above) will be stored in "/ixmRPC/f_pushButton/client/IDL_definitions/" and in "/ixmRPC/f_pushButton/server/IDL_definitions/". Different shim files will be created for the Client and for the Server. The name of the shim code contains the function name and the programming language. In the case of a simple pushbutton connected to an RPi GPIO pin, on a Raspberry Pi 4, the client shim name will be:
PushButton_MicroPython_Shim_ixmRPC_Client.py
and the server shim name will be:
PushButton_MicroPython_RPi_OnBoard_Shim_ixmRPC_Blocking_Server.py

Client Code

The Client code will be defined in two parts, "the initialization" code and the "read the PushButton" code. For the moment, we shall presume that the Client and the Server are on the same RPi core machine.

The client "initialization" code will be:

    #identify the client and server core by ID
    clientCore="abf3"
    serverCore="abf3"

    GPIO22="22"
    intTimeOut=20000

    #Create the pushButton object only if the client and serverCore are the same
    if clientCore==serverCore :
        isCreated,PB22 = Init_PushButton_RPi_OnBoard_MicroPython_Shim_ixmRPC_Blocking_Server( \
        null,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",lowTemp00,intTimeOut)
        if not isCreated :
            print("Error the PB22 object was not created.")
        else:
            print("The PB22 object was created.")
        #if end
    #if end
The actual code to initialize the PB22 object must appear somewhere. That "somewhere" is here.


    def Init_PushButton_RPi_OnBoard_MicroPython_Shim_ixmRPC_Blocking_Server( \
    null,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",intTimeOut):

        #Create the pushButton object only if the client and serverCore are the same
        if clientCore==serverCore :

            ######################################################
            # 
            #PB22 = etc    #initialize the PB22 object here
            import time
            import RPi.GPIO as GPIO
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(GPIO22,GPIO.IN)
            ######################################################

        #if end
        isCreated = True
        # I don't think GPIO is the same as the object PB22
        # But the following statement might work
        return isCreated,GPIO
    #def end

The client MicroPython ixmRPC "read the pushbutton" code usage should have the usual error-checking mechanisms. That is the reason for the "long code segment" that follows. The code will be:

    #main.py

    GPIO22 = "22"
    intTImeOut=20000

    #The PB22 object must be created before the first RPC "throw"
    #This is true whether or not the client and server are the same machine

    isCreated, PB22 = Init_PushButton_MicroPython_Shim_ixmRPC_Client( \
    null,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",lowTemp00,intTimeOut)
    if not isCreated :
        print("ERROR PB22 was not created")
    #if end

    # End of client initialization

    #

    # Begin client "read the pushButton" routine

    intMaxWait = 60000	# allow the user 60 seconds to push the pushbutton
    intTimeOut = 20000	# 20 seconds
    if intMaxWait < intTimeOut :
        print("ERROR - Max timeOut must be greater than Loop timeOut")
    #if end

    intSecsMaxWait = intMaxWait/1000  #convert msec to sec
    # wait until PushButton on GPIO22 is pressed
    print("Press pushButton on ",GPIO22, "within ",intSecsMaxWait, " seconds")

    intCode = 1          #intCode means "Timed Out"

    while intCode==1:
        # The Blocking-Server needs the Client Routine to handle the time-Outs.

        # NOTE that the PB22 object must be created (as above) before the Throw
        #      if the client and the server are the same machine
	intCode,isPushButton01_True = Throw_PushButton_MicroPython_Shim_ixmRPC_Client( \
        PB22,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",lowTemp00,intTimeOut)

        if intCode>1: print("Error code during Throw:",intCode)
        if intCode==0 : break
        intMaxWait = intMaxWait - intTimeOut
        if intMaxWait < 0 :
            print("Error: No response within ", intSecsMaxWait)
            break
    #while end
    if isPushButton01_True :
        print("PushButton was pressed.")
    else:
        Print("ixmRPC GPIO22 pushButton Error")
    #if end
    #etc

Blocking-Server Code:

The server code will be defined in two parts, "the initialization" code and the "read the pushButton" code. For the moment, we shall presume that the client and the server are on the same RPi machine.

The following code is for a "Blocking-Server". A "Blocking-Server" is a simple server that can only perform one task at a time. Small computers are often "Blocking-Servers" and are not "smart enough" to "juggle" two tasks at a time. They must complete the task at hand before going on to the next task. Some of them just queue up the waiting tasks. Bigger and better computers use electronic interrupts that permit one task to go to "sleep" when its computer has to wait for an external task to be completed. An example of this is when it is waiting for a human to push a button, or when it is waiting for a disk drive to read some data. While the "smart" computer is "sleeping" it can turn its attention to another task and then return to finish the previous task(s) later.

It is interesting to note that the client routines do not need to contain any actual detailed pushButton code. This is normal because it is the server code that must deal with the "messy details" of actually reading the pushButton.

The Blocking-Server MicroPython "initialization code" will be:
    #This code must appear in the main.py
    #identify the client and server core by ID
    clientCore="abf3"
    serverCore="abf3"

    GPIO22="22"
    intTimeOut=20000

    #Create the pushButton object only if the clientCore and serverCore are different
    if clientCore<>serverCore :
        isCreated,PB22 = Init_PushButton_RPi_OnBoard_MicroPython_Shim_ixmRPC_Blocking_Server( \
        null,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",lowTemp00,intTimeOut)
        if not isCreated :
            print("Error PB22 was not created")
        else:
            print("PB22 was created")
        #if end
    #if end
    print("PB22 object is available")
    #etc
The Blocking-Server MicroPython "read the pushbutton" shim code will be:
        #If the clientCore and the serverCore are the same, this code should be in the 
        # Throw shim routine. . . and it should be invoked within the Throw routine.
        #In fact, this statement will be the only major statement in the throw 
	#routine definition.

        #The PB22 object will be an incoming Parameter to the Throw routine as will
        #GPIO22 = "22"
        #intTimeOut=20000
        #clientCore="abf3"
        #serverCore="abf3"

 	Catch_PushButton_RPi_OnBoard_MicroPython_Shim_ixmRPC_Blocking_Server( \
        PB22,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",lowTemp00,intTimeOut)
However, it IS necessary for the actual server shim code to be defined somewhere. That "somewhere" is here:
        #If the clientCore and the serverCore are the same, this code should be called by the 
        # Throw shim routine. That is, it should be invoked within the client Throw routine.
        In fact, a call of this routine will be the only statement in the client Throw routine definition.


 	def Catch_PushButton_RPi_OnBoard_MicroPython_Shim_ixmRPC_Blocking_Server( \
        PB22,clientCore,serverCore,"ixmRPC",GPIO22,15,"Generic",lowTemp00,intTimeOut):

            ###############################################################

            # BP22 should be GPIO in the statement above
            #
            #The actual code to read the pushButton on GPIO22 is needed here
            # This code will not work because GPIO is not PB22

            # default return values if timed-Out
            intCode = 1    		# 1 means "timed out"
            isPushButton01_True = False	# default is "PB was not pressed"
            intSleepTime=intTimeOut/1000
            try:
                while True
                    if GPIO.input(GPIO22):
                        isPushButton01_True = True
                        intCode = 0    # 0 means success
                    else:
                        # needs some "time-Out code" here
                        Doh = True
                        # sleep for a "few" seconds
                        time.sleep(intSleepTime)
                        break
                    #if end
                #while end
            finally:            # CTRL-C comes here
                GPIO.cleanup()
            #try end
            ###############################################################

            #isPushButton01_True = True     #This return with no code above would
            #                             indicate that the GPIO22 is always pushed.
            return intCode,isPushButton01_True
        #def end

The Actual Transport Mechanism

When the clientCore and the serverCore are the same machine, it is not necessary to have a transport mechanism. When the two cores are different machines, it IS necessary to have a communications channel ie a transport such as a serial USB line (or cable) linking the two machines. [ The author has moved the whole ixmRPC part of this article into a new different article (to Article 193 from Article 191) before addressing the Transport mechanism. The actual detailed code dealing with the pushButton will also be deferred until then. This move has now been done and this note will soon disappear. ]

The ixTransport

The ixTransport mechanism is a greatly simplified version of the eRPC transport mechanism. The eRPC is designed to be used by many companies and many individuals to link anyone to anyone across the Internet. Often, the ixmRPC will be used within a single company or household. Such a small purview greatly simplifies the need for a Transport. The transport layer within eRPC needs to route signals between two machines going through many layers such as shown below:

	Client: pin OF device OF machine OF core
	          Routing Between
	Server: pin OF device OF machine OF core
	
In the ixmRPC, only a single identifier (the unique "transportID") is sufficent to link the Client and the Server in ixmRPC. It is sufficient for each signal instance to merely refer to a single identifier such as the following:"

	Client: transportID
	  Routing Between
	Server: transportID
	

Signal Reading Request (SRR)

In fact, the Client and the Server transportIDs could be included as part of the data item when the request (for a datum reading) is Thrown, but they are not because they are already defined in the IDL. Such a Signal Reading Request (SRR) could simply have the following components:

	UniqueDatumRequestID 		(the unique "Throw ID" defines the Throw and the Catch and data)
	TimeStamp			(the Unix timestamp when this DatumRequest was created)
	TransportID			(the TransportID, one ID per bundle of "virtual" wires)
	
This is sufficient information to request an "acquisition" (or "control") "Throw" in ixmRPC. Often the complete routing information in ixmRPC will be limited to one or two (or a small number) of signal pins between only two cores. Merely the Client and Server TransportIDs and other information in the IDL are sufficient to correctly route the signal information. The SRR simply defines a single datum request by its TransportID and TimeStamp. The same SRR can be used for all Signal Requests taken at one TimeStamp. Or a different SRR can be used for each Signal Request. The purpose of the SRR is to define which TransportID unites the data in the SRR records.

Definition of each TransportID collection

All of the ClientTransportID and ServerTransportID definitions should be stored in the /ixmRPC/transports/ folder. Each pair represents a virtual "wire" and is defined by a file in the /ixmRPC/transports/ folder. Each virtual "wire" can be defined by a TransportLink which is identified by a TransportID, as shown below:
	TransportID			(the unique "Transport ID")
	TimeStamp			(the Unix timestamp when the Transport ID was defined)
	ClientTransportID		(the Client Transport I/F ID)
	C(GPIO22)			(the Client pin name)
	SRTFolderID			(containing the Transport definitions each defining a Transport ID)
	signalName			(containing the name of the signal being Transported by this Transport Link
	S(GPIO11)			(the Server pin name)
	ServerTransportID		(the Server Transport I/F ID)
	
Note that more than 1 file in the folder will usually appear with the same unique "Transport ID". This occurs when many virtual "wires" are bundled together in the same Transport Bundle. But note that this Transport Bundle (of virtual wires) need only be defined once. It may never change unless a virtual wire or signalName changes. The ixmRPC mechanism will not use the data in the Transport Links, but will only use the TransportID. At a minimum, each unique TransportID can be the only datum in each record. The TransportID is not to be confused with the ClientTransportID nor the ServerTransportID (both which are not needed in ixmRPC).

In "quick and dirty" ixmRPC code, only one TransportID is needed for a whole collection of data. Again, the TransportID is simply an ID number for a virtual bundle of virtual wires. In the ixmRPC system, only one SRR record need be defined for each "signal" instance to be sensed or controlled. This is explained next.

	TransportID			(the unique "Transport ID")
	
The above record is all that is needed to define a virtual bundle of wires. Unfortunately, it does not document the bundle at all. The code developed by the user defines everything. A second, different virtual bundle of wires must be assigned a different TransportID. This is one major way that the ixmRPC system is much simpler than the eRPC system.

It is not necessary to define the TransportIDs in any detail, except as a good means of documenting the Transport. Only the TransportID (a single number) need be defined. However it is recommended that a description of each TransportID be made for future coding references. Note that these TransportIDs are an important part of the definition of each UniqueDatumRequestID. The "cost" in number of bytes of each "Throw" request can be limited to:

	UniqueDatumRequestID 		 30 characters
	Each "Throw" Request		 22 characters
	Client Signal/Pin Name		  6 characters (eg GPIO22)
	Signal Data Response		  6 characters (Variable length, minimum 6 characters)
	Each signal Data "Overhead"	 25 characters
	Each Acknowledgement		 24 characters
		TOTAL			121 characters
	
This should be an average "reading cost" or "signal data storage cost" of 121 characters (or 115 characters plus the length of each Signal Datum string.) This is comparable to the cost of "simple logging" of such signals which is of the order of 100 characters per Signal Datum. Another consideration is that each "Signal Datum" travels along a real wire at the speed of light, limited only by the processing speed of the cores involved. Whereas an RPC system transfers Signal Data which moves at a speed that is dependant upon the speed (in MBits/second) of the primary Transport mechanism used by the RPC system. The ixmRPC system often uses a serial USB speed of 115,200 bits/second, which is quite fast (but very slow compared to the speed of light).

Each set of ixmRPC data Acquisition packets need only be comprised of:

	UniqueDatumRequestID 		(the "Throw ID")
	TimeStamp			(the Unix timestamp when the SRR was created)
	"TA"				(signifying an Acquisition request being Thrown)
	
Note that the TimeStamp of the UniqueDatumRequestID need not be the same as the TimeStamps of the SRR datumRequests that refer to one UniqueDatumRequestID. In fact, a "pair" (or group) of SRR UniqueDatumRequests (a Throw and a Catch) with different TimeStamps will always relate (link) to the same SRR UniqueDatumRequestID. Then the Response to an Acquisition Request might be:

	UniqueDatumRequestID 		(the same "Throw ID")
	TimeStamp			(the Unix timestamp which may be different)
	"TAR"				(signifying a Response to a Thrown Acquisition request)
	Signal Data			(will be a single bool or integer or alphanumeric datum)
	CompletionCode			(indication Success or Failure Code)
	
possibly followed by an acknowledgement data packet (which might optionally not even be sent)
	UniqueDatumRequestID 		(the same "Throw ID")
	TimeStamp			(the Unix timestamp which may be different)
	"TARK"				(signifying an acKnowledgement Response to a 
						Thrown Acquisition request Response)
	
A Control request signal packet might be:

	UniqueDatumRequestID 		(the "Throw ID")
	TimeStamp			(the Unix timestamp of the Control request)
	"TC"				(signifying Throwing a Control request)
	Signal Data			(will be a single bool or integer or alphanumeric datum)
	
possibly followed by an acknowledgement data packet (which might optionally not even be sent)
	UniqueDatumRequestID 		(the same "Throw ID")
	TimeStamp			(the Unix timestamp which may be different)
	"TCK"				(signifying an acKnowledgement Response to a 
						Thrown Control request )
	
... And the optional response to a Control Request might be:

	UniqueDatumRequestID	 	(the same "Throw ID")
	TimeStamp			(the Unix timestamp which may be different)
	"TCC"				(signifying a confirmation
					  of Completion of Thrown Control request)
	CompletionCode			(indication Success or Failure Code)
	
possibly followed by an acknowledgement data packet (which might optionally be sent):

	UniqueDatumRequestID	 	(the same "Throw ID")
	TimeStamp			(the Unix timestamp which may be different)
	"TCCK"				(signifying  an acKnowleddement of
					  Completion of a Thrown Control request)
	
All of these packets are only necessary if the user needs absolute confirmation of every single datum that is exchanged. In today's world, signal datums are seldom lost. Furthermore when a single signal datum is lost, it rarely creates a life-threatening or costly emergency. The ixmRPC should never be used in such dangerous cases, eRPC should be used instead.

Each data packet should be less than 50 bytes total. The ixmRPC system will only use 8-bit ASCII characters and the English language (no EDCDIC or UNICODE fonts). The overhead of the ixmRPC is very "lite", making it usable in tiny devices like the Wio Terminal often requiring only local Transport capability.

Perhaps it will be necessary to transport whole IDL or SRR files from the Client to the Server, but that requirement has not been planned for. If deemed necessary, the Unique Data Requests will need to be expanded to include the transport of small (under 5000 characters long) .idl or .srr files. This will not be a major problem.

Note that the length of the Signal Data might, in the future, be expanded to permit the transfer of larger objects such as files with the following extensions: .uf2, .py, .jpg, .wav and .zip . In fact, a small number of "OS-like" requests might also be included. To transfer the contents of uSD cards using pathed file names will also be useful, although nothing in this paragraph will be included in the original (first) release of ixmRPC.

Using a VT100 (or minicom or PuTTY) with ixmRPC

Once the UniqueDatumRequest "Line" has been defined, it is possible to Manually request individual Data Acquistion Signal Data (or individual send Data Control Signals). This is normally done using a VT100 emulator such as minicom (or Putty). To request a signal datum (a single reading) the user need only type:

	"1,2,TA" and hit Enter
	
Of course, this must be preceded by the definition of the cores and the ".csr". However the "signal definition" can be defined by:

	Field				Description						Eg. Value
	----------------------		---------------------------------------------------	------
	UniqueDatumRequestID 		(the "Throw ID")					0
	TimeStamp			(the Unix timestamp)					1 (or blank)
	Client Signal/Pin Name/#	(eg pbTrue,GPIO22 or 15)				15
	TransportID			(the Client Transport I/F ID)				3
	CRSFolderID			(containing the list of CRS files defining the pins)	4
The signal reading could be setup very simply by typing "0,1,15,3,4,5" followed by Enter. Or it could even be as simple as "0,0,15,0,1". If the timestamp field is empty, the ixmRPC system will insert the Unix Timestamp automatically into the Throw command. Defining the Signal Datum Request followed by the actual "Throw" request would require the user to only type into the serial USB:

"0,,15,0,1" Enter "0,,TA" Enter.
The status of the pushButton at physical pin 15 will then be displayed on the "Client" screen as "True" or "False" meaning the PushButton is "closed" or "Open" for each reading.

To turn on/off a LED at physical pin 6, once the Transport etc has been defined, simply type in:
"1,,6,0,1" Enter "1,,TC,True" Enter 
"2,,6,0,1" Enter "2,,TC,False" Enter
Of course, the ixmRPC will reply by displaying appropriate responses on the screen. The ixmRPC system is forgiving in that acknowledgements are not necessary.

Recommended ID ranges

It is recommended the the various IDs be assigned numbers as follows:
pin numbers		  	    00 to    99
signal numbers eg puButton00	    00 to    99
transportIDs		 	   200 to   499
IDL			 	   500 to   999
CRS folder ID			  3000 to  9999
SRR				 40000 to 99999
UniqueDatumRequestID		100000 and up   (all unique)
timeStamps			actual Unix Times (in seconds or milliseconds)
Using low recommended numbers, the previous Throw requests would be as in the example following the naming of the fields in the first "datum request".

"UniqueDatumRequestID, Unix time-stamp, physical pin number, transportID, CRSfolderID
"100000,,15,203,3001" Enter "100000,,TA" #request pb status Enter.
and
"100001,,6,203,3002" Enter "100001,,TC,True"  #led on. Enter 
"100002,,6,203,3002" Enter "100002,,TC,False" #led off immediately. Enter
In the above, note that the UniqueDatumRequestID precedes the unix timestamp. This is done so that when the records in the Log File are sorted, all the records pertaining to the same UniqueDatumRequesID will be together, even though each record was probably created at a different time. The other records having the same UniqueDatumRequestID would be the datum value (ie the Response) and/or the acknowledgement .

It is not absolutely necessary for IDs to be in the above ranges but being in the correct range permits the user to identify which value is in which field..

This completes the full definition of the ixmRPC Transport process.

3 UDR (Unique Data Requests)

In the above examples, 3 UDRs are defined: 100001,100002 and 100003. One TransportID, 203, is defined because only one virtual cable is used. Two CRS, 3008 and 3009, specify two devices: a PushButton and an LED. Three Throws are specified, one TA and two TC Throws. It is interesting to see that more folders are required than the number of Unique Data Requests. Of course, once the folders are defined, they can be used many, many times.

IDL Connections: the Absolute Need for a CRS Table


Consider that a Client program is written to read a pushButton on GPIO22 on machine A using ixmRPC. The Server program on a different machine (say machine B) would be coded to actually be interfaced to GPIO11 on its Server machine (core). A good RPC system should be able to convert the GPIO22 to GPIO11 without changing any (or very little) client code. To do this, a user-defined "routing" (or equivalence) table is needed. This table (with an extension of .crs) defines a Client signal Routed to a Server signal. When this is done using hardware, a wire is connected from the Client GPIO22 to the Server GPIO11. Within the ixmRPC system, the C_IDL_R_S_IDL.crs table can be used. The naming of the .crs file applies to control actions that go from the client to the server. Some readers might say that name is not valid for data being sent from the server to the client. (It is true, the name doesn't apply to both directions, we must learn to "just live with it".) To accomplish the equivalent of the GPIO22 to GPIO11 substitution, within the same machine, the C_IDL_R_S_IDL.crs file would be:

	#Note: Route GPIO22 to GPIO11 on the same server
	#
	#attribute	#client	    <->	#server
	------------	-----------	-----------
	crsID		3001		3001
	core		"abf3"		"abf3"
	sensorMfr       Raspberry	Raspberry
	Code:		MicroPython	MicroPython
	AorC:		A		A
	deviceType:	digIn		pushButton
	SignalName	digIn		digIn
	sensorModel	generic         generic
        comment         RPi             use other pin
	device		onBoard		onBoard
	GPIOpin		GPIO22		GPIO11
	PhysPin		15		23
	InitialState:   False		False
	Units		Bool		Bool
	ConvertFunc	unity()         1

	#/C_IDL_R_S_IDL_a.crs
	
As can be seen the GPIOpin or the PhysPin can either be defined in core code as a parameter or in the CRS. If defined in both places, the core code parameter will take precedence over the CRS file. The ixmRPC data log, in the "/ixmRPC/signalData/UniqueDatumRequestIDs/" folder, will certainly show which pins were actually used.

In the above case, consider that the ixmRPC will imitate a "wire" being run from client core GPIO22 to server core GPIO11. The real electronic signal (or data) from the server core will be read from the real server pin GPIO11 and will be "sent" (via the ixmRPC system Transport) to the software on the client core as if it were being read from client core pin GPIO22. No signal will actually be noticed on the pin GPIO22 of the client core machine. This will be done soley by the client core's ixmRPC software in the absence of the existance of a real "wire". Instead, the information sent via the ixmRPC Transport will accomplish what a real "wire" would have done. The software in the client core will "think" that the data on its pin GPIO22 was the same as the data that was on the server core pin GPIO11. This is the beauty of the concept of an RPC. If this concept remains unclear, please re-read this article or ask a knowledgable RPC person for a clearer explanation.

This concept permits the "magical" ixmRPC system to transfer signals from one computer to another without using actual real wires. RPC systems have "super powers". An eRPC system can make i2C transports work like "magic" wires and can turn router Transports into the equivalent of real wires. What an amazing concept! Sampling at its best.

CRS Tables

The following crs table defines a led controlled by a GPIO pin
	#Note: Route GPIO22 to GPIO11 on the same server
	#
	#attribute	#client	    <->	#server
	------------	-----------	-----------
	crsID		3002		3002
	core		"abf3"		"abf3"
	sensorMfr       Raspberry	PiR2
	Code:		MicroPython	MicroPython
	AorC:		A		C
	deviceType:	led		led
	SignalName	digOut		yelLed
	sensorModel	generic         generic
        comment         RPi             use same pin as pushButton
	device		onBoard		onBoard
	GPIOpin		GPIO17		GPIO17
	PhysPin		11		11
	InitialState:   False		False
	Units		Bool		Bool
	ConvertFunc	unity()         1

	#/C_IDL_R_S_IDL_a.crs
	
Within an RPC system, the CRS table is what defines the equivalent of a "real wire" to the Client and Server software. Hopefully the following few examples will illustrate how this is done.

A .crs Table to Route GPIO22 to an Adafruit 4132


To route the GPIO22 signal to an Adafruit model 4132 board (from pin GPIO22 to 4132 pin B01), use the .crs table shown below:
	#Note Route RPi GPIO22 to Adafruit 4132 pin B01 on same server
	#
	#attribute	#client	    <->	#server
	----------	-----------	-----------
	crsID		3003		3003
	core		"abf3"		"abf3"
	sensorMfr       Raspberry	Adafruit
	Code:		MicroPython	MicroPython
	AorC:		A		A
	deviceType:	PushButton	PushButton
	SignalName	digIn		digIn
	sensorModel	generic         4132
	comment         RPi             existing pushB
	device		onBoard		onBoard
	GPIOpin		GPIO22		B01
	PhysPin		15		9
	InitialState:   False		False
	Units		Bool		Bool
	ConvertFunc	unity()         1
	
	#/C_IDL_R_S_IDL_b.crs
	

A .crs Table to Route GPIO22 to a digLight CD sensor on PiR2null


The routing table shown below will route GPIO pin GPIO22 to a digLight sensor on PiR2null connected to the same core (machine). This is shown in the C_IDL_R_S_IDL_c.crs table shown below. The digLight sensor is on GPIO17 on the PiR2Null device.
	#Note Route RPi GPIO22 to PiR2Null GPIO17 on same server
	# Source 01: Article 153: PiR2Null digLight on GPIO17(phys pin 11)
	#
	#attribute	#client	    <->	#server
	------------	-----------	--------------
	crsID		3004		3004
	core		"abf3"		"abf3"
	sensorMfr       Raspberry	ICH180RR
	Code:		MicroPython	MicroPython
	AorC:		A		A
	deviceType:	PushButton	ambientCDLight
	SignalName	digIn		digLight
	sensorModel	generic         PiR2Null
	comment         RPi             home-built
	device		onBoard		onBoard
	GPIOpin		GPIO22		GPIO17
	PhysPin		15		11
	InitialState:   False		False
	Units		Bool		Bool
	ConvertFunc	unity()         1

	#/C_IDL_R_S_IDL_c.crs
	
A collection of numerous .crs tables define all the routings for any single environment. These files must be placed in the folder named "/ixmRPC/crs_routings/". The ixmRPC should verify that the same client pin (ie signal) is not routed to more than one server pin and vice-versa. If all three .crs files (above) were all located in the "/ixmRPC/crs_routings/" folder, the ixmRPC system would reject them as erroneous. The ixmRPC system should also verify that the InitialState of the client and server signals are identical in any single .crs file. If they are not, a WARNING message should result.

Each of the above examples of CRS tables does the equivalent of connecting a real "wire" from the Client core (machine) to the Server core (machine). This is done in the absence of a real "wire".

The whole complexity of the ixmRPC lies in the combination of the CRS table and the parameters passed to the Function called for each signal line. The power of the ixmRPC system is that the parameters and CRS tables can house a host of information describing each virtual wire for each signal line (ie each pin). In ixmRPC, each signal Transport can be very simple or quite complex. It is up to the user (the programmer) and the exact situation at hand.

Various ConvertFunc Routines Are Needed

Hopefully, the .crs files (explained above) will greatly simplify the transfer of code from one application to another, whether it applies to transfers within the same core (machine) or from one core to another via a transport such as a serial USB connection.

Note the potential requirement for a "ConvertFunc" that will be used to convert the units in the server "signal" to units in the client "signal". Examples of different ConvertFunc functions are:

	Unity() - This function makes no change to a numerical signal.
	          This function makes no change to a logical signal.
	          This function makes no change to an alphanumeric signal.
	Invert()- This function converts True to False and vice-versa
	          This function converts a 1 to a 0 and vice-versa
	CfromF()- This function converts Fahrenheit to Centigrade (or Celsius)
	          A sensor on the server might read in Fahrenheit.
	          The conversion CfromF() would be as follows:
	             tempC = CfromF(tempF) where the formula CfromF() is
	             tempC = (tempF - 32 )* 100 / 180.
	          The number read by the server in Fahrenheit must be converted 
	             to Centigrade by RPC software using the CfromF() function before
                     it is returned as a result in Centigrade.
	
It is a valid situation if the .crs folder is empty. Perhaps this is simply to test that the shim routines all work correctly before making any pin changes. Perhaps this is a case of using the transport to use all the device-specific software "as is" on one core. Then to permit sense and control from another identical core using identical GPIO pins. In the latter case, a transport such as a serial USB line is used to connect the 2 cores.

It is the responsibility of the person (the programmer) creating the .crs file to ensure that its contents are correct (including the correct conversion function). The eRPC system will do some of this work automatically when it uses the final code that the user made from the shim code. But the ixmRPC system generates very little code automatically other than invoking the ConvertFunc() when needed.

In this way, the use of the .crs files can greatly simplify the software coding needed to accomplish simple changes of GPIO pins to accomodate different hardware situations. But this is only possible if the ixmRPC code modifications have already been made to the original programs. It is possible to use generic GPIO pins such as "GPIOaa" in the client code, but I believe that a set of working GPIO pins facilitates the coding and testing of the former client code. Generic GPIO pins can often cloud the situation. Furthermore, when converting "old" code to ixmRPC code, it is easier to fact-check the new code if the exact same GPIO pin numbers or names are retained.

It is interesting to note that a conversion from MicroPython to CircuitPython (or vice-versa) can easily be done using .crs files that define two different machines (one with MicroPython and the other with CircuitPython). It is only the one set of shim code that will need to be altered instead of making changes to all of the "deprecated" code. Even changes to the pin names can be automated in this fashion, if necessary. Of course, the "deprecated" code will still need to be converted to its ixmRPC equivalent, manually by the user (ie the programmer). This should be a simpler task than converting the old code directly to CircuitPython code. Furthermore, once the old code has been changed to a type of RPC code, future pin/device adjustments will be much simpler to accomplish.

In the past, the author has found it "bothersome" to pass the actual machine objects as calling parameters to subroutines or functions that need to deal with the pins. The use of the ixmRPC does not change this situation, the objects (eg PB22 in the above examples) still need to be passed as calling parameters.

Folders Used By ixmRPC

	/ixmRPC/f_deCUTime_WioT/client/IDL_definitions/
	/ixmRPC/f_deCUTime_WioT/server/IDL_definitions/
	/ixmRPC/f_deCUTime_WioT/client/shims/
	/ixmRPC/f_deCUTime_WioT/CRS_routings/
	/ixmRPC/f_deCUTime_WioT/server/shims/
	/ixmRPC/f_uTimeoTime_WioT/client/IDL_definitions/
	/ixmRPC/f_uTimeoTime_WioT/server/IDL_definitions/
	/ixmRPC/f_uTimeoTime_WioT/client/shims/
	/ixmRPC/f_uTimeoTime_WioT/CRS_routings/
	/ixmRPC/f_uTimeoTime_WioT/server/shims/
	/ixmRPC/f_ix_UUID_WioT/client/IDL_definitions/
	/ixmRPC/f_ix_UUID_WioT/server/IDL_definitions/
	/ixmRPC/f_ix_UUID_WioT/client/shims/
	/ixmRPC/f_ix_UUID_WioT/CRS_routings/
	/ixmRPC/f_ix_UUID_WioT/server/shims/
	/ixmRPC/f_pushButton/client/IDL_definitions/
	/ixmRPC/f_pushButton/client/shims/
	/ixmRPC/f_pushButton/CRS_routings/
	/ixmRPC/f_pushButton/server/shims/
	/ixmRPC/f_pushButton/server/IDL_definitions/
	/ixmRPC/f_led/client/IDL_definitions/
	/ixmRPC/f_led/client/shims/
	/ixmRPC/f_led/CRS_routings/
	/ixmRPC/f_led/server/shims/
	/ixmRPC/f_led/server/IDL_definitions/
	/ixmRPC/transports/TransportIDs/
	/ixmRPC/signalData/UniqueDatumRequests/
	
There is no need for a folder for Signal Reading Requests (SRR). The SRR are sufficiently defined by each UniqueDatumRequests There is an ixmRPC folder (beginning with "f_" for each ix function. Each ix function has the following 5 folders: client/IDL_definitions/ client/shims/ CRS_routings/ server/shims/ server/IDL_definitions/ Note that the above 5 folders are in 3 folders directly under the function folder. Often the shim folders are empty. The CRS_routing tables are perhaps the most important because they specify the manufacturer device names, part numbers models and pin numbers. Unlike in eRPC, none of the data in these folders is used directly by the ixmRPC system. None of the ixmRPC coding makes direct use of the information in these folders. All of the information in the folders is gathered for the coder (programmer) to reference. The ONLY folders that need information are the ixmRPC/transports/, ixmRPC/CRS_routings/ and ixmRPC/signalData/UniqueDatumRequests/. The CRS_routingID numbers must be listed in the ixmRPC/transports/ folder under the appplicable folder. (This has not been explained yet.) No explicit definition of each CRS_routingID is needed. Note that the folder "/ixmRPC/signalData" can be emptied or backed up without losing the integrity of the ixmRPC system. It is recommended that all the "crs_routings" files be retained in case the same situation should need to be repeated in the future.

Of course, the user's AandC programs should be backed up on a regular basis. When such a backup is done, it is recommended that all of the "/ixmRPC/function_*/ folders (and the /ixmRPC/Transport" folders) should also be backed up as well (and stored along with the AandC programs).

As more and more RPC functions are defined, more functions must be given different names. These unique function names should specify the different devices, manufacturers and programming languages that distinguish them.

Signal Reading/control Requests (SRR)

Each SRR ID is first defined, then it is used in a series of Unique Datus Requests (UDR). The acKnowledgements should occur. The only situation when acknowledgement would be suppressed is when the sample readings or control signals are at very high speeds. At high speeds, the UDRs can be so close together (with such small time intervals between signals) that there is no time to send the acKnowledgements. As can be seen in the log listed below, the timeStamps are NOT in IXcomplex format; there is no "j" in each timestamp. The IXcomplex format is not yet necessary because the Unix time and the control (or response) signals appear together in the same UDR record. There is no possibility of the timeStamp and its signal sample getting separated. If the signal stream is extremely fast, there might not be enough time for the log to "keep up with" the actual electronic signals, it is possible for the IXcomplex format to be sent as a data file instead of sending each signal sample (or signal control number) separately. Of course, in this case, the whole list of control signals must be sent before the string of numbers begins. In the case of signal sample readings, the IXcomplex list must be buffered in the server and sent after the whole list of readings have been collected. Very frequent sample readings or control signals can exceed the memory capacity of the server. This situation will eventually result in ixmRPC transmission errors in one direction or the other.
#				# 203 below is transportID
"100000,1683570944,15,203,3001"	# define a UDR, ref to pb use
"100000,1683570946,TA" 		# request pb status
"100000,1683570947,TAR,False,0"	# pb is up (False)
"100000,1683570948,TARK"	# acK
"100001,1683570960,6,203,3002"	# define a UDR,  ref to led use
"100001,1683570962,TC,True"  	# led on (True).
"100001,1683570963,TCK"		# acK
"100001,1683570964,TCC,0"	# success
"100001,1683570964,TCCK"	# acK
"100002,1683570965,6,203,3002"	# define a UDR,  ref to led use
"100002,1683570966,TC,False" 	# led off (False) immediately.
"100002,1683570966,TCK"		# acK
"100002,1683570968,TCC,0"	# success
"100002,1683570969,TCCK"	# acK
Three things should be noted about the logged UDR records shown above. First, there is neither parity information nor message hash totals included in the ixmRPC system. Second, each timeStamp is in Unix Time format. Despite the fact that MicroPython uses a different time epoch than the Unix Epoch, the ixmRPC UDR records will only use Unix Time. However, the IXcomplex format timeStamps, as defined in ixmRPC, can work with a different time epoch, such as the time epoch used by MicroPython. If the actual Unix Time is not known by the server, the server is permitted to use time stamps that are relative to the time of the each SRR definition which is always sent by by the client core. (The client core always is aware of the exact Unix Time.) No indication of the server's use of relative times is necessary because relative times are always so much smaller than today's Unix Time (as of 2023). Third, the IDs, timeStamps and data are all text strings, not integers (nor floating point number) formats. The sequence of UDRs could be transmitted much faster if the numbers were sent in binary format. But the transfer of extremely high speed data is NOT the goal of the ixmRPC mechanism which often uses serial USB transports. To achieve the highest speed transfers, the user should implement the eRPC system which hopefully includes parity, hash totals, packet sequence control and high speed transports such as I2C or the Internet.

Resume of ixmRPC virtual data

A human interactive interface exists for the ixmRPC system. Using this interface, a human user can manually sense and control various devices. More importantly, software can automatically sense and control these same devices. Whether interractive or automatic, some data tables are necessary. Perhaps the most basic data table is the transport table. The transport table gives a name and ID number to the transport, even if the transport is a null transport. A null transport is what is called a connection between devices or pin in the same (client or server) computer. Normal hardware transports require a cable composed of multiple wires. A null transport connects one pin to another in the same device ( say a Raspberry computer). A null transport has no actual cable, but a male and a female pin might make the connection or even a jumper wire. A virtual transport uses a virtual cable, virtual pins and "virtual signals". The ixmRPC system connects one or more virtual signals from one virtual pin to another virtual pin. These virtual signals are called virtual data.

A real pushButton can be connected to a real LED using either a real wire or using a virtual wire (if the ixmRPC system is used). My Article 196 will describe how to set up a real pushButton and a real LED ready to be remotely controlled using ixmRPC. The ixmRPC software will enable the real pushButton to control a real LED without any wires. The transport used will be a serial USB cable. Once set up, the user can press and then release the pushButton to turn the LED on and off. This will be done with no wires connecting the pushButton and LED. A log of this activity will be analyzed in Article 196.

ixmRPC Waveforms

The waveforms (eg a sine wave at a certain frequency and amplitude) can be passed along a virtual wire using the ixmRPC system. The waveform must be sampled often enough for the "shape" of the sine wave to be evident. When digital computers are used to "emulate" waveforms, a sampling technique is used very often. A list of samples of the signal is the result. The list of signal samples that accumulates in the "/ixmRPC/signalData/UniqueDatumRequestIDs/" folder is a similar list of samples. In Article 164 (Source 07) and Article 168 (Source 06) the author has written about the use of "digital oscilloscopes" and "digital signal generators" using digital sampling software. Article 164 is a very long article that describes actual sampling hardware, methods and examples. The Raspberry Pi Pico computer is equipped to create a set of electronic samples (a "sampled" waveform) and to do the sampling of an analogue waveform. The Raspberry Pi Pico uses the Raspberry RP2040 IC chip to incorporate a small number of very simple high speed state-machines that can be used to create high frequency digital waveforms or to sample the equivalent analog waveforms. These state-machines generate PIO, PWM, SPI, I2C etc. The "Maker Pi Pico" (described in Article 164 in Source 07) by Cytron adds tiny peripheral devices to the Raspberry Pi Pico to convert it into a great device for digital waveform analysis and generation.

ixmRPC Lexicon (c2023)

See article 193 for a Lexicon of ixmRPC terms.

Wio Terminal PinOuts

(To enlarge .....Click it)
thumb: Wio-Terminal-pinout-mischianti-high-resolution.png

Wio Terminal Best PinOuts (from mischianti.org)

Other Thoughts

CAVEAT: Servers With Passive Components

Any RPC system will NOT function correctly if either the client or the server makes use of "passive components" connected directly to the physical transport. The previous sentence conveys a lot of information. Unfortunately, the Wio Terminal does INCLUDE such "passive components". The physical transport used by the Wio Terminal is the set of 40 GPIO pins. The Wio Terminal can be connected to the physical transport but without any power. The non-physical transports used by the Wio Terminal are the serial USB connector, BlueTooth and WiFi. The "passive components" in the Wio Terminal are the various devices that are connected to the GPIO pins. Examples of these "passive components" on the Wio Terminal are some of the following devices:

the 3 pushButtons
the 5 uJoystick buttons
the tiny blue led
the microphone
the buzzer
the InfraRed emitter
the light sensor
the ADCs
the uSD card
the Pulse Modulated Outputs
the UARTs
the LCD monitor screen
the devices attached to the Grove Connectors
In the absence of power (and with no software running on the Wio Terminal), the "passive components" will not be activated by the Wio Terminal. Therefore they will not exhibit the desired (expected) behavior by ixmRPC. However, these "passive components" can interact with (control or be controlled by) signals on each wire or pin of the physical transport: the GPIO connector. When the Wio Terminal has power and "is running" the ixmRPC software, there should be no problem with the ixmRPC "mechanism" or system.

In simpler terms, a Wio Terminal can be connected (by pins or wires) to a client core such as an RPi computer. The Wio Terminal will interact with electronic signals on the GPIO interface (for example, the blue led might flash on/off when controlled by the RPi). The Wio Terminal can do this even if power and software are not provided to the Wio Terminal. Unless power and the ixmRPC software are both provided to the Wio Terminal, the ixmRPC software cannot properly control its "passive components" such as the blue led on the Wio Terminal. On the Wio Terminal, some of the "passive components" can interact electronically in the absense of power and active ixmRPC software.

In normal electronic terms, "passive" components are modern devices without semiconductors e.g. resistors, capacitors, pushButtons, switches etc. Under this heading, "passive components" include the semiconductors in the devices listed above.

LA104: Digital Logic Analyzer

(To enlarge .....Click it)
thumb: LA104.jpg

2.8" 4 channel USB 100MHz LA104

(To enlarge .....Click it)
thumb: LA104Screen.jpg

2.8" 4-channel LA104 Display

This LA104 device can be bought at Amazon for US$244 and is shipped from China. I have not yet bought a LA104.

My first thoughts were to use a Digital Logic Analyzer on the serial USB line. But, initial investigations indicated that associated with any USB interface there are many control signals. These signals are sent to distinguish between multiple IDs, set speeds, types of signals along with the actual serial data. A serial USB channel is not simple, it is very complex compared to an old-fashioned asynchronous serial bit stream. Data going through a single UART is much less complex. The ancient RS232 ports of 40 years ago seldom exist in today's computers (as of 2023).

The Wio Terminal could be persuaded to transmit such signals, but who would be there to receive them? A good example of a modern sensor is the tiny TMP102 IC that measures temperature, converts the reading into Centigrade digits, and sends the final "human-readable" value via an I2C transport along a shared serial 4-wire cable. Today's automobiles use long I2C cables to communicate with all the devices in the car. This I2C communications protocol

Insert / Overwrite

The other day, I accidentally converted my typing cursor from a vertical bar "|" into a solid square (meaning "overwrite" mode of typing). I was unable to change it back into "insert" mode. When I hit the key marked "Ins / prt sc" on my old "HP Pavilion dv7" laptop keyboard, it offered to save an image of a portion of the screen. Today, I discovered how to convert the keyboard back to "insert" mode. I needed to use fn-"Ins / prt sc" which I did by holding the "fn" key down while I hit the "Ins / prt sc" key. Of course, this made a lot of sense, once I knew what to do.

Maker Pi pHAT

See Source 02 (MagPi issue 129 pg ) for this 3 year old, useful expansion board by Cytron (shown below mounted on a old Raspberry Pi board).

(To enlarge .....Click it)
thumb: Maker_Phat.jpg

Maker pHAT for Raspberry Pi

Also see the Pi: Maker pHAT Users Manual (Source 03) by Cytron, or my Article 170 which also describes the Maker pHAT. The Source 03 also explains how to use PuTTY, which is an alternative to minicom, that I normally use. The Maker pHAT contains a UART that can communicate using old-fashioned serial Asynchronous communications (not USB serial). PuTTY can be used to initially communicate with the "client" laptop or RPi computer via the Maker pHAT module. PuTTY either communicates using serial USB or WiFi. Once operational, it is possible to run the RPi in headless mode (without any keyboard, mouse or display) using Remote Desktop Connection (RDC) that comes with Windows. It's a pity that the Maker pHAT doesn't have any ADC capability, something that is sorely lacking on every Raspberry Pi computer.

The Maker pHAT Users Manual also contains a schematic diagram for the Maker pHAT board. My Article 170 also contains a list of 50 Useful Linux Terminal Commands. The Article 170 also shows how to create your "first" Raspberry Pi microSDcard using only an Ethernet cable. Another part of Article 170 describes how to easily view (document) the current status of your Raspberry Pi by using the "sh Environ.sh" terminal command. The Environ.sh routine needs some additional small files, so make sure to set it up correctly.

One of the reasons that the Maker pHAT board is mentioned here is because it is possible to communicate with the RPi using plain serial asychronous communications (in addition to serial USB) via the Rx (U2RX) and Tx (U2TX) pins on the Maker pHAT board. It is possible because the Maker pHAT board has a non-USB UART onboard in the FT231XS IC. The U2RX and U2TX pins on the Maker pHAT are not to be confused with GPIO pins named GPIO15 (UART_RXD) and GPIO14 (UART_TXD) on the RPi. When the GPIO of the Maker pHAT is connected to the GPIO of an RPi, there are 2 serial USB ports, one on the Maker and one on the RPi. The serial USB port on the RPi is used to control the RPi via a USB cable connected to a nearby Laptop (or a second RPi). This leaves the serial USB port on the Maker available. Therefore, it is possible to connect any other serial USB device to the Maker. Any device connected to the Maker pHAT via its serial USB connector will be able to communicate via the Rx (U2RX) and Tx (U2TX) pins on the Maker pHAT board. If you find this confusing, reread this paragraph or refer to the User Manual in Source 03.

Conclusion

End of Article (Sources Follow)

Sources

Video Sources

Video Source V195:01:www Exploring the Wio Terminal ( 1:14 min) by Seeed Studio in 2021

Web Sources

Web Source S195:01:www Pi: PiR2Null Area Controller (153) by D@CC as of 2021BFeb08
Web Source S195:02:www Pi: Maker pHAT for 40 pin GPIO by PhilKing as of c2020EMay00
Web Source S195:03:www Pi: Maker pHAT Users' Manual by Cytron as of c2020EMay00
Web Source S195:04:www Pi: Useful Raspberry Pi Device Family Terminal Commands (170.html) by David Cole as of c2022BFeb25
Web Source S195:05:www LA104 Logic Analyzer User Manual by minidso as of 2014CMar24

WebMaster: Ye Old King Cole

There is a way to "google" any of the part-numbers, words and phrases in all my articles. This "google" search limits itself ONLY to my articles. Just go to the top of "ePC Articles by Old King Cole" and look for the "search" input box named "freefind".

Click here to return to ePC Articles by Old King Cole

Date Written : 2023 E May 09
Last Updated : 2023 G Jul 02

All rights reserved 2023 by (c) ICH180RR

saved in E:\E\2022\DevE\MyPagesE\Globat\ePhotoCaption.com\a\195\195.html
backed up to ePhotoCaption.com\a\195\195_2023EMay09.html
Font: Courier New 10 (monospaced)
/195.html