HaddingtonDynamics / Dexter

GNU General Public License v3.0
367 stars 85 forks source link

USB Interface? #44

Open JamesNewton opened 5 years ago

JamesNewton commented 5 years ago

Could another mode be added to DexRun.c that accepted the same standard command format currently used for the network socket interface, but via the USB console connection? Upon connection, the host program (e.g. DDE) could issue commands to pkill DexRun then ./DexRun 1 4 0 (where 4 is the serial command mode) and then start communicating with DexRun. The binary return data might be an issue, but it could be translated into hex, or even ascii numbers. The limitation on socket size doesn't apply to a USB connection.

The advantage of a USB connection is that for a single computer / Dexter com link, there is no issue of IP address or mismatched subnets.

The disadvantage is that it can be difficult to recognize which USB serial port is Dexter if there are more than one serial device connected. The only information provided by a USB device is the VID (Vendor ID) and PID (Peripheral ID) and the chip used on the MicroZed board is just a standard SciLabs CP2102, which is often used in other USB/serial devices. Changing the VID/PID is possible but would cause the OS to not know what driver to load. Registering a new VID/PID with an OS vendor is a non-starter. Providing a driver that isn't registered is prohibited on later Windows versions. The best way to id the Dexter is probably to ask the user to disconnect it, look at the ports list, then reconnect it, and the port that shows up is the Dexter. Once the chip has enumerated as a serial port, the port number shouldn't change, even if the Dexter is disconnected and reconnected, so future communications should be immediate.

cfry commented 5 years ago

I've liked this basic idea for a long time.

Why would we have stop kill and restart Dexrun? Can't it just always listen on a serial port AND the regular socket interface? If it gets a valid oplet on the serial port, it handles it as it would a regular oplet and sends out the response on the serial port.

As for detecting what serial port is a dexter, how about I do something in DDE kind of like I did for Ping, i.e. send a "g" instruction to all the serial ports and whichever ones return a value robot status, I inform the user?

In a Dexter object instance in DDE, the ip_address can be a path to a serial port instead of an IP address, and pretty much DDE would work similarly.

JamesNewton commented 5 years ago

It might be possible to accept commands from both the sockets and serial from the same run. But it would be a problem if both serial and network commands were sent at the same time. As long as we don't worry about that, it should be ok. We would need to flag the source of the command, so the response would go back to the same place...

A mad scientist might connect a doomsday device to his or her USB port via the CP2102 and program it to blow up the world if it ever receives the command "g" for "go destroy the world". More seriously, you can't just send characters out serial ports without understand what the device on that port is going to do with that command. Perhaps we could setup the serial interface such that it would send a character or string /from/ dexter every so often... DDE could listen on each unconnected port for that signal. But in that case, if DexRun is always sending those string to the serial console will cause a serious slowdown when nothing is there to pick them up. Not sure how to resolve that issue.

cfry commented 5 years ago

" More seriously, you can't just send characters out serial ports without understand what the device on that port is going to do with that command." My "port scanner" idea has this problem, but once you know that you're using a particular serial port for something, my architecture is the same as normal communications. I agree that sending from Dexter every so often just in case DDE is listening is bad. We could automate the process somewhat of:

  1. "grab list of serial port devices."
  2. "tell user to plug in their Dexter"
  3. "tell them what's changed in the list collected in step 1."

On Sat, Dec 1, 2018 at 11:46 PM JamesNewton notifications@github.com wrote:

It might be possible to accept commands from both the sockets and serial from the same run. But it would be a problem if both serial and network commands were sent at the same time. As long as we don't worry about that, it should be ok. We would need to flag the source of the command, so the response would go back to the same place...

A mad scientist might connect a doomsday device to his or her USB port via the CP2102 and program it to blow up the world if it ever receives the command "g" for "go destroy the world". More seriously, you can't just send characters out serial ports without understand what the device on that port is going to do with that command. Perhaps we could setup the serial interface such that it would send a character or string /from/ dexter every so often... DDE could listen on each unconnected port for that signal. But in that case, if DexRun is always sending those string to the serial console will cause a serious slowdown when nothing is there to pick them up. Not sure how to resolve that issue.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/HaddingtonDynamics/Dexter/issues/44#issuecomment-443481250, or mute the thread https://github.com/notifications/unsubscribe-auth/ABITfZGYUgm9qtEfb78WICu4T-nnxuBfks5u01sUgaJpZM4Y8vEe .

AndrewSmart commented 5 years ago

The best way to id the Dexter is probably to ask the user to disconnect it, look at the ports list, then reconnect it, and the port that shows up is the Dexter.

As for detecting what serial port is a dexter, how about I do something in DDE kind of like I did for Ping, i.e. send a "g" instruction to all the serial ports and whichever ones return a value robot status, I inform the user?

More seriously, you can't just send characters out serial ports without understand what the device on that port is going to do with that command.

This is what I do with lots of instruments, but they largely follow a standard protocol, SCPI.

Consider the industry standard (for test and measurement devices) SCPI query "*IDN?". Device should return a 4 field, comma delimited response identifying what it is, e.g.: "TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04" means you're talking to a TEKTRONIX TDS210! The last field often says a serial number and firmware version.

Per SCPI spec:

4.1.3.6 *IDN?
IEEE 488.2 is purposefully vague about the content of each of the four fields in the response syntax. SCPI adds no further requirement, but here are some suggestions:
All devices produced by a company should implement the *IDN? response consistently.
   Field 1, the Manufacturer field, should be identical for all devices produced by a single company.
   Field 2, the Model field, should NOT contain the word “MODEL”.
   Field 4, the Firmware level field, should contain information about all separately revisable subsystems. This information can be contained in single or multiple revision codes.

By sending an IDN? string to each connected serial interface, I can know what is hooked up where. Sometimes devices use different commands, for those I send a sequence of termination characters so it clears its buffer and doesn't get confused next time something tries to talk to it (code at old company, don't recall what the sequence was, like \r\n maybe other obscure ASCII chars in a certain order). But, responding to IDN? would allow you to play nice with others. I wouldn't be surprised if someone playing with Dexter also has a programmable DC Powersupply, multimeter, oscilloscope, or somesuch also connected over serial to his computer.

I don't think you need to deal with VISA to be nicer. It would say if something is already talking over that interface, so you don't interrupt!, and many other nice features, but maybe complexity of software not worth it (e.g. from DDE wrap around the VISA C API, requires installation of the VISA Shared Components). Handling "*IDN?" query would be sufficient.

Dec04 EDIT: If you do want to look into VISA, I suppose testing with any suitably licensed 3rd party's redistribution of the VISA Shared Components would be fine. Link against visa64.dll (or equivalent on Mac/Linux platforms). I apologize I can't do much coding right now... time crunch with other priorities but I thought I'd share this possibility with you. It is a nice technology, I highly recommend it especially if you want to connect to multiple devices (robot arms, other test & measurement devices) from the same computer and/or do the aforementioned serial polling by cfry. I don't believe there would be any license or vendor lock-in issues (you don't need NI products or MATLAB's instrument toolbox), you just need the visa64 shared library. Looks like the R&S VISA utilities are free anyway (but you don't need them, they're just nice & convenient UIs).

JamesNewton commented 5 years ago

The current placement of the fan, at the bottom of the microzed board, blocks all the USB connectors (and the sd card). Moving the fan out to the skin and ducting the air to the stepper motor drivers would give us the physical access we need for this USB connector... and the USB hub for connecting peripherals to Dexter.

JamesNewton commented 5 years ago

The problem with a serial connection to the Zinq is that it is already connected to the CP2102 USB converter chip. To connect directly that chip would have to be removed or bypassed.

An Android tablet (available for as little as $40) could host a USB OTG connection to the console connector on the microZed, and run an app developed to be the control panel, or an app that provides a terminal, or one that provides display services to a program running on Dexter.

It is possible to lock an Android down to a "kiosk" mode which runs only one app: https://developer.android.com/work/dpc/dedicated-devices

An app like DroidScript (which runs JavaScript programs) can access the OTG USB port and communicate effectively. http://droidscript.org/

JamesNewton commented 5 years ago

The idea of using an Android tablet via USB OTG to the console cable appears to work well. An app has been developed that shows the basic functionality.

The problem is finding a low cost but still in production tablet which will BOTH operate in OTG mode AND charge over a single USB port. A list has been started based on research: http://techref.massmind.org/techref/io/usb/OTG.htm

In any case, this requires a special form of USB OTG cable: an Accessory Charging Adapter: http://techref.massmind.org/techref/io/usb/power.htm#ACA

However, a tablet with a DC power jack avoids this issue by not using the USB connector for power. Currently an Ainol Q88 Android 7.1 with 1GB RAM is on the way. It has a DC power jack and is said to support OTG.

JamesNewton commented 5 years ago

Ainol Q88 Android 7.1 works nicely and has been connected to the console overnight without discharging. It did NOT come with the DC power adapter, but I had one from the prior tablet which had died so I was able to use that. +5 volt 1 amp adapters are easily found. Getting the correct connector may be slightly more difficult, but can be done. Or the case can be opened / removed and the wires just soldered directly to the +5 volt bus on Dexter.

JamesNewton commented 3 years ago

Kamino cloned this issue to HaddingtonDynamics/OCADO