Serial Port Classes


#1

Just posted some Serial Port classes at [link removed: contained malware]

Currently Win32 and Mac only (linux can probably use the Mac code, with the enumeration functions stripped out)

from the header:

[code]a typical serialport scenario may be:
{
//get a list of serial ports installed on the system, as a StringPairArray containing a friendly name and the port path
StringPairArray portlist = SerialPort::getSerialPortPaths();
if(portlist.size())
{
//open the first port on the system
SerialPort * pSP = new SerialPort(portlist.getAllValues()[0], SerialPortConfig(9600, 8, SerialPortConfig::SERIALPORT_PARITY_NONE, SerialPortConfig::STOPBITS_1, SerialPortConfig::FLOWCONTROL_NONE));
if(pSP->exists())
{
//create streams for reading/writing
SerialPortOutputStream * pOutputStream = new SerialPortOutputStream(pSP);
SerialPortInputStream * pInputStream = new SerialPortInputStream(pSP);

		pOutputStream->write("hello world via serial", 22); //write some bytes

		//read chars one at a time:
		char c;
		while(!pInputStream->isExhausted())
			pInputStream->read(&c, 1);

		//or, read line by line:
		String s;
		while(pInputStream->canReadLine())
			s = pInputStream->readNextLine();

		//or ask to be notified when a new line is available:
		pInputStream->addChangeListener(this); //we must be a changelistener to receive notifications
		pInputStream->setNotify(SerialPortInputStream::NOTIFY_ON_CHAR, '\n');

		//or ask to be notified whenever any character is received
		//NOTE - use with care at high baud rates!!!!
		pInputStream->setNotify(SerialPortInputStream::NOTIFY_ALWAYS);

		//please see class definitions for other features/functions etc		
	}
}

}[/code]


Serial port classes
#2

I would have killed for this a few months ago!

ended up using some C-wrapper that I can’t remember the name of.

was less grim than learning COM port stuff and writing some classes.

if I have to write another foot-pedal app I’ll be using your classes.

good work sir!


#3

Nice, may have a use for that later.


#4

Very convenient class, many thanks to the author. There is a slight correction to get this to compile with new Juce, relating to how Threads are being done now:

in SerialPort.h, two constructors need update:

SerialPortInputStream(SerialPort * port) :port(port),bufferedbytes(0), notify(NOTIFY_OFF), notifyChar(0)
becomes

SerialPortInputStream(SerialPort * port) :port(port),bufferedbytes(0), notify(NOTIFY_OFF), notifyChar(0), Thread("SerialInThread")

similar with SerialPortOutputStream, it should read

SerialPortOutputStream(SerialPort * port) :port(port),bufferedbytes(0), Thread("SerialOutThread")


#5

Hi,

I wanted to get try with your classes but didn’t get them to compile (on mac os x).

I have inserted the file in my xcode projects inclue Serialport.h in my app
but get a strange :
“uint32 does not name a type”

Any idea (juce.h is in my path and of course I can compile other home made juce apps without any problem).

Sylvain


#6

using UInt32 instead seems to fix it…


#7

Has anyone been able to use this class for byte-to-byte nonoverlapped type of communication? I’m using pretty much the suggested code in the header file of the class. SerialPortOutputStream::write and SerialPortInputStream::read functions with one byte data (under Win XP). The first write/read call seems to return the single byte I’m looking for, the second fails (input stream exhausted). I have a serial port monitor which says there’s no answer the second time. Is my setup wrong?

//open the first port on the system
SerialPort * pSP = new SerialPort("COM1", SerialPortConfig(4800, 8, SerialPortConfig::SERIALPORT_PARITY_NONE, SerialPortConfig::STOPBITS_1, SerialPortConfig::FLOWCONTROL_NONE));
  if(pSP->exists())
    {
      //create streams for reading/writing
      SerialPortOutputStream * pOutputStream = new SerialPortOutputStream(pSP);
      SerialPortInputStream * pInputStream = new SerialPortInputStream(pSP);
      char c = 0;
      char data = CMD_READ_TXCTRVERSION;
      pOutputStream->write (&data, 1);
      while(!pInputStream->isExhausted())
        pInputStream->read(&c, 1);

      /* Do something with c ... */

      data = CMD_EXECUTEREQUEST;
      pOutputStream->write (&data, 1);
      while(!pInputStream->isExhausted())
        pInputStream->read(&c, 1);

      /* Do something with c ... */

}
delete pSP;

Thanks in advance
LB


#8

Never mind, I had to set the DTR & RTS using the EscapeCommFunction API function.


#9

I have just been trying to implement this class within a project on a mac but its coming up with many errors, even after fixing the reported correction relating to the Thread class. Most of the error’s are due to undeclared variables and functions.
Has anyone got this class working in more recent times?


#10

waking up this dead thread… I revived graffiti’s code to run with Juce 2.1.1

(after wasting precious life energy trying to get BOOST to work in Xcode to get the blipzone serial driver to work!)

I’ve done a little testing (RX on OSX works) but it needs more…

I tried to make it into a module but there’s more to that than making a manifest file, and there’s no howto anywhere so I’ll leave that to someone else. As it is you can just add these three source files to your project and it’ll selectively compile for OSX or WIN.

Attached… Have fun!

Marc


#11

If you want to make code modules, as in Unity Build oriented building of code, check my FileModularizer.


#12

uh, thanks jrlanglois for sending me to an uncompilable project.

also, no OSX target. so I made one and:

[code]CompileC /Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/Objects-normal/i386/Modularizer.o …/…/Source/Code/Modularizer.cpp normal i386 c++ com.apple.compilers.llvm.clang.1_0.compiler
cd /Users/mlindahl/BEA/juce/FileModularizer-master/Builds/MacOSX
setenv LANG en_US.US-ASCII
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x c++ -arch i386 -fmessage-length=0 -std=c++11 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wreturn-type -Wnon-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wformat -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-enum-conversion -Wno-shorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -D_DEBUG=1 -DDEBUG=1 -DJUCER_XCODE_MAC_F6D2F4CF=1 -fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -g -fvisibility=hidden -fvisibility-inlines-hidden -Wno-sign-conversion -iquote /Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/FileModularizer-generated-files.hmap -I/Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/FileModularizer-own-target-headers.hmap -I/Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/FileModularizer-all-target-headers.hmap -iquote /Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/FileModularizer-project-headers.hmap -I/Users/mlindahl/BEA/juce/FileModularizer-master/Builds/MacOSX/build/Debug/include -I…/…/JuceLibraryCode -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/DerivedSources/i386 -I/Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/DerivedSources -Wreorder -F/Users/mlindahl/BEA/juce/FileModularizer-master/Builds/MacOSX/build/Debug -MMD -MT dependencies -MF /Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/Objects-normal/i386/Modularizer.d --serialize-diagnostics /Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/Objects-normal/i386/Modularizer.dia -c /Users/mlindahl/BEA/juce/FileModularizer-master/Builds/MacOSX/…/…/Source/Code/Modularizer.cpp -o /Users/mlindahl/Library/Developer/Xcode/DerivedData/FileModularizer-ecbsihsknqpqyoelfgoqyiexcldc/Build/Intermediates/FileModularizer.build/Debug/FileModularizer.build/Objects-normal/i386/Modularizer.o

clang: error: no such file or directory: '/Users/mlindahl/BEA/juce/FileModularizer-master/Builds/MacOSX/…/…/Source/Code/Modularizer.cpp’
clang: error: no input files
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 1
[/code]

that’s about all the time I have for that.


#13

I work with VS on Win, sorry. I’ve no way to test it on a Mac.

Looks like it’s just missing files in the xcode project, though (?)


#14

I updated the IJ project, and added the xcode exporter by default.

Edit: And thanks for at least trying it out!


#15

Hello,

Thought I'd share a quick fix if anyone is out there using this code and finds it not working on Windows 10.  This code uses overlapped I/O however it doesn't properly respond to the ERROR_IO_PENDING response from ReadFile.  In the case of ERROR_IO_PENDING you do not want to keep calling ReadFile (which is what the code currently does) but you want to wait for the first ReadFile request to process and get the results with GetOverLappedResult

 


if(!ReadFile(port->portHandle,&c,1,&bytesread,&ovRead))
{
     if(GetLastError() == ERROR_IO_PENDING)
     {
          bool waitingToRead=true;
          while(waitingToRead && !threadShouldExit())
          {
               if(WAIT_OBJECT_0==WaitForSingleObject(ovRead.hEvent, 500))
               {
                    GetOverlappedResult(port->portHandle,&ovRead,&bytesread,FALSE);
                    waitingToRead=false;
               }
          }
     }
}
​

 

