System design and custom software to support “Eskin 4 the Visually Impaired” to be presented at ISEA, the International Symposium of Electronic Art in Durban, South Africa, 23rd –30th of June 2018.

Overview

A performance stage is instrumented with stage sensor units, equipped with a projection and a surround sound system. An audio-visual controller unit is used to implement the logic of the multimedia installation and produces visualizations as well as surround sound output based on the performers position and actions.

3 stage sensor units are combined to provides an approximately 3m x 9m large performance space that tracks the performers location and pose, received sensor data from the performers wearables, and relays this data to the controller unit for processing.

The performance space is monitored with several Microsoft Kinect body tracking controllers.

The performer is equipped with two wearables, a MYO bracelet that tracks the performers relative arm motion and captures gestures, and a Bitalino based skin sensor that records biometric features of the performer.

All units communicate with each other via a local ethernet network. Wearables communicate with the stage sensor unit wirelessly via Bluetooth.

The controller’s programs combines the data streams of the performers into an audio-visual presentation as HD video for the audience. The spatialized audio creates a feed-back loop for the performers and is kept in sync with the performance.

The eSkin components including individual sensors, sensor/Kinect PCs, Max/MSP audio processing and TouchDesigner video processing are connected via a local area network (LAN).

Source Code

http://www.ferzkopp.net/Projects/eSkin4.zip

Requirements

  • Windows 10 (any edition, version 1709 or later)
  • VisualStudio 2017 (any edition)
  • Internet connection to download nuget packages

Detailed System Design

eSkin4Sensors : Kinect

Introduction

The eSkin4Kinect program interfaces with one Kinect v2 unit and sends the tracking data of up to 4 bodies to a MQTT message queue or as OSC UDP packets to control multimedia applications.

Requirements

  • PC with a minimum dual-core @3.5GHz and USB 3 input (quad-core needed for >15Hz tracking rate)
  • Kinect for XBox One with PC adapter kit
  • KinectSDK v2.0 installed (KinectSDK-v2.0_1409-Setup.exe)

User Interface

[1] Indicates Kinect sensor is enabled and connected.

[2] Indicates a body that is tracked. Each body is identified with a unique body ID which remains the same as long as the body is continuously tracked. Shown is a sample of the tracking data (the head position) for the body. Up to 4 bodies are tracked.

[3] Preview of the camera with an approximate overlay of the skeletal tracking information.

[4] Open notepad with the default/permanent configuration of the program. After a configuration change, the program needs to be closed and relaunched.

[5] MTQQ broker IP, topic path, messaging count and rate (updated once a second).

The “Reconnect” button allows to reset the connection to the MQTT broker if the connection was lost or is stuck or if the IP was changed manually.

Messages can be saved to a text file for debugging or external use using the “Save messages to log file”. The file is created when the checkbox is enabled, after which collection of any new messages starts. The file is closed and collection is stopped when the checkbox is disabled again.

[6] OSC target IP and port.

The “Reconnect” button allows to reset the OSC connection if the IP was changed manually.

[7] The bottom of the UI shows a console log; most recent message are shown on the top.

Configuration

The eSkin4Kinect.exe.config file stores a several <appSettings>  – these can be changed by editing the .config file with a text editor before launching the program. A runtime configuration is currently not supported.

Use the [Config] button in the program to launch the correct App.config file.

The kinectJoints node of the settings allows the selection of any of the 25 available joints for messaging: SpineBase, SpineMid, Neck, Head, ShoulderLeft, ElbowLeft, WristLeft, HandLeft, ShoulderRight, ElbowRight, WristRight, HandRight, HipLeft, KneeLeft, AnkleLeft, FootLeft, HipRight, KneeRight, AnkleRight, FootRight, SpineShoulder, HandTipLeft, ThumbLeft, HandTipRight, ThumbRight

 <!--
  Define list of joints to be processed.
  - Comma seperated list of joint names:
  - Shortcut "All" to select all available joints. 
 -->
     <add key="kinectJoints" value="All" />
  

The  mqttBrokerHostname node configures the target MTQQ broker hostname or IP:  

    <add key="mqttBrokerHostname" value="192.168.0.200" />

The OSC output is configured via the oscAddress and oscPort nodes:

    <add key="oscAddress" value="192.168.0.202" />
    <add key="oscPort" value="7780" />

