Serial Port: connecting to Arduino

Hi. I’m totally new to JUCE and, while I am pretty fluent in C, I am also fairly new to C++ so please bear with me if I am being stupid!

I may have taken on a tough challenge for my first JUCE ‘learning’ project :thinking: but I am trying to write a ‘simple’ GUI to send and receive ASCII data via the USB Serial connection to an Arduino.

I have been using the Serial Port module originally written by graffiti and updated by Chris Roberts.

I have managed to get a list of serial ports on my PC (Win10), add them to a combo box to let me select the port that the Arduino is connected to and the Arduino reboots in the normal way when I select the port but I’m at a loss as to how to receive the data that the Arduino is sending. It starts with a simple ASCII string terminated by a newline to identify itself. I have set the input stream to notify when a newline is received.

I’ve tried adding a Listener but what is the Serial port object that is sending the message?

Is there a way for me to post the code here? I don’t see any ‘code’ tags :cry:

I’d be very grateful for any help or suggestions.


It‘s as simple as pasting it here and putting three backticks ``` in the line above and below it

Regarding the question, I don’t know that module but having a quick look at the example code (which is full of memory leaks by the way :see_no_evil:) it seems that you just need to read from the SerialPortInputStream instance created for a certain port once you are notified by the change broadcaster. The SerialPortInputStream seems to inherit juce::InputStream. But as I said this is my conclusion from looking at the code for two minutes, never actually worked with it


The MainComponent.cpp

#include "MainComponent.h"

    setSize (600, 400);





        //get a list of serial ports installed on the system, as a StringPairArray containing a friendly name and the port path
        portlist = SerialPort::getSerialPortPaths();

            DBG("There is(are) " + juce::String(portlist.size()) + " ports.");
            // add Serial Port names to the combo-box

    for (int i = 0; i < portlist.size(); i ++ )

    // Set up the handler function for when the user chooses an item in the list
    serialPortMenu.onChange = [this] { serialPortMenuChanged(); };
    getButton.onClick = [this] { getPatches(); };
    sendButton.onClick = [this] { sendPatches(); };
    saveButton.onClick = [this] { savePatches(); };
    loadButton.onClick = [this] { loadPatches(); };


void MainComponent::paint (juce::Graphics& g)
    // (Our component is opaque, so we must completely fill the background with a solid colour)


void MainComponent::resized()
    // This is called when the MainComponent is resized.
    // If you add any child components, this is where you should
    // update their positions.
        auto area = getLocalBounds();
        auto buttonsSpace = 4;

        auto buttonsHeight = 40;
        auto buttonsWidth = 60;
        auto dropBoxWidth = 100;

        buttonsArea = area.removeFromBottom(buttonsHeight);
        textLabel.setBounds (10, 10, getWidth() - 20, 20);
        serialPortMenu.setBounds (10, 40, dropBoxWidth, 30);

void MainComponent::serialPortMenuChanged()
        DBG("serialPortMenuChanged function called");
        pSP = new SerialPort(portlist.getAllValues()[serialPortMenu.getSelectedId() - 1], SerialPortConfig(57600, 8, SerialPortConfig::SERIALPORT_PARITY_NONE, SerialPortConfig::STOPBITS_1, SerialPortConfig::FLOWCONTROL_NONE));
			//create streams for reading/writing
			pOutputStream = new SerialPortOutputStream(pSP);
			pInputStream = new SerialPortInputStream(pSP);
			pOutputStream->write("hello world via serial", 22); //write some bytes
			// 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');
			//please see class definitions for other features/functions etc		

void MainComponent::getPatches()
    DBG("getPatches button clicked");

void MainComponent::sendPatches()
    DBG("sendPatches button clicked");

 void MainComponent::savePatches()
    DBG("savePatches button clicked");

 void MainComponent::loadPatches()
    DBG("loadPatches button clicked");

 void MainComponent::serialEvent()


and the .h file:

#pragma once

#include <JuceHeader.h>

    This component lives inside our window, and this is where you should put all
    your controls and content.
class MainComponent  : public juce::Component

    ~MainComponent() override;

    void paint (juce::Graphics&) override;
    void resized() override;
    void getPatches();
    void sendPatches();
    void savePatches();
    void loadPatches();
    void serialEvent();
   void serialPortMenuChanged();

    // Your private member variables go here...
    juce::TextButton sendButton;
    juce::TextButton getButton;
    juce:: TextButton loadButton;
    juce::TextButton saveButton;
    juce::Rectangle<int> buttonsArea;
    juce::Label textLabel { {}, "Serial Ports" };
    juce::Font textFont   { 16.0f };
    juce::ComboBox serialPortMenu;
    juce::StringPairArray portlist;
    SerialPort * pSP;
    SerialPortOutputStream* pOutputStream;
    SerialPortInputStream* pInputStream;


Hi Phil. Let me know where I can send you some code. I have a sample app that might be helpful in getting up and running. :slight_smile:

Thanks buddy,

I have sent you a message with my email address.