Microsoft MakeCode is one of our favorite programming methods. It is super easy to learn, yet it has many capabilities to build more advanced projects and even really good games.

A common project in MakeCode is to read sensors like temperature, light, moisture, etc. and record or display the values for the user. The display part can be easy with lights and displays. But recording data for later use has been laborious. Here at Adafruit, we made a project to log data to a Google Sheets spreadsheet but that required attaching a phone, a big peripheral, for the full length of the data collection.

With an additional extension, MakeCode can also write data to a file, if the microcontroller has some flash memory aboard. Adafruit's Express series, which is programmable in both MakeCode and CircuitPython, has extra flash used (up to now) for CircuitPython. The MakeCode extensions Datalogger and Storage use that flash storage to allow the programmer to write data out as files.


For this project, we are going to use the Adafruit Circuit Playground Express. It has built-in sensors and 2 megabytes of flash storage all at one low price involving zero soldering. Other Express boards from Adafruit also have similar capabilities, although adding the sensors to gather data may take additional boards or wires.

Circuit Playground Express (CPX for short) comes as a round, black board from Adafruit - you might have a red Digi-Key CPX or even a green 4-H logo CPX! They all work 100% the same, so there are no worries if you see a picture and your CPX is a different color.

Circuit Playground Express is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and...
In Stock
Circuit Playground Express is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and...
In Stock

These packs will have all the parts you need!

We are super pleased to enjoy a partnership with an engaging, empowering foundation like 4-H. Here at Adafruit we drive ourselves to "be...
In Stock
We are super pleased to enjoy a partnership with an engaging, empowering foundation like 4-H. Here at Adafruit we drive ourselves to...
In Stock
It's the Circuit Playground Express Base Kit! It provides the few things you'll need to get started with the new
Out of Stock

If you are new to Microsoft MakeCode, Adafruit has some excellent tutorials on learning the basics. See the tutorial MakeCode for Circuit Playground Express for the details.

What is an Extension?

Extensions in MakeCode are groups of code blocks that are normally not part of the basic code blocks found in MakeCode. Extensions, like the name implies, adds blocks for specific functionality. There are extensions for a wide array of very useful features, adding gamepad, keyboard, mouse, servo and robotics capabilities and much more.

Extensions in MakeCode Versions

For this tutorial we will use MakeCode for Circuit Playground Express. If you are using another board, use MakeCode Maker, go to Advanced -> Extensions and see if the Storage extension is available for your board.

FYI, the Circuit Playground Express capability in MakeCode Maker (beta as of this guide) did not have Storage listed but going to MakeCode for CPX has full capability for Storage.

Loading an Extension

Open a new project in MakeCode and you will get the default "ready to go" screen shown here.

See the black ADVANCED button at the bottom of the column of different block groups, circled in red to the left.

Clicking ADVANCED will show 7 additional block groups. At the bottom is a grey box named EXTENSIONS. Click that button.

Above, in the list of extensions available for Circuit Playground Express, both the Datalogger and Storage extensions are available. If you are using MakeCode Maker, you might not see one or the other depending on the board you chose to use. It might be available if you type in "Datalogger" or "Storage" in the search feature circled in yellow above. If you see neither, that capability is probably not available for the board you chose.

Click the extension you will want to use and a new block group will appear in the main MakeCode screen.

Apparently, if you pick the Datalogger extension, the Storage extension will not be shown as available. It appears using both at the same time is not possible. Read the pages in this guide to see which extension may be best for your application.

The Datalogger extension allows you to write chosen data values to a file at specified time intervals.

This type of storage is great for sensor readings, error logging, etc. 

Below are the blocks available with the Datalogger Extension.

With the data logger set separator block at the bottom, you can select which keyboard character you want to use to separate data values: tab, comma, or semicolon. Different computer programs process files differently, so this choice is good.

Using commas to separate values is very often used, programmers have done this going back many years. Comma Separated Values (CSV) files, as they are called, are very common in data collection and many programs can read in files in this format.

CSV files are great - you can read them in plain text editors and all spreadsheets can read them to capture the data into a nifty spreadsheet. Just what we often want! So, let's find out how to use this capability.

Below is a basic data logging program to record the values of the CPX temperature sensor, light sensor, and the value of analog pin A1 (a homemade soil sensor) periodically. 

Using a wire, you can connect the Circuit Playground Express pad A1 to a nail placed in a potted plant. The readings will be directly proportional to the moisture in the soil.

For more on soil sensing, see the following guide:

Loading the Program to the CPX

Save the file on your computer. It is the name of the project with a UF2 file extension. Plug your Circuit Playground Express into your computer with a known good data+power USB cable. The CPX will show up as a flash drive in your file explorer/finder program as a flash drive named CPLAYBOOT. (If you see a drive named CIRCUITPY, press the reset button twice).

Copy the UF2 file to the CPLAYBOOT flash drive. The drive will eject itself as a flash drive. On Windows, you will see a message saying "Installing CPlay Express (app)" and the CPlay Express (app) device will appear in Settings -> Devices. Other operating systems may give a similar message.


