UART Serial Comunication?


#1

Guys, been a long time, but I’m working on a very tinny small open-source project. I need to read/write via a virtual UART Serial to an Arduino. Does Juce support that? I couldn’t find any info on the website and online docs. Of course, maybe I’m using the wrong names? It must be cross-platform, but maybe I will start with regular Windows stuff, if needed.

The idea is very simple, to create a program that reads from the Arduino Virtual Serial UART and output MIDI Information. (The Arduino sketch would, of course, send MIDI Serial data to the computer, so its just a matter of copying/sending) It would be fun to be Stand-Alone with the option of which MIDI Interface to use and also Plugin Formats. 8)

Any info would be much appreciated. :wink:

Best Regards, WilliamK


#2

So far I found this for Win32. :wink:

http://www.codeguru.com/forum/archive/index.php/t-289810.html

[quote]To use the serial port in Win32 you can use the CreateFile (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/createfile.asp) function to setup a handle to the hardware. Specify the port name in place of the file name (e.g. “COM1”). Then you need to use the DCB (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/dcb_str.asp) struct. The DCB struct has members for setting up the baud rate, flow control, parity…etc. Set all of the parameters you want in the DCB struct, or have dialogs that let the user select the ones they want, and then use the SetCommState (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setcommstate.asp) function to configure the port with the parameters in the DCb struct. You will also need to set the timeouts for the port with the SetCommTimeouts (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setcommtimeouts.asp). Also you’ll need to set buffer sizes with the SetupComm (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setupcomm.asp) function.

Once the port is opened (briefly outlined above) use the ReadFile and WriteFile functions to read and write from and to the port. To switch individual lines on the port (RTS, DTR…etc) use EscapeCommFunction (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/escapecommfunction.asp). [/quote]


#3

Here’s an example I have to test out yet…

[code]int ReadByte(CString PortSpecifier)
{
DCB dcb;
int retVal;
BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;

HANDLE hPort = CreateFile(

PortSpecifier,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);

if (!GetCommState(hPort,&dcb))
return 0x100;

dcb.BaudRate = CBR_9600; //9600 Baud
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop

if (!SetCommState(hPort,&dcb))
return 0x100;

SetCommMask (hPort, EV_RXCHAR | EV_ERR); //receive character event
WaitCommEvent (hPort, &dwCommModemStatus, 0); //wait for character

if (dwCommModemStatus & EV_RXCHAR)
ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0); //read 1
else if (dwCommModemStatus & EV_ERR)
retVal = 0x101;
retVal = Byte;
CloseHandle(hPort);
return retVal;
}[/code]


#4

And here’s how to write to a COM port.

[code]bool WriteComPort(CString PortSpecifier, CString data)
{
DCB dcb;
DWORD byteswritten;

HANDLE hPort = CreateFile(

PortSpecifier,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);

if (!GetCommState(hPort,&dcb))
return false;

dcb.BaudRate = CBR_9600; //9600 Baud
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop

if (!SetCommState(hPort,&dcb))
return false;

bool retVal = WriteFile(hPort,data,1,&byteswritten,NULL);
CloseHandle(hPort); //close the handle
return retVal;
} [/code]


#5

I’ve 2 classes for this, derived from a post one guy posted on the forum a while ago. PM me your email so I can transfer them to you.


#6

Thank you so much! 8) :smiley:

Best Regards, WilliamK


#7

Thanks to the contribution code, its all working already. Now, before I reinvent the wheel, is there a way to get midi data from the serial port and convert to MidiBuffer events, or something like that? So I could check on every processBlock for new Serial data and just add new Midi Messages to the buffer from the Serial port.

Kinda like this:

Which is, of course, bad, and doesn’t work. :oops:

If I have to check for data manually, I don’t mind, I can do it tomorrow, just checking with you guys before I do this when its already done somewhere. And yeah, I did look the Juce API docs for this info but couldn’t figure out, yet… :wink:

Wk


#8

The following does work correctly, so I guess, if there’s no such thing already, I will just go ahead and add the checks for SysEx and stuff like that, which are not 3 bytes in size.