The following are development settings that enable or disable features and should not be changed:

    <add key="kinectIsEnabled" value="true" />
    <add key="mqttIsEnabled" value="true" />
    <add key="oscIsEnabled" value="true" />

Messaging

Whenever a new tracked skeleton is reported by Kinect, the program emits a message for each tracked joint to the connected MTQQ broker.

The message has the following JSON formatted payload:

 {
   "BodyId": "00000de2", 
   "JointId": "Head",           
   "X": -0.428,
   "Y": 0.057,
   "Z": 1.541,
   "Type": "KinectBodyMessage",
   "Source": "ESKINPC1",
   "Timestamp": "2017-11-19T16:11:54.1884804-08:00"
 }

BodyId: unique identifier for a tracked body; stays the same as long as the same body is being tracked continuously, but changes whenever a body leaves the field-of-view and re-enters the scene.

JointId: the joint for which the position is being reported; SpineBase, SpineMid, Neck, Head, ShoulderLeft, ElbowLeft, WristLeft, HandLeft, ShoulderRight, ElbowRight, WristRight, HandRight, HipLeft, KneeLeft, AnkleLeft, FootLeft, HipRight, KneeRight, AnkleRight, FootRight, SpineShoulder, HandTipLeft, ThumbLeft, HandTipRight, ThumbRight

X,Y,Z: position coordinates reported by Kinect for the joint;

  • The origin (x=0, y=0, z=0) is located at the center of the IR sensor on Kinect
  • X grows to the sensor’s left
  • Y grows up (note that this direction is based on the sensor’s tilt)
  • Z grows out in the direction the sensor is facing
  • 1 unit = 1 meter

Type: always KinectBodyMessage

Source: name of the PC that send the message; used to differentiate Kinect message for multi-Kinect/multi-PC setups.

Timestamp: local time of the PC when the message was sent in the format Year-Month-Day T Hour:Minute:Second.Subseconds – GMT Offset

Sample Message Sequence

