Is there a way to automatically connect serial object to usb modem?

nicnut's icon

Hi,

I am trying to create a Max patch for a prototype that will be tested on various computers and incorporates an Arduino sending serial data.

When I open the patch and hit a "print" button connected to the serial object I can see the port that the usbmodem is on. On my computer it's always port e, but it's different on various computers.

Is there a way to automate, or somehow set the serial port to always select the "usbmodem"?

I know that with the "ctlout" object you can send it a message that says something like "port mididevicename" and it will go to that port. Is there a way to do this for a serial object and how would I format that?

If this isn't possible, can I send it a bang when I open the patch that will send out all available port info and have it automatically connect to the usbmodem if it's available? maybe using a select object that will recognize the usbmodem text and grab that port letter.

When I hit "print" message connected to my serial object I actually get "usbmodem14631." I'm not sure what those additional numbers are, but that's the port I want to connect to on any computer opening this patch.

Thank you and any help would be greatly appreciated.

Nick

Source Audio's icon

serial object accepts port message using device symbol instead of port abbreviation.
in that case loadbang a message
port usbmodem14631
but .... usbmodem14631 might get differently named on different platform/OS versions

nicnut's icon

Hi Source Audio.

This is helpful information. I'll do a test on a few computers and see what that 14631 is about. Maybe if the hardware is the same the numbers will be the same. I hope so.

nicnut's icon

Hi again, I just wanted to report some things I tried out.

If I open my patch with the serial object having the arguments [serial 9600 8 1 0] and I send it a message "port e" it works and connects to my arduino. But this isn't ideal because that letter will change on a different computer.

If I open my patch with the serial object having the arguments [serial 9600 8 1 0] and I send it a message "port usbmodem14631" it works and connects to my arduino but I get this error message:

serial: error setting tty attribute (/dev/cu.usbmodem14631)

But at least it works and that's promising.

If I open my patch with the serial object having the arguments [serial usbmodem14631 9600 8 1 0] it works and it's sending data right away.

I need to figure out what that 14631 part is and hope that it's consistent on different computers and operating systems. I'll try this out.

Thanks again for the input.

Nick

Source Audio's icon

that usbmodem14631 is just assigned id to that specific device,
operating system does that.
What is that device anyway ?
you don't need to write arguments into serial objects which are anyway
having default values as you want them.
Also, you can loadbang comma separated message like this :
port usbmodem14631, baud 57600, databits 8, stopbits 0, dtr 1 and so on

your only possible problem could be if different operating systems
assign different id to that device.
But also that can be treated, like building select menu with
populated available serial ports,
store id as text file to read and initialise on app start etc
also matching usbmodemxxxxx could be used ignoring the numbers
to auto pick menu device which contains "usbmodem" using regexp or similar.


P.S. it is probably ATmega32u4, u8 etc based arduino,
they get usbmodemxxxxx ID on OSX.

on OSX (tested only on El Capitan and High Sierra), ATmega32u4 based arduino
got same ID on both systems, BUT one programmed as HID keyboard
appeared as usbmodemHIDP1, the other one left as factory default usbserial device appeared as usbmodem1421, and it did not matter which usb port
it got plugged in.
On windows 10 ... bullshit - max serial object does not really output anything else
then COM4, COM5 at right outlet - totally useless.
and everytime I replugged the 2 arduinos it got different port and COM number assigned.
Only way to get arround was to use max console object
to capture print output which then was :
port f: COM5 (USB Serial Device) - this is usb serial one
port d: COM4 (USB Serial Device) - this is HID one
and even worse, port letters changed depending on USB slot device was pluged in.
And one could not make difference between HID and usbserial device as on Mac.

now the solution :
1 capture console output, search for (USB Serial Device)
2 use port letter of the matched line, in example above :
port f: COM5 (USB Serial Device)

nicnut's icon

Hi SourceAudio.

The USB device is a Arduino Uno Rev 3 with two sensors attached to it.
I am on a Mac OS 10.13.6, but this will need to work for mac and windows, so the usbmodem vs. COM issue is kind of important.

This is some helpful info. I didn't know about the console object. When I send the console object the "textfilter port" message it will output the port I need as the last message and come out of the middle outlet of console. I don't know if this is luck or not, or maybe since the Arduino is the most recent thing plugged in.