The full run method for SerialPortInputStream:

 

​​void SerialPortInputStream::run()
{
    DWORD dwEventMask=0;
    //overlapped structure for the wait
    OVERLAPPED ov;
    memset(&ov,0,sizeof(ov));
    ov.hEvent = CreateEvent( 0,true,0,0);
    //overlapped structure for the read
    OVERLAPPED ovRead;
    memset(&ovRead,0,sizeof(ovRead));
    ovRead.hEvent = CreateEvent( 0,true,0,0);
    while(port && port->portHandle && !threadShouldExit())
    {
        unsigned char c;
        DWORD bytesread=0;
        WaitCommEvent(port->portHandle,&dwEventMask, &ov);
        if(WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent, 100))
        {
            DWORD dwMask;
            if (GetCommMask(port->portHandle,&dwMask) )
            {
                if ( dwMask & EV_RXCHAR )
                {
                    do
                    {
                        if(!ReadFile(port->portHandle,&c,1,&bytesread,&ovRead))
                        {
                            if(GetLastError() == ERROR_IO_PENDING)
                            {
                                bool waitingToRead=true;
                                while(waitingToRead && !threadShouldExit())
                                {
                                    if(WAIT_OBJECT_0==WaitForSingleObject(ovRead.hEvent, 500))
                                    {
                                        GetOverlappedResult(port->portHandle,&ovRead,&bytesread,FALSE);
                                        waitingToRead=false;
                                    }
                                }
                            }
                        }
                        
                        if(bytesread==1)
                        {
                            const ScopedLock l(bufferCriticalSection);
                            buffer.ensureSize(bufferedbytes+1);
                            buffer[bufferedbytes]=c;
                            bufferedbytes++;
                            if(notify==NOTIFY_ALWAYS||((notify==NOTIFY_ON_CHAR) && (c == notifyChar)))
                                sendChangeMessage();
                        }
                    }while(bytesread);    
                }
            }
            ResetEvent ( ov.hEvent );
        }
    }
    CloseHandle(ovRead.hEvent);
    CloseHandle(ov.hEvent);
}

#16

I've been trying to use this code in my juce application, @NatanH wrote a very clean wrapper for this in one of his open source projects. It works, however on my El Capitan computer none of the USB port serial devices are displaying, only ones which are always available.

 

Has anyone gotten any serial IO working on El Capitan?


#17

Depending on the chipset with USB-serial cables you might have to manually go out and find the driver and install it (which is a weird feeling in 2016). Is it appearing at all in system profiler or /dev? Mine is a TRENDnet TU-S9, which required a download of the PL-2303 drivers.


#18

Hey thanks for reply.

This is the weird bit, it's just an arduino and I do see it on my system.

Running ls /dev/tty.* & in the arduino IDE i see it : (sorry it won't load the image into the post)

This is basically an image of all the serial devices on my computer & through my USB hubs

https://www.dropbox.com/s/maspunykn1fyr9r/Screen%20Shot%202016-03-23%20at%201.10.28%20PM.png?dl=0

 

 

However when i run this code in JUCE and call for the all the connected devices I get this returned : 

This is the same list minus the object which is plugged into my USB ports

https://www.dropbox.com/s/w700qgkqk8m57wl/Screen%20Shot%202016-03-23%20at%201.11.18%20PM.png?dl=0

 

I'm running El Capitan and haven't been able to test on a previous OS.

 

EDIT: 

So, sent the app to a friend who is still on yosemite, they were able to see their arduino connections through the vst. Sadly, it must be something with El Capitan, which is a bit beyond me i believe. I think i'll try disabling rootless when i get a chance and see if that is doing anything funny. Otherwise, if anyone see this & has any ideas lemme know : ) 


#19

[link removed: contained malware]
^ something is not right here. I wonder if transitioning to the new forum caused this.

graffiti, do you still have these classes somewhere? Maybe GitHub?

Could you post a link?

π


#20

Does anyone still have this code?

EDIT: think I found it here: https://github.com/robertsonics/WAV-Trigger-Remote/blob/master/Source/mac_Serial.cpp