How to output from UNO R3 commands from a C# application ?

Some history - Some time ago, with arduino forum help, I managed to read a good bunch of LDR's using ADC0808 connected to Arduino Uno R3 pins, using a specialized arduino program that was converting all this received data and plot the results not only in the Serial Monitor of Arduino, but also into a C# application that was listening on COM5 @ 9600 baud rate.
Ok. So those pins used in arduino they were used as INPUTS.
My question to you, is how to reverse it?
-How to output from Arduino UNO R3, commands from a C# application?
My guess is to use -probably- another dedicated arduino program that will convert C# data and output it on Uno R3 I/O pins ?
Thank you !

Just as you are probably imagining.

The C# application sends/writes commands to the COM port. The Arduino reads them and sets it's output pins accordingly.

What kind of outputs do you want to achieve? Analog, digital, PWM...?

1 Like

Hi @PaulRB
Well, mostly digital but it will be good to have all 3 enumerated.
A complete menu.

One thing you cannot have on Uno R3 is a true analog output. This can only be achieved with additional external circuits. These could work in several ways.

  1. A PWM output can be converted to analog using a low-pass filter circuit. It may also be necessary to use a buffer chip so that the external device doesn't affect the correct operation of the low pass filter.
  2. An additional Digital-to-Analog-Converter chip connected via i2c or SPI bus.
  3. Build your own simple DAC using multiple output pins and a resistor ladder. Again, a buffer chip may be needed.
1 Like

I understand, so no pure analog. Let's leave it aside for the moment and concentrate only on the digital and PWM signals.
Can you post such a program file that will do this job for me?
Thank you !

First thing is to design a protocol that both sides will adhere to. You can base the Arduino side on Robins updated Serial Input Basics; the basics are e.g. in example 3.

The protocol can e.g. be something like <pin,value> to switch a pin on or off or pass a value from 0 to 255 for PWM. Example 5 in above topic will show you how to receive and parse so if you e.g. send <3,128> from the C# application the Arduino can parse it and give pin 3 a PWM value of 128.

You can send a number of them in series like <3,240><7,1><13,0>. There are other ways to send multiple info but they may make life more complicated

Note:
Using text is easier than binary; you can implement the Uno side of things testing with Serial Monitor and once that works as expected you can concentrate on the C# side of things.


I've moved your topic to a section of the forum that is dedicated to interfacing with software on the PC.

2 Likes

Thank you, Im looking into it right now.

@PaulRB do you have something else for me or should I dive into @sterretje page ?

I do not have, and will not be writing, free code for you. But I, and other forum members, will help you to write this code yourself.

2 Likes

using C# you can use the SerialPort class to open a COM port, use the write() method to send data to the UNO, create a DataReceived event handler to process data received from the UNO
received data can be displayed in TextBoxes and you can type data into TextBoxes for transmission over serial

remember to close the IDE Serial Monitor before attempting to run your C# program - two programs cannot access the same serial port concurrently

EDIT: have a look at VB and C# terminal emulators

1 Like

This is my first time dealing with serial port in programming, even in C#.
So, what I manage to do until now, I managed to copy-paste Example 3 Arduino code and on the Serial Monitor I got "Arduino is ready".
ReceiveOutput.ino (1.3 KB)
Then, I jumped in C#, and for a couple of hours I tried to find a code and to make it work there. And I find something very simple and straight. Next I needed to test that code so I had to do what the tutorials told me, and install some serial COM emulators, for creating virtual COM ports and opening the virtual window to see the data. After literally a couple of hours, I managed to figure out the "steps" in C# how to make it work. It was a dance of Closing and Opening the serial port, in the begining, imediatly after opening the C# application. Otherwise I was keep getting errors. So I finally managed to create a virtual Com9 and Com8, and actually send small strings from my C# app set to Com8 into this virtual Com9 emulator. I could only send data to it, but not receive from it.



Next, I tried to comunicate with my arduino COM5 but I was welcomed with a bunch of errors. My suspicion is that I can not initialize my program in C# to COM5. I need some other COMx to link it to COM5 used by arduino. Another problem is that I need something that is creating a "pair" between COM5 and COMx before coding anything in C#. After making the "pair", I can add in my C# that COMx to initialize with and it should work. But I have no idea how to make that "pair" with. Probably some obscure program that I never heard of. Again, all this is very new to me and Im learning as I go.
If you happen to know better than me on this subject, please tell me what to do next. Because Im in a big impas.
Thank you.

I am not totally sure what you may be looking for, but there is a C# client library for StandardFirmata.

I am not a C# programmer, so I cannot vouch for the library.

If you are willing to go to Python, I can recommend Telemetrix. This is a shameless plug - I am the author of Telemetrix.

We can't see your errors so have no idea. We also can't see you C# code so no idea.

Please do not attach small codes; you can use edit/copy for forum in the IDE and paste it in a reply.