Then I use a regexp object to untangle the message . Then I send that letter to the serial object.

I also have a not so elegant way to do this, which is just press on a message for port a, port b, port c, etc, till you see numbers coming in from the serial port.

I made a little patch illustrating what I have so far.

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

you don't need console on Mac.
Only on windows, because serial object does not output port infos properly.
this is screenshot showing Arduino Leonardo (32u4 based) console output on windows

Here on Mac using serial object's right outlet

On mac you simply send port usbmodem1421 to serial object
-------
On windows, you can use port letter like d e f etc
or COM4 COM5 etc, BUT the stupid thing is that without console
output you have no idea which COM port plugged device gets assigned.
I plugged that arduino this morning again, into same usb slot
and it got COM7 or letter g assigned.
this is screenshot of same patch and arduino on windows

so yesterday f COM6, today g COM7 ....
--------------
So what to do ?
Depends also if exactly same Arduino board is going to be used, which I doubt ?

with only 2 sensors, any board would do the job, even the smallest variants, and they all use different usb serial chips (some need drivers installed) , and so named ports.
---------------
The real universal solution is to populate umenu with available ports on Mac,
and let user select device and store it for next app start.
On Windows one would have to use console , because of that annoying
changes to COM ports assignments.
In addition, depending on chip used, it could be called (USB Serial Device)
or (USB Serial Port) or something different
here screenshot of console populated umenu with 2 Arduinos plugged in,
one Atmega 32u4 (COM7) , the other using FTDI usb to serial chip (COM8)

----------------
If you would use same arduino, and ask users to plug only single Usb Serial device at a time one could simply search USB in the console output to match the port.
Here is patch with prefilled menues from windows, and at right complete auto-select
solution using console example

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

P.S. actually proper way is to
1 scan serial devices
2 check if one we want to use is connected
3 if yes, set serial port and activate polling etc and visually signal that device is ready to use.
if not, close serial port and display error

Mac-serial auto.maxpat.zip
application/zip 4.11 KB

nicnut's icon

Source Audio,

Hey, this second solution is really great. Populating the umenu with all available ports is the way to go, great idea. I'm still studying this to figure out exactly how you did that, but the cool thing is that this works. The numbers associated with my usb modem id changed already, but with this menu I can easily see what's happening and make the adjustments.

Thank You so much!! really cool.

Source Audio's icon

That second patch is mac only, it won't work on windows directly,
you have to use console.
It should be easy to replace serial object's right outlet with console
output from the first - windows patch, and add the rest from max patch.
I have windows Max installation at hand, so if you want me to make that for you,
no problem, but you would have to post exactly what you want to use,
store device id as text or not, etc.

nicnut's icon

Source Audio,

Let me know if this is what you mean to make this compatible with Windows and Mac. All I did was copy the part of the Windows patch with the console and paste it into the Mac patch, and have the output of Console go where the right outlet of serial was going in the Mac Patch.

On the left pull down menu, from the Mac patch, I can see the Arduino USB serial modem connection. I can see it on the right pulldown menu too. I can test it out on Windows computer tomorrow. But let me know what you think. Thanks again for the valuable info.

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

I am afraid it is too mixed, you need only one menu
and only one matching string.
You can use console only on windows. on mac it makes no sense.
I have no time now to do so now,
but wil clean the patch you posted tomorrow for windows.

If you tell me exactly what you want to do on Mac, I'll translate it for windows for you.

nicnut's icon

Hi Source Audio,

Ah, Ok. I was basically trying to combine your Mac and Windows patch into one patch with one umenu to view and select the available serial ports. Maybe I need 2 separate patches, one for Mac and one for Windows, and just incorporate your Windows patch.

Here is the one that has been working for Mac, which is the one you created earlier. So If I just take the info from the Console object instead of the serial object I suppose it would work for Windows. Let me know what you think. Thank you again for your input.

Source Audio's icon

You will definitely need different patches for Mac and Windows.
Because you get needed information from different sources.
And next question is how much of that Mac patch you want to use ?
I was also expecting that at least same Arduino board on Mac keeps same ID,
but if that is not the case, one would need better patch than what I posted.
Than - does serial port connection need to be completely automated
or not ?
If not, one can simply use menu with connected devices to select one.
If it has to be automated, one needs to store expected ID
or part of it and read it on every app start.
On Mac questionable is number after usbmodemxxxxx
On Windows one expects (Usb Serial Device) and if found selects COMx port associated with it.

If in both cases expected ID completely changes, because of different board
or OS than one has to store new ID to recognise as text.

But now the problem is that nothing really works completely.
I'll put an example :
On Mac one gets usbmodem12345 on port d
One splits usbmodem and 12345, searches for usbmodem as first
and if matched merge usbmodem and that number again and send
port usbmodem12345 to serial object.
if number changed to 32324 it does not matter, merged message is usbmodem32324
BUT if ID changed to chser-12345 - one is in trouble, because search string changed
and one can't extract it from the device menu .
One would have to write new search string chser- into text file manually.
---------
On windows it is a better situation because each serial device gets
info appended, like (USB Serial Port) or similar, which seems to remain unchanged
and can be stored into text using device menu (extract of it).
Only port letter or COM gets changed .
I hope you recognise the difference.
-----------
Now to create 100% working solution for automated connection
on unknown OS and Arduino Board ,
one would need user's input, to recognise Device and enter search string.
On windows easy, on Mac one would need to split part of the ID which remains constant
from the one that changes.
here is windows patch :

Max Patch
Copy patch and select New From Clipboard in Max.

Robb Mitchell's icon

I am trying a non-automated (very clunky) way for novice users of my patches to select the correct serial port.
Just simple message buttons with "port" + letters a, b, c, etc.

message buttons to select usbmodem serial port - note the use of dollar sign 1 (instead of port letter)

Obviously, this is not as ideal (or near-ideal) as some of the amazing suggestions above. But I share it here in case any Max newbies come looking for a quick-ish fix that should work on both Mac and PC.

A question please about this approach: does anyone know how many port letters need to be listed? (Should I go all the way from "a" to "z" ?!! :)

(Maybe in my next version I will simply ask for a simple, single character, keyboard input instead)

Source Audio's icon

1- that $1 is not ok, all it does is cause errors as that port is not available,
I'd leave a there .

Rather print available devices to fill umenu with devices and select port from there.
that would need just few objects, and will be safe solution.

Max Patch
Copy patch and select New From Clipboard in Max.


if you insist on using this as you say (very clunky) solution with all possible letters,
one could fill umenu with full alphabet
and send middle output to
port $1 -> to serial object
it is hard to say what is maximum possible letters needed to cover all
port abbreviations.
----------
I hope you checked all in this thread to understand Mac - Windows differences

Robb Mitchell's icon

Thanks very, very much Source Audio, for the great advice and patch! And also thanks for how tactfully you corrected my errors. I hope others can learn from my mistakes.

Yes, as I hope to export patches as applications (rather than collectives), the Mac - Windows differences are of great interest. However, the patch you recently shared seems to work fine on both Mac and PC. Although the only Windows machine I have been able to test on so far is a tablet with only one USB socket and it seems to just have the one serial port option.

People who stumble upon this page later might also like to look at another (quite similar) way to use umenu to offer serial port options posted by Luke Woodbury: https://cycling74.com/forums/%22error-opening-serial-port%22-sending-data-from-arduino-to-max

ironside's icon

I've worked a lot with arduinos and max, and have a few workarounds on usbmodem addressing, particularly the issues that can occur when you have multiple ardunios connected.

By far the most reliable way I've found to address usbmodem devices (which can also include DMX interfaces and other things emulating serial without an FTDI chip) is to build in a device ID into the Arduino sketch which is printed to the serial port in response to a prompt (i.e. receiving an 'A' into the serial port), and using this in combination with the umenu techniques from above.
So, workflow goes:
Ask serial/comport object what devices are connected -> find anything which starts with 'usbmodem' -> open device -> ask device for device ID -> use device ID to route correct max messages to device -> open next device if necessary.
This works cross platform, and is quite scaleable. I've used a modified version of this approach to network 70 arduinos over ethernet etc. It makes setup very easy. (You can get fancy and start storing device IDs in the EEPROM etc, so you don't have to have multiple versions of a sketch if using many devices).

Hope this might help someone!