Introduction

atlas_front

To use the Atlas class, you need to import it from atlas.py into your program. Then, it needs to be initialized and set to a variable. Put the following code at the top of your main program file to do this.

from atlas import Atlas

device = Atlas()

Now, you can use the device variable to access the various components on the Atlas device. For example, you can turn the red LED on with the following code.

device.red_led.value(1)

The rest of this book goes over using all of the different components on the Atlas device. You can find information about the specific components in the sections listed below.

LEDs

The Atlas kit has three LEDs on the right side of the device. If you soldered them on in the way that our guide specifies, then from top to bottom, they should be in the order: red, green, blue.

leds

In code using the Atlas class you can reference each of these LEDs individually or you can reference them from an array.

Red LED

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_RED_LED_PIN = 0

...

class Atlas:
    def __init__(self):

        ...

        self.red_led = Pin(_RED_LED_PIN, Pin.OUT)
        self.red_led.value(0)

...

Usage

Get or set the value of the red LED pin.

Atlas.red_led.value([x])

With no parameter the value function will return the current value of the LED pin, either a 1 (for on) or a 0 (for off). Putting a 1 or a 0 for argument x will set the state of the LED pin to on or off respectively.

Examples

from atlas import Atlas

device = Atlas()

device.red_led.value() # read the value of the LED pin
device.red_led.value(1) # turn the LED on
device.red_led.value(0) # turn the LED off

Green LED

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_GREEN_LED_PIN = 4

...

class Atlas:
    def __init__(self):

        ...

        self.green_led = Pin(_GREEN_LED_PIN, Pin.OUT)
        self.green_led.value(0)

...

Usage

Get or set the value of the green LED pin.

Atlas.green_led.value([x])

With no parameter the value function will return the current value of the LED pin, either a 1 (for on) or a 0 (for off). Putting a 1 or a 0 for argument x will set the state of the LED pin to on or off respectively.

Examples

from atlas import Atlas

device = Atlas()

device.green_led.value() # read the value of the LED pin
device.green_led.value(1) # turn the LED on
device.green_led.value(0) # turn the LED off

Blue LED

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_BLUE_LED_PIN = 5

...

class Atlas:
    def __init__(self):

        ...

        self.blue_led = Pin(_BLUE_LED_PIN, Pin.OUT)
        self.blue_led.value(0)

...

Usage

Get or set the value of the blue LED pin.

Atlas.blue_led.value([x])

With no parameter the value function will return the current value of the LED pin, either a 1 (for on) or a 0 (for off). Putting a 1 or a 0 for argument x will set the state of the LED pin to on or off respectively.

Examples

from atlas import Atlas

device = Atlas()

device.blue_led.value() # read the value of the LED pin
device.blue_led.value(1) # turn the LED on
device.blue_led.value(0) # turn the LED off

LED Array

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_RED_LED_PIN = 0
_GREEN_LED_PIN = 4
_BLUE_LED_PIN = 5

...

class Atlas:
    def __init__(self):

        ...

        self.red_led = Pin(_RED_LED_PIN, Pin.OUT)
        self.green_led = Pin(_GREEN_LED_PIN, Pin.OUT)
        self.blue_led = Pin(_BLUE_LED_PIN, Pin.OUT)
        self.leds = [self.red_led, self.green_led, self.blue_led]

...

Usage

Access the red, green, and blue LEDs indexed at 0, 1, and 2 respectively.

Atlas.leds[i]

i must be an integer value of 0, 1, or 2 to access the items in the array.

Examples

from atlas import Atlas

device = Atlas()

for led in device.leds: # turn on all of the leds
    led.value(1)

for led in device.leds: # turn off all of the leds
    led.value(0)

Buttons

The Atlas kit has three buttons on the bottom left side of the device. These buttons are labeled from left to right: "Mode", "Incr", and "Decr".

buttons

The Atlas class has references to all three of these buttons. The Atlas class also has default callbacks that are already attached to the buttons.

Mode Button

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_MODE_BUTTON_PIN = 12

...

class Atlas:
    def __init__(self):

        ...

        self.mode_button = Pin(_MODE_BUTTON_PIN, Pin.IN, Pin.PULL_UP)
        self.mode_button.irq(trigger=Pin.IRQ_FALLING, handler=self.mode_button_callback)

    ...

    def mode_button_callback(self, pin):
        if self._debounce(self.mode_button):
            for led in self.leds:
                self.toggle_pin(led)

...

Usage

Check the value of the mode button pin.

Atlas.mode_button.value()

The value function will return the current value of the mode button pin, either a 1 (for on) or a 0 (for off).

Callback

The atlas.py file has a predefined callback as part of the Atlas class. For the mode button it is called mode_button_callback. As defined in the source code this callback toggles all of the LEDs on the device. Feel free to change this to whatever you want! I only recommend keeping your code within the if statement that is checking the _debounce function.

def mode_button_callback(self, pin):
    if self._debounce(self.mode_button):
        # your code here

Examples

from atlas import Atlas

device = Atlas()

device.mode_button.value() # read the value of the button pin