No, you should be able to open COM5 from the C# application without any problems; you do need to close any other application that uses the serial port (e.g. serial monitor as mentioned in reply #10).

in addition to being able to transmit serial data the C# code need s to be able to receive serial data (e.g. sensor data to display, error messages, etc) and display it, e.g. in a TextBox
have a look at methods serialPort1_DataReceived() (serial event handler receives data) and AddDataMethod() (delegate to display received data in a TextBox) in C# Form.cs

I managed to make a transmit and receive serial comunication --test--.
Next, Ill try with COM5.

Nothing, I can not transmit to COM5.
And I could receive an "Ardoino is ready" when Im opening TeraTerm5



monitoring window, then close it, and in my C#app, I could receive it only the first time Im connecting to COM5. After disconnecting and conecting again from my C#app, it is not receiving that message again.
So TeraTerm5 is doing something better than the functions in my C# code.
But that is the receiving part.
The sending part is impossible from my C# app to COM5 where Arduino is linked.

Here is the entire C# project made in VS2010, which should not be a problem to convert to higher versions of VS.
WindowsFormsApplication2.zip (51.0 KB)
Here, only the text file code -easier to inspect in my opinion.
Form1.txt (3.0 KB)
and here is the actual code that will be quite long to read here in this tiny page:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            cmdClose.Enabled = false;
            foreach (String s in System.IO.Ports.SerialPort.GetPortNames())
            {
                txtPort.Items.Add(s);
            }
        }
      
        public System.IO.Ports.SerialPort sport;

        public void serialport_connect(String port, int baudrate, Parity parity, int databits, StopBits stopbits)
        {
            DateTime dt = DateTime.Now;
            String dtn = dt.ToShortDateString();

            sport = new System.IO.Ports.SerialPort(
            port, baudrate, parity, databits, stopbits);

            try
            {
                sport.Open();
                cmdClose.Enabled = true;
                cmdConnect.Enabled = false;
                txtReceive.AppendText("[" + dtn + "]" + "Connected\n");
                sport.DataReceived += new SerialDataReceivedEventHandler(sport_DataReceived);
            }
            catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error"); }    
        }

        void sport_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            DateTime dt = DateTime.Now;
            String dtn = dt.ToShortTimeString();

            txtReceive.AppendText("[" + dtn + "]" + "Received: "+ sport.ReadExisting()+"\n");
        }

        private void cmdConnect_Click(object sender, EventArgs e)
        {
            String port = txtPort.Text;
            int baudrate = Convert.ToInt32(cmbbaudrate.Text);
            Parity parity = (Parity)Enum.Parse(typeof(Parity), cmbparity.Text);
            int databits = Convert.ToInt32(cmbdatabits.Text);
            StopBits stopbits = (StopBits)Enum.Parse(typeof(StopBits), cmbstopbits.Text);

            serialport_connect(port, baudrate, parity, databits, stopbits);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            String dtn = dt.ToShortTimeString();
            String data = txtDatatoSend.Text;
            sport.Write(data);

            txtReceive.AppendText("[" + dtn + "]" + "Sent: " + data + "\n");
        }

        private void cmdClose_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            String dtn = dt.ToShortTimeString();

            if (sport.IsOpen)
            {
                sport.Close();
                cmdClose.Enabled = false;
                cmdConnect.Enabled = true;
                txtReceive.AppendText("[" + dtn + "]" + "Disconnected\n");
            }
        }
    }
}

try downloading Visual Studio Community 2022

  1. download ZIP file from VB and C# terminal emulators
  2. unzip VB_terminal_emulator-master.zip
  3. open VB_terminal_emulator-master\CsharpTerminal\CsharpTerminal.sln
  4. hit CTRL/F5 which will compile and run the C# program

can you connect and communicate with the microcontroller??

should give you a starting point

1 Like


So I can't work with that version of VS. Im using w7, that's why.
But my VS2010 should work just fine if I could understand how this thing should work.
Your second link -VB and C# terminal emulators- I believe should have pointed to this link here.
I'll see if I can adapt the code inside -VB and C# terminal emulators- into my VS2010. By the way, it doesnt want to open that Csharp Terminal.sln project file at all. I suspect it is a newer VS than my VS2010 and he doesn't understand how to open it. Inside this *.sln file I see this "Visual Studio Express 14 for Windows Desktop" so that is what is made with and probably is why you told me to install this new Visual Studio Community 2022 in the first place. Hell, it doesn't work. Haha. But I will make it work, or I will find a way, or another way.
-In the mean time, can you explain in a couple of detailed points how this serial communication should actually work? What should I expect from it?
Thank you @horace !

what if you try to open CsharpTerminal.csproj

1 Like

yes, that worked, for sure I dont know all details in VS, and I didnt know this one.
Very cool, It opened and I could compile it.


The blue_marked ports are virtual ones created with com0com virtual thing.
So now we are as before.