Let's start with A0 which is in the bottom right corner, and work our way counter-clockwise
A0 (a.k.a D12) - This is a special pin that can do true analog output so it's great for playing audio clips. In can be digital I/O, or analog I/O, but if you do that it will interfere with the built-in speaker. This is the one pin that cannot be used for capacitive touch.
A1 / D6 - This pin can be digital I/O, or analog Input. This pin has PWM output and can be capacitive touch sensor
A2 / D9 - This pin can be digital I/O, or analog Input. This pin has PWM output and can be capacitive touch sensor
A3 / D10 - This pin can be digital I/O, or analog Input. This pin has PWM output and can be capacitive touch sensor
A4 / D3 - This pin can be digital I/O, or analog Input. This pin is also the I2C SCL pin, and can be capacitive touch sensor
A5 / D2 - This pin can be digital I/O, or analog Input. This pin is also the I2C SDA pin, and can be capacitive touch sensor
A6 / D0 - This pin can be digital I/O, or analog Input. This pin has PWM output, Serial Receive, and can be capacitive touch sensor
A7 / D1 - This pin can be digital I/O, or analog Input. This pin has PWM output, Serial Transmit, and can be capacitive touch sensor
// blink the onboard LED
/**
* Special function that loops forever.
*/
forever(function () {
// turn the onboard LED on
pins.LED.digitalWrite(true)
// wait 500 milliseconds (half a second)
pause(500)
// turn the onboard LED off
pins.LED.digitalWrite(false)
// wait 500 milliseconds (half a second)
pause(500)
})
// blink an external LED
// attach GND to negative leg, A1 to positive leg
let LED_PIN = pins.A1 // store the chosen pin in a variable
/**
* Special function that loops forever.
*/
forever(function () {
// turn the pin on
LED_PIN.digitalWrite(true)
// wait 500 milliseconds (half a second)
pause(500)
// turn the pin off
LED_PIN.digitalWrite(false)
// wait 500 milliseconds (half a second)
pause(500)
})
// blink an onboard neopixel
let neopixel = 0 // track which neopixel to blink
// the forever function runs over and over again
forever(function () {
// turn the Neopixel red by specifying:
// full red (highest value of 255), no green and no blue
light.setPixelColor(neopixel, light.rgb(255, 0, 0))
pause(1000) // wait for a second
// turn the Neopixel off by specifying:
// no red, no green and no blue
light.setPixelColor(neopixel, light.rgb(0, 0, 0))
pause(1000) // wait for a second
})
// use the light sensor to control neopixels
// when there is a lot of light, all are pink
// when it is dark, they sparkle
let LIGHT_THRESHOLD = 20; // you may need to play with this
forever(function () {
// if the darkness is above a threshold value
if (input.lightLevel() > LIGHT_THRESHOLD) {
// turn all neopixels off
light.clear()
// then show a sparkle animation for .5 seconds
light.showAnimation(light.sparkleAnimation, 500)
}
// otherwise
else {
// light all neopixels pink
light.setAll(light.rgb(255, 20, 147))
}
})
// use the sound sensor to control neopixels
// when there is a lot of sound, sparkle
// otherwise, all are pink
let SOUND_THRESHOLD = 100; // set a threshold value
forever(function () {
// if the darkness is above a threshold value
if (input.soundLevel() > SOUND_THRESHOLD) {
// turn all neopixels off
light.clear()
// then show a sparkle animation for .5 seconds
light.showAnimation(light.sparkleAnimation, 500)
}
// otherwise
else {
// light all neopixels pink
light.setAll(light.rgb(255, 20, 147))
}
})
// print the light sensor value to the console
forever(function () {
console.logValue("light sensor", input.lightLevel())
pause(100)
})
let temp = 0
forever(function () {
temp = input.temperature(TemperatureUnit.Fahrenheit)
if (temp > 90) {
light.setAll(0xff0000)
} else if (temp < 89) {
light.setAll(0x00ffff)
} else {
light.setAll(0xffff00)
}
pause(100)
})
input.buttonA.onEvent(ButtonEvent.Click, function () {
light.clear()
})
input.buttonB.onEvent(ButtonEvent.Click, function () {
light.setAll(input.ambientColor())
})
forever(function () {
})
// set up the velostat and wiring:
// https://docs.google.com/document/d/1Ve4l8B4V112InWYsD8NXnqRUdxUZQAYjeTp3Ix2Yo0U/edit
// use the serial monitor to find these values
// if MakeCode is refusing to cooperate...
// use Arduino...
let THRESH1 = 800
let THRESH2 = 900
forever(function () {
// most pressure
if (pins.A3.analogRead() >= THRESH2) {
light.setAll(0xff0000)
}
// medium pressure
else if (pins.A3.analogRead() >= THRESH1) {
light.setAll(0xffff00)
}
// not enough pressure
else {
light.clear()
}
})
// For the CPX, use the green ultrasonic RCWL-1601 (3.3V)
// Trig to A2, Echo to A1
let distance = 0
forever(function () {
pins.A2.digitalWrite(false)
control.waitMicros(2)
pins.A2.digitalWrite(true)
control.waitMicros(10)
pins.A2.digitalWrite(false)
distance = pins.A1.pulseIn(PulseValue.High) / 58
// have the neopixel ring show "bar graph" up to 50
light.graph(distance, 50)
// if in a certain range
if (distance >= 5 && distance <= 10)
// play a sound!
music.baDing.play()
})
// if you have errors, use EXTENSIONS -> servo
servos.A1.setAngle(0) // start at 0
// wait .5 second to get back to 0 in case it wasn't close
pause(500)
// on button A click, sweep forward
input.buttonA.onEvent(ButtonEvent.Click, function () {
servos.A1.setAngle(0)
// wait .5 second to get back to 0 in case it wasn't close
pause(500)
// iterate from 0 degrees to 180 degrees
// in steps of 1 degree
for (let pos = 0; pos <= 180; pos++) {
// tell servo to go to position in variable 'pos'
servos.A1.setAngle(pos)
// waits 5 ms for the servo to reach the position
pause(5)
}
})
// on button B click, sweep back
input.buttonB.onEvent(ButtonEvent.Click, function () {
servos.A1.setAngle(180)
// wait .5 second to get to 180 in case it wasn't close
pause(500)
// iterate from 0 degrees to 180 degrees
// in steps of 1 degree
for (let pos = 180; pos >= 0; pos--) {
// tell servo to go to position in variable 'pos'
servos.A1.setAngle(pos)
// waits 15 ms for the servo to reach the position
pause(5)
}
})
// This program uses the onboard neopixels to respond to tilting
// X axis is left/right (labeled on baord) lights pink/purple
// Y axis is forward back (also labeled on board) lights orange/yellow
// Z axis is which side is up lights blue/teal
let xAbs = 0
let yAbs = 0
let zAbs = 0
// X is left/right tilting
function respondToX() {
if (input.acceleration(Dimension.X) < 0) {
light.showRing(
`purple purple purple purple purple black black black black black`
)
} else {
light.showRing(
`black black black black black pink pink pink pink pink`
)
}
}
// Y is forward/back tilting
function respondToY() {
if (input.acceleration(Dimension.Y) > 0) {
light.showRing(
`orange orange orange black black black black orange orange orange`
)
} else {
light.showRing(
`black black yellow yellow yellow yellow yellow yellow black black`
)
}
}
// Z is face up/down
function respondToZ() {
if (input.acceleration(Dimension.Z) > 0) {
light.setAll(0x00ffff)
} else {
light.setAll(0x0000ff)
}
}
forever(function () {
// we will use a threshold to see if which is most significant
xAbs = Math.abs(input.acceleration(Dimension.X))
yAbs = Math.abs(input.acceleration(Dimension.Y))
zAbs = Math.abs(input.acceleration(Dimension.Z))
// console.log(input.rotation(Rotation.Roll))
console.log(input.acceleration(Dimension.Z))
// determine which is biggest
if (xAbs > yAbs && xAbs > zAbs) {
respondToX()
} else if (yAbs > xAbs && yAbs > zAbs) {
respondToY()
} else if (zAbs > xAbs && zAbs > yAbs) {
respondToZ()
}
// should never happen...
else
light.clear()
})
/**
* This program supports chasing lights effect.
* First, it uses the onboard "strip" (the ring of built-in neopixels),
* then uses an external strip attached to pin A1.
*/
forever(function () {
// change this part
// right now, it uses the onboard strip which has 10 neopixels
// and chases a blue (0xRRGGBB) color every 200 milliseconds
// for 2 rounds
chaseNeopixels(light.onboardStrip(), 10, 0x0000ff, 200, 2)
// and this part, still uses the onboard strip which has 10 neopixels
// but chases a purple (0xRRGGBB) color every 100 milliseconds
// for 3 rounds
chaseNeopixels(light.onboardStrip(), 10, 0xff00ff, 100, 3)
// I think this part should set up an external strip with 15 neopixels,
// but I can't test since I don't have one!
let externalNeopixelStrip = light.createNeoPixelStrip(pins.A1, 15)
// so this should use the external strip with 15 neopixels
// to chase a green (0xRRGGBB) color every 50 milliseconds
// for 4 rounds
chaseNeopixels(externalNeopixelStrip, 15, 0x00ff00, 50, 4)
})
/**
* Have the neopixels "chase" along the strip.
* speed is the number of milliseconds each pixel stays on
* color is the RGB value to use for the light in format 0xRRGGBB
* numPixels is the number of neopixels in the strip
* numRounds is the number of rounds to execute
*/
function chaseNeopixels(strip: light.NeoPixelStrip, numPixels: number,
color: number, speed: number, numRounds: number) {
for (let chaseIndex = 0; chaseIndex < numRounds; chaseIndex++)
for (let pixIndex = 0; pixIndex < numPixels; pixIndex++) {
// turn on the pixel
strip.setPixelColor(pixIndex, color)
loops.pause(speed) // keep it on
// turn off the pixel
strip.setPixelColor(pixIndex, 0x000000)
}
}
Reference: https://makecode.adafruit.com/javascript
Notes: https://github.com/microsoft/pxt-adafruit/blob/master/docs/learnsystem/hot-potato.md
How I found the pins and such: https://github.com/microsoft/pxt-adafruit/blob/master/libs/circuit-playground/device.d.ts, code below
declare namespace pins {
// pin-pads
//% fixedInstance shim=pxt::getPin(PIN_A0)
const A0: AnalogOutPin;
//% fixedInstance shim=pxt::getPin(PIN_A1)
const A1: PwmPin;
//% fixedInstance shim=pxt::getPin(PIN_A2)
const A2: PwmPin;
//% fixedInstance shim=pxt::getPin(PIN_A3)
const A3: AnalogInPin;
//% fixedInstance shim=pxt::getPin(PIN_A4)
const A4: AnalogInPin;
//% fixedInstance shim=pxt::getPin(PIN_A5)
const A5: AnalogInPin;
//% fixedInstance shim=pxt::getPin(PIN_A6)
const A6: AnalogInPin; // could be PwmPin when mbed fixed
//% fixedInstance shim=pxt::getPin(PIN_A7)
const A7: AnalogInPin; // could be PwmPin when mbed fixed
// Define aliases, as Digital Pins
//% fixedInstance shim=pxt::getPin(PIN_A4)
const SCL: DigitalInOutPin;
//% fixedInstance shim=pxt::getPin(PIN_A5)
const SDA: DigitalInOutPin;
//% fixedInstance shim=pxt::getPin(PIN_A6)
const RX: DigitalInOutPin;
//% fixedInstance shim=pxt::getPin(PIN_A7)
const TX: DigitalInOutPin;
//% fixedInstance shim=pxt::getPin(PIN_D13)
const LED: DigitalInOutPin;
//% fixedInstance shim=pxt::getPin(PIN_IR_OUT)
const IROut: DigitalInOutPin;
//% fixedInstance shim=pxt::getPin(PIN_IR_IN)
const IRIn: DigitalInOutPin;
}
declare namespace input {
/**
* Left button.
*/
//% indexedInstanceNS=input indexedInstanceShim=pxt::getButton
//% block="button A" weight=95 fixedInstance
//% shim=pxt::getButton(0)
const buttonA: Button;
/**
* Right button.
*/
//% block="button B" weight=94 fixedInstance
//% shim=pxt::getButton(1)
const buttonB: Button;
/**
* Left and Right button.
*/
//% block="buttons A+B" weight=93 fixedInstance
//% shim=pxt::getButton(2)
const buttonsAB: Button;
}
declare namespace input {
/**
* Capacitive pin A1
*/
//% block="touch A1" fixedInstance shim=pxt::getTouchButton(PIN_A1)
const touchA1: TouchButton;
/**
* Capacitive pin A2
*/
//% block="touch A2" fixedInstance shim=pxt::getTouchButton(PIN_A2)
const touchA2: TouchButton;
/**
* Capacitive pin A3
*/
//% block="touch A3" fixedInstance shim=pxt::getTouchButton(PIN_A3)
const touchA3: TouchButton;
/**
* Capacitive pin A4
*/
//% block="touch A4" fixedInstance shim=pxt::getTouchButton(PIN_A4)
const touchA4: TouchButton;
/**
* Capacitive pin A5
*/
//% block="touch A5" fixedInstance shim=pxt::getTouchButton(PIN_A5)
const touchA5: TouchButton;
/**
* Capacitive pin A6
*/
//% block="touch A6" fixedInstance shim=pxt::getTouchButton(PIN_A6)
const touchA6: TouchButton;
/**
* Capacitive pin A7
*/
//% block="touch A7" fixedInstance shim=pxt::getTouchButton(PIN_A7)
const touchA7: TouchButton;
/**
* Capacitive pin A1
*/
//% block="pin A1" fixedInstance shim=pxt::getTouchButton(PIN_A1)
const pinA1: TouchButton;
/**
* Capacitive pin A2
*/
//% block="pin A2" fixedInstance shim=pxt::getTouchButton(PIN_A2)
const pinA2: TouchButton;
/**
* Capacitive pin A3
*/
//% block="pin A3" fixedInstance shim=pxt::getTouchButton(PIN_A3)
const pinA3: TouchButton;
/**
* Capacitive pin A4
*/
//% block="pin A4" fixedInstance shim=pxt::getTouchButton(PIN_A4)
const pinA4: TouchButton;
/**
* Capacitive pin A5
*/
//% block="pin A5" fixedInstance shim=pxt::getTouchButton(PIN_A5)
const pinA5: TouchButton;
/**
* Capacitive pin A6
*/
//% block="pin A6" fixedInstance shim=pxt::getTouchButton(PIN_A6)
const pinA6: TouchButton;
/**
* Capacitive pin A7
*/
//% block="pin A7" fixedInstance shim=pxt::getTouchButton(PIN_A7)
const pinA7: TouchButton;
}
Here's an example for how to use a paper circuit with the CPE -- you can use alligator clips to connect to the copper tape.
To make a better connection for the LED onto the paper circuit:
Use needle nose pliers to curl the LED leads.
Be sure you know which one is positive and which is negative!
Then, rest the LED on copper tape and use a small piece to "sandwich" the curled leads and make a decent connection.
Here's another example that shows how to connect two LEDs (in parallel).
You may need to play with the threshold value. If it's too low, then it will be very sensitive; sometimes just attaching an alligator clip will count as a "touch." In this case, use the Serial monitor to determine a better threshold value.
Build a little component that "sandwiches" the velostat between two conductive layers of "bread."
Materials
1 small rectangle of velostat
The size is up to you -- the pictures in this tutorial use about 2" x 3"
In Fimbel, velostat is located in the Electronics Cabinet
A 10K resistor
In Fimbel, these are in the organizer above the soldering station. Look for the drawer that says 10k.
Copper tape
Paper/cardboard
Draw/cut out your sandwich "bread" layers using your velostat to guide the size. In the picture below, you'll see that the righthand side is set up to have 2 attachment areas, while the left side only has one.
Use copper tape to cover each "bread" layer/side.
The strips of copper tape should be complementary to each other to ensure that current can flow (through the velostat) from one side to the other.
Make sure that the copper tape from each layer of bread does not touch -- there must be velostat sandwiched between.
Use copper tape to attach the 10k resistor to one side. Use another piece of copper tape to attach the resistor.
Place the velostat between the two sides, and your velostat "sandwich" pressure sensor is complete!
Use 3 alligator clips to attach:
the resistor to a GND pin
the other strip of the same (ground) side to an analog pin
use A3 on the Circuit Playground to work with the sample code
the strip on the other side to a voltage 3.3V pin
Micro Servo 9g SG90 (in Elegoo kits)
Attach your wires from the Servo to the CPE:
GND to GND (brown in the image)
Voltage to 3.3V or Vout (red in the image)
PWM control to A1 (orange in the image)
Double-check your connections and make sure no metal is touching other metal that you don't want!