{"BodyId":"00000e30","JointId":"SpineBase","X":0.325,"Y":-0.335,"Z":1.2,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.1884804-08:00"}
{"BodyId":"00000e30","JointId":"SpineMid","X":0.341,"Y":0.02,"Z":1.264,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2531769-08:00"}
{"BodyId":"00000e30","JointId":"Neck","X":0.352,"Y":0.351,"Z":1.308,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2571754-08:00"}
{"BodyId":"00000e30","JointId":"Head","X":0.329,"Y":0.492,"Z":1.36,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2571754-08:00"}
{"BodyId":"00000e30","JointId":"ShoulderLeft","X":0.225,"Y":0.186,"Z":1.405,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2581792-08:00"}
{"BodyId":"00000e30","JointId":"ElbowLeft","X":0.126,"Y":0.046,"Z":1.527,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2581792-08:00"}
{"BodyId":"00000e30","JointId":"WristLeft","X":-0.011,"Y":0.152,"Z":1.554,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2581792-08:00"}
{"BodyId":"00000e30","JointId":"HandLeft","X":-0.039,"Y":0.19,"Z":1.562,"Type":"KinectBodyMessage","Source":"ESKINPC1","Timestamp":"2017-11-19T17:00:08.2581792-08:00"}
…

References

Kinect for Windows SDK 2.0

https://www.microsoft.com/en-us/download/details.aspx?id=44561

Custom software can use functionality using managed API in C#.

https://msdn.microsoft.com/en-us/library/windowspreview.kinect.aspx

MaxMSP Integration

JSON-formatted messages are send to specified IP and port on the /Kinect/Joints route in OSC format.

In MaxMSP reception would use: udpreceive [Port] -> route /Kinect/Joints -> dict.deserialize -> dict.unpack [Key] where [Key] is one of the message properties: BodyId, JointId, X, Y, Z, Type, Source, Timestamp.

Additional References

 

TouchDesigner Integration

JSON-formatted messages are send to the specified MQTT broker (i.e. 192.168.0.200). A MQTT client needs to subscribe to the /Kinect/[JointName] topic and parse the data contained in the message into a DAT table.

Example for SpineBase joint:

  • Create output DAT table (i.e. /project1/MQTTdata/kinectSpineBaseDat)
  • Create MQTT client (i.e. /project1/MQTTdata/mqttclient1)
  • Add the following Python code to the MQTT client TD object
#
# eskin4 Kinect MQTT message adapter
#

# Module for parsing JSON
TDJ = op.TDModules.mod.TDJSON

# Output DATs
kinectSpineBaseDat = op('/project1/MQTTdata/kinectSpineBaseDat')
# Repeat for other joints as needed:
# kinectWristLeftDat = op('/project1/MQTTdata/kinectWristLeftDat')
# kinectWristRightDat = op('/project1/MQTTdata/kinectWristRightDat')

# Input MQTT connection and topics
a = op('/project1/MQTTdata/mqttclient1')
a.subscribe('/Kinect/SpineBase',qos=0)
# Repeat for other joints as needed:
# a.subscribe('/Kinect/WristLeft',qos=0)
# a.subscribe('/Kinect/WristRight',qos=0)

# Called when connection established
def onConnect(dat):
 return

# Called when connection failed
# dat - the OP which is cooking
# msg - reason for failure
def onConnectFailure(dat, msg):
 return

# Called when current connection lost
# dat - the OP which is cooking
# msg - reason for failure
def onConnectionLost(dat, msg):
 return

# Called when server receives subscription request
# dat - the OP which is cooking
def onSubscribe(dat):
 return

# Called when subscription request fails.
# dat - the OP which is cooking
# msg - reason for failure
def onSubscribeFailure(dat, msg):
 return

# Called when server receives unsubscription request
# dat - the OP which is cooking
def onUnsubscribe(dat):
 return

# Called when unsubscription request fails.
# dat - the OP which is cooking
# msg - reason for failure
def onUnsubscribeFailure(dat, msg):
 return

# Called when server receives publish request
# dat - the OP which is cooking
def onPublish(dat):
 return

# Called when new content received from server
# dat - the OP which is cooking
# topic - topic name of the incoming message
# payload - payload of the incoming message
# qos - qos flag for of the incoming message
# retained - retained flag of the incoming message
# dup - dup flag of the incoming message
def onMessage(dat, topic, payload, qos, retained, dup):
 message = payload.decode('utf-8')
 kinectJsonObject = TDJ.textToJSON(message, orderedDict=False, showErrors=False)
 if (topic == '/Kinect/SpineBase'):
 kinectDat = kinectSpineBaseDat
# Repeat for other joints as needed:
# if (topic == '/Kinect/WristLeft'):
# kinectDat = kinectWristLeftDat
# if (topic == '/Kinect/WristRight'):
# kinectDat = kinectWristRightDat
 kinectDat.clear()
 [kinectDat.appendRow([key, val]) for key, val in sorted(kinectJsonObject.items())]

 

eSkin4 Sensors : MYO

Introduction

The eSkin4Myo program interfaces with up to 3 MYO armbands and sends the pose and tracking data to a MQTT message queue or as OSC UDP packets to control multimedia applications.

Requirements

  • The PC with a Myo Bluetooth USB dongle attached.
  • Myo Connect application installed.
  • Myo bands paired with the PC, named and calibrated.

User Interface

[1] Indicates Myo sensors are enabled and the Myo Hub interface is connected.

[2] Indicates a Myo band that is tracked. Each Myo is identified with a name (as set using the Myo Connect Armband Manager application). The last received gesture pose is shown.

[3] Value level data that are streaming in (Gyroscope, Accelerometer, Orientation) will be shown here as XYZ or WXYZ.

[4] Open notepad with the default/permanent configuration of the program. After a configuration change, the program needs to be closed and relaunched.

[5] Topic (MQTT) and route (OSC) paths are shown here. The route is dynamic and include the Myo name.

[6] MTQQ broker IP, messaging count and rate (updated once a second).

The “Reconnect” button allows to reset the connection to the MQTT broker if the connection was lost or is stuck or if the IP was changed manually.

Messages can be saved to a text file for debugging or external use using the “Save messages to log file”. The file is created when the checkbox is enabled, after which collection of any new messages starts. The file is closed and collection is stopped when the checkbox is disabled again.

[7] OSC target IP and port.

The “Reconnect” button allows to reset the OSC connection if the IP was changed manually.

[8] The bottom of the UI shows a console log; most recent message are shown on the top.

Configuration

The eSkin4Myo.exe.config file stores a several <appSettings>  – these can be changed by editing the .config file with a text editor before launching the program. A runtime configuration is currently not supported.

Use the [Config] button in the program to launch the correct App.config file.

MYO

The myoRateReductionLevel node configures a rate reduction for streaming Myo data:

    <!-- Reduces rate of MYO data, 1 to 10 -->
    <add key="myoRateReductionLevel" value="5" />

1 – all events are send as message

5 – only every 5th event is send as a message

10 – only every 10th event is send as a message

MQTT

The  mqttBrokerHostname node configures the target MTQQ broker hostname or IP:  

    <add key="mqttBrokerHostname" value="192.168.0.200" />

OSC

The OSC output is configured via the oscAddress and oscPort nodes:

    <add key="oscAddress" value="192.168.0.202" />
    <add key="oscPort" value="7780" />

Developer

The following are development settings that enable or disable features and should not be changed:

    <add key="myoIsEnabled" value="true" />
    <add key="mqttIsEnabled" value="true" />
    <add key="oscIsEnabled" value="true" />

Messaging

Whenever a new pose is reported by the Myo band, the program emits a Pose message.

The Pose messages have the following JSON formatted payload:
{“Arm”:”Right”,”Pose”:”FingersSpread”,”DeviceId”:”2601497391824″,”DeviceName”:”eSkin4Myo1″,”Type”:”MyoPoseMessage”,”Source”:”ESKINPC1″,”Timestamp”:”2017-11-26T02:35:47.6709262-08:00″}

A constant stream of tracking data from each Myo band is also reported at a fixed rate as Value messages:

The Value messages have the following JSON formatted payload:

Gyroscope

{“Arm”:”Right”,”X”:-0.438,”Y”:0.375,”Z”:-0.438,”DeviceId”:”2601497391824″,”DeviceName”:”eSkin4Myo1″,”Type”:”MyoValueMessage”,”Source”:”ESKINPC1″,”Timestamp”:”2017-11-26T02:35:47.6649109-08:00″}

Orientation

{“Arm”:”Right”,”W”:-0.198,”X”:0.077,”Y”:-0.207,”Z”:0.955,”DeviceId”:”2601497391824″,”DeviceName”:”eSkin4Myo1″,”Type”:”MyoValueMessage”,”Source”:”ESKINPC1″,”Timestamp”:”2017-11-26T02:35:47.7391081-08:00″}

Accelerometer

{“Arm”:”Right”,”X”:0.06,”Y”:-0.407,”Z”:0.858,”DeviceId”:”2601497391824″,”DeviceName”:”eSkin4Myo1″,”Type”:”MyoValueMessage”,”Source”:”ESKINPC1″,”Timestamp”:”2017-11-26T02:35:47.7401139-08:00″}

DeviceName: The device name as configured with the Myo Connect application. The mirrors the topic/route used to send the messages.

DeviceId: a unique identifier for the device; remains the same as for each connected Myo band for each invocation of the program

Arm: the arm that was configured (or detected) for the Myo band; values can be Right or Left.

Pose: The detected pose; one of: Rest, Fist, WaveIn, WaveOut, FingersSpread, DoubleTap, Unknown

W,X,Y,Z: values reported by Myo for the specific sensor data:

Accelerometer: The X, Y Z accelerometer data of myo is reported in units of g.

Gyroscope: The X,Y, Z gyroscope data of myo is reported in units of deg/s.

Orientation: The orientation data of myo is reported as a W,X,Y,Z Quaternion.

Source: name of the PC that send the message; used to differentiate Myo messages for multi-Myo/multi-PC setups.

Timestamp: local time of the PC when the message was sent in the format Year-Month-Day T Hour:Minute:Second.Subseconds – GMT Offset

References

Bluetooth Setup

Each MYO sensor needs to be paired with the PC via the systems Settings -> Bluetooth dialog

In the Bluetooth dialog, select “Add device…” and select the MYO band in the dialog (should be identifiable by a name).

If the device cannot be found, remove old (unknown) pairings – usually called “Myo Armband” and try again:

Also make sure the MYO band is not already paired with another device – otherwise it will not be discoverable.

The Myo band name should be a unique word without spaces or special characters (i.e “eSkin4Myo1”) as it is used in the topic/route of the message.

Myo Control Configuration

The default configuration of Myo Control needs to be updated for presentation use to disable the presentation functions. From the Myo Control taskbar icon, open “Preferences”

Also the Application Manager has to be configured as follows:

MaxMSP Integration

JSON-formatted messages are send to specified IP and port on the /[Name]/[Sensor] route in OSC format.

For MaxMSP reception one would use: udpreceive [Port] –> route /[Name]/[Sensor] –> dict.deserialize –> dict.unpack [Key] where

  • [Name] is the Myo name,
  • [Sensor] is Pose, Gyroscope, Accelerometer or Orientation
  • [Key] is one of the message properties:
    • DeviceName
    • DeviceId
    • Arm
    • Pose
    • W
    • X
    • Y
    • Z
    • Type
    • Source

Additional References on MaxMSP Integration

 

TouchDesigner Integration

JSON-formatted messages are send to the specified MQTT broker. A MQTT client needs to subscribe to the /[Name]/[Sensor] topic, where

  • [Name] is the Myo name,
  • [Sensor] is Pose, Gyroscope, Accelerometer or Orientation

The received message content can then be converted into a DAT structure; i.e. pseudocode:

 
def onMessage(dat, topic, payload, qos, retained, dup):
 message = payload.decode('utf-8')
 jsonObject = TDJ.textToJSON(message, orderedDict=False, showErrors=False)
 if (topic == '/[Name]/[Sensor]'):
 sensorDat = sensorTopicDat
 sensorDat.clear()
 [sensorDat.appendRow([key, val]) for key, val in sorted(jsonObject.items())]

Additional References on TouchDesigner Integration

eSkin4Sensors : Bitalino

Introduction

The eSkin4Bitalino program interfaces with up to 3 Bitalino sensor boards and sends the digital and analog data to a MQTT message queue or as OSC UDP packets to control multimedia applications.

Requirements

  • The PC with a Bluetooth interface (built-in or USB dongle)
  • Bitalino boards paired with the PC.

User Interface

[1] Indicates Bitalino sensor board configuration (MAC address of the Bluetooth interface and a name); the name is only shown when the board is connected

[2] Indicates a Bitalino sensor board is connected. Each board is identified with a name (as configured in the applications configuration). Digital (D1 to D4) and analog (A1 and A6) channel data that is streaming in will be shown.

[3] Open notepad with the default/permanent configuration of the program. After a configuration change, the program needs to be closed and relaunched.

[4] Topic (MQTT) and route (OSC) paths are shown here. The route is dynamic and include the Bitalino name.

[5] MTQQ broker IP, messaging count and rate (updated once a second).

The “Reconnect” button allows to reset the connection to the MQTT broker if the connection was lost or is stuck or if the IP was changed manually.

Messages can be saved to a text file for debugging or external use using the “Save messages to log file”. The file is created when the checkbox is enabled, after which collection of any new messages starts. The file is closed and collection is stopped when the checkbox is disabled again.

[6] OSC target IP and port.

The “Reconnect” button allows to reset the OSC connection if the IP was changed manually.

[7] The bottom of the UI shows a console log; most recent messages are shown on the top.

Configuration

The eSkin4Bitalino.exe.config file stores a several <appSettings>  – these can be changed by editing the .config file with a text editor before launching the program. A runtime configuration is currently not supported.

Use the [Config] button in the program to launch the correct App.config file.

Bitalino

The bitalino1Address and bitalino1Name nodes configure Bitalino 1:

    <add key ="bitalino1Address" value="20:16:07:18:23:73" />
    <add key ="bitalino1Name" value="eSkin4Bit1" />

The bitalino2Address and bitalino2Name nodes configure Bitalino 2:

    <add key ="bitalino2Address" value="20:16:12:22:50:69" />
    <add key ="bitalino2Name" value="eSkin4Bit2" />

The bitalino3Address and bitalino3Name nodes configure Bitalino 3:

    <add key ="bitalino3Address" value="" />
    <add key ="bitalino3Name" value="eSkin4Bit3" />

The bitalinoSampleRate node sets the sample rate for the data acquisition of all connected Bitalino’s:   

    <add key ="bitalinoSampleRate" value="10" />

and can be set to a value of 1, 10 or 100.

MQTT

The  mqttBrokerHostname node configures the target MTQQ broker hostname or IP:  

    <add key="mqttBrokerHostname" value="192.168.0.200" />

OSC

The OSC output is configured via the oscAddress and oscPort nodes:

    <add key="oscAddress" value="192.168.0.202" />
    <add key="oscPort" value="7780" />

Developer

The following are development settings that enable or disable features and should not be changed:

    <add key="bitalinoIsEnabled" value="true" />
    <add key="mqttIsEnabled" value="true" />
    <add key="oscIsEnabled" value="true" />

Messaging

The bitalino sensor board sends its data as a data frame. The Frame messages have the following JSON formatted payload:

{
 "Address":"20:16:07:18:23:73",
 "Seq":7,
 "D1":true,
 "D2":true,
 "D3":false,
 "D4":false,
 "A1":605,
 "A2":506,
 "A3":0,
 "A4":517,
 "A5":38,
 "A6":0,
 "Type":"BitalinoFrameMessage",
 "Source":"ESKINPC1",
 "Timestamp":"2017-11-26T05:54:29.3909639-08:00"
}

Address: The MAC address of the sending Bitalino.

Seq: A sequence number for the frame; changes from 1 to 16.

D1 to D4: State of the digital inputs.

  • D1: Switch

A1 to D6: Values of the analog inputs.

  • A1: EMG (muscle/motion); 10-bit resolution (0-1023)
  • A2: ; 10-bit resolution (0-1023)
  • A3: EDA (resistance); 10-bit resolution (0-1023)
  • A4: ; 10-bit resolution (0-1023)
  • A5: Accelerometer; 6-bit resolution (0-63)
  • A6: LUX (light); 6-bit resolution (0-63)

Type: Always BitalinoFrameMessage.

Source: name of the PC that send the message; used to differentiate Bitalino messages for multi-Bitalino/multi-PC setups.

Timestamp: local time of the PC when the message was sent in the format Year-Month-Day T Hour:Minute:Second.Subseconds – GMT Offset

Out-Of-Range Condition

When the sensor goes out of range, data acquisition initially slows, then stops. This condition is recoverable as long as the Bluetooth connection is maintained.

If the Bluetooth connection fully breaks, the data acquisition thread stops and a manual [Reconnect] needs to be initiated (auto-recovery is currently not supported).

References

Bluetooth Setup

Each Bitalino sensor needs to be paired with the PC via the systems Settings -> Bluetooth dialog

In the Bluetooth dialog, select “Add device…” and select the Bitalino band in the dialog (should be identifiable by the last two digits of the MAC address (i.e. “Bitalino-25-76”).

MaxMSP Integration

JSON-formatted messages are send to specified IP and port on the /[Name]/Frame route in OSC format.

For MaxMSP reception one would use: udpreceive [Port] –> route /[Name]/Frame –> dict.deserialize –> dict.unpack [Key] where

  • [Name] is the Bitalino name as configured in the App.config,
  • [Key] is one of the message properties:
    • Address
    • Seq
    • D1 to D4
    • A1 to A6
    • Type
    • Source

Additional References for MaxMSP

TouchDesigner Integration

JSON-formatted messages are send to the specified MQTT broker. A MQTT client needs to subscribe to the /[Name]/Frame topic, where

  • [Name] is the Bitalino name as configured in the App.config,

The received message content can then be converted into a DAT structure; i.e. pseudocode:

 
def onMessage(dat, topic, payload, qos, retained, dup):
 message = payload.decode('utf-8')
 jsonObject = TDJ.textToJSON(message, orderedDict=False, showErrors=False)
 if (topic == '/[Name]/Frame'):
 sensorDat = sensorTopicDat
 sensorDat.clear()
 [sensorDat.appendRow([key, val]) for key, val in sorted(jsonObject.items())]

Additional References on TouchDesigner Integration

eSkin4 : Message Simulator

The included utility application eSkin4MessageSimulator can be used to send custom MQTT messages on demand or in regular intervals to the MQTT broker for development purposes.

 

 

eSkin 4 Sensors

Leave a Reply

Your email address will not be published. Required fields are marked *