Anything I can forget to do manually, I will forget to do manually! It's even more likely to be forgotten if it only happens once a month.Tormach don't release a new version every day!
Anything I can forget to do manually, I will forget to do manually! It's even more likely to be forgotten if it only happens once a month.Tormach don't release a new version every day!
There's a #define you can change to do regular digitalRead() instead. Also, I think the 32u4/Leonardo has fewer I/Os so you may need to change the specific pins used. The MSG_PIN (pin with LED) may be a different pin, too? I haven't used the Arduinos in a long time, so I don't remember exactly.is there anything else Teensy specific in your example?
And, finally, do the Leonardos do SerialUSB instead of Serial for the USB serial port? You'd have ot update that, too.
And if your serial port needs a baud rate, Tormach uses 38400.
The basic loop and command/serial parsing should work fine. It's really not very complicated, once I figured out the bits it wanted.
I added a #define to make it work with a regular Uno instead (set ON_ARDUINO to 1) and you should be able to go from there!
Thanks for your help, again. I hope to try things over the next few days.
@jwatte
I have been looking over your Teensy/Arduino code. You have obviously found out some things about the PathPilot USB interface that don't seem to be documented anywhere. I have some questions, and I want to be sure that I haven't misunderstood your code. I gather that
- Pathpilot communicates in both directions with NL- or CR-terminated ASCII lines, sent at 38400 baud
- Sometimes (when?) PP sends a VE message, expecting a string (will any string do?) in return. Does the VE interaction serve as a handshake, allowing PP to see that this USB port is the one with the appropriate hardware?
- M64 and M65 generate 7-character messages SR abcd, where a, b, c, and d (each '0' or '1') are the new settings for outputs 0, 1, 2, and 3, respectively. In return, PP expects a 4-character message efgh, where e, f, g, and h (each '0' or '1') are the current input values.
- M66 generates a 1-character message ? (question mark), in response to which it expects an 11-character message * abcd efgh, where a, b, c, d, e, f, g, and h (each '0' or '1') encode the current output and input values, as above.
Have I got it right?
Actually, PathPilot sends \r terminated strings, but expects \n terminated strings back (using the Serial.readline()) function.
On start-up, PathPilot sends the VE command, and parses the string to determine that
1. it is a USB I/O board and not something else (smartcool, ATC, etc.)
2. which of the four boards it is (looking at the ID in the string)
Your interpretation of M64 and M65 is correct (the P word controls which digit is changed to 1/0)
M66 just lives on top of the M64/M65 status, polling the return values, AFAICT.
The "?" command is something I added for debugging, which the PathPilot will never send on its own.
Another thing I've found is that the usbio.py and virtualCOM_serial.py modules seem to use more threads than necessary.
There is a thread with message queues for "commands in" and "status returned," but every caller of this method waits synchronously for the result, so the separate thread is totally pointless.
There's also management of these threads that cause quite noticeable race conditions on start-up -- the usbio may get a -1 error, a -3 error, or a success, and it will re-try until it gets a success. With more attention to sequencing, this could easily be simplified.
However, all of that goes on the inside of the PathPilot implementation, and thus gets overwritten by each update, so I prefer to just live with the behavior as-implemented.
Do you know anything more about this sequence? I copied your code into a pure-Arduino program (no conditional compiles), but PathPilot cannot recognize the Arduino as its I/O board. The sequences
- uncheck USB I/O button
- power down mill
- plug Arduino into USB port
- power up mill
- check USB I/O button
and
- check USB I/O button
- power down mill
- plug Arduino into USB port
- power up mill
lead to the same diagnostic message: PathPilot thinks that the board is either absent or malfunctioning.
There is also a udev rule that creates the USBIO# symlink in /dev/ and those are the devices that PathPilot looks for.I copied your code into a pure-Arduino program (no conditional compiles), but PathPilot cannot recognize the Arduino as its I/O board.
You need to figure out the USB vendor/device ID for the Arduino board (you can do this with lsusb when the board is plugged in and out, and see what changes.)
Use the 40-teensy.rules file as a template and change the vendor and device ID to match. Then restart udev to make it take effect the next time the board is plugged in.
The entry I see in the lsusb results isAre 403 & 6001 the vendor & product IDs that I need?Code:Bus 003 Device 005 ID 0403:6001 Future Technologies ...
Your rule is one line, here broken into twoUse the 40-teensy.rules file as a template and change the vendor and device ID to match.Should the inserted rule be the same except for the ATTRS(idVendor) and ATTRS(idProduct) values? Also, I can find rules.d, but I am not a Unix person, so I don't know how to find an editor that will work on it.Code:SUBSYSTEMS=="usb",KERNEL=="ttyACM*",ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0483",SYMLINK+="USBIO%n",GROUP="dialout",MODE="0666"
I assume that just rebooting the mill will do the trick.Then restart udev to make it take effect the next time the board is plugged in.
Bob, have you tried this in simulation? I think testing would be much easier in running PP in simulation than at the mill.
I have Tormach's usb I/O and it works fine in sim.
Thanks. I use simulation as much as I can, but I've somehow never succeeded in getting the simulator to see hardware USB devices. I can get stuff in and out using shared folders, but not thumb drives.
My guess is that what I need to do in the simulator is the same as what I need to do on the mill. I believe that I'll be there with just a little help from @jwatte.
What I really ought to do is to bite the bullet and acquire basic Unix competence. My ignorance of Unix is especially embarrassing in the light of the fact that long ago, I hired Dennis Ritchie for what I think was his first computer job. That was LONG ago.
I still need help, but a little less than I needed earlier today. I successfully created a new RRF.rules file in the rules.d directory, with the content
but PathPilot still can't see the Arduino.Code:SUBSYSTEMS=="usb",KERNEL=="ttyACM*",ATTRS{idVendor}=="0403",ATTRS{idProduct}=="6001",SYMLINK+="USBIO%n",GROUP="dialout",MODE="0666"
Many months ago, I discovered that the Tormach touchscreen worked with some of the controller's USB ports, but not others. On the off chance that something similar might be happening here, I tried plugging the Arduino into each of the unused USB ports in turn. No luck.
My guess is that either
- contrary to the README file in rules.d, the ordering of rules, and naming of rules files, may make a difference here, or
- the line shown above is wrong.
All suggestions are welcome.
You can tell whether the line works, by doing
ls -l /dev/USBIO*
If it shows something, then it probably worked. If not, you have to debug the udev rules.
You may be able to find an error message by doing something like:
sudo udevadm monitor
and then plugging in the Arduino.
For trouble-shooting, what does "lsusb" say when the Arduino is plugged in?
What does "ls /dev/tty*" say ?
It may be that the Arduino is a different kind of tty device than ttyACM, so you may need another KERNEL= match rule.
Isn't hardware hacking fun? :-)
No joy. It can't find a directory.
I plugged in the Arduino, started sudo udevadm monitor, then unplugged & replugged the Arduino. The output was
It is the same output as when I first tried it. The pertinent line isCode:[...] [unplug] KERNEL[793.200489] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0/tty/ttyUSB0 (tty) KERNEL[793.200552] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial) KERNEL[793.200578] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb) KERNEL[793.200603] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb) UDEV [793.201467] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0/tty/ttyUSB0 (tty) UDEV [793.201527] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial) UDEV [793.201664] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb) UDEV [793.202142] remove /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb) [replug] KERNEL[796.521561] add /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb) KERNEL[796.523923] add /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb) KERNEL[796.523961] add /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial) KERNEL[796.524109] add /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0/tty/ttyUSB0 (tty) UDEV [796.526428] add /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb) UDEV [796.531310] add /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb) UDEV [796.531754] add /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 /ttyUSB0 (usb-serial) UDEV [796.534403] add /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 /ttyUSB0/tty/ttyUSB0 (tty) KERNEL [3287.284231] change /devices/platform/regulatory.0 (platform) UDEV [3287.286474] change /devices/platform/regulatory.0 (platform) KERNEL [3288.363913] change /devices/platform/regulatory.0 (platform) UDEV [3288.365871] change /devices/platform/regulatory.0 (platform) KERNEL [3288.512411] change /devices/platform/regulatory.0 (platform) UDEV [3288.514591] change /devices/platform/regulatory.0 (platform) KERNEL [3288.616117] change /devices/platform/regulatory.0 (platform) UDEV [3288.618175] change /devices/platform/regulatory.0 (platform)
Code:Bus 003 Device 008IC ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) ICIt might be fun if I were working from documentation. Thrashing in ignorance is not fun.Code:/dev/tty /dev/tty1, /dev/tty2, ..., /dev/tty 63 /dev/ttyprintk /dev/ttyS0, /dev/ttyS1, ..., /dev/ttyS31 /dev/ttyUSB0
The murder mystery angle is what adds the spice!
Anyway, the commands you ran show that it's a "ttyUSB*" not a "ttyACM*" device, and thus you need to change that bit in the KERNEL== in the udev.d rules file to make it recognized.
That change results in incomplete progress. The ls -l /dev/USBIO* command now returnsThe result of sudo udevadm monitor is the same as it was yesterday, except for the bracketed timestamps or sequence numbers at the beginning of each line. The results of lsusb and ls /dev/tty* are also unchanged from yesterday.Code:lrwxrwxrwx 1 root root 7 Jan 16 09:23 /dev/USBIO -> ttyUSB
With the Arduino plugged in and the USB I/O box checked in PathPilot, the Arduino's LEDs show that its RX & TX lines are getting traffic; I don't think this was true yesterday. Unfortunately, PathPilot saysCode:USBIO: Board malfunction. Cannot connect to board.
Great, now we know that PathPilot is trying to talk to it.
The Arduino isn't responding as it wants, though, which is why it's saying it's "unusable."
I can think of three possible causes for this:
1) The Arduino bootloader might confuse the board detection.
2) The Arduino sketch doesn't set the right baud rate on the serial port when it starts (I think it should be Serial.begin(38400))
3) The sketch has some bug that doesn't parse the commands correctly
If it's 1) I don't know how to solve that, other than replacing the Arduino with some board that uses "native" USB, such as the Arduino Leonardo, or the Teensy.
If it's 2) then the fix should be making sure that the baud rate is right.
If it's 3) then it should be possible to fix the sketch to talk the right protocol, but obviously this needs some way of debugging what's going on.
Right. As it happens, I have some Teensys on order, so that possibility is easy to test.
Right again. I'll just try all the possibilities from 9600 to 115200. Stand by.
When I talk to the board from the Arduino IDE, it does just what it should.
Oh, another possible option for option 1)
If it's the bootloader, then you can program the Arduino sketch using a ICSP USB programmer instead of the bootloader.
That way, it won't run the bootloader on start-up, and won't try to confuse things on the serial port.
There may still be some problems with the DTR tied to reset situation for FTDI-based Arduinos, though. Teensy sounds safer :-)
I decided to do some tests with an Arduino Nano clone. Perhaps my test results will help someone:
- This clone Nano has a VID/PID of 1A86/7523
- For my device the line in the rules.d file must specify "ttyUSB" rather than "ttyACM"
- The VID/PID in the rules.d file is case sensitive so must be entered as "1a86" rather than as "1A86"
- ls /dev/USBIO* then shows USBIO00
- When the USBIO board is enabled the Nano attempts to download a new image and after much flashing of Tx/Rx LEDs PP decides that the USBIO board is not responding.