CircuitPython Code

GEMMA M0 boards can run CircuitPython — a different approach to programming compared to Arduino sketches. In fact, CircuitPython comes factory pre-loaded on GEMMA M0. If you’ve overwritten it with an Arduino sketch, or just want to learn the basics of setting up and using CircuitPython, this is explained in the Adafruit GEMMA M0 guide.

These directions are specific to the Gemma M0 board. The original GEMMAs with an 8-bit AVR microcontroller (v1 and v2) doesn’t run CircuitPython…for those boards, use the Arduino sketch on the “Arduino code” page of this guide.

Below is CircuitPython code that works similarly (though not the same) as the Arduino sketch shown on a prior page. To use this, plug the GEMMA M0 into USB…it should show up on your computer as a small flash drive…then edit the file “main.py” with your text editor of choice. Select and copy the code below and paste it into that file, entirely replacing its contents (don’t mix it in with lingering bits of old code). When you save the file, the code should start running almost immediately (if not, see notes at the bottom of this page).

If GEMMA M0 doesn’t show up as a drive, follow the GEMMA M0 guide link above to prepare the board for CircuitPython.

This code requires two additional libraries be installed:

  1. adafruit_mlx90614
  2. adafruit_bus_device
  3. neopixel

If you’ve just reloaded the board with CircuitPython, create the “lib” directory and then download the Adafruit CircuitPython Bundle.

#  Designed specifically to work with the MLX90614 sensors in the
#  adafruit shop
#  ----> https://www.adafruit.com/product/1747
#  ----> https://www.adafruit.com/product/1748
#
#  These sensors use I2C to communicate, 2 pins are required to
#  interface Adafruit invests time and resources providing this open
#  source code,
#  please support Adafruit and open-source hardware by purchasing
#  products from Adafruit!

import time
import board
import busio as io
import neopixel
import adafruit_mlx90614

# the mlx90614 must be run at 100k [normal speed]
# i2c default mode is is 400k [full speed]
# the mlx90614 will not appear at the default 400k speed
i2c = io.I2C(board.SCL, board.SDA, frequency=100000)
mlx = adafruit_mlx90614.MLX90614(i2c)

# neopixel setup
num_leds = 24           # how many LEDs
led_pin = board.D1      # which pin the neopixel ring is connected to
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1)

# change these to adjust the range of temperatures you want to measure
# (these are in Farenheit)
cold_temp = 60
hot_temp = 80

def remapRange(value, leftMin, leftMax, rightMin, rightMax):
    # this remaps a value from original (left) range to new (right) range
    # Figure out how 'wide' each range is
    leftSpan = leftMax - leftMin
    rightSpan = rightMax - rightMin

    # Convert the left range into a 0-1 range (int)
    valueScaled = int(value - leftMin) / int(leftSpan)

    # Convert the 0-1 range into a value in the right range.
    return int(rightMin + (valueScaled * rightSpan))

# Fill the dots one after the other with a color
def colorWipe(color):
    for j in range(len(strip)):
        strip[j] = (color)

while True:
    # get object temperature in celsius
    temp = mlx.object_temperature

    # convert object temperature to fahrenheit
    temp = (temp * 9/5) + 32

    if temp < cold_temp:
        temp = cold_temp

    if temp > hot_temp:
        temp = hot_temp

    # map temperature to red/blue color
    # hotter temp -> more red
    red = remapRange(temp, cold_temp, hot_temp, 0, 255)
    # hotter temp -> less blue
    blue = remapRange(temp, cold_temp, hot_temp, 255, 0)

    colorWipe((red, 0, blue))

    # can adjust this for faster/slower updates
    time.sleep(.05)
This guide was first published on Apr 10, 2014. It was last updated on Apr 10, 2014. This page (CircuitPython Code) was last updated on Feb 11, 2020.