Introduction: How to Show Arduino Sensor Data in a Windows Application
Once you have your Arduino sensor setup and returning data you need to do something with the data - showing it for example. In this Instructable I show you how to do just that with a small program that you can write using your own computer. So that you have your sensor data displayed beautifully.
I will be using the Temperature Sensor for the data collection device and display it on a live graph in Microsoft Windows. The source code is available as a free download.
The quickest way to get through this Instructable is to watch the included video. even if you follow this guide the video will still contain information that can help you complete this task.
Step 1: A Quick Look at the Final Result.
Before we get into the meat of the tutorial we will have a quick look at the result to make sure this Instructable is something you are interested in. The application is very simple. It shows the temperature in the top graph which moves much like the graphs on your computer showing CPU and Memory usage.
The graph is a free control and all you have to do to get it to show your data is tell it what value to display.
At the bottom of the application is a box which, like the Serial Monitor in the Arduino IDE, displays the output of the Serial.println() command in your Arduino Sketch. Don't worry the source code is coming and will be explained.
You can move the window around your desktop and the program continues to update in real time, there are no delays which makes this perfect for telemetries - processing and displaying live sensor data.
And now for the code...
Step 2: The Arduino Sketch
void setup(void)
{ Serial.begin(115200);sensors.begin();
sensors.getAddress(tempDeviceAddress, 0); sensors.setResolution(tempDeviceAddress,10); }
As you can see the Setup for the code is very simple, it has only 4 instructions. It sets up the Serial Connection which we need to receive the data from the sensor. It starts the sensor and sets the resolution.
void loop(void)
{ sensors.requestTemperatures(); Serial.println(String(sensors.getTempCByIndex(0))); }
The main loop of the program is a short as possible. With only two instructions the sensor data can be collected very quickly. We ask for the temperature to be collected.
Then we send the sensor data as a string to the serial device.
That is all there is to this Sketch. There are some global setup that I have not included but are is self-explanatory and is included in the source code file.
Step 3: The Windows Application Code...
The Windows application is split into two different parts. The first part shown is a small library I wrote to connect to the Arduino, and get the data from the serial connection. As you can see the source code is very heavily commented. However, if you find you have any problems with it there is plenty of places where you can ask me for help or indeed your peers. The program is written in C# if you would prefer VB.NET versions then feel free to ask me. Or you can use this converter to change the supplied code to VB.
This section of the code has four main functions.
- To easily connect to a serial port.
- To get serial data and send it to another part of the application (main form)
- To allow connecting to multiple serial ports to get multiple Arduino data
- To allow the main GUI to run without interruption
Point One: Easily Connect to Serial Port
<p>public Serial(string portName, int baudRate, bool openConnection = true)<br> { _sp.PortName = portName; _sp.BaudRate = baudRate; _sp.DataReceived += _sp_DataReceived; _sp.ErrorReceived += _sp_ErrorReceived; _sp.PinChanged += _sp_PinChanged; if (openConnection) _sp.Open(); }</p>
This method allows us to connect to a particular serial connection at a particular speed. You will remember that within the Arduino Sketch we set the baudRate to 115200 in the Serial.begin() call. The portName is the name of the port which the Arduino Sketch was uploaded to. You can find that in the bottom Left of the Arduino IDE.
You can see in the image my Serial port is COM9. So this method would be called like this:
Serial("COM9",115200);
the _sp.DataReceived, ErrorReceived and PinChanged are events that the Arduino tells us happened and that we can tell the main program so that we can decide what to do. We will only examine the _sp.DataReceived here as the other two are almost identical and we are only truly interested in getting the data and showing it.
Step 4: Point Two: Get Serial Data and Send It to Another Part of the Application
<p>private void _sp_DataReceived(object sender, SerialDataReceivedEventArgs e)<br> { if (_stopping) return; var sp = (SerialPort)sender; DataRecieved(sp.ReadLine()) }</p>
When the serial port has data waiting for us to process our program automatically jumps to this event method. If the program is stopping we just return. Otherwise, we get the data (sp.ReadLine()) and send it to the DataRecieved method.
private void DataRecieved(string dataReceived)
{ArduinoDataRecievedEvent?.Invoke(dataReceived);
}
This method passes the data on to the main application, if the main application is waiting for data. That is all the question mark means in the code really.
Step 5: Point Three: Allow Connecting to Multiple Serial Ports to Get Multiple Arduino Data
We want to be able to communicate with many different sensors possibly connected to many different Arduinos. I have made that very simple to do.
// The Serial Device we will be communicating with.
private readonly Serial _serial = new Serial("COM9", 115200, false);
The above instruction only needs to be copied and slightly modified to allow us to connect to multiple Arduinos. We would need to change the "COM9" port to the correct port, the 115200 baud rate to the correct baud rate as defined in the Arduino Sketch and change the _serial to a new name; such as _serial5 for "COM5". After doing that we can receive data from multiple Arduinos at the same time!
I did say I wanted to make this easy for you!
Step 6: Point Four: to Allow the Main GUI to Run Without Interruption
We don't want the main application to freeze when so by splitting the application in two we can keep the main GUI running without interruption. All long running operations should normally be done in a different thread so that the GUI remains responsive - so yes, this will make your application multi-threaded.
So what about the actual display of the data?
Okay, okay, here it is.
tracker.Value = (int)(toDecimal * 100);
The data we receive is provided to 2 decimal points. The graph however, only accepts integers. To get around this and still maintain the resolution of two decimal points we multiply the received data by 100 making 21.05 degrees 2105 degrees - and display that. I know, I know! I have made it too easy!
As for the data being displayed at the bottom? Well that is also embarrassingly easy.
control.AppendText(DateTime.Now + "\t" + text);
The "control" is a RichTextBox I append to the bottom of the page the Date and time that the data is being displayed, followed by a Tab - usually 4 or 8 spaces, and the text which we received from the sensor. That truly is it.
But worry not, the next Instructable will be even better - We are going to build an aircraft cockpit using Arduino sensors and a windows application to display the cockpit controls and sensor data!
* This is my first Instructable - be kind :D
Source Code: https://github.com/7ASecond/ArduinoNet
20 Comments
6 years ago
i think that you have to look and try this. it s top
http://www.e-mole.cz/diy/molegraph
6 years ago
very good project.
is it possible to have the .exe (compiled file) in github ?
one more fonction will be very nice, it s the generation of a csv file of the data.
Reply 6 years ago
Exes are now included in the GitHub repository and this Repository includes the saving of the data to a CSV file
https://github.com/7ASecond/ArduinoNet/tree/master/ArduinoNet-TempCSV
Reply 6 years ago
thanks a lot but the ArduinoNet-TempCSV.exe won't launch, it crash each time i double click.
the ArduinoNet-Example.exe launch but say : you don' t have com9
what did it happen if the arduino board is on another com ?
for the arduino.ino
i tried :
void setup(void)
{
Serial.begin(115200);
sensors.begin();
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress,10);
}
void loop(void)
{
sensors.requestTemperatures();
Serial.println(String(sensors.getTempCByIndex(0)));
}
but it doesn't compile.
is it possible to have some .ino in exemple
1 exemple for 1 value (exemple temperature)
1exemple for 2 value (exemple temperature and humiditie)
put the exemple in github will be great.
thanks for all
you're really quick.
Reply 6 years ago
Ok I have added the Sketches.
Also I think the Exes in the bin/debug folders should work now
Reply 6 years ago
thanks a lot, i just download the last version
now i understand the sketch.
for the exe,
ArduinoNet-Cockpit launch
ArduinoNet-Example launch but say their is no com9
ArduinoNet-TempCSV crash
is it possible to have a selector for the port com. i don't know how to compile C#
thanks a lot
Reply 6 years ago
Ok watch this video to install C# on your computer for Free
The Git repositories have been updated - TempCSV now automatically detects the Arduino if it is connected and set's it's port. You will see how that is done in the ArduinoNet.Hardware code.
Reply 6 years ago
you re really reactive.
thanks for the video
tempCSV launch, but the port com don't arrived. i ve a arduino board connect.
did you know guino for arduino :
here is a sketch. add the lib to arduino. did you think you could add an csv export to this project ? :
#include <EasyTransfer.h>
#include <EEPROM.h>
#include <Guino.h>
//libraries at http://duinoedu.com/dl/lib/dupont/EDU_Guino/
int Guinotracegraphique_ABVAR_1_analogReadA0 = 0 ;
int GuinoPotentiometreVirtuel_ABVAR_2_pot1 = 0 ;
int GuinoInterrupteurvirtuel = 0 ;
int GuinoInterrupteurvirtuel_ABVAR_3_inter1 = 0 ;
void setup()
{
GUINO_BRANCHER();
pinMode( 2 , OUTPUT);
}
void GUINO_DEFINIR_INTERFACE()
{
GUINO_AFFICHER_TITRE("title here");
GUINO_AFFICHER_GRAPH("graph1",Guinotracegraphique_ABVAR_1_analogReadA0,0,1023);
GUINO_AFFICHER_LIGNE();
GUINO_AFFICHER_POTENTIOMETRE("graph1",Guinotracegraphique_ABVAR_1_analogReadA0,0,1023);
GUINO_AFFICHER_LIGNE();
GUINO_AFFICHER_POTENTIOMETRE("pot1",GuinoPotentiometreVirtuel_ABVAR_2_pot1,0,255);
GUINO_AFFICHER_LIGNE();
GUINO_AFFICHER_PAUSE(GuinoInterrupteurvirtuel);
GUINO_AFFICHER_INTERRUPTEUR("inter1",GuinoInterrupteurvirtuel_ABVAR_3_inter1);
}
void loop()
{
GUINO_GERER_INTERFACE();
Guinotracegraphique_ABVAR_1_analogReadA0=analogRead(A0);
GUINO_LIRE(Guinotracegraphique_ABVAR_1_analogReadA0);
analogWrite(2 , GuinoPotentiometreVirtuel_ABVAR_2_pot1);
GUINO_GERER_PAUSE(GuinoInterrupteurvirtuel);
digitalWrite(2 , GuinoInterrupteurvirtuel_ABVAR_3_inter1);
}
source : https://github.com/madshobye/guino
project : https://www.instructables.com/id/Guino-Dashboard-fo...
video : https://vimeo.com/49428434
Reply 6 years ago
I have added guino to the list - it should now find it. It now looks for Arduino, Genuino, and Guino.
If you add the export to the Arduino code then the data will be saved locally on to the Arduino. I don't have anyway to do that - no permanent storage like an sd card adapter.
So the only way you can do it is by using a computer program like the one I showed in TempCSV to save the data to the computer.
I will have a look for an SD card shield for the Arduino - but I do not expect it to arrive quickly if I find one.
Reply 6 years ago
Guino is like TempCSV.
it s an application you launch
look those link :
source : https://github.com/madshobye/guino
project : https://www.instructables.com/id/Guino-Dashboard-fo...
video :
did you think you could modify the source of guino for an csv export ?
Reply 6 years ago
Ok - I could not really understand Guino's code so here is what you have to do:
create a function with this code in it
FILE*f = fopen("file.txt","w");i
f(f == NULL)
{
printf("Error opening file!\n");
exit(1);}
/* print some text */
/* text below is the string variable you wish to save to file*/
fprintf(f,"%s\n", text);
fclose(f);
Then call the function and that is it.
Reply 6 years ago
Ok thank you.
Reply 6 years ago
Also - here is a good tutorial on writing to files in C
http://www.dirac.org/linux/programming/tutorials/f...
Reply 6 years ago
Ah - I see! Sorry. I will look now.
Reply 6 years ago
Sorry forgot to say - near the top of the C# code you will see the Serial connection being created with the "COMx" port being named - change that to the correct com port number. So if you are using Com5 change it to "COM5".
Reply 6 years ago
Ok I shall look at it - and let you know
Reply 6 years ago
I will let you know when it is done - I think I may place the EXE on Google's drive for people to download. I will also add the function for you.
Reply 6 years ago
Thank you
it will be really good.
6 years ago
Very well done!
Reply 6 years ago
Thank you !!