The program logs the data to the flash memory (displaying green LEDs) until you press the A button, at which time the CPX displays yellow LEDs. This is your indication the data logging is stopped and you can copy the data to your computer as shown below.

Viewing Your Data

When your project is logging, a new flash drive should appear named MAKECODE.

The SPIFLASH directory contains program data. Logging data is written to a file named log.csv

Be sure you have stopped logging your data prior to accessing log.csv with any program. Pressing Reset or unplugging the CPX without pausing the data logging with the A button will corrupt the log.csv file!

In the example, press the A button to stop logging which will properly close the file and allow copying the data.

Copy the log.csv file to your hard drive to save it and view it.

Opening the log.csv file on the MAKECODE flash drive directly may be problematic if logging was not turned off prior to using. Stop logging, copy log.csv to a hard drive and open it there for best results.

Open a spreadsheet program such as Google Sheets, Microsoft Excel, macOS Numbers etc. Open the log.csv file. The spreadsheet should recognize the CSV (if your program does not, you might have to specify you are trying to open a CSV file or use an import feature). In Google Sheets, the file just opens correctly.

The sep= and NAN lines may be ignored if they appear.

Line 2 has the headings for the data you read. Time first, then for the example: temp, light, and soil moisture readings in each column.

The data can go for quite a ways as the example logs data every 10 s. You can log data slower, 60 seconds (1 minute), 300 seconds (5 minutes), etc.

The data may be used to for analysis or to graph values over the time period. Using the Google Sheets graph function, push the graph button on the toolbar and without any formatting you have a great graph!

Configuration Blocks

Configuration blocks are best placed in an on start block although using the data logger block later to stop logging is recommended. 

data logger set separator allows you to choose tab, comma, or semicolon - if you have a program which will look through the log file, choosing the separator may help in a program opening the data file correctly. Using comma allows for opening in a program that understands comma separated values (CSV).

The set data logger sampling interval helps to ensure data is not sampled less than the interval you specify. If you have a pause during reading greater than the sample period, you'll assure you will not exceed the sample period.

data logger to console allows the logged data to be sent to the MakeCode console for viewing, handy for seeing what is being written to the file. NOTE: The graphing in the console only shows a value called "data" which does not appear to be any of the values - possibly a bug.

Use the data logger block to turn logging off and on. You should turn the logging on before writing to the log file with the Data blocks. NOTE: Use data logger off to close the logging file for use. If you do not, your system may hang trying to open the log file as the operating system still believes the file is in use.

If you have multiple recording sessions, new data is appended to the bottom of an existing file. To ensure you get new data only, either delete the old log.csv or rename the file. The program will create a new log.csv for the new data. Ensure logging is off before looking to modify files.

Data Blocks

The data blocks are used to write data to the log file.

The default values output is a time code based on when the board you are using was last reset.

You can add one or more data values to log. Each value should have a data logger add block where the "x" is a text tag for what the data is (which goes in the column heading) and the number is a value you want written.

Once all the data values for a particular timestamp has been written with the data logger add block(s), use the data logger add row block to complete that particular set of readings and prepares the data file for a new set of data at a new timestamp. In a spreadsheet, this would be similar to going to a new row.

The Storage extension is for writing data to a file. It is more generalized than the Datalogger extension so there is more flexibility at the expense that the coder might have to do some of the setup and outputting of the data.

Below is a simple program to demonstrate writing text to a file named log.txt. A complete line of text is joined together, including reading the soil moisture on analog pin A1, and the timer. The program loops once per minute (60 seconds, 60000 milliseconds).

When the Circuit Playground Express (CPX) is reset, one reading is taken per minute and written to the file log.txt. The program displays a rainbow animation while taking readings. When the program has taken 10 readings, collection is done and the pixels turn all green.

The append file with line block is used. If log.txt already exists, the new values will be added to the end of the file, otherwise a new file will be opened and the text output. If you want to have a clean file for each data run, rename log.txt to another name between runs.

An on start block is used here as for this example only a finite number of readings is desired. Then we want MakeCode to close the file and make it available on the MAKECODE flash drive for viewing.

Opening log.txt in a text editor shows the output from this program:

You can see the formatting of the data output line took more blocks, but it is more flexible than the Datalogger extension allows.

The Storage module also allows for reading files. This is ideal for reading a configuration file which may specify to the program how to accomplish the task at hand.

There are two forms of adding text to an existing file: append file with and append file with line. Both add the specified text to the file listed but append file with line adds a carriage return so the next write begins on a new line. Append will make a new file if the filename does not exist or add to an existing file.

If the goal is always to start fresh with a new file, no matter if the file might exist, overwrite file with will do this. Be careful as you can lose your old data with this block.

If you are looking to read a file rather than write, the read file value block will do that. This may be good for values a program needs to run like configuration data.

The file exists block checks to see if the named file already exists. A program can use this conditional to avoid writing to an existing file or check if a file exists before trying to read it.

The remove file block should be used very carefully. It checks if a file exists, and if so it deletes it.

The size of file block returns a value that is the length of a file in characters. 

This guide was first published on Aug 27, 2019. It was last updated on Aug 27, 2019.