We’re here to help in the event of a school closure. See our resources.
Send Arduino data to a file CSV using Python

Arduino Data Logger (CSV) with Sensors and Python

We sometimes use affiliate links in our content. This won't cost you anything, but it helps us to offset the costs of paying our writing team. You can support us directly on BuyMeACoffee. Thank you!

Online Robotics Course by Learn Robotics
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn
What good is reading analog sensor data from an Arduino if you can’t store it for later? In this tutorial, I’m going to show you how to collect and display data from multiple analog sensors using an Arduino Uno. We’re going to create an Arduino Data Logger to generate CSV files.

We’ll do this by reading multiple analog sensors on the Arduino and displaying the information to the Serial Monitor. Then, we’ll use a Python script to capture real-time data, serially, and log into a CSV (Comma Separated Value) file.

At the end of this project, you’ll have a CSV file that you can use in Excel for a variety of data analytics and decision-making projects. Essentially, we’re creating a way for you to connect Arduino Sensors to Excel to capture environment data for processing.

How to generate log files for Arduino projects using Python and Excel
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn

This project can be applied to many applications in Industrial Manufacturing, Smart Homes (IoT), and more. If you have a project that you want to add data logging to, then adding this Python script will allow you to strategically collect data for future analysis.

Heads Up, this Project is More Advanced

Props to landing on this tutorial! That means you either A) have an interesting project you want to build or B) you’re looking to gain intermediate skills with Arduino and Python. Both are great places to be in, but I want to set some expectations before you head into this tutorial.

While this is an in-depth tutorial, it does require prior experience with simple analog circuits, Arduino sketches, and Python programming. That means I’ll be covering high-level steps on what you need to do to get this working. Unfortunately, I will not cover these topics in-depth.

If you’re brand-new to Arduino, sensors, circuits, and coding, I highly recommend enrolling in my Level 1 course, Arduino for Beginners, before attempting to piece this project together. If you’re new to Python, here are a few Python courses I recommend checking out.

You can also check out my Robotics Engineering Bundle if you’re interested in getting a taste of robotics engineering projects. Plus, you’ll gain professional skills in hardware I/O, data collection, decision-making, and mechatronics systems.

Now, are you ready to get started?

Step 1. Connect Analog Sensors to Arduino

First, wire up the analog sensors that you want to use for this project. This project requires at least two analog sensors. I’ve chosen a rotational potentiometer and a photoresistor.

Here’s the Fritzing Diagram for the circuit used in this example.

wire multiple analog sensors to Arduino Uno
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn

The potentiometer is connected to A0 and the photoresistor is connected to A1. You can use whichever open pins you’d like.

Once you have your circuit wired, it’s time to write the Arduino Sketch.

ELEGOO Upgraded 37 in 1 Sensor Modules Kit with...
100% compatible with Arduino official IDE, Raspberry Pi and STM32.
$32.99
Sale
ARDUINO UNO R3 [A000066]
Arduino Uno is the most used and documented board in the world
$29.95 −$6.95 $23.00
Sale
ELEGOO Upgraded Electronics Fun Kit w/Power Supply...
The highest cost performance kit with more than 300pcs components; Datasheet and tutorial is available to download from our official website
$24.99 −$7.01 $17.98

Step 2. Write Arduino Sketch to Read & Send Data Serially

Next, open up a new Arduino sketch and assign two global variables to pins A0 and A1 (or whatever pins your sensors are connected to). Then, begin the Serial Monitor at 9600 baud, and set these sensors as INPUTS in the setup() method.

int sensor1 = A0;
int sensor2 = A1;

void setup(){
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

Now we can develop our loop() method. Create a few globals to store data from both of the sensors. Then, use the analogRead() method to read the pin. Add a delay so that we’re not collecting data too fast.

//globals
int data1, int data 2; //store data from both sensors
int freq = 1000; //data collection frequency ~x milliseconds

void loop(){
    data1 = analogRead(sensor1);
    data2 = analogRead(sensor2);

    delay(freq);
}

We have the data, now we need to display it on the Serial Monitor. We’re going to use the CSV format for our data, so the data should look like this: data1,data2

//globals
int data1, int data 2; //store data from both sensors
int freq = 1000; //data collection frequency ~x milliseconds

void loop(){
    data1 = analogRead(sensor1);
    data2 = analogRead(sensor2);

    //Display Data to Serial Monitor
    Serial.print(data1);
    Serial.print(",");
    Serial.println(data2);

    delay(freq);
}

This code works as-is, and you can upload it to your Arduino and test it out. Open a Serial Monitor, and you should have readings that look like the following.

Print out values from Arduino as a CSV file
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn

Idea A: Display Data Only if the Sensor Readings are Different

Sometimes, you’ll want to impose conditions on your data collection. A good example of this is if the current reading is the same value as the previous reading.

In some cases, you may not want to print out the same reading every single time. You’ll only want to log a reading if it’s different than previously.

To do this, we can set some global variables equal to the current reading and then collect a new reading for comparison.

//globals
int curr1, int curr2;

void loop(){
    data1 = analogRead(sensor1);
    data2 = analogRead(sensor2);
    
    if (curr1 != data1 || curr2 != data2){

        //Display Data to Serial Monitor
	Serial.print(data1);
	Serial.print(",");
	Serial.println(data2);

	//set the current equal to the data
	curr1 = data1;
	curr2 = data2;
	
	delay(freq);
    }
}

Idea B: Print Data based on Conditional Ranges

Furthermore, sensor readings can be a bit picky and oscillate between +/- 1 of the same reading. So, if you run the code above, and you’re not happy with how it’s working, you may need to set up a conditional range.

For example, you can display data if the new reading is +/- 5% of the current reading. To set this up, you can create a couple of globals to easily adjust your thresholds. 1024 comes from our analog pin, which has a 10-bit resolution. (2^10 = 1024). Therefore 5% = 1024*.05 = 51.2, which is rounded to 51.

Note: This will trigger the next increment of the threshold the next time the sensor meets this requirement unless you add a delay.
//globals
float percent = 0.05;
int threshold = 1024*percent; //within x% in either direction

We can use this threshold in our conditional statement.

//globals
float percent = 0.05;
int threshold = 1024*percent; //within x% in either direction

void loop(){
    data1 = analogRead(sensor1);
    data2 = analogRead(sensor2);

    if((curr1 >=data1+threshold || curr1 <=data1-threshold) || (curr2>=data2+threshold || curr2<=data2-threshold) ){

        //Display Data to Serial Monitor
	Serial.print(data1);
	Serial.print(",");
	Serial.println(data2);

	//set the current equal to the data
	curr1 = data1;
	curr2 = data2;
    }
    delay(freq);
}

Rather than checking to see if the current value is different than the new value, we can check to see if the current value is greater than or equal to the new value + 5% or if the current value is less than or equal to the new value – 5%.

And that’s basically it! Upload the code to your board, and open the Serial Monitor. You can adjust the percentage and frequency so that data is displayed most appropriately for your application.

Idea C: Show Column Headers in the CSV File

Now, this section is completely optional, but if you want to stylize your CSV file, you’ll want to send over your column headers. This is what will be displayed in the first row of Excel.

I used the names of the sensors as my column headers, but you can use whatever you like.

To do this, you can use some global variables to store the header names. Then, set up a loop that runs once and prints them out. Make sure you use the CSV format!

I also set a boolean so that we only run this loop once.

//gloabls
String dataLabel1 = "Potentiometer";
String dataLabel2 = "Photoresistor";
bool label = true;

void loop(){
	
    //print out column headers
    while(label){ //runs once
        Serial.print(dataLabel1);
        Serial.print(",");
        Serial.println(dataLabel2);
        label=false;
  }

    data1 = analogRead(sensor1);
    data2 = analogRead(sensor2);

    if((curr1 >=data1+threshold || curr1 <=data1-threshold) || (curr2>=data2+threshold || curr2<=data2-threshold) ){

	//Display Data to Serial Monitor
	Serial.print(data1);
	Serial.print(",");
	Serial.println(data2);

	//set the current equal to the data
	curr1 = data1;
	curr2 = data2;
    }
    delay(freq);
}

This completes the code on the Arduino side. Feel free to make modifications or adjust it to capture things that best suit your project.

Now, it’s time to move into Python and develop the code that can read and log data from our serial connection.

Step 3. Develop Python Code to Read Serial Data from Arduino

The third step is to create a new Python file and import the serial module. Then, set a few variables for the port the Arduino is on the baud rate, and the CSV file name.

import serial

arduino_port = "/dev/cu.usbmodem14201" #serial port of Arduino
baud = 9600 #arduino uno runs at 9600 baud
fileName="analog-data.csv" #name of the CSV file generated

The Arduino serial port will be in the format “COMX” on Windows or “/dev/cu.usbmodemxxx” on Mac. Use the same address that you selected in the Arduino IDE under Tools > Port.

Next, set up the serial connection and create the file. You can use the input parameter “w” to write a new file or “a” to append to an existing file.

ser = serial.Serial(arduino_port, baud)
print("Connected to Arduino port:" + arduino_port)
file = open(fileName, "a")
print("Created file")

I added a few print statements to let the user know what’s happening in the code.

Step 4. Create an Arduino Data Logger: Send Serial Data into a CSV File

After that, you can read the serial port, parse the data, and print it to the terminal. Then, add the data to the file.

#display the data to the terminal
getData=str(ser.readline())
data=getData[0:][:-2]
print(data)

#add the data to the file
file = open(fileName, "a") #append the data to the file
file.write(data + "\\n") #write data with a newline

#close out the file
file.close()

Technically, we’re finished, here but if you’d like to set the number of samples to collect, you can throw everything into a while loop, like so.

samples = 10 #how many samples to collect
print_labels = False
line = 0 #start at 0 because our header is 0 (not real data)
while line <= samples:
    # incoming = ser.read(9999)
    # if len(incoming) > 0:
    if print_labels:
        if line==0:
            print("Printing Column Headers")
        else:
            print("Line " + str(line) + ": writing...")
    getData=str(ser.readline())
    data=getData[0:][:-2]
    print(data)

    file = open(fileName, "a")
    file.write(data + "\\n") #write data with a newline
    line = line+1

print("Data collection complete!")
file.close()

You’ll notice that I’ve added a boolean that allows you to choose if you want to display the current line number or if you want to just see raw data. This, again, is all optional, but I think it’s a nice addition.

Once you have the code written, be sure to save it. I named mine read-serial.py.

Step 5. How to use the Python Code for your Arduino Data Logger (CSV)

It should go without saying, but make sure you have the code written from Step 2 uploaded to your Arduino before running the Python script.

Additionally, be sure that your Arduino is connected to your computer’s USB port. Otherwise, none of this will work.

Next, open up a terminal window, navigate to the folder where your code is saved, and run the code using the following command.

python read-serial.py

You should see 10 samples flow through, so long as the data has changed based on your conditions (from Step 3).

Use Python to read Arduino Sensors and log to a CSV
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn
You’ll also have another file called analog-data.csv added in the same directory as your Python script.

Create an Analog Data CSV
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn
You can open this file with a text editor or with Excel to view the data readings.

How to view Arduino Data using Excel
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn
And that’s how you get real-time readings from the Arduino Uno into Excel using Python and serial communication.

I hope you found this tutorial useful for your next project!

Want a copy of the code files?

You can unlock a copy of all of these project files when you support us on BuyMeACoffee.

 

What project are you working on that requires Arduino data logging? Let me know in the comments below!

And, if you enjoyed this tutorial or it helped you in any way, please consider sending us a coffee!

You May Also Like

Have a question? Need Help?

Thanks for dropping by! Comments are no longer moderated daily.
Before posting your comment, please consider buying me a coffee. If you need immediate support, you can schedule an appointment. Providing customized information for your individual scenario takes a lot of my time. I’m happy to help, but I can no longer provide individualized advice pro bono.
Thank you for understanding.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Free Learn Robotics Swag

Patch/Sticker with every LR Kit

Work with an Engineer

Live Chat with an Instructor

365 Day Course Access

1 year access to every course

100% Secure Checkout

PayPal / MasterCard / Visa

Become a Learn Robotics Insider

Sign up and receive product announcements and discounts!

 

Success! Check your email for a surprise!

Pin It on Pinterest