Incr Button

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_INCR_BUTTON_PIN = 10

...

class Atlas:
    def __init__(self):

        ...

        self.incr_button = Pin(_INCR_BUTTON_PIN, Pin.IN, Pin.PULL_UP)
        self.incr_button.irq(trigger=Pin.IRQ_FALLING, handler=self.incr_button_callback)

    ...

    def incr_button_callback(self, pin):
        if self._debounce(self.incr_button):
            self.increment_num()

...

Usage

Check the value of the incr button pin.

Atlas.incr_button.value()

The value function will return the current value of the incr button pin, either a 1 (for on) or a 0 (for off).

Callback

The atlas.py file has a predefined callback as part of the Atlas class. For the mode button it is called incr_button_callback. As defined in the source code this callback increments the current number on the displays. Feel free to change this to whatever you want! I only recommend keeping your code within the if statement that is checking the _debounce function.

def incr_button_callback(self, pin):
    if self._debounce(self.incr_button):
        # your code here

Examples

from atlas import Atlas

device = Atlas()

device.incr_button.value() # read the value of the button pin

Decr Button

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_DECR_BUTTON_PIN = 2

...

class Atlas:
    def __init__(self):

        ...

        self.decr_button = Pin(_DECR_BUTTON_PIN, Pin.IN, Pin.PULL_UP)
        self.decr_button.irq(trigger=Pin.IRQ_FALLING, handler=self.incr_button_callback)

    ...

    def decr_button_callback(self, pin):
        if self._debounce(self.incr_button):
            self.decrement_num()

...

Usage

Check the value of the decr button pin.

Atlas.decr_button.value()

The value function will return the current value of the decr button pin, either a 1 (for on) or a 0 (for off).

Callback

The atlas.py file has a predefined callback as part of the Atlas class. For the mode button it is called decr_button_callback. As defined in the source code this callback decrements the current number on the displays. Feel free to change this to whatever you want! I only recommend keeping your code within the if statement that is checking the _debounce function.

def decr_button_callback(self, pin):
    if self._debounce(self.incr_button):
        # your code here

Examples

from atlas import Atlas

device = Atlas()

device.decr_button.value() # read the value of the button pin

Buzzer

The Atlas kit has one buzzer on the bottom right side of the device.

buzzer

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_BUZZER = 0

...

class Atlas:
    def __init__(self):

        ...

        self.buzzer = Pin(_BUZZER, Pin.OUT)
        self.buzzer.value(1)
        self.note_timer = Timer(2)
        self.note_timer.deinit()

    ...

    def buzzer_callback(self, pin):
        self.toggle_pin(self.buzzer)

    def play_note(self, freq):
        self.note_timer.init(freq=freq, mode=Timer.PERIODIC, callback=self.buzzer_callback)
    
    def stop_note(self):
        self.note_timer.deinit()
        self.buzzer.value(1)

...

sounds.py

NOTES = {
    'C3': 130.8,
    'CS3': 138.6,
    'DF3': 138.6,
    'D3': 146.8,
    'DS3': 155.6,
    'EF3': 155.6,
    'E3': 164.8,
    'F3': 174.6,
    'FS3': 185.0,
    'GF3': 185.0,
    'G3': 196.0,
    'GS3': 207.7,
    'AF3': 207.7,
    'A3': 220.0,
    'AS3': 233.1,
    'BF3': 233.1,
    'B3': 246.9,

    'C4': 261.6,
    'CS4': 277.2,
    'DF4': 277.2,
    'D4': 293.7,
    'DS4': 311.1,
    'EF4': 311.1,
    'E4': 329.6,
    'F4': 349.2,
    'FS4': 370.0,
    'GF4': 370.0,
    'G4': 392.0,
    'GS4': 415.3,
    'AF4': 415.3,
    'A4': 440.0,
    'AS4': 466.2,
    'BF4': 466.2,
    'B4': 493.9,

    'C5': 523.3,
    'CS5': 554.4,
    'DF5': 554.4,
    'D5': 587.3,
    'DS5': 622.3,
    'EF5': 622.3,
    'E5': 659.3,
    'F5': 698.5,
    'FS5': 740.0,
    'GF5': 740.0,
    'G5': 784.0,
    'GS5': 830.6,
    'AF5': 830.6,
    'A5': 880.0,
    'AS5': 932.3,
    'BF5': 932.3,
    'B5': 987.8,
}

Usage

Pulse the buzzer at a specified frequency.

Atlas.play_note(f)

f is a float value of the frequency you with to pulse the buzzer at.

Turn off the buzzer.

Atlas.stop_note()

Examples

from atlas import Atlas
from time import sleep_ms

device = Atlas()

# play a note by specifying a frequency
device.play_note(440.0)
sleep_ms(5000)
device.stop_note()
from atlas import Atlas
from sounds import NOTES
from time import sleep_ms

device = Atlas()

# specify a frequency using the the "NOTES" dictionary from sounds.py
device.play_note(NOTES["A4"])
sleep_ms(5000)
device.stop_note()

Displays

The Atlas kit has two 3-digit 7-segment displays.

displays

They are driven by a MAX7219 LED display driver which is located at in the center of the device at the bottom.

max7219

atlas.py

from machine import Pin, SPI, Timer, RTC
import network
import time

...

_NOOP = 0x0
_DIGIT0 = 0x1
_DIGIT1 = 0x2
_DIGIT2 = 0x3
_DIGIT3 = 0x4
_DIGIT4 = 0x5
_DIGIT5 = 0x6
_DECODE_MODE = 0x9

_DIGIT_DICT = {
    0: _DIGIT0,
    1: _DIGIT1,
    2: _DIGIT2,
    3: _DIGIT3,
    4: _DIGIT4,
    5: _DIGIT5,
}

_DP = 0x80

...

_SPI_CS_PIN = 15

...

_MAX_VALUE_DEC = 999999
_MIN_VALUE_DEC = -99999

...

_MAX_VALUE_DP = 0b111111
_MIN_VALUE_DP = 0b000000

...

_DECODE_MODE = 9
_INTENSITY = 10
_SCAN_LIMIT = 11
_SHUTDOWN = 12
_DISPLAY_TEST = 15

...

class Atlas:
    def __init__(self):

        ...

        self._spi = SPI(1, baudrate=10000000, polarity=1, phase=0)
        self._cs = Pin(_SPI_CS_PIN)
        self._cs.init(self._cs.OUT, True)

        ...

        self._register(_SHUTDOWN, 0)
        self._register(_DISPLAY_TEST, 0)
        self._register(_SCAN_LIMIT, 7)
        self._register(_DECODE_MODE, 0)
        self._register(_SHUTDOWN, 1)
        self.display_clear()
        self.display_brightness(5)
        
    ...

    def display_brightness(self, value):
        if 0 <= value <= 15:
            self._register(_INTENSITY, value)
        else:
            raise ValueError("Brightness out of range")

    def display_clear(self):
        self._register(_DECODE_MODE, 0xFF)
        for i in range(6):
            self._register(_DIGIT_DICT[i], 0x0F)

        self.current_num = None

    def write_num(self, value, dp=0b000000):
        self._register(_DECODE_MODE, 0xFF)

        if (0 <= value <= _MAX_VALUE_DEC) and (_MIN_VALUE_DP <= dp <= _MAX_VALUE_DP):
            self.current_num = value
            self.current_dp = dp

            for i in range(6):
                current_value = value % 10

                if dp & 1:
                    self._register(_DIGIT_DICT[i], current_value | _DP)
                else:
                    self._register(_DIGIT_DICT[i], current_value)

                dp = dp >> 1
                value = value // 10

        elif (0 > value >= _MIN_VALUE_DEC) and (_MIN_VALUE_DP <= dp <= _MAX_VALUE_DP):
            self.current_num = value
            self.current_dp = dp

            value = -value
            self._register(_DIGIT5, 0xA)

            for i in range(5):
                current_value = value % 10

                if dp & 1:
                    self._register(_DIGIT_DICT[i], current_value | _DP)
                else:
                    self._register(_DIGIT_DICT[i], current_value)

                dp = dp >> 1
                value = value // 10

        else:
            raise ValueError("Value out of range")

    ...

    def increment_num(self):
        if self.current_num is None:
            raise ValueError("No value to increment")
        else:
            if (self.current_num + 1) > _MAX_VALUE_DEC:
                self.current_num = -1

            self.write_num(self.current_num + 1, self.current_dp)

    def decrement_num(self):
        if self.current_num is None:
            raise ValueError("No value to decrement")
        else:
            if (self.current_num - 1) < _MIN_VALUE_DEC:
                self.current_num = 1

            self.write_num(self.current_num - 1, self.current_dp)

    ...

    def _register(self, command, data):
        self._cs.value(0)
        self._spi.write(bytearray([command, data]))
        self._cs.value(1)

...

Display Settings

Usage

Clear all of the displays.

Atlas.display_clear()

Change the brightness of the displays.

Atlas.display_brightness(x)

x is a value between 0 and 15 inclusive. 0 is the least bright setting and 15 is the brightest.

Examples

from atlas import Atlas

device = Atlas()

device.write_num(1)
device.display_brightness(15) # set the display the brightest setting 
device.display_clear() # turn off all of the LEDs on the displays

Displaying Numbers

Usage

Write a number to the display.

Atlas.write_num(v, dp=[d])

v is a integer value to write to the display. This number can range from -99999 to 999999. d is an optional integer argument that indicates the location of decimal points. Decimal points are placed based on the binary representation of the integer argument. For example 0b100000 would put a decimal point in the first position. 0b111111 would put a decimal point in every position.

Atlas.increment_num()

Increase the current number on the display by 1.

Atlas.increment_num()

Decrease the current number on the display by 1.

Atlas.decrement_num()

Examples

from atlas import Atlas

device = Atlas()

device.write_num(123456) # write 123456 to the display
device.increment_num() # increment the number to 123457
device.decrement_num() # decrement the number to 123456