char d[3]; while(!pInputStream->isExhausted()) { pInputStream->read(&d, 3); midiMessages.addEvent((void*)d,3,0); }

Wk


#9

don’t forget about Running Status…


#10

Indeed, thanks bud. 8)

Wk


#11

@William - I’d be interested in checking out your serial code? A while ago I implemented serial in JUCE updating some pre-existing juce-centered serial code I found online (can’t find the link right now, but his name was Graffiti).

My project is currently requiring me to rewrite some of that to pass data around and whatnot so I’d be keen to see what you cooked up!

@Jules - Do you think you’d ever plan to roll serial communication into JUCE? It would be great to have, especially since projects like the Arduino (et al) have made working with physical computer and sensors super accessible, and easy to integrate with other projects. Anyway! :slight_smile:


#12

Serial comms is all a bit “last century”!

But it’s the sort of thing that’ll be a perfect candidate for the new modularised system that I’m working on (nearly finished!) A serial comms module could provide all this functionality in a neat package, so only people who need it would need to add it to their codebase.


#13

[quote=“jules”]
Serial comms is all a bit “last century”! [/quote]

Oh my god, you’re so wrong! While we are all going to the “embedded” world with both feet first, serial comm has never been so useful.
Take any android phone, if you need a root access, you only have to plug the serial port (ok, it’s not usually available on the phone official connectors, but on the phone PCB), then you can try the usual hack.
Same goes for any embedded device, since having a serial link is only “wasting” 2 GPIO pins, while any other low bandwidth bidirectional link takes more.

Even on new µ-controller (ARM Cortex M3), they all natively implement a “virtual COM PORT” on USB using the “USB CDC Serial class”, so all the Arduino/AVR/PIC world need Serial Class.
I’ve been offering the juce Serial class I’m maintaining in this thread and other since few month, and I received a lot of request for them, so the interest is still here.

The Serial RS232 connector is dead yes for sure, but the RS232 connection is clearly not.


#14

Oh, I do understand that it’s alive and kicking, and like I said, it’d make a great juce add-on module.

But it does feel so old-fashioned! Anyone else remember Spitting Image (puppet-based TV satire show in the mid 1980s) doing a song about the RS232 interface…?


#15

Ok, I had to go and look it up…

http://www.youtube.com/watch?v=CDlj0jBtYmQ


#16

I’ve just gone through a similar process writing a cross-platform application for the blipbox [1], a hardware device which uses an arduino-style serial-over-usb connection.

I got a solution working on the Mac and Linux with termios, not realising it wasn’t going to port to Windows. So I did another implementation, using boost::asio. That turned out to be much easier and less painful overall, should have gone with boost from the start I guess.

FWIW the code is GPL and can be found here [2], look for AsioSerial and TermiosSerial. Only one would ever be compiled into a project at a time.

A problem I’ve not managed to solve yet is how to enumerate the serial ports on Windows. I have somewhat naively done this:

#if JUCE_MAC
  DirectoryIterator it(File("/dev"), false, "tty.usbserial-*");
#elif JUCE_WINDOWS
  DirectoryIterator it(File("\\\\.\\"), false, "COM*");
#elif JUCE_LINUX
  DirectoryIterator it(File("/dev"), false, "ttyUSB*");
#endif

It works fine on Linux and Mac, but again, no luck with Windows. The funny \.\ bit is supposed to be the device namespace.

cheers,

/m

[1] http://blipbox.org
[2] https://github.com/pingdynasty/BlipZones


#17

I’m trying to setup a serial communication with graffiti’s code , but i basically don’t understand how you call the comport routine from within a JUCE programme . I have a MainComponent that’s bascially doing everything and I declared a function void serialcom () ;. This function instantiates the comport’s inputstream and outputstream ( just like the example in Graffiti’s code) . But it seems to me that this function is never called …

I tried to see what it does when I put that code under void timerCallback() ; and then I get 1 outputstream sending some data but only when I open my programme, then it stops . Anybody that can shed some light on this ?


#18

It’s working !! Added a ChangeListener !


#19

The RS232 video just made my morning…Thanks, I needed that. And all the funnier since I’m finishing an Arduino project in Java and just had to make extensive use of RS-232 serial comm’s…