Package: optoforce
import optoforceA package which simplifies connecting to and reading from optoforce sensors, using PythonThis is mainly here to accompany myblog postson communicating with embedded systems using python, where the optoforce sensor is an example. I hope this package is simple enough to serve as a template for others. I see that there areother packageson GitHub which help with thisI don't imagine it'll have many users, sincethe optoforce websiteredirects to another company which doesn't even mention them, andthatcompany'soptoforce pageis pretty blank. BUT I use one, so perhaps there are others?Installationpython-mpipinstalloptoforceUsageFrom a python script:# 16 byte frame/single-channel 3 axis force sensor (OMD-45-FH-2000N)fromoptoforceimportOptoForce16asOptoForcefromoptoforce.statusimportno_errorswithOptoForce(speed_hz=100,filter_hz=15,zero=False)asforce_sensor:measurement=force_sensor.read(only_latest_data=False)assertmeasurement.valid_checksumassertno_errors(measurement.status)do_stuff_with_force_readings(measurement.Fx,measurement.Fy,measurement.Fz)A call toOptoForce.read()returns a measurement packet (a NamedTuple) containing force readings and other potentially useful data. For the specifics of each sensor model, seeReading16,Reading34andReading22inoptoforce/reading.py. For exampleOptoForce34returns force readings asFx1,Fy1,Fz1,Fx2, ... (notFx,Fy,Fz) as there are multiple channelsIt's still a little verbose, so you may want to define shortcuts for your particular application. For example, if you don't care about anything except the vertical force:withOptoForce()asforce_sensor:read_fz=lambda:force_sensor.read(only_latest_data=False).FzwhileTrue:print(read_fz())If you haven't read the force force sensor in a little while and want to get all the packets waiting in the buffer, use:measurements=force_sensor.read_all_packets_in_buffer()Or from the command line, to log to a file:$python-moptoforce--filenameforce-data.csvIf you want to detect and handle sensor errors as reported in the status word, look at the doc string inoptoforce/status.py. It was written for completeness after I finished my use for the OptoForce, so it hasn't been tested!OptoForce models supportedPossibly,16 byte frame/single-channel 3 axis force sensor (OMD-45-FH-2000N)34 byte frame/multi-channel 3 axis force sensor (4 channels)22 byte frame/single-channel 6 axis force/torque sensorbut I only have access to the 16 byte frame model, so I can't test the other two. The 34 byte modelhas been reported to work too. I imagine this means that the 22 byte model will be fine, but the torque readings aren't scaled as I don't have that datasheet :/SourcesOptoForce General DAQ - USB,CAN,UART - v1.7.pdfwas used to implement this moduleThe force scale parameters are fromSensitivityReport-PFH0A052.pdfA friend mentioned that I might not be allowed to share those docs, since the company is quite secretive, and I unfortunately haven't seen them onlineCommon bugsIf you get permission errors when trying to open the serial port and you run linux, try running the code below (source)$sudochmod666/dev/ttyACM0# replace with your serial portPermission errorscan also happen on Windows-- you'll know that's the case when you get an error which includesOriginal message: PermissionError(...).  That can happen whensomething else is using the device. In that case, making sure no other program is connected to the device should work. You could do that by unplugging the sensor, and plugging it back in again.DevelopingSeepython-templatefor some general tips on Python package development.Run unit tests usingpytest. You should see output similar to,$python-mpytest========================================testsessionstarts========================================platformlinux--Python3.9.6,pytest-6.2.4,py-1.10.0,pluggy-0.13.1
rootdir:/home/alex/dev/optoforce,configfile:pyproject.toml,testpaths:tests
collected6itemstests/test_all.py......=========================================6passedin0.02s=========================================If you havematplotlibinstalled, you can run a more visual test using$pythontest-plot.pyPublishing a new versionInstallflit, which makes publishing packages ridiculously easy. You can install it as part of your development environment, or in a base/systemwide environment, as it's just used for publishing but isn't a requirement of the package itself.Next, increase the__version__number inoptoforce/__init__.py. Then, create a (local) tag for the commit and publish:# make a local tag of the current commit$gittagv0.0.1# push local tag to remote repo$gitpushoriginv0.0.1# generate files into dist/ and upload them to pypi$flitpublish