As noted in Arduino for STM32 Black 'n Blue Pills, ESP32-S[2,3] ,
SimHub's Custom Serial devices plugin has limitations
- SimHub plugin Javascript is relatively inefficient, hard to debug and maintain.
- Plugin can log but not process received serial port messages e.g. from Arduino.
- Serial data is limited to 7 bits per character.
This Fake8
SimHub C# plugin connects to an STM32 Arduino USB COM port,
using 8 bit characters and SimHub properties,
some of which are from SimHub's Custom Serial device plugin messages
via a second serial port and signed virtual com0com
Null-modem.
This leverages the SimHub Custom Serial devices plugin user interface:
... while most heavy lifting gets done by this Fake8
plugin.
Sadly, Custom Serial devices
user interface Settings are local to that plugin and inaccessible elsewhere.
Consequently, a Custom Serial devices
profile
sends control settings for processing by this plugin,
via a COM8 com0com
null modem Serial port.
Overhead is minimized by using simple NCalc expressions to generate setting change messages.
Unlike JavaScript, NCalc Update messages repeat even if unchanged unless explicitly conditional
by change().
Incoming COM8
serial data to SimHub's Custom Serial plugin may combine Arduino and Fake8
strings.
Inspired by MIDI, Fake8
to Arduino 8-bit protocol supports 73 commands:
- For [re]synchronization, only the first byte of each command has msb == 1
- For 63 of 73 commands. 5 lsb of first byte is an Arduino sketch-specific command:
- setting e.g. PWM parameters: (frequency, % range, predistortion, pin or clock number)
- second byte is either 7-bit data or count for appended 7-bit byte array of values.
- One array command echoes that array.
- One non-array command echoes that second byte.
- For 3-byte commands, 2 lsb of first byte are 2 msb of 16-bit data.
- For a single 2-byte command, 5 lsb of first byte are 5 msb of 12-bit data.
- A single 1-byte command restarts Arduino run-time sketch.
- plugin communicates both with SimHub Custom Serial plugin (via
com0com
) and STM32 Arduino- current Arduino sketch merely echos ASCII hex for received bytes, confirming 8-bit communications
- next step will be adding configurable PWM to the Arduino sketch
for e.g. PC fans and Direct Drive harness tension testing.
- skeletal PWM_FullConfiguration sketch implemented, along with F8reset in
Fake8.cs
- unable to get both COM ports working robustly in a single class.
Simply create properties from Custom Serial port messages inFake7
plugin;
then, use those properties inFake8
plugin for Arduino.
This will not impact game latency, since telemetry will not come thru Custom Serial plugin. - look into building both plugins in a single project
search results
- The problem is Fake7 hanging on write back to Custom Serial via
com0com
;
Read works ok, and and both Read and Write work to e.g. Arduino Serial Monitor.
Changed F8.iniFake8rcv
setting tof9
fromArduino
,
allowing Fake7 to read a property that changes without Fake8.
- Confirmed that Custom Serial
Incoming serial data
andcom0com
are by default incompatible;
FWIW, Arduino serial terminal works fine on COM8 instead of SimHub's Custom Serial device...??!!
finally got beyondCustomSerial.Write(prop);
timeout by forcingcom0com
setting:
change CNCB0 PortName=COM2,EmuOverrun=yes,ExclusiveMode=no,cts=on,dsr=on,dcd=on
EmuOverrun=yes
by itself did not suffice; isolating essential setting is low priority. - Both ports work; Fake8receiver() can call Fake7.CustomSerial.Write(),
but needs exception handling (e.g. reopen)
- Recover Arduino USM COM disconnect/reconnect events; similar code for
com0com
implemented but untested.
- Delegate fork merged to main.
- Write() timeout recovery for Custom Serial
- Arduino queues a power-on message
- SimHub initializes Fake8 before Custom Serial
- Fake8 Arduino message Write() to Custom Serial times out.
- could increase Write() timeout, but recovery is generally wanted.
- Custom Serial port now gets checked at each DataUpdate()
- SourceForge's
com0com
virtual null modem package does not work on recent Windows 10 versions.- get Pete Batard's signed
com0com
driver. - an alternative may be test-signing the SourceForge
com0com
driver.
- get Pete Batard's signed
- Trying to use
com0com
virtual COM ports in C# fails unless its PortName begins withCOM
.- Free 'busy' COM port numbers using COM Name Arbiter Tool
Run as Admin, uncheck wanted and currently unused ports:
- Free 'busy' COM port numbers using COM Name Arbiter Tool
Arduino.DtrEnable = true;
is required for C# to read from Arduino, but not forcom0com
.- Unable to restart Arduino sketch by toggling
Arduino.DtrEnable
andArduino.RtsEnable
. - Unable to get both COM ports working robustly in a single class.
- Working example using delegate for data from C# Serial Port
DataReceived
thread to invoking thread. - SimHub Custom Serial device receiving (Incoming serial data) seems uniquely incompatible with
com0com
.
Configure a com0com
virtual null modem
- Run as Adminstrator
com0com\setupc.exe
: (see com0com ReadMe for instructions)
command> change CNCB0 PortName=COM2
CNCA8 PortName=-
CNCB8 PortName=-
CNCA0 PortName=FAKE8
CNCB0 PortName=SIM8
change CNCB0 PortName=COM2
Restarted CNCB0 com0com\port \Device\com0com20
ComDB: COM2 - logged as "in use"
command> change CNCB0 ExclusiveMode=yes
CNCA8 PortName=-
CNCB8 PortName=-
CNCA0 PortName=FAKE8
CNCB0 PortName=COM2
change CNCB0 PortName=COM2,ExclusiveMode=yes
Restarted CNCB0 com0com\port \Device\com0com20
command> change CNCA0 PortName=COM8
CNCA8 PortName=-
CNCB8 PortName=-
CNCA0 PortName=FAKE8
change CNCA0 PortName=COM8
Restarted CNCA0 com0com\port \Device\com0com10
CNCB0 PortName=COM2,ExclusiveMode=yes
ComDB: COM8 - logged as "in use"
command> change CNCA0 PlugInMode=yes
CNCA8 PortName=-
CNCB8 PortName=-
CNCA0 PortName=COM8
change CNCA0 PortName=COM8,PlugInMode=yes
Restarted CNCA0 com0com\port \Device\com0com10
CNCB0 PortName=COM2,ExclusiveMode=yes
command> list
CNCA8 PortName=-
CNCB8 PortName=-
CNCA0 PortName=COM8,PlugInMode=yes
CNCB0 PortName=COM2,ExclusiveMode=yes
Seemingly, PlugInMode=yes
and ExclusiveMode=yes
make no difference..
- Serial Port Communication codeproject.com "Although the code is self explanatory, I will explain little."
- uses
Invoke()
; closes serial port after each read
- uses
- Serial Comms in C# for Beginners codeproject.com useful, ignoring hardware pin handling
- mostly about UI; also uses
Invoke()
.
- mostly about UI; also uses
- Improving the Performance of Serial Ports Using C# codeproject.coma
- handshaking protocol; multiple threads.
- Arduino, C#, and Serial Interface codeproject.com
- Uses, but does not implement
NewWeatherDataReceived
event handler.
- Uses, but does not implement
- Top 5 SerialPort Tips
- Inapplicable to
ReadExisting
; potential deadlock onClose()
.
- Inapplicable to
- SerialPort Encoding
- Instead, use bytes...
- learn SerialPort Class
- uses threads and no event handlers
- instructables Serial Port Programming With .NET
- very simplistic, no data handling;
does not use passed object inSerialDataReceivedEventHandler
, which is presumably acallback()
...
- very simplistic, no data handling;
- Communicate with Serial Port in C# c-sharp corner
- Introduces delegate for cross-thread data transfer and a read thread,
- Using a C# Application to Communicate with an Arduino
- Far better than usual comments and descriptions; very modular and simple code.
- Signed
com0com
Null-modem emulator - Link for Installing; FAQs
- callback()s run in other threads, can set only statics while invoked
- have some static class for handling callback updates asynchronously
- STM32 Blue Pills are relatively cheap and easy by BluePill
- configuring as other than COM port, not so much
- Merge Fake8 with MIDIio, so that e.g. asynchronous serial reads from Blue Pill
can be directly written to e.g. vJoy or MIDI