# CPU Temperature Logging with CircuitPython

## Introduction

![](https://cdn-learn.adafruit.com/assets/assets/000/046/741/medium800/temperature_gemmetemp.jpg?1506533560 Temperature icon by MarkieAnn Parker @ Noun Project)

[CircuitPython](https://github.com/adafruit/circuitpython) (a derivative of&nbsp;[MicroPython](https://micropython.org/)) is designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads.

Version 2.0.0 introduced a lot of features, among which were the `storage` module (allows CircuitPython to save data to the internal filesystem) and `microcontroller.cpu.temperature` object. So, let's put the two together and create a very tiny temperature logger!

Warning: 

2.0.0 was released September 12, 2017, so if you bought your board before or around that time there’s a good chance it needs updating. Download the update and follow the instructions on the [2.0.0 release page](https://github.com/adafruit/circuitpython/releases/tag/2.0.0).

We'll be using an [Adafruit Gemma M0](https://www.adafruit.com/product/3501) for this guide but _any_ CircuitPython-capable device that uses the SAMD21 can run this code. If you are not using SAMD21 you will be missing the cpu temperature capability so just wire up an external temp sensor

# CPU Temperature Logging with CircuitPython

## Getting the temperature

One of the new packages included in 2.0.0 is `microcontroller.cpu.temperature`: this gives you the temperature (in Celsius) of the board’s CPU. It isn’t an accurate room temperature sensor like the&nbsp;[TMP36](https://www.adafruit.com/product/165) or [DHT22](https://www.adafruit.com/product/385), since it’s the temperature of the CPU, not the ambient air, but it’s&nbsp;still a data point and it is very accurate!

Getting the temperature is as simple as can be. In the [REPL](../../../../adafruit-gemma-m0/serial-console-repl):

```auto
Adafruit CircuitPython 2.0.0 on 2017-09-12; Adafruit Gemma M0 with samd21e18
&gt;&gt;&gt; import microcontroller
&gt;&gt;&gt; microcontroller.cpu.temperature
29.6556
```

If you’d like it in Fahrenheit, you can create a function for that.

```auto
&gt;&gt;&gt; def fahrenheit(celsius):
...     return (celsius * 9 / 5) + 32
...
&gt;&gt;&gt; fahrenheit(microcontroller.cpu.temperature)
90.1077
```

Once you've got all that working, we can go on to the next step, storage!

# CPU Temperature Logging with CircuitPython

## Writing to the filesystem

Getting the temperature in the REPL is all well and good, but requires you to type the command every time.

Thankfully, CircuitPython 2.0.0 also introduced the `storage` module, which lets you access the internal storage of the board. There isn’t a lot of it, but for storing a few readings it should be plenty. By default you can write to the system via USB (ie saving **code.py** ) and not in code, so first you’ll need to change that.

### Setting readonly to False on boot

You can only use this in **boot.py** , which is executed before the USB connection is made. If **boot.py** doesn’t exist, create it with this:

Danger: 

```auto
import storage

storage.remount("/", False)
```

On every boot the root filesystem will be mounted so that CircuitPython can write to it.

Warning: 

You can now write to the internal storage via the REPL:

```auto
&gt;&gt;&gt; with open("/tmp.txt", "a") as fp:
...     fp.write("hello, world!")
...
```

You might need to reboot the board before you see the file, but it will be there in the file explorer.

Only one thing can have write access at a time, though, so by allowing your Python code to write to the device **you’ve disabled USB write access**. This means updating **code.py** will no longer work! Even worse, you can’t edit **boot.py** either, so at first you might think you’re stuck like this forever.

![](https://cdn-learn.adafruit.com/assets/assets/000/046/747/medium800/temperature_readonly.png?1506536754)

Luckily, you can edit and remove/rename files via the REPL:

```auto
&gt;&gt;&gt; import os
&gt;&gt;&gt; os.listdir("/")
&gt;&gt;&gt; os.rename("/boot.py", "/boot.bak")
```

Then reboot the device and you’ll be able to edit via USB as normal.

## Selectively setting readonly to False on boot

Recreate **boot.py** :

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Gemma/Introducing_Gemma_M0/Gemma_Logger_boot/code.py

This will read the value of the D0 pin, which has been set to a pullup: it reads `True` (`HIGH`, `1`, etc in Arduino) if it has not been grounded, but if connected to ground it reads `False`. Since we want it to be readonly False when the board should be written by the code and not USB, you only need to connect the D0 pin to ground when you want the board to be able to write via the code.

Warning: 

The Circuit Playground makes this easy: the **D7** pin is the toggle switch.

On other boards, like the Gemma M0, you’ll need to use wires or alligator clips like so:

![](https://cdn-learn.adafruit.com/assets/assets/000/046/743/medium800/temperature_IMG_4816.jpg?1506535556)

# CPU Temperature Logging with CircuitPython

## Logging the temperature

Let’s put it all together: make this your **code.py** :

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Gemma/Introducing_Gemma_M0/Gemma_Logger/code.py

This code creates a `led` variable, sets it to the D13 pin and configures it for output (this is the built-in LED pin). Then it opens the **temperature.txt** file for appending (so future reboots add to the end of the file instead of overwriting it), gets the temperature and writes it to the file with a line break after each reading (on Windows, some editors like Notepad won’t recognize the line ending). The LED blinks on and off in a two second loop: each change indicates a value has been written to the file.

There could be an error opening the file for writing, or for writing the file: maybe your board doesn’t have D0 pulled low to enable writing. Maybe your internal storage is out of space. The `except` block handles an `OSError` exception. If the error code is 28 that means the device is out of space. The LED will blink four times a second to indicate this. Otherwise the “issue” is probably that the board set to read-only (which is probably by design!) and will blink twice a second.

![](https://cdn-learn.adafruit.com/assets/assets/000/046/749/medium800/temperature_temp.png?1506537060)

# CPU Temperature Logging with CircuitPython

## Keep going

You now have code that will change the read/write status of the drive depending on a pin state, log the temperature once a second a provide three different status indicators. But there could be more to do, if you’d like.

Maybe you want to add better error reporting (the OSError error code for a read only device is 30). Or log differently, or log to a different file. This was only a starting point, so make it your own!

## Acknowledgements

The code from this guide is based on code from [@jerryneedell](https://github.com/jerryneedell/) and [@edgecollective](https://github.com/edgecollective/circuitpython-flash-logger).


## Featured Products

### Adafruit GEMMA M0 - Miniature wearable electronic platform

[Adafruit GEMMA M0 - Miniature wearable electronic platform](https://www.adafruit.com/product/3501)
The **Adafruit Gemma M0** is a super small microcontroller board, with just enough built-in to create many simple projects. It may look small and cute: round, about the size of a quarter, with friendly alligator-clip sew pads. But do not be fooled! The Gemma M0 is incredibly...

In Stock
[Buy Now](https://www.adafruit.com/product/3501)
[Related Guides to the Product](https://learn.adafruit.com/products/3501/guides)
### Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE

[Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE](https://www.adafruit.com/product/3500)
The&nbsp;Adafruit Trinket M0 may be small, but do not be fooled by its size! It's a tiny microcontroller board, built around the Atmel ATSAMD21, a little chip with _a lot_ of power. We wanted to design a microcontroller board that was small enough to fit into any project, and low...

In Stock
[Buy Now](https://www.adafruit.com/product/3500)
[Related Guides to the Product](https://learn.adafruit.com/products/3500/guides)
### Adafruit Feather M0 Express

[Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
At the Feather M0's heart is an ATSAMD21G18 ARM Cortex M0+ processor, clocked at 48 MHz and at 3.3V logic, the same one used in the new&nbsp;[Arduino Zero](https://www.adafruit.com/products/2843). This chip has a whopping 256K of FLASH (8x more than the Atmega328 or 32u4) and...

In Stock
[Buy Now](https://www.adafruit.com/product/3403)
[Related Guides to the Product](https://learn.adafruit.com/products/3403/guides)
### Adafruit METRO M0 Express - designed for CircuitPython

[Adafruit METRO M0 Express - designed for CircuitPython](https://www.adafruit.com/product/3505)
Metro is our series of microcontroller boards for use with the Arduino IDE. This new **Metro M0 Express** board looks a whole lot like our&nbsp;[original Metro 328](https://www.adafruit.com/product/2488), but with a huge upgrade. Instead of the ATmega328, this Metro...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3505)
[Related Guides to the Product](https://learn.adafruit.com/products/3505/guides)
### Circuit Playground Express

[Circuit Playground Express](https://www.adafruit.com/product/3333)
 **Circuit Playground Express** is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and made it even better! Not only did we pack even more sensors in, we also made it even easier to...

In Stock
[Buy Now](https://www.adafruit.com/product/3333)
[Related Guides to the Product](https://learn.adafruit.com/products/3333/guides)

## Related Guides

- [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython.md)
- [Adafruit Metro M0 Express](https://learn.adafruit.com/adafruit-metro-m0-express.md)
- [Adafruit Trinket M0](https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino.md)
- [Adafruit Circuit Playground Express](https://learn.adafruit.com/adafruit-circuit-playground-express.md)
- [Sipping Power With NeoPixels](https://learn.adafruit.com/sipping-power-with-neopixels.md)
- [Magical Cardboard Craft Obsidian Sword](https://learn.adafruit.com/cardboard-obsidian-sword.md)
- [Introducing Adafruit Feather](https://learn.adafruit.com/adafruit-feather.md)
- [MakeCode Maker](https://learn.adafruit.com/makecode-maker.md)
- [Light-Activated Pixel Heart](https://learn.adafruit.com/light-activated-pixel-heart.md)
- [Deco Two-Key Feather Macro Pad](https://learn.adafruit.com/deco-two-key-keypad-macropad-circuitpython-feather.md)
- [CircuitPython Basics: Analog Inputs & Outputs](https://learn.adafruit.com/circuitpython-basics-analog-inputs-and-outputs.md)
- [Screaming Cauldron](https://learn.adafruit.com/screaming-cauldron.md)
- [Installing CircuitPython on SAMD21 Boards](https://learn.adafruit.com/installing-circuitpython-on-samd21-boards.md)
- [Creating and sharing a CircuitPython library](https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library.md)
- [Circuit Playground Digital Input](https://learn.adafruit.com/circuit-playground-digital-input.md)
- [Motorized Grinch Fireplace](https://learn.adafruit.com/grinch-fireplace.md)
- [Textile Potentiometer Hoodie](https://learn.adafruit.com/textile-potentiometer-hoodie.md)
- [FruitBox Sequencer: Musically Delicious Step Pattern Generator ](https://learn.adafruit.com/circuitpython-fruitbox-sequencer-musically-delicious-step-pattern-generator.md)
- [LED Reactive Light-Up Hockey Puck in MakeCode](https://learn.adafruit.com/led-hockey-puck.md)
