Difference between revisions of "Tinkering workshop"

From Interaction Station Wiki
Jump to navigation Jump to search
 
(54 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Yoana:
 
  
introduction on Adafruit Circuit Playground Express
 
  
install CircuitPython
+
=='''Introduction on Adafruit Circuit Playground Express'''==
  
install mu editor
+
===Install CircuitPython===
  
Interacting to the Serial Console
+
===Install mu editor===
  
The REPL
+
[[file:Circuitpython_circuit_playground_adafruit_blinka_computer.png|450px]] [[file:17850097.png|200px]]
  
short cuts:
+
Python is the fastest-growing programming language. And CircuitPython is based on Python language but designed to run on microcontroller boards.
  
Indentation and commenting options
+
CircuitPython is designed with education in mind.
  
Python programs are Space holder Character Sensitive.
+
It's easy to start learning how to program and you get immediate feedback from the board.  
  
To indent the three lines, I selected them all and then pressed the Tab key.
 
  
To unindent, select some lines and press Shift-Tab. For commenting: select lines and press command(control)-k
 
  
http://interactionstation.wdka.hro.nl/wiki/Cpx-basic
+
Before we start we all have to do this to set up:
  
 +
==='''1. Install or update CircuitPython!'''===
  
Nan==
+
https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart
install library..
 
  
examples:
+
*1. Click the link below and download the latest UF2 file:
 +
https://circuitpython.org/board/circuitplayground_express/
  
library CircuitPython Made Easy
+
*2. Plug your Circuit Playground Express into your computer via a (data)USB cable.<br>
  
1. Smiley face with NeoPixels
+
*3. Double-click the small Reset button in the middle of the CPX(short for circuit playground express).
 +
  you will see all of the LEDs turn green. If they turn all red, check the USB cable, try another USB port, etc.
 +
  (If double-clicking doesn't do it, try a single-click!)
  
 +
*4. You will see a new disk drive appear called '''CPLAYBOOT'''
 +
  Drag the '''adafruit-circuitpython-etc...uf2''' file onto it.
  
2. Capacitive Touch & NeoPixels
+
*5. The '''CPLAYBOOT''' drive will disappear and a new disk drive will appear called '''CIRCUITPY'''
 +
'''That's it! You're done :)'''
  
3. Play audio file
+
==='''2. Installing Mu Edito'''r===
  
4. Drum machine
+
Download Mu from(if you are using computers from school, the Mu Editor is already installed)
  
5. final infrared tagging games(maybe)
+
https://codewith.mu
  
 +
[[File:Circuitpython mu-front-page.png|400px]]
  
  
 +
The first time you start Mu, you will be prompted to select your 'mode' -
  
=timing / schedule=
+
you can always change your mind later. For now please select '''CircuitPython!'''
  
''start 13:00'' ''end 17:00''
 
  
 +
[[File:Circuitpython Screen Shot 2017-12-24 at 2.55.02 PM.png|400px]]
  
13:00 - 14:00 Yoana introduction part
 
  
14:00 - 14:15 - break
+
Mu attempts to auto-detect your board, so please plug in your CircuitPython device and make sure it shows up as a CIRCUITPY drive before starting Mu
  
14:15 - 16:00 Nan's part
+
[[File:Circuitpython Screen Shot 2017-12-24 at 3.16.23 PM.png]]
  
16:00 - 16:15 break
 
  
16:15 - 17:00 Play
 
  
===3'''. Hello, World!'''===
+
'''SAVE AS:'''
In the code area, where it says, # Write your code here :-), write the following code:
 
  
'''print( 8 )'''
+
if you want to save the code.py file in different names as well as in different locations:
  
Then click the Save button to save the code and run it on the CircuitPlayground.
+
double click on the file name in Mu editor.  
  
You should see this message appear in the Serial Dialogue Panel:
+
[[File:Save-as-Capture.PNG|500px]]
  
'''code.py output:
+
'''Indentation and commenting options'''
8'''
 
  
Change the message to something else. If you want to print characters instead of numbers, you must use quotation marks.
+
Python programs are Space holder Character Sensitive.
 +
 
 +
To indent the three lines, I selected them all and then pressed the '''Tab key'''.  
 +
 
 +
To unindent, select some lines and press '''Shift-Tab.'''
 +
For commenting: select lines and press '''command(control)-k'''
 +
 
 +
[[File:Mu CircuitPython Mode Cheat Sheet 1.jpg |600px]]
  
'''print( "hello" )'''
+
==='''3. Hello World (Blink in Circuitpython)'''===
  
Let's program the device to print two things, with a time delay in between the two print statements:
+
<syntaxhighlight lang="python" line='line'>
 +
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
 +
# SPDX-License-Identifier: MIT
  
'''import time'''
+
"""This is the "Hello, world!" of CircuitPython: Blinky! This example blinks the little red LED on
 +
and off!"""
  
'''print( "hello" )'''
+
import time
 +
from adafruit_circuitplayground import cp
  
'''time.sleep( 0.5 )'''
+
while True:
 +
    cp.red_led = True
 +
    time.sleep(0.5)
 +
    cp.red_led = False
 +
    time.sleep(0.5)
  
'''print( "Nan" )'''
+
</syntaxhighlight>
  
Now let's make a loop, so the message will be running forever:
+
==='''4. Interacting to the Serial Console''' ===
  
'''import time
 
 
'''while True:'''
 
 
  '''print( "hello" )'''
 
  '''time.sleep( 0.5 )'''
 
  '''print( "Nan" )'''
 
  
 +
==== '''The REPL'''====
  
 +
The other feature of the serial connection is the '''Read-Evaluate-Print-Loop''', or REPL.
  
 +
The REPL allows you to enter individual lines of code and have them run immediately.
  
'''Indentation and commenting options'''
+
It's really handy if you're running into trouble with a particular program and can't figure out why.
  
Python programs are Space holder Character Sensitive.  
+
It's interactive so it's great for testing new ideas.
  
To indent the three lines, I selected them all and then pressed the '''Tab key'''.  
+
To use the REPL, you first need to be connected to the serial console.  
  
To unindent, select some lines and press '''Shift-Tab.'''
+
Once that connection has been established, you'll want to press '''Ctrl + C'''.
For commenting: select lines and press '''command(control)-k'''
 
  
[[File:Mu CircuitPython Mode Cheat Sheet 1.jpg |600px]]
+
If there is code running, it will stop and you'll see Press any key to enter the REPL. Use '''CTRL-D to reload'''.  
  
 +
Follow those instructions, and press any key on your keyboard.
  
 +
https://learn.adafruit.com/adafruit-circuit-playground-express/the-repl
  
==='''6. CircuitPython Made Easy'''===
+
==''' CircuitPython Made Easy'''==
  
 
====Libraries:====
 
====Libraries:====
Line 132: Line 143:
 
https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express
 
https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express
  
=code examples=
+
 
==Neopixel smiley face ==
+
=='''Interaction with touch sensor and neopixel'''==
<syntaxhighlight lang="python" line='line'>
+
 
 +
 
 +
During this workshop, we will learn how to design and create an interactive game that enhances communication,
 +
 
 +
expression, and collaboration in the current 1.5 social distance reality.
 +
 
 +
we will focus on sending “touch signal” to each other without physical contact,
 +
 
 +
but in the forms of lights, color and sound.
 +
 
 +
 
 +
===1.Neopixel smiley face ===
 +
 
 +
'''A Smiley Face'''😊
 +
 
 +
<syntaxhighlight lang="python">
 +
 
 
from adafruit_circuitplayground import cp
 
from adafruit_circuitplayground import cp
  
Line 142: Line 169:
 
while True:
 
while True:
 
     # The smiley's eyes
 
     # The smiley's eyes
     cp.pixels[0] = (255, 0, 0)
+
     cp.pixels[1] = (255, 0, 0)
     cp.pixels[9] = (255, 0, 0)
+
     cp.pixels[3] = (255, 0, 0)
  
 
     # The smiley's mouth
 
     # The smiley's mouth
    cp.pixels[3] = (255, 0, 255)
 
    cp.pixels[4] = (255, 0, 255)
 
 
     cp.pixels[5] = (255, 0, 255)
 
     cp.pixels[5] = (255, 0, 255)
 
     cp.pixels[6] = (255, 0, 255)
 
     cp.pixels[6] = (255, 0, 255)
 +
    cp.pixels[7] = (255, 0, 255)
 +
    cp.pixels[8] = (255, 0, 255)
 +
    cp.pixels[9] = (255, 0, 255)
 +
  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==touch sense==
+
'''Let's blink a smiley face by using time.sleep'''
 +
 
 +
<syntaxhighlight lang="python" line='line'>
 +
 
 +
from adafruit_circuitplayground import cp
 +
 +
# The NeoPixels are super-bright. Change the global brightness.
 +
cp.pixels.brightness = 0.3
 +
 
 +
import time 
 +
 
 +
while True:
 +
    time.sleep(1)
 +
    # The smiley's eyes
 +
    cp.pixels[1] = (255, 0, 0)
 +
    cp.pixels[3] = (255, 0, 0)
 +
 +
    # The smiley's mouth
 +
    cp.pixels[5] = (255, 0, 255)
 +
    cp.pixels[6] = (255, 0, 255)
 +
    cp.pixels[7] = (255, 0, 255)
 +
    cp.pixels[8] = (255, 0, 255)
 +
    cp.pixels[9] = (255, 0, 255)
 +
    time.sleep(1)
 +
 
 +
    # The smiley's eyes
 +
    cp.pixels[1] = (0, 0, 0)
 +
    cp.pixels[3] = (0, 0, 0)
 +
 +
    # The smiley's mouth
 +
    cp.pixels[5] = (0, 0, 0)
 +
    cp.pixels[6] = (0, 0, 0)
 +
    cp.pixels[7] = (0, 0, 0)
 +
    cp.pixels[8] = (0, 0, 0)
 +
    cp.pixels[9] = (0, 0, 0)
  
 +
</syntaxhighlight>
  
==Drum Machine==
+
<br>
  
https://learn.adafruit.com/adafruit-circuit-playground-express/playground-drum-machine
+
hmm... now the code seems to be too long
  
 +
'''let's Shorten the code by implementing variables, "for" loops '''
  
 
<syntaxhighlight lang="python" line='line'>
 
<syntaxhighlight lang="python" line='line'>
#light meter
 
  
 
import time
 
import time
 
from adafruit_circuitplayground import cp
 
from adafruit_circuitplayground import cp
cp.pixels.auto_write = False
+
#neoPixel pins for the smiley face
cp.pixels.brightness = 0.3
+
pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
+
# The NeoPixels are super-bright. Change the global brightness.
+
cp.pixels.brightness = 0.1
def scale_range(value):
+
light_colour=(105,0,105)
#"""Scale a value from 0-320 (light range) to 0-9 (NeoPixel range).
+
OFF=(0,0,0)
#    Allows remapping light value to pixel position."""
+
 
     return round(value / 280 * 9)
+
while True:
 +
    for i in range (7):
 +
        cp.pixels[pixels_pin[i]]=light_colour     
 +
    time.sleep(1)
 +
    for i in range (7):
 +
        cp.pixels[pixels_pin[i]]=OFF   
 +
     time.sleep(1)
 
      
 
      
while True:
 
    peak = scale_range(cp.light)
 
    print(cp.light)
 
    print(int(peak))
 
 
    for i in range(10):
 
        if i <= peak:
 
            cp.pixels[i] = (0, 255, 255)
 
        else:
 
            cp.pixels[i] = (0, 0, 0)
 
    cp.pixels.show()
 
    time.sleep(0.2)
 
  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
 +
much better!!! now if you add a time.sleep(0.5) in the for loop you will see a fading animation of the smiley face.
 +
 +
===2.Touch sense as trigger===
 +
 +
there are in total 7 touch pins on CPX.
 +
let's try to use the touch sensor to trigger the smiley face.
 +
 +
 +
'''if we touch pin A4, The smiley face will appear if not the smiley face will disappear.'''
  
  
 
<syntaxhighlight lang="python" line='line'>
 
<syntaxhighlight lang="python" line='line'>
 +
import time
 +
from adafruit_circuitplayground import cp
 +
#neoPixel pins for the smiley face
 +
pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 +
# The NeoPixels are super-bright. Change the global brightness.
 +
cp.pixels.brightness = 0.1
 +
light_colour=(105,0,105)
 +
OFF=(0,0,0)
  
 
+
while True:
 +
    if cp.touch_A4:
 +
        for i in range (7):
 +
            cp.pixels[pixels_pin[i]]=light_colour 
 +
            time.sleep(.1)
 +
            print("A4-touched!")
 +
    else:
 +
        for i in range (7):
 +
            cp.pixels[pixels_pin[i]]=OFF   
 +
            time.sleep(.1)
 +
   
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
===3.Touch piano keyboard===
  
===touch sense===
 
 
<syntaxhighlight lang="python" line='line'>
 
<syntaxhighlight lang="python" line='line'>
 
+
import time
 
from adafruit_circuitplayground import cp
 
from adafruit_circuitplayground import cp
 +
#neoPixel pins for the smiley face
 +
pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 
   
 
   
cp.pixels.brightness = 0.3
+
playtime=0.2
+
# NOTE C4-B4
 +
c4=262
 +
d4=294
 +
e4=330
 +
f4=349
 +
g4=392
 +
a4=440
 +
b4=494
 +
 
 
while True:
 
while True:
 
     if cp.touch_A1:
 
     if cp.touch_A1:
         print("Touched A1!")
+
        cp.play_tone(c4, playtime)
        cp.pixels[6] = (255, 0, 0)
+
         print("A1-touched!")
 
     if cp.touch_A2:
 
     if cp.touch_A2:
         print("Touched A2!")
+
        cp.play_tone(d4, playtime)
        cp.pixels[8] = (210, 45, 0)
+
         print("A2-touched!")
 
     if cp.touch_A3:
 
     if cp.touch_A3:
         print("Touched A3!")
+
        cp.play_tone(e4, playtime)
        cp.pixels[9] = (155, 100, 0)
+
         print("A3-touched!")
 
     if cp.touch_A4:
 
     if cp.touch_A4:
         print("Touched A4!")
+
        cp.play_tone(f4, playtime)
        cp.pixels[0] = (0, 255, 0)
+
         print("A4-touched!")
 
     if cp.touch_A5:
 
     if cp.touch_A5:
         print("Touched A5!")
+
        cp.play_tone(g4, playtime)
        cp.pixels[1] = (0, 135, 125)
+
         print("A5-touched!")
 
     if cp.touch_A6:
 
     if cp.touch_A6:
         print("Touched A6!")
+
        cp.play_tone(a4, playtime)
        cp.pixels[3] = (0, 0, 255)
+
         print("A6-touched!")
     if cp.touch_TX:
+
     if cp.touch_A7:
        print("Touched TX!")
+
         cp.play_tone(b4, playtime)
         cp.pixels[4] = (100, 0, 155)
+
        print("A7-touched!")
    time.sleep(0.1)
 
  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Play audio file===
+
===3.Play audio file ===
 +
here some audio files you can download and copy to the circuit playground express.
 +
 
 +
Dip: http://interactionstation.wdka.hro.nl/mediawiki/images/6/61/Dip.wav
 +
 
 +
Rise: http://interactionstation.wdka.hro.nl/mediawiki/images/2/2b/Rise.wav
 +
 
 +
Explosion: http://interactionstation.wdka.hro.nl/mediawiki/images/f/f8/Explosion.wav
 +
 
 +
Kiss.wav: http://interactionstation.wdka.hro.nl/mediawiki/images/d/df/Kiss.wav
 +
 
 +
Happy-ringtone: http://interactionstation.wdka.hro.nl/mediawiki/images/9/9b/Happy-ringtone.wav
 +
 
 +
Wrong-buzzer: http://interactionstation.wdka.hro.nl/mediawiki/images/6/61/Wrong-buzzer.wav
 +
 
 +
Yelling-yeah: http://interactionstation.wdka.hro.nl/mediawiki/images/9/95/Yelling-yeah.wav
 +
 
 +
Jazz-piano: http://interactionstation.wdka.hro.nl/mediawiki/images/a/a9/Jazz-piano.wav
 +
 
 +
 
 
<syntaxhighlight lang="python" line='line'>
 
<syntaxhighlight lang="python" line='line'>
  
#Copy the "dip.wav" file to your CIRCUITPY drive.
+
import time
 
#Once the file is copied, this example plays a wav file!"""
 
 
from adafruit_circuitplayground import cp
 
from adafruit_circuitplayground import cp
cp.pixels.brightness = 0.3
+
#neoPixel pins for the smiley face
 +
pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 +
 
 +
# The NeoPixels are super-bright. Change the global brightness.
 +
cp.pixels.brightness = 0.1
 +
colour01=(105,0,105)
 +
colour02=(0,100,105)
 +
OFF=(0,0,0)
  
 
while True:
 
while True:
     if cp.touch_A1:
+
     if cp.touch_A4:
         print("Touched A1!")
+
         for i in range (7):
         cp.pixels[6] = (255, 0, 0)
+
            cp.pixels[pixels_pin[i]]=colour01 
         cp.play_file("dip.wav")
+
            time.sleep(0.03)
 +
            print("A4-touched!")
 +
         cp.play_file("yelling-yeah.wav")
 +
    else:
 +
        for i in range (7):
 +
            cp.pixels[pixels_pin[i]]=OFF   
 +
            time.sleep(0.03)
 +
    if cp.touch_A3:
 +
        for i in range (7):
 +
            cp.pixels[pixels_pin[i]]=colour02 
 +
            time.sleep(0.03)
 +
            print("A3-touched!")
 +
 +
         cp.play_file("jazz-piano.wav")
 +
    else:
 +
        for i in range (7):
 +
            cp.pixels[pixels_pin[i]]=OFF
 +
            time.sleep(0.03)
 +
 
 +
</syntaxhighlight>
 +
 
 +
===4.Drum Machine===
 +
 
 +
https://learn.adafruit.com/adafruit-circuit-playground-express/playground-drum-machine
 +
 
 +
 
 +
copy the drum samples there:
 +
 
 +
[[https://cdn-learn.adafruit.com/assets/assets/000/047/298/original/drumSamples.zip?1507938887|drum samples]]
  
 +
<syntaxhighlight lang="python" line='line'>
 +
# Circuit Playground 808 Drum machine
 +
import time
 +
import board
 +
import touchio
 +
import digitalio
 +
 +
try:
 +
    from audiocore import WaveFile
 +
except ImportError:
 +
    from audioio import WaveFile
 +
 +
try:
 +
    from audioio import AudioOut
 +
except ImportError:
 +
    try:
 +
        from audiopwmio import PWMAudioOut as AudioOut
 +
    except ImportError:
 +
        pass  # not always supported by every board!
 +
 +
bpm = 120  # Beats per minute, change this to suit your tempo
 +
 +
# Enable the speaker
 +
speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
 +
speaker_enable.direction = digitalio.Direction.OUTPUT
 +
speaker_enable.value = True
 +
 +
# Make the input capacitive touchpads
 +
capPins = (board.A1, board.A2, board.A3, board.A4, board.A5,
 +
          board.A6, board.TX)
 +
 +
touchPad = []
 +
for i in range(7):
 +
    touchPad.append(touchio.TouchIn(capPins[i]))
 +
 +
# The seven files assigned to the touchpads
 +
audiofiles = ["bd_tek.wav", "elec_hi_snare.wav", "elec_cymbal.wav",
 +
              "elec_blip2.wav", "bd_zome.wav", "bass_hit_c.wav",
 +
              "drum_cowbell.wav"]
 +
 +
audio = AudioOut(board.SPEAKER)
 +
 +
 +
def play_file(filename):
 +
    print("playing file " + filename)
 +
    file = open(filename, "rb")
 +
    wave = WaveFile(file)
 +
    audio.play(wave)
 +
    time.sleep(bpm / 960)  # Sixteenth note delay
 +
 +
 +
while True:
 +
    for i in range(7):
 +
        if touchPad[i].value:
 +
            play_file(audiofiles[i])
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
'''connect to a proper speaker:'''
 +
 +
we can use A0 and GND as audio output and connect it to a proper speaker.
 +
 +
you can use M3 bolts and nuts to fix the electrical wire on the circuit playground express.
 +
 +
[[File:Circuit playground hp.png]] [[File:IMG 3518.jpeg|500px]]
  
 
==='''infrared tagging game:'''===
 
==='''infrared tagging game:'''===
Line 252: Line 462:
  
 
<syntaxhighlight lang="python" line='line'>
 
<syntaxhighlight lang="python" line='line'>
from adafruit_circuitplayground.express import cpx
 
 
import board
 
import board
 
from adafruit_circuitplayground import cp
 
from adafruit_circuitplayground import cp
Line 258: Line 467:
 
import pulseio
 
import pulseio
 
import array
 
import array
import touchio
+
import sys
import digitalio
 
  
 
# change into your own color by changing the rgb value
 
# change into your own color by changing the rgb value
myID_colour=(0,255,255)
+
myID_color = (0, 55, 50)
# NeoPixel brightness
+
OFF = (0, 0, 0)
 +
color_got_hit = (255, 0, 0)
 +
color_got_saved = (100, 0, 100)
 +
Neo_smiley_face = [4,  5,  1, 0, 8, 9]
 +
full_led = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 +
counter = 0
 +
lifes = 10-counter
 +
 
 +
# Initializes NeoPixel ring
 +
cp.pixels.brightness = 0.2
 +
# my id color
 +
cp.pixels.fill(myID_color)
 +
 
  
 
# Create IR input, maximum of 59 bits.
 
# Create IR input, maximum of 59 bits.
Line 300: Line 520:
 
     return True
 
     return True
  
# Initializes NeoPixel ring
 
cp.pixels.brightness= 0.2
 
# my id color
 
cp.pixels.fill(myID_colour)
 
#cp.pixels.show()
 
  
 
# serial print once when activated
 
# serial print once when activated
Line 310: Line 525:
  
 
while True:
 
while True:
# when button is pressed, send IR pulse
+
    # when A3 or A4 is Touched, send IR pulse
# detection is paused then cleared and resumed after a short pause
+
    # detection is paused then cleared and resumed after a short pause
# this prevents reflected detection of own IR
+
    # this prevents reflected detection of own IR
 
     while cp.touch_A3:
 
     while cp.touch_A3:
 
         pulseIn.pause()  # pauses IR detection
 
         pulseIn.pause()  # pauses IR detection
Line 326: Line 541:
 
         pulseIn.resume()
 
         pulseIn.resume()
 
# Wait for a pulse to be detected of desired length
 
# Wait for a pulse to be detected of desired length
     while len(pulseIn) >= 59:  # our array is 59 bytes so anything shorter ignore
+
     # our array is 59 bytes so anything shorter ignore
 +
    while len(pulseIn) >= 59:
 
         pulseIn.pause()
 
         pulseIn.pause()
 
# converts pulseIn raw data into useable array
 
# converts pulseIn raw data into useable array
Line 335: Line 551:
 
     # Got a pulse, now compare against stored pulse_A and pulse_B
 
     # Got a pulse, now compare against stored pulse_A and pulse_B
 
         if fuzzy_pulse_compare(pulse_A, detected):
 
         if fuzzy_pulse_compare(pulse_A, detected):
             print('Received correct Button A control press!')
+
             print('Received A3 control A!')
 
             t_end = time.monotonic() + 0.8  # saves time 2 seconds in the future
 
             t_end = time.monotonic() + 0.8  # saves time 2 seconds in the future
             while time.monotonic() < t_end: # plays sparkels until time is up
+
             while time.monotonic() < t_end:
                 for x in range(10):
+
                cp.pixels.fill(OFF)
                     if x!= 0 and x!=2 and x!=4:
+
                 for x in range(6):
                        cp.pixels[x]=(250, 55, 100)
+
                     cp.pixels[Neo_smiley_face[x]] = (color_got_saved)
 +
                cp.play_file("yelling-yeah.wav")
 +
                time.sleep(0.2)
  
                     else:
+
                if counter < 10 and counter > 0:
                        cp.pixels[x]=(0, 0, 0)
+
                     counter = counter-1
                 cp.play_file("kiss.wav")
+
                    lifes = 10-counter
                 time.sleep(1.5)
+
                cp.pixels.fill(OFF)
                 cp.pixels.fill(myID_colour)
+
 
 +
        else:
 +
            for i in range(lifes):
 +
                 cp.pixels[full_led[i]] = myID_color
 +
                 pulseIn.clear()
 +
                 pulseIn.resume()
  
 
         if fuzzy_pulse_compare(pulse_B, detected):
 
         if fuzzy_pulse_compare(pulse_B, detected):
             print('Received correct Button B control press!')
+
             print('Received A4 control B !')
 
             t_end = time.monotonic() + 0.8
 
             t_end = time.monotonic() + 0.8
 
             while time.monotonic() < t_end:
 
             while time.monotonic() < t_end:
                 #rainbow_cycle(.001)
+
                 print(counter)
                 cp.pixels.fill((255, 0, 0))
+
                 print(lifes)
                 cp.play_file("explosion.wav")
+
                 cp.pixels.fill(OFF)
                time.sleep(0.5)
+
                 cp.pixels.fill(color_got_hit)
                 cp.pixels.fill(myID_colour)
 
  
 +
                cp.play_file("failure.wav")
 +
                time.sleep(0.2)
 +
                counter = counter+1
 +
                lifes = 10-counter
 +
                if lifes < 1:
 +
                    sys.exit()
 +
                cp.pixels.fill(OFF)
 +
                for i in range(lifes):
 +
                    cp.pixels[full_led[i]] = myID_color
  
 +
        else:
 +
            for i in range(lifes):
 +
                cp.pixels[full_led[i]] = myID_color
 +
                pulseIn.clear()
 +
                pulseIn.resume()
  
 
         time.sleep(.1)
 
         time.sleep(.1)
Line 365: Line 601:
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
[[Category:Circuit Playground Express]][[Category:Circuit Python]][[Category:Mu Editor]]

Latest revision as of 15:54, 13 March 2024


Introduction on Adafruit Circuit Playground Express

Install CircuitPython

Install mu editor

Circuitpython circuit playground adafruit blinka computer.png 17850097.png

Python is the fastest-growing programming language. And CircuitPython is based on Python language but designed to run on microcontroller boards.

CircuitPython is designed with education in mind.

It's easy to start learning how to program and you get immediate feedback from the board.


Before we start we all have to do this to set up:

1. Install or update CircuitPython!

https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart

*1. Click the link below and download the latest UF2 file:
https://circuitpython.org/board/circuitplayground_express/
*2. Plug your Circuit Playground Express into your computer via a (data)USB cable.
*3. Double-click the small Reset button in the middle of the CPX(short for circuit playground express).
 you will see all of the LEDs turn green. If they turn all red, check the USB cable, try another USB port, etc.
 (If double-clicking doesn't do it, try a single-click!)
*4. You will see a new disk drive appear called CPLAYBOOT
  Drag the adafruit-circuitpython-etc...uf2 file onto it.
*5. The CPLAYBOOT drive will disappear and a new disk drive will appear called CIRCUITPY

That's it! You're done :)

2. Installing Mu Editor

Download Mu from(if you are using computers from school, the Mu Editor is already installed)

https://codewith.mu

Circuitpython mu-front-page.png


The first time you start Mu, you will be prompted to select your 'mode' -

you can always change your mind later. For now please select CircuitPython!


Circuitpython Screen Shot 2017-12-24 at 2.55.02 PM.png


Mu attempts to auto-detect your board, so please plug in your CircuitPython device and make sure it shows up as a CIRCUITPY drive before starting Mu

Circuitpython Screen Shot 2017-12-24 at 3.16.23 PM.png


SAVE AS:

if you want to save the code.py file in different names as well as in different locations:

double click on the file name in Mu editor.

Save-as-Capture.PNG

Indentation and commenting options

Python programs are Space holder Character Sensitive.

To indent the three lines, I selected them all and then pressed the Tab key.

To unindent, select some lines and press Shift-Tab. For commenting: select lines and press command(control)-k

Mu CircuitPython Mode Cheat Sheet 1.jpg

3. Hello World (Blink in Circuitpython)

 1# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
 2# SPDX-License-Identifier: MIT
 3
 4"""This is the "Hello, world!" of CircuitPython: Blinky! This example blinks the little red LED on
 5and off!"""
 6
 7import time
 8from adafruit_circuitplayground import cp
 9
10while True:
11    cp.red_led = True
12    time.sleep(0.5)
13    cp.red_led = False
14    time.sleep(0.5)

4. Interacting to the Serial Console

The REPL

The other feature of the serial connection is the Read-Evaluate-Print-Loop, or REPL.

The REPL allows you to enter individual lines of code and have them run immediately.

It's really handy if you're running into trouble with a particular program and can't figure out why.

It's interactive so it's great for testing new ideas.

To use the REPL, you first need to be connected to the serial console.

Once that connection has been established, you'll want to press Ctrl + C.

If there is code running, it will stop and you'll see Press any key to enter the REPL. Use CTRL-D to reload.

Follow those instructions, and press any key on your keyboard.

https://learn.adafruit.com/adafruit-circuit-playground-express/the-repl

CircuitPython Made Easy

Libraries:

Libraries are codes other people have written for you. The libraries we will be using are included as part of the CircuitPython code, but you still must import them into your program. Other libraries, for many uses, must be downloaded and placed in a folder named lib on the CIRCUITPY drive.


CircuitPython Libraries already included in CPX, But if you are using CPB, (CPX = Circuit Playground Express, CPB = Circuit Playground Bluefruit)

you need to install CircuitPython Libraries by download the file and put them in the folder named lib on the CIRCUITPY drive.

we will useCircuitPython Made Easy libraries, a simple way to include the Circuit Playground functionality in our code.

more reference and examples:

https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express


Interaction with touch sensor and neopixel

During this workshop, we will learn how to design and create an interactive game that enhances communication,

expression, and collaboration in the current 1.5 social distance reality.

we will focus on sending “touch signal” to each other without physical contact,

but in the forms of lights, color and sound.


1.Neopixel smiley face

A Smiley Face😊

from adafruit_circuitplayground import cp

# The NeoPixels are super-bright. Change the global brightness.
cp.pixels.brightness = 0.3

while True:
    # The smiley's eyes
    cp.pixels[1] = (255, 0, 0)
    cp.pixels[3] = (255, 0, 0)

    # The smiley's mouth
    cp.pixels[5] = (255, 0, 255)
    cp.pixels[6] = (255, 0, 255)
    cp.pixels[7] = (255, 0, 255)
    cp.pixels[8] = (255, 0, 255)
    cp.pixels[9] = (255, 0, 255)

Let's blink a smiley face by using time.sleep

 1from adafruit_circuitplayground import cp
 2 
 3# The NeoPixels are super-bright. Change the global brightness.
 4cp.pixels.brightness = 0.3
 5
 6import time  
 7
 8while True:
 9    time.sleep(1)
10    # The smiley's eyes
11    cp.pixels[1] = (255, 0, 0)
12    cp.pixels[3] = (255, 0, 0)
13 
14    # The smiley's mouth
15    cp.pixels[5] = (255, 0, 255)
16    cp.pixels[6] = (255, 0, 255)
17    cp.pixels[7] = (255, 0, 255)
18    cp.pixels[8] = (255, 0, 255)
19    cp.pixels[9] = (255, 0, 255)
20    time.sleep(1)
21
22    # The smiley's eyes
23    cp.pixels[1] = (0, 0, 0)
24    cp.pixels[3] = (0, 0, 0)
25 
26    # The smiley's mouth
27    cp.pixels[5] = (0, 0, 0)
28    cp.pixels[6] = (0, 0, 0)
29    cp.pixels[7] = (0, 0, 0)
30    cp.pixels[8] = (0, 0, 0)
31    cp.pixels[9] = (0, 0, 0)


hmm... now the code seems to be too long

let's Shorten the code by implementing variables, "for" loops

 1import time
 2from adafruit_circuitplayground import cp
 3#neoPixel pins for the smiley face
 4pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 5# The NeoPixels are super-bright. Change the global brightness.
 6cp.pixels.brightness = 0.1
 7light_colour=(105,0,105)
 8OFF=(0,0,0)
 9
10while True:
11    for i in range (7):
12        cp.pixels[pixels_pin[i]]=light_colour       
13    time.sleep(1)
14    for i in range (7):
15        cp.pixels[pixels_pin[i]]=OFF     
16    time.sleep(1)


much better!!! now if you add a time.sleep(0.5) in the for loop you will see a fading animation of the smiley face.

2.Touch sense as trigger

there are in total 7 touch pins on CPX. let's try to use the touch sensor to trigger the smiley face.


if we touch pin A4, The smiley face will appear if not the smiley face will disappear.


 1import time
 2from adafruit_circuitplayground import cp
 3#neoPixel pins for the smiley face
 4pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 5# The NeoPixels are super-bright. Change the global brightness.
 6cp.pixels.brightness = 0.1
 7light_colour=(105,0,105)
 8OFF=(0,0,0)
 9
10while True:
11    if cp.touch_A4:
12        for i in range (7):
13            cp.pixels[pixels_pin[i]]=light_colour   
14            time.sleep(.1)
15            print("A4-touched!")
16    else:
17        for i in range (7):
18            cp.pixels[pixels_pin[i]]=OFF     
19            time.sleep(.1)

3.Touch piano keyboard

 1import time
 2from adafruit_circuitplayground import cp
 3#neoPixel pins for the smiley face
 4pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 5 
 6playtime=0.2
 7# NOTE C4-B4
 8c4=262 
 9d4=294
10e4=330
11f4=349
12g4=392
13a4=440
14b4=494
15
16while True:
17    if cp.touch_A1:
18        cp.play_tone(c4, playtime) 
19        print("A1-touched!")
20    if cp.touch_A2:
21        cp.play_tone(d4, playtime)
22        print("A2-touched!")
23    if cp.touch_A3:
24        cp.play_tone(e4, playtime)
25        print("A3-touched!")
26    if cp.touch_A4:
27        cp.play_tone(f4, playtime)
28        print("A4-touched!")
29    if cp.touch_A5:
30        cp.play_tone(g4, playtime)
31        print("A5-touched!")
32    if cp.touch_A6:
33        cp.play_tone(a4, playtime)
34        print("A6-touched!")
35    if cp.touch_A7:
36        cp.play_tone(b4, playtime)
37        print("A7-touched!")

3.Play audio file

here some audio files you can download and copy to the circuit playground express.

Dip: http://interactionstation.wdka.hro.nl/mediawiki/images/6/61/Dip.wav

Rise: http://interactionstation.wdka.hro.nl/mediawiki/images/2/2b/Rise.wav

Explosion: http://interactionstation.wdka.hro.nl/mediawiki/images/f/f8/Explosion.wav

Kiss.wav: http://interactionstation.wdka.hro.nl/mediawiki/images/d/df/Kiss.wav

Happy-ringtone: http://interactionstation.wdka.hro.nl/mediawiki/images/9/9b/Happy-ringtone.wav

Wrong-buzzer: http://interactionstation.wdka.hro.nl/mediawiki/images/6/61/Wrong-buzzer.wav

Yelling-yeah: http://interactionstation.wdka.hro.nl/mediawiki/images/9/95/Yelling-yeah.wav

Jazz-piano: http://interactionstation.wdka.hro.nl/mediawiki/images/a/a9/Jazz-piano.wav


 1import time
 2from adafruit_circuitplayground import cp
 3#neoPixel pins for the smiley face
 4pixels_pin=[1,  3,  5, 6, 7, 8, 9,10]
 5
 6# The NeoPixels are super-bright. Change the global brightness.
 7cp.pixels.brightness = 0.1
 8colour01=(105,0,105)
 9colour02=(0,100,105)
10OFF=(0,0,0)
11
12while True:
13    if cp.touch_A4:
14        for i in range (7):
15            cp.pixels[pixels_pin[i]]=colour01   
16            time.sleep(0.03)
17            print("A4-touched!")
18        cp.play_file("yelling-yeah.wav")
19    else:
20        for i in range (7):
21            cp.pixels[pixels_pin[i]]=OFF     
22            time.sleep(0.03)
23    if cp.touch_A3:
24        for i in range (7):
25            cp.pixels[pixels_pin[i]]=colour02   
26            time.sleep(0.03)
27            print("A3-touched!")
28 
29        cp.play_file("jazz-piano.wav")
30    else:
31        for i in range (7):
32            cp.pixels[pixels_pin[i]]=OFF
33            time.sleep(0.03)

4.Drum Machine

https://learn.adafruit.com/adafruit-circuit-playground-express/playground-drum-machine


copy the drum samples there:

[samples]

 1# Circuit Playground 808 Drum machine
 2import time
 3import board
 4import touchio
 5import digitalio
 6 
 7try:
 8    from audiocore import WaveFile
 9except ImportError:
10    from audioio import WaveFile
11 
12try:
13    from audioio import AudioOut
14except ImportError:
15    try:
16        from audiopwmio import PWMAudioOut as AudioOut
17    except ImportError:
18        pass  # not always supported by every board!
19 
20bpm = 120  # Beats per minute, change this to suit your tempo
21 
22# Enable the speaker
23speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
24speaker_enable.direction = digitalio.Direction.OUTPUT
25speaker_enable.value = True
26 
27# Make the input capacitive touchpads
28capPins = (board.A1, board.A2, board.A3, board.A4, board.A5,
29           board.A6, board.TX)
30 
31touchPad = []
32for i in range(7):
33    touchPad.append(touchio.TouchIn(capPins[i]))
34 
35# The seven files assigned to the touchpads
36audiofiles = ["bd_tek.wav", "elec_hi_snare.wav", "elec_cymbal.wav",
37              "elec_blip2.wav", "bd_zome.wav", "bass_hit_c.wav",
38              "drum_cowbell.wav"]
39 
40audio = AudioOut(board.SPEAKER)
41 
42 
43def play_file(filename):
44    print("playing file " + filename)
45    file = open(filename, "rb")
46    wave = WaveFile(file)
47    audio.play(wave)
48    time.sleep(bpm / 960)  # Sixteenth note delay
49 
50 
51while True:
52    for i in range(7):
53        if touchPad[i].value:
54            play_file(audiofiles[i])

connect to a proper speaker:

we can use A0 and GND as audio output and connect it to a proper speaker.

you can use M3 bolts and nuts to fix the electrical wire on the circuit playground express.

Circuit playground hp.png IMG 3518.jpeg

infrared tagging game:

  1import board
  2from adafruit_circuitplayground import cp
  3import time
  4import pulseio
  5import array
  6import sys
  7
  8# change into your own color by changing the rgb value
  9myID_color = (0, 55, 50)
 10OFF = (0, 0, 0)
 11color_got_hit = (255, 0, 0)
 12color_got_saved = (100, 0, 100)
 13Neo_smiley_face = [4,  5,  1, 0, 8, 9]
 14full_led = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 15counter = 0
 16lifes = 10-counter
 17
 18# Initializes NeoPixel ring
 19cp.pixels.brightness = 0.2
 20# my id color
 21cp.pixels.fill(myID_color)
 22
 23
 24# Create IR input, maximum of 59 bits.
 25pulseIn = pulseio.PulseIn(board.IR_RX, maxlen=59, idle_state=True)
 26# Clears any artifacts
 27pulseIn.clear()
 28pulseIn.resume()
 29
 30# Creates IR output pulse
 31pwm = pulseio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15)
 32pulse = pulseio.PulseOut(pwm)
 33
 34# Array for button A pulse, this is the pulse output when the button is pressed
 35# Inputs are compared against this same array
 36# array.array('H', [x]) must be used for IR pulse arrays when using pulseio
 37# indented to multiple lines so its easier to see
 38pulse_A = array.array('H', [1000, 3800, 65000, 950, 300, 200, 300, 1000, 350, 175,
 39    275, 215, 275, 250, 275, 215, 275, 225, 275, 215, 275, 1000, 300, 225, 275,
 40    950, 300, 950, 300, 1000, 300, 950, 300, 250, 275, 700, 300, 950, 300, 450,
 41    300, 475, 300, 215, 275, 725, 300, 950, 300, 200, 300, 715, 325, 900, 315,
 42    425, 315, 1000, 65000])
 43pulse_B = array.array('H', [1000, 3800, 65000, 960, 300, 200, 300, 950, 350, 190,
 44    215, 245, 300, 225, 275, 225, 275, 215, 275, 200, 300, 700, 300, 200, 300,
 45    700, 300, 1000, 315, 675, 300, 1000, 300, 200, 300, 700, 300, 950, 300,
 46    950, 300, 700, 300, 700, 300, 450, 300, 475, 275, 715, 300, 225, 275, 450,
 47    300, 450, 300, 1000, 65000])
 48
 49# Fuzzy pulse comparison function. Fuzzyness is % error
 50def fuzzy_pulse_compare(pulse1, pulse2, fuzzyness=0.5):
 51    if len(pulse1) != len(pulse2):
 52        return False
 53    for i in range(len(pulse1)):
 54        threshold = int(pulse1[i] * fuzzyness)
 55        if abs(pulse1[i] - pulse2[i]) > threshold:
 56            return False
 57    return True
 58
 59
 60# serial print once when activated
 61print('IR Activated!')
 62
 63while True:
 64    # when A3 or A4 is Touched, send IR pulse
 65    # detection is paused then cleared and resumed after a short pause
 66    # this prevents reflected detection of own IR
 67    while cp.touch_A3:
 68        pulseIn.pause()  # pauses IR detection
 69        pulse.send(pulse_A)  # sends IR pulse
 70        time.sleep(.2)  # wait so pulses dont run together
 71        pulseIn.clear()  # clear any detected pulses to remove partial artifacts
 72        pulseIn.resume()  # resumes IR detection
 73    while cp.touch_A4:
 74        pulseIn.pause()
 75        pulse.send(pulse_B)
 76        time.sleep(.2)
 77        pulseIn.clear()
 78        pulseIn.resume()
 79# Wait for a pulse to be detected of desired length
 80    # our array is 59 bytes so anything shorter ignore
 81    while len(pulseIn) >= 59:
 82        pulseIn.pause()
 83# converts pulseIn raw data into useable array
 84        detected = array.array('H', [pulseIn[x] for x in range(len(pulseIn))])
 85#        print(len(pulseIn))
 86#        print(detected)
 87
 88    # Got a pulse, now compare against stored pulse_A and pulse_B
 89        if fuzzy_pulse_compare(pulse_A, detected):
 90            print('Received A3 control A!')
 91            t_end = time.monotonic() + 0.8  # saves time 2 seconds in the future
 92            while time.monotonic() < t_end:
 93                cp.pixels.fill(OFF)
 94                for x in range(6):
 95                    cp.pixels[Neo_smiley_face[x]] = (color_got_saved)
 96                cp.play_file("yelling-yeah.wav")
 97                time.sleep(0.2)
 98
 99                if counter < 10 and counter > 0:
100                    counter = counter-1
101                    lifes = 10-counter
102                cp.pixels.fill(OFF)
103
104        else:
105            for i in range(lifes):
106                cp.pixels[full_led[i]] = myID_color
107                pulseIn.clear()
108                pulseIn.resume()
109
110        if fuzzy_pulse_compare(pulse_B, detected):
111            print('Received A4 control B !')
112            t_end = time.monotonic() + 0.8
113            while time.monotonic() < t_end:
114                print(counter)
115                print(lifes)
116                cp.pixels.fill(OFF)
117                cp.pixels.fill(color_got_hit)
118
119                cp.play_file("failure.wav")
120                time.sleep(0.2)
121                counter = counter+1
122                lifes = 10-counter
123                if lifes < 1:
124                    sys.exit()
125                cp.pixels.fill(OFF)
126                for i in range(lifes):
127                    cp.pixels[full_led[i]] = myID_color
128
129        else:
130            for i in range(lifes):
131                cp.pixels[full_led[i]] = myID_color
132                pulseIn.clear()
133                pulseIn.resume()
134
135        time.sleep(.1)
136        pulseIn.clear()
137        pulseIn.resume()