Tutorials

From Arduino to C#: How to Read & Save to CSV(2025 Guide)

18 June, 2025 Denesh Neupane
Arduino

1. Introduction

Arduino is an open-source based on easy-to-use hardware and software. Arduino boards (like Uno, Mega, Nano) contain microcontrollers (e.g., ATmega328P) that can read inputs (like sensors) and control outputs (like LEDs, motors). The Arduino IDE (Integrated Development Environment) is used to write and upload code (called sketches) to the board.

In this guide, you’ll learn:

  • How to Read the sensor Data using Arduino.
  • How to receive and display the Serial data in a C# desktop app.
  • How to save those data to a CSV file for further analysis.

2. Project Demo

3. Hardware & Software Requirements

Hardware

  • Arduino Uno/Nano
  • Sensors 
  • USB cable

Software

4. Step 1: Arduino Code (Send Sensor Data)

Arduino program

For Arduino Tutorials click Here

In this tutorial, we are focusing on designing the application and saving the file. You can click here for Arduino tutorials.

Things to remember: use Serial.begin(115200); and Serial.println(value);.

Serial.begin() establishes serial communication, and Serial.println() sends the value to the PC using the serial port.

Example Code

C++
void setup() {
  Serial.begin(115200); //you can use any option available
}

void loop() {
  int sensorValue = analogRead(A0); // Read analog sensor
  Serial.println(sensorValue);  
   //in this code i am using this as a sample serial data
 Serial.print("RcvData koki-: 0, cmd:123, data 2343, 23344, 0,0,345,123,0,0,44,44,44,0,0,0,0,0 ");
 Serial.println("OyakiData : 3450.44, 20.41,0.00,0.00,0.00");
  delay(1000); // Wait 1 second
}

5. Step 2: C# App (Receive & Display Data)

Arduino C# app

Set Up Serial Port

  1. Open Visual Studio → Windows Forms App (.NET Framework).
  2. Add a Buttons and datagridview(for logs) .

You can Download source code from here.

To use the serialPort and to save the data we need to this inbuilt library

C#
using System.IO.Ports;
using System.IO;

Initialize Port

Note: Here BaudRate must be same as Arduino

C#
 private void InitializeSerialPort()
 {
     serialPort = new SerialPort
     {
         PortName = "COM9", // ⚠️ Adjust to your port
         BaudRate = 115200,
         Parity = Parity.None,
         DataBits = 8,
         StopBits = StopBits.One,
         Handshake = Handshake.None
     };
     serialPort.DataReceived += SerialPort_DataReceived;
 }
  private void InitializeTimer()
 {
     uiUpdateTimer = new Timer
     {
         Interval = 100 // ms
     };
     uiUpdateTimer.Tick += UiUpdateTimer_Tick;
     uiUpdateTimer.Start();
 }

Connect and Disconnect button

C#
  //connect
  private void button1_Click(object sender, EventArgs e)
  {
      try
      {
          if (!serialPort.IsOpen)
          {
              serialPort.Open();
              button1.BackColor = Color.Green;
              button3.BackColor = Color.Gray;
          }
          else
          {
              MessageBox.Show("シリアル通信されています.");
          }
      }
      catch (Exception ex)
      {
          MessageBox.Show("Error: " + ex.Message);
          button1.BackColor = Color.Red;
      }
  }
  //disconnect
   private void button3_Click(object sender, EventArgs e)
 {
     if (serialPort.IsOpen)
     {
         serialPort.Close();
         button1.BackColor = Color.Gray;
         button3.BackColor = Color.Red;
     }
 }

SerialPort Received

You can Filter the received Data according to your needs here i filter the text and display only Data.

C#
 private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
 {
     try
     {
         string line = serialPort.ReadLine();
         serialQueue.Enqueue(line);
     }
     catch (Exception ex)
     {
         serialQueue.Enqueue("Read error: " + ex.Message);
     }
 }

 private void UiUpdateTimer_Tick(object sender, EventArgs e)
 {
     while (serialQueue.TryDequeue(out string data))
     {
         string cleaned = CleanReceivedData(data);

         if (!string.IsNullOrWhiteSpace(cleaned) && !cleaned.Trim().Equals("00") &&
             !cleaned.Trim().Equals("mode-0") && !cleaned.Trim().Equals("mode-1"))
         {
             AppendToRichTextBox(cleaned);
             UpdateDataGridView(cleaned);
         }
     }
 }

 private string CleanReceivedData(string input)
 {
     try
     {
         string cleaned = input.Replace("RcvData koki-: ", "")
                               .Replace("cmd:", "")
                               .Replace("data ", "");

         int oyakiIndex = cleaned.IndexOf("OyakiData : ");
         if (oyakiIndex < 0) return input;

         string firstPart = cleaned.Substring(0, oyakiIndex).Trim();
         string secondPart = cleaned.Substring(oyakiIndex + "OyakiData : ".Length).Trim();
         string result = $"{firstPart},{secondPart}";

         return Regex.Replace(result, @"\s*,\s*", ",");
     }
     catch
     {
         return input;
     }
 }

 private void UpdateDataGridView(string dataRow)
 {
     try
     {
         string[] values = dataRow.Split(',');

         if (values.Length == 23)
         {
             // Prepend serial number
             string[] newRow = new string[24];
             newRow[0] = serialNumber.ToString();
             for (int i = 0; i < 23; i++)
             {
                 newRow[i + 1] = values[i];
             }

             dataGridView1.Rows.Add(newRow);
             serialNumber++;

             dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;
         }
         else
         {
             AppendToRichTextBox($"Invalid data length: {values.Length} (expected 23)");
         }
     }
     catch (Exception ex)
     {
         AppendToRichTextBox("Grid update error: " + ex.Message);
     }
 }
 

6. Step 3: Save Arduino Data to CSV

C#
 private void button2_Click(object sender, EventArgs e)
 {
     try
     {
         using (SaveFileDialog saveFileDialog = new SaveFileDialog())
         {
             saveFileDialog.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*";// save the data to csv file
             saveFileDialog.FilterIndex = 1;
             saveFileDialog.RestoreDirectory = true;
             saveFileDialog.FileName = $"ArduinoData_{DateTime.Now:yyyyMMdd_HHmmss}.csv";

             if (saveFileDialog.ShowDialog() == DialogResult.OK)
             {
                 StringBuilder csvContent = new StringBuilder();
                 var headers = dataGridView1.Columns.Cast<DataGridViewColumn>().Select(c => c.HeaderText);
                 csvContent.AppendLine(string.Join(",", headers));

                 foreach (DataGridViewRow row in dataGridView1.Rows)
                 {
                     if (!row.IsNewRow)
                     {
                         var cells = row.Cells.Cast<DataGridViewCell>()
                                             .Select(cell => EscapeCsvValue(cell.Value?.ToString() ?? ""));
                         csvContent.AppendLine(string.Join(",", cells));
                     }
                 }

                 File.WriteAllText(saveFileDialog.FileName, csvContent.ToString());
                 MessageBox.Show($"Data saved successfully to:\n{saveFileDialog.FileName}",
                                 "Export Complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
             }
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show($"Error saving CSV file:\n{ex.Message}",
                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }

7. Troubleshooting

  • COM Port Error? Check Arduino’s port in Device Manager.
  • Baud Rate Mismatch? Ensure same as Arduino’s Serial.begin().


About author

Denesh Neupane

Denesh Neupane



0 Comments

No comments yet.


Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *