For the specific case of controlling hobby servos for harness tensioning by STM32 "blue pill" modules,
single (7-bit) character controls were implemented here:
and more addressable channels (pins) is wanted (at least, by @sierses and me),
involving multi-character USB message support for more than 7 bits of information,
while minimizing overhead in data traffic, SimHub message and Arduino code complexity.
Since USB, unlike e.g. TCP/IP, lacks inherent message integrity,
a mechanism is wanted that minimizes bad consequences for characters lost e.g. to EMI.
Arduino sketch and matching SimHub profiles on Github
single (7-bit) character controls were implemented here:
.. but a more general implementation with more value precision (reducing a need for lookup tables)Human vision can discern roughly 100 just noticeable differences in print densities and CRT display intensities, which made 8-bit digital intensity values, with appropriate non-linearities, suitable for rendering smooth tone gradients. On the other hand, for simulating acceleration forces by harness tensioning, slowly and smoothly incrementing tensions is not compelling. So long as e.g. felt differences between tension steps 4 and 12 are roughly equal to differences between steps 8 and 16, I see no value in rendering an undetected tension increment between any two adjacent steps.
A custom serial Javascript SimHub message was hacked to test for noticeable tension increments:
.. resulting in this "linearization" of perceived tension increments:JavaScript:// Repurpose gain sliders for just noticeable tension steps // servo range: 2 to 90 if ($prop('Settings.max_test') || $prop('Settings.TestOffsets')) return; var d = new Date(); var dg = Math.max($prop('Settings.decel_gain'),2); // base tension var yg = $prop('Settings.yaw_gain'); // tension increment if (null == root["odg"]) { root["odg"] = dg; root["oyg"] = yg; } if (dg != root["odg"] || yg != root["oyg"] || null == root["Time"]) { root["Time"] = d.getTime(); root["odg"] = dg; root["oyg"] = yg; } var s = root["Time"]; var t = d.getTime() - s; // four tension difference pulses over 3.5 seconds if (3500 < t) d = 2; // timeout: release tension else if (3000 < t) d = dg + yg; // base + difference tensions else if (2500 < t) d = dg; // base tension else if (2000 < t) d = dg + yg; else if (1500 < t) d = dg; else if (1000 < t) d = dg + yg; else if (500 < t) d = dg; else d = dg + yg; // may be even or odd var o = 1 + d; // the other one //return d.toString()+"\t"+o.toString(); return String.fromCharCode(d)+String.fromCharCode(o);
View attachment 476039
.. where servo values 2 to 90 map to percent rotation values 0 to 100 in the previous reply.
With maximum servo tension about so much as wanted without being distracting,
only 21 tension increments could be perceived under nearly ideal conditions,
including not being distracted by trying to drive at the same time.
Slightly coarsening steps to 16 allows encoding tensions to 4 bits,
leaving 3 of 7 ASCII bits for addressing 7 servos and one address reserved
for downloading a lookup table to convert those 4 tension bits back to servo values.
Applying swingarm geometry to servo values results in this plot
for equalizing perceived tension increments with belt movement:
View attachment 476048
and more addressable channels (pins) is wanted (at least, by @sierses and me),
involving multi-character USB message support for more than 7 bits of information,
while minimizing overhead in data traffic, SimHub message and Arduino code complexity.
Since USB, unlike e.g. TCP/IP, lacks inherent message integrity,
a mechanism is wanted that minimizes bad consequences for characters lost e.g. to EMI.
Arduino sketch and matching SimHub profiles on Github
Last edited: