Sunday, March 4, 2018

CircuitPython Program for Writing Sensor Data to CSV File

As part of my new book, tentatively titled "Make: Getting  Started with Circuit Playground Express", one neat trick is writing sensor values to a file on the built-in flash file system. If the values are written as a text file in Comma Separated Values (CSV) format, nearly any word processor or spreadsheet program can read the file.

The Circuit Python code for reading the onboard temperature and light intensity sensors - feel free to change the readings to other sensors like the accelerometer. Name the file

# Read Temperature and Light Intensity, output as a CSV file
# Mike Barela for Getting Started with Circuit Playground Express
# 2018 MIT License, attribution appreciated

import time
from import cpx

# Set NeoPixel 0 to green as status of board, NeoPixel 1 to collecting data
cpx.pixels[0] = (0, 90, 0)  # coded red, green, blue
cpx.pixels[1] = (0, 0, 90)  # Pixel 1 blue when collecting data

num_readings = 10  # set to any finite value you want

# we try to open/create the file for append access and write the 
#    heading line. If an error occurs, go to except statement
    with open("/temp-light.csv", "a") as fp:
        fp.write('Temperature, Light Intensity\n')  # headings
        for x in range(0, num_readings):  
            temp = cpx.temperature
            # do the C-to-F conversion here if you would like
            fp.write(str(temp) + "," + str(cpx.light) + "\n")
            # Change the value of sleep time below in seconds
            # 1 minute=60 sec, 5 mins=300 sec, 1 hour=3600 sec, etc.
            if cpx.button_a:
        # Done, set NeoPixel 1 to green also
        cpx.pixels[1] = (0, 90, 0)

except OSError as e:
    # set NeoPixel 1 off and blink NeoPixel 0 (status) depending on 
    #    the OS error
    cpx.pixels[1] = (0, 0, 0)           # Blank NeoPixel 1
    message_color = (99, 0, 0)          # Red for generic problem
    if e.args[0] == 28:                 # Device out of space
        message_color = (228, 160, 40)  # set to Orange
    elif e.args[0] == 30:               # Device is read only
        message_color = (181,  90,  0)  # set to Yellow
    for x in range(1, 10):              # Flash message 10 seconds
        cpx.pixels[0] = message_color
        cpx.pixels[0] = (0, 0, 0)

The filesystem normally is locked for writing unless specially set up at board boot. You can do this by placing the following file in the flash filesystem as

# Set Circuit Playground Express flash chip to program writeable 
#   If toggle switch is right, 
#      flash is program writeable and file access is frozen
#   If toggle switch is left,
#      flash chip file access ok, file writes give an error
# via Dan Conley 
#   writing-to-the-filesystem
# 2018 Mike Barela for Getting Started with Circuit Playground Express

import storage
from import cpx

storage.remount("/", cpx.switch)

This sets the Circuit Playground Express slide switch to control if a program can write to flash or not.

Running the program without setting the slide switch to the right side results in a yellow NeoPixel.

Running the program with the slide switch on the other side the code should show a green and blue NeoPixel. When the data collection is complete, you will get two green NeoPixels. Slide the switch back, press the Reset button to reboot and open the CIRCUITPY drive on your computer file explorer. The file temp-light.csv should be there with the readings. If you run the program multiple times, it appends the results with headings on each run. With my system, I have MS Office installed and Windows correctly shows the CSV file as openable by default with Excel. You may have to expand the default column widths but otherwise the data is spot on.

More detail will be in the book out later this year. This is enough to help you if you have not got the tricks it takes to write to the filesystem.

Thanks to Dan Halbert for some Python file wizardry and Dan Conley for his tutorial on