Components and supplies
Force-sensitive Resistor
Adafruit NeoPixel Digital RGB LED Strip 144 LED, 1m White
Sewable Conductive Thread
Raspberry Pi 3 Model B
Pressure-sensitive conductive sheet (Velostat/Linqstat)
7-inch touch screen monitor
Tiny Nanny Cam
74AHCT125 Quad Level-Shifter
Arduino Leonardo
NiMH Battery 7.2V 3000mAh
mcp3008 8-channel 10-bit ADC with SPI Interface
Lipo battery 7.4V 5200mAh
Standard LCD - 16x2 White on Blue
Tools and machines
Sewing Machine
Bantam Tools Desktop PCB Milling Machine
Apps and platforms
Raspbian
Arduino IDE
Processing
Project description
Code
For Arduino
arduino
The file to be complied on Arduino, controlling the "Add Friends" and "Unfriends" features. Input sensors are contacting (conductive) rings, and a push switch. Output: Adafruit Neopixel and two 8x8 DotMatrixs
1 #include <LedControl.h> 2#include <Adafruit_NeoPixel.h> 3 4#define PIXEL_PIN 6 // Digital IO pin connected to the NeoPixels. 5#define PIXEL_COUNT 46 6 7int DIN = 12; 8int CS = 11; 9int CLK = 10; 10int count = 0; 11String number = ""; 12long a = random(50, 255); 13char Array[2]; 14byte one[8] = {0x18, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x3e}; 15byte two[8] = {0x1c, 0x22, 0x2, 0x2, 0x1c, 0x20, 0x20, 0x3e}; 16byte three[8] = {0x1c, 0x22, 0x2, 0x2, 0x1e, 0x2, 0x22, 0x1c}; 17byte four[8] = {0xc, 0x14, 0x24, 0x44, 0x7f, 0x4, 0x4, 0x4}; 18byte five[8] = {0x7e, 0x40, 0x40, 0x78, 0xe, 0x2, 0x2, 0x7c}; 19byte six[8] = {0x3c, 0x42, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x3c}; 20byte seven[8] = {0x7e, 0x2, 0x2, 0x4, 0x8, 0x10, 0x10, 0x10}; 21byte eight[8] = {0x3c, 0x42, 0x42, 0x3c, 0x66, 0x42, 0x42, 0x3c}; 22byte nine[8] = {0x3c, 0x42, 0x42, 0x42, 0x3e, 0x2, 0x42, 0x3c}; 23byte zero[8] = {0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c}; 24byte smile[8] = {0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C}; 25byte sad[8] = {0xff, 0x81, 0xa5, 0x81, 0x99, 0xa5, 0x81, 0xff}; 26 27bool smile_sw = false; 28 29LedControl lc = LedControl(DIN, CLK, CS, 2); // Pins: DIN,CLK,CS, amount of display connected 30Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); 31 32const int unFriend_pin = 4; // the number of the pushbutton pin 33const int addFriend_pin = 5; //the number of rings switch 34const int ledPin = 13; // the number of the LED pin 35int buttonState = 0; 36int ringState = 0; 37int oldState = 0; 38int oldRingState = 0; 39int showType = 0; 40 41void setup() { 42 Serial.begin(9600); 43 lc.shutdown(0, false); //The MAX72XX is in power-saving mode on startup 44 lc.setIntensity(0, 1); // Set the brightness to maximum value. scale is 0-15; 15 is the brightest 45 lc.clearDisplay(0); // and clear the display 46 47 lc.shutdown(1, false); //The MAX72XX is in power-saving mode on startup 48 lc.setIntensity(1, 1); // Set the brightness to maximum value. scale is 0-15; 15 is the brightest 49 lc.clearDisplay(1); // and clear the display 50 51 pinMode(ledPin, OUTPUT); 52 // initialize the pushbutton pin as an input: 53 pinMode(unFriend_pin, INPUT); 54 strip.begin(); 55 strip.show(); // Initialize all pixels to 'off' 56 57} 58 59void loop() { 60 61 buttonState = digitalRead(unFriend_pin); 62 ringState = digitalRead(addFriend_pin); 63 Serial.print("unfreinds x "); 64 Serial.print(buttonState + " add freinds x "); 65 Serial.println(addFriend_pin); 66 // Get current button state. 67 int newState = digitalRead(unFriend_pin); 68 int newRingState = digitalRead(addFriend_pin); 69 // Check if state changed from high to low (button press). 70 // if (newState >= 830 && oldState < 830) { //if analogRead 71 if (newState == HIGH && oldState == LOW) { 72 // Short delay to debounce button. 73 delay(20); 74 // Check if button is still low after debounce. 75 newState = digitalRead(unFriend_pin); 76 77 // if (newState >=830) { //if analogRead 78 if (newState == HIGH) { 79 showType = 10; 80 count--; 81 if (count <= 0) { 82 count = 0; 83 } 84 printFir_Byte(sad); 85 printSec_Byte(sad); 86 startShow(showType); 87 showNum(); 88 89 digitalWrite(ledPin, HIGH); 90 delay(250); 91 } 92 93 } 94 if (newRingState == HIGH && oldRingState == LOW) { 95 // Short delay to debounce button. 96 delay(20); 97 newRingState = digitalRead(addFriend_pin); 98 if (newRingState == HIGH) { 99 showType++; 100 count++; 101 if (showType > 9) { 102 showType = 0; 103 } 104 a = random(50, 255); 105 Serial.println(a); 106 printFir_Byte(smile); 107 printSec_Byte(smile); 108 startShow(showType); 109 showNum(); 110 111 digitalWrite(ledPin, HIGH); 112 delay(250); 113 } 114 115 } 116 117 // Set the last button state to the old state. 118 oldState = newState; 119 oldRingState = newRingState; 120 // lc.clearDisplay(0); 121 122 123} 124 125void startShow(int i) { 126 switch (i) { 127 case 1: theaterChase(strip.Color(a, 0, 0), 50); // Green 128 break; 129 case 2: theaterChase(strip.Color(0, a, 0), 50); // Blue 130 break; 131 case 3: theaterChase(strip.Color(0, 0, a), 50); // light blue 132 break; 133 case 4: theaterChase(strip.Color(0, 100, a), 50); // mint 134 break; 135 case 5: theaterChase(strip.Color(0, a, 100), 50);// warm yellow 136 break; 137 case 6: theaterChase(strip.Color(a, 100, 0), 50); // violet 138 break; 139 case 7: theaterChase(strip.Color( 100, a, 100), 50); // christmas green 140 break; 141 case 8: theaterChase(strip.Color(0, 50, a), 50); // dark red 142 break; 143 case 9: theaterChase(strip.Color(50, a, 0), 50); // super hero blue 144 break; 145 case 0: theaterChase(strip.Color(a, 0, 50), 50); // bright red 146 break; 147 case 10: theaterChase(strip.Color(255, 0, 0), 50); // super hero blue 148 break; 149 } 150 Serial.println(i); 151 strip.show(); 152} 153 154void showNum() { 155 char Array[2]; 156 if (count <= 99) { 157 dtostrf(count, 2, 0, Array); 158 } else { 159 count = 0; 160 dtostrf(count, 2, 0, Array); 161 } 162 Serial.print(Array[0]); 163 Serial.print(" , "); 164 Serial.println(Array[1]); 165 if (Array[0] == ' ') { 166 printFir_Byte(zero); 167 } else if (Array[0] == '1') { 168 printFir_Byte(one); 169 } else if (Array[0] == '2') { 170 printFir_Byte(two); 171 } else if (Array[0] == '3') { 172 printFir_Byte(three); 173 } else if (Array[0] == '4') { 174 printFir_Byte(four); 175 } else if (Array[0] == '5') { 176 printFir_Byte(five); 177 } else if (Array[0] == '6') { 178 printFir_Byte(six); 179 } else if (Array[0] == '7') { 180 printFir_Byte(seven); 181 } else if (Array[0] == '8') { 182 printFir_Byte(eight); 183 } else if (Array[0] == '9') { 184 printFir_Byte(nine); 185 } else if (Array[0] == '0') { 186 printFir_Byte(zero); 187 } 188 189 190 if (Array[1] == '1') { 191 printSec_Byte(one); 192 } else if (Array[1] == '2') { 193 printSec_Byte(two); 194 } else if (Array[1] == '3') { 195 printSec_Byte(three); 196 } else if (Array[1] == '4') { 197 printSec_Byte(four); 198 } else if (Array[1] == '5') { 199 printSec_Byte(five); 200 } else if (Array[1] == '6') { 201 printSec_Byte(six); 202 } else if (Array[1] == '7') { 203 printSec_Byte(seven); 204 } else if (Array[1] == '8') { 205 printSec_Byte(eight); 206 } else if (Array[1] == '9') { 207 printSec_Byte(nine); 208 } else if (Array[1] == '0') { 209 printSec_Byte(zero); 210 } 211 212} 213 214void printFir_Byte(byte fir_char[]) 215{ 216 int i = 0; 217 for (i = 0; i < 8; i++) 218 { 219 lc.setRow(0, i, fir_char[i]); 220 } 221} 222 223 224void printSec_Byte(byte sec_char []) 225{ 226 int i = 0; 227 for (i = 0; i < 8; i++) 228 { 229 lc.setRow(1, i, sec_char[i]); 230 } 231} 232 233//Theatre-style crawling lights. 234void theaterChase(uint32_t c, uint8_t wait) { 235 for (int j = 0; j < 10; j++) { //do 10 cycles of chasing 236 for (int q = 0; q < 3; q++) { 237 for (int i = 0; i < strip.numPixels(); i = i + 3) { 238 strip.setPixelColor(i + q, c); //turn every third pixel on 239 } 240 strip.show(); 241 delay(wait); 242 for (int i = 0; i < strip.numPixels(); i = i + 3) { 243 strip.setPixelColor(i + q, 0); //turn every third pixel off 244 245 } 246 } 247 } 248} 249 250// Input a value 0 to 255 to get a color value. 251// The colours are a transition r - g - b - back to r. 252uint32_t Wheel(byte WheelPos) { 253 WheelPos = 255 - WheelPos; 254 if (WheelPos < 85) { 255 return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); 256 } 257 if (WheelPos < 170) { 258 WheelPos -= 85; 259 return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 260 } 261 WheelPos -= 170; 262 return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 263} 264
MCP3008 (Processing)
processing
put this file in the same folder of the file name User Interface (Processing)
1import processing.io.SPI; 2 3// MCP3008 is a Analog-to-Digital converter using SPI 4// other than the MCP3001, this has 8 input channels 5// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf 6 7class MCP3008 extends SPI { 8 9 MCP3008(String dev) { 10 super(dev); 11 settings(500000, SPI.MSBFIRST, SPI.MODE0); 12 } 13 14 float getAnalog(int channel) { 15 if (channel < 0 || 7 < channel) { 16 System.err.println("The channel needs to be from 0 to 7"); 17 throw new IllegalArgumentException("Unexpected channel"); 18 } 19 byte[] out = { 0, 0, 0 }; 20 // encode the channel number in the first byte 21 out[0] = (byte)(0x18 | channel); 22 byte[] in = transfer(out); 23 int val = ((in[1] & 0x03) << 8) | (in[2] & 0xff); 24 // val is between 0 and 1023 25 return val/1023.0; 26 } 27}
For Raspberry Pi
python
Code for a FSR sensor (Following feature) to Adafruit Neopixel and 16x2 LCD, and a micro switch (Follower feature) to 16x2 LCD. Run with Rpi terminal
1#!/usr/bin/python 2# Example using a character LCD connected to a Raspberry Pi or BeagleBone Black. 3import time 4import Adafruit_CharLCD as LCD 5from ScrollLCD import* 6#-----# 7import Adafruit_GPIO.SPI as SPI 8import MCP3008 9#-----# 10from neopixel import * 11import argparse 12import signal 13import sys 14 15# Raspberry Pi pin configuration: 16# Note this might need to be changed to 21 for older revision Pi's. 17lcd_rs = 27 #26 18lcd_en = 22 #19 19lcd_d4 = 25 #13 20lcd_d5 = 24 #6 21lcd_d6 = 23 #5 22lcd_d7 = 17 #11 23lcd_backlight = 4 24 25# Define LCD column and row size for 16x2 LCD. 26lcd_columns = 16 27lcd_rows = 2 28#Hardware SPI configuration: 29SPI_PORT = 0 30SPI_DEVICE = 0 31mcp = MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE)) 32 33# Initialize the LCD using the pins above. 34lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, 35 lcd_columns, lcd_rows, lcd_backlight) 36 37def signal_handler(signal, frame): 38 colorWipe(strip, Color(0,0,0)) 39 sys.exit(0) 40 41def opt_parse(): 42 parser = argparse.ArgumentParser() 43 parser.add_argument('-c', action='store_true', help='clear the display on exit') 44 args = parser.parse_args() 45 if args.c: 46 signal.signal(signal.SIGINT, signal_handler) 47 48def wheel(pos): 49 """Generate rainbow colors across 0-255 positions.""" 50 if pos < 85: 51 return Color(pos * 3, 255 - pos * 3, 0) 52 elif pos < 170: 53 pos -= 85 54 return Color(255 - pos * 3, 0, pos * 3) 55 else: 56 pos -= 170 57 return Color(0, pos * 3, 255 - pos * 3) 58 59# LED strip configuration: 60LED_COUNT = 48 # Number of LED pixels. 61LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!). 62#LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0). 63LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 64LED_DMA = 10 # DMA channel to use for generating signal (try 10) 65LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest 66LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 67LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53 68LED_STRIP = ws.WS2811_STRIP_GRB # Strip type and colour ordering 69#LED_STRIP = ws.WS2812_STRIP 70 71LED_i =0 72light = True 73aftertouch=False 74count=0 75aftertap=False 76following=0 77 78def tuang(strip,wait_ms=20,iterations=1): 79 """Draw 1 pixel at a time.""" 80 for j in range(1): 81 print(j) 82 for i in range(strip.numPixels()): 83 strip.setPixelColor(strip.numPixels()-i, wheel((int(i * 256 / strip.numPixels())+j) & 255)) 84 strip.show() 85 time.sleep(0.05) 86 # strip.show() 87 # time.sleep(0.05) 88 for i in range(strip.numPixels()): 89 strip.setPixelColor(strip.numPixels()-i, 0) 90 strip.show() 91 time.sleep(wait_ms/1000.0) 92 LED_i = i 93 print(LED_i) 94 95#text="Hi! I'm Tuang. I do cool things." 96#breaker=False 97#n = 16 98#rows = [text[i:i+n] for i in range(0, len(text), n)] 99#n_rows = len(rows) 100#scroll(lcd,text,False,False,1) 101 102print('Reading MCP3008 values, press Ctrl-C to quit...') 103# Print nice channel column headers. 104print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*range(8))) 105print('-' * 57) 106 107# Main program logic follows: 108if __name__ == '__main__': 109 #Process arguments 110 opt_parse() 111 # Create NeoPixel object with appropriate configuration. 112 strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP) 113 #Intialize the library (must be called once before other functions) 114 strip.begin() 115 while True: 116 #Read all the ADC channel values in a list. 117 values = [0]*8 118 for i in range(8): 119 #The read_adc function will get the value of the specified channel (0-7). 120 values[i] = mcp.read_adc(i) 121 #Pause for half a second. 122 print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values)) 123 time.sleep(0.2) 124 #lcd.clear() 125 if values[1]>800: 126 if aftertouch: 127 count=count+1 128 lcd.clear() 129 lcd.message('following: '+str(following)) 130 lcd.message('\ 131followers: '+str(count)+' ') 132 #scroll(lcd,text,count,breaker,False,False,0) 133 aftertouch=False 134 else: 135 aftertouch=True 136 #scroll(lcd,text,count,breaker,False,False,0) 137 lcd.message('following: '+str(following)) 138 lcd.message('\ 139followers: '+str(count)+' ') 140 if values[2]>600: 141 if aftertap: 142 #print('sholder tap!') 143 following=following+1 144 lcd.clear() 145 lcd.message('following: '+str(following)) 146 lcd.message('\ 147followers: '+str(count)+' ') 148 #scroll(lcd,text,count,breaker,False,False,0) 149 aftertap=False 150 else: 151 aftertap=True 152 #scroll(lcd,text,count,breaker,False,False,0) 153 lcd.message('following: '+str(following)) 154 lcd.message('\ 155followers: '+str(count)+' ') 156 if values[0]>600: 157 print("Hi5!") 158 light=True 159 else: 160 light=False 161 if light: 162 tuang(strip) 163 light=False 164 else: 165 for i in range(strip.numPixels()): 166 strip.setPixelColor(i,0) 167 strip.show() 168 #for x in range(n_rows): 169 # lcd.home() 170 # lcd.clear() 171 # nxt = x + 1 172 # lcd.message(rows[x]) 173 # lcd.message('\ 174Follower:'+str(count)+' ') #space 3 times to avoid any char on the first row drops 175 # if nxt == n_rows: 176 # sleep(2) 177 #break 178 #else: 179 # lcd.message(rows[nxt]) 180 # sleep(1) 181
User Interface (Processing)
processing
Save this file on Raspberry Pi, and run this file using Processing for Raspberry Pi. You will need to export font "ProcessingSanPro-Semibold-[SIZE].vlw" from the Processing program and put in the folder "data". Export this font in 3 sizes --48,70,250.
1import processing.io.*; 2MCP3008 adc; 3PFont font; 4int count=0; 5boolean readytoHit=true; 6boolean debugging =false; 7int scale =2; 8color[] colors; 9float a, b; 10int startTime; 11int totalTime=3000; 12int currentTime; 13boolean glitch=false; 14int smile=0, laugh=0, cry=0, kiss=0, confused=0; 15void settings() { 16 if (debugging) { 17 size(800/scale, 480/scale); 18 } else { 19 fullScreen(0); 20 } 21 colors = new color [3]; 22 colors[0] = color(255, 0, 0); 23 colors[1] = color(0, 255, 0); 24 colors[2] = color(0, 0, 255); 25} 26 27void setup() { 28 //printArray(SPI.list()); 29 adc = new MCP3008(SPI.list()[0]); 30 font = loadFont("ProcessingSansPro-Semibold-250.vlw"); 31 textFont(font, 250); 32} 33 34void draw() { 35 if (glitch) { 36 blendMode(BLEND); 37 a = random(100); 38 b = random(100, 255); 39 background(255); 40 fill(b, a, 0); 41 } else { 42 background(255, 0, 0); 43 fill(255); 44 } 45 textAlign(CENTER, CENTER); 46 //text("LIKES: "+count, width/2, height/2); 47 countHit(); 48 graphic(); 49 timer(); 50 println(adc.getAnalog(0)); 51} 52void countHit() { 53 if (adc.getAnalog(0)<0.75 && adc.getAnalog(0)>0.0) { 54 readytoHit=true; 55 } 56 57 if (readytoHit) { 58 if (adc.getAnalog(0)>=0.75) { 59 count++; 60 glitch=true; 61 readytoHit=false; 62 } 63 } 64 65 println("hit: "+readytoHit); 66 //println("glitch: "+glitch); 67 //println("FSR chan 0: "+adc.getAnalog(0)); 68 delay(200); 69} 70 71void graphic() { 72 //ProcessingSansPro-Semibold-48.vlw 73 pushMatrix(); 74 translate(0, height); 75 rotate(radians(-90)); 76 textSize(50); 77 text("LIKE ME!?", height/2, 50); 78 textSize(30); 79 text("my likes today:", height/2, 100); 80 textSize(200); 81 text(count, height/2, width/2-50); 82 textSize(35); 83 text(" X ", height-60, 150); 84 textSize(26); 85 text("--------------------------------------------", height/2, width-340); 86 text("how?", height/2, width-300); 87 textAlign(LEFT); 88 text(" ^_^ ", 50, width-250); 89 text(" ^D^ ", 50, width-200); 90 text(" T_T ", 50, width-150); 91 text(" v3v ", 50, width-100); 92 text(" *c* ", 50, width-50); 93 noFill(); 94 stroke(255, 255, 255); 95 strokeWeight(3); 96 ellipse(81, width-260, 60, 45); 97 ellipse(81, width-210, 60, 45); 98 ellipse(81, width-160, 60, 45); 99 ellipse(81, width-110, 60, 45); 100 ellipse(81, width-60, 60, 45); 101 ellipse(height-60, 150, 80, 65); 102 noStroke(); 103 textAlign(RIGHT); 104 text(smile, height-50, width-250); 105 text(laugh, height-50, width-200); 106 text(cry, height-50, width-150); 107 text(kiss, height-50, width-100); 108 text(confused, height-50, width-50); 109 textAlign(CENTER); 110 if (glitch) { 111 blendMode(EXCLUSION); 112 textSize(50); 113 text("i got a like now", (height/2)-5, width/2-50); 114 textSize(30); 115 text("my likes today:", height/2, 100); 116 textSize(200); 117 text(count, height/2, (width/2)-3); 118 textSize(52); 119 text("LIKE ME!", (height/2), width-250); 120 text("LIKE ME!", (height/2), width-200); 121 text("LIKE ME!", (height/2), width-150); 122 text("LIKE ME!", (height/2), width-100); 123 text("LIKE ME!", (height/2), width-50); 124 } else { 125 blendMode(BLEND); 126 } 127 popMatrix(); 128} 129 130void timer() { 131 currentTime=millis()-startTime; 132 133 if (currentTime>totalTime) { 134 glitch = false; 135 fill(255); 136 startTime = millis(); 137 //println("*******restart*********"); 138 } 139 // println("time: "+ round(currentTime)); 140} 141int i=0; 142void mousePressed() { 143 /*text("(^_^)",50,width-250); 144 text("(^D^)",50,width-200); 145 text("(T_T)",50,width-150); 146 text("(V3V)",50,width-100); 147 text("(*c*)",50,width-50);*/ 148 if (mouseY<425 && mouseY>363) { 149 if (mouseX >527 && mouseX<557) { 150 smile++; 151 count++; 152 glitch=true; 153 } else if (mouseX >577 && mouseX<607) { 154 laugh++; 155 count++; 156 glitch=true; 157 } else if (mouseX >627 && mouseX<657) { 158 cry++; 159 count++; 160 glitch=true; 161 } else if (mouseX >677 && mouseX<707) { 162 kiss++; 163 count++; 164 glitch=true; 165 } else if (mouseX >726 && mouseX<756) { 166 confused++; 167 count++; 168 glitch=true; 169 } 170 } else if (mouseY < height-50 && mouseY>0) { 171 if (mouseX >125&&mouseX<175) { 172 count--; 173 println("unlike"); 174 } 175 } 176 //i++; 177 //println(i+" x: "+mouseX+" y: "+mouseY); 178}
For Arduino
arduino
The file to be complied on Arduino, controlling the "Add Friends" and "Unfriends" features. Input sensors are contacting (conductive) rings, and a push switch. Output: Adafruit Neopixel and two 8x8 DotMatrixs
1 #include <LedControl.h> 2#include <Adafruit_NeoPixel.h> 3 4#define 5 PIXEL_PIN 6 // Digital IO pin connected to the NeoPixels. 6#define PIXEL_COUNT 7 46 8 9int DIN = 12; 10int CS = 11; 11int CLK = 10; 12int count = 0; 13String 14 number = ""; 15long a = random(50, 255); 16char Array[2]; 17byte one[8] = {0x18, 18 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x3e}; 19byte two[8] = {0x1c, 0x22, 0x2, 0x2, 20 0x1c, 0x20, 0x20, 0x3e}; 21byte three[8] = {0x1c, 0x22, 0x2, 0x2, 0x1e, 0x2, 22 0x22, 0x1c}; 23byte four[8] = {0xc, 0x14, 0x24, 0x44, 0x7f, 0x4, 0x4, 0x4}; 24byte 25 five[8] = {0x7e, 0x40, 0x40, 0x78, 0xe, 0x2, 0x2, 0x7c}; 26byte six[8] = {0x3c, 27 0x42, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x3c}; 28byte seven[8] = {0x7e, 0x2, 0x2, 29 0x4, 0x8, 0x10, 0x10, 0x10}; 30byte eight[8] = {0x3c, 0x42, 0x42, 0x3c, 0x66, 31 0x42, 0x42, 0x3c}; 32byte nine[8] = {0x3c, 0x42, 0x42, 0x42, 0x3e, 0x2, 0x42, 33 0x3c}; 34byte zero[8] = {0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c}; 35byte 36 smile[8] = {0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C}; 37byte sad[8] = 38 {0xff, 0x81, 0xa5, 0x81, 0x99, 0xa5, 0x81, 0xff}; 39 40bool smile_sw = false; 41 42LedControl 43 lc = LedControl(DIN, CLK, CS, 2); // Pins: DIN,CLK,CS, amount of display connected 44Adafruit_NeoPixel 45 strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); 46 47const 48 int unFriend_pin = 4; // the number of the pushbutton pin 49const int addFriend_pin 50 = 5; //the number of rings switch 51const int ledPin = 13; // the number 52 of the LED pin 53int buttonState = 0; 54int ringState = 0; 55int oldState = 0; 56int 57 oldRingState = 0; 58int showType = 0; 59 60void setup() { 61 Serial.begin(9600); 62 63 lc.shutdown(0, false); //The MAX72XX is in power-saving mode on startup 64 65 lc.setIntensity(0, 1); // Set the brightness to maximum value. scale is 0-15; 66 15 is the brightest 67 lc.clearDisplay(0); // and clear the display 68 69 70 lc.shutdown(1, false); //The MAX72XX is in power-saving mode on startup 71 72 lc.setIntensity(1, 1); // Set the brightness to maximum value. scale is 0-15; 73 15 is the brightest 74 lc.clearDisplay(1); // and clear the display 75 76 77 pinMode(ledPin, OUTPUT); 78 // initialize the pushbutton pin as an input: 79 80 pinMode(unFriend_pin, INPUT); 81 strip.begin(); 82 strip.show(); // Initialize 83 all pixels to 'off' 84 85} 86 87void loop() { 88 89 buttonState = digitalRead(unFriend_pin); 90 91 ringState = digitalRead(addFriend_pin); 92 Serial.print("unfreinds x "); 93 94 Serial.print(buttonState + " add freinds x "); 95 Serial.println(addFriend_pin); 96 97 // Get current button state. 98 int newState = digitalRead(unFriend_pin); 99 100 int newRingState = digitalRead(addFriend_pin); 101 // Check if state changed 102 from high to low (button press). 103 // if (newState >= 830 && oldState < 830) 104 { //if analogRead 105 if (newState == HIGH && oldState == LOW) { 106 // Short 107 delay to debounce button. 108 delay(20); 109 // Check if button is still low 110 after debounce. 111 newState = digitalRead(unFriend_pin); 112 113 // if 114 (newState >=830) { //if analogRead 115 if (newState == HIGH) { 116 showType 117 = 10; 118 count--; 119 if (count <= 0) { 120 count = 0; 121 } 122 123 printFir_Byte(sad); 124 printSec_Byte(sad); 125 startShow(showType); 126 127 showNum(); 128 129 digitalWrite(ledPin, HIGH); 130 delay(250); 131 132 } 133 134 } 135 if (newRingState == HIGH && oldRingState == LOW) { 136 // 137 Short delay to debounce button. 138 delay(20); 139 newRingState = digitalRead(addFriend_pin); 140 141 if (newRingState == HIGH) { 142 showType++; 143 count++; 144 if 145 (showType > 9) { 146 showType = 0; 147 } 148 a = random(50, 255); 149 150 Serial.println(a); 151 printFir_Byte(smile); 152 printSec_Byte(smile); 153 154 startShow(showType); 155 showNum(); 156 157 digitalWrite(ledPin, 158 HIGH); 159 delay(250); 160 } 161 162 } 163 164 // Set the last button 165 state to the old state. 166 oldState = newState; 167 oldRingState = newRingState; 168 169 // lc.clearDisplay(0); 170 171 172} 173 174void startShow(int i) { 175 switch 176 (i) { 177 case 1: theaterChase(strip.Color(a, 0, 0), 50); // Green 178 break; 179 180 case 2: theaterChase(strip.Color(0, a, 0), 50); // Blue 181 break; 182 183 case 3: theaterChase(strip.Color(0, 0, a), 50); // light blue 184 break; 185 186 case 4: theaterChase(strip.Color(0, 100, a), 50); // mint 187 break; 188 189 case 5: theaterChase(strip.Color(0, a, 100), 50);// warm yellow 190 break; 191 192 case 6: theaterChase(strip.Color(a, 100, 0), 50); // violet 193 break; 194 195 case 7: theaterChase(strip.Color( 100, a, 100), 50); // christmas green 196 197 break; 198 case 8: theaterChase(strip.Color(0, 50, a), 50); // dark 199 red 200 break; 201 case 9: theaterChase(strip.Color(50, a, 0), 50); 202 // super hero blue 203 break; 204 case 0: theaterChase(strip.Color(a, 0, 205 50), 50); // bright red 206 break; 207 case 10: theaterChase(strip.Color(255, 208 0, 0), 50); // super hero blue 209 break; 210 } 211 Serial.println(i); 212 213 strip.show(); 214} 215 216void showNum() { 217 char Array[2]; 218 if (count 219 <= 99) { 220 dtostrf(count, 2, 0, Array); 221 } else { 222 count = 0; 223 224 dtostrf(count, 2, 0, Array); 225 } 226 Serial.print(Array[0]); 227 Serial.print(" 228 , "); 229 Serial.println(Array[1]); 230 if (Array[0] == ' ') { 231 printFir_Byte(zero); 232 233 } else if (Array[0] == '1') { 234 printFir_Byte(one); 235 } else if (Array[0] 236 == '2') { 237 printFir_Byte(two); 238 } else if (Array[0] == '3') { 239 printFir_Byte(three); 240 241 } else if (Array[0] == '4') { 242 printFir_Byte(four); 243 } else if (Array[0] 244 == '5') { 245 printFir_Byte(five); 246 } else if (Array[0] == '6') { 247 printFir_Byte(six); 248 249 } else if (Array[0] == '7') { 250 printFir_Byte(seven); 251 } else if (Array[0] 252 == '8') { 253 printFir_Byte(eight); 254 } else if (Array[0] == '9') { 255 printFir_Byte(nine); 256 257 } else if (Array[0] == '0') { 258 printFir_Byte(zero); 259 } 260 261 262 if 263 (Array[1] == '1') { 264 printSec_Byte(one); 265 } else if (Array[1] == '2') 266 { 267 printSec_Byte(two); 268 } else if (Array[1] == '3') { 269 printSec_Byte(three); 270 271 } else if (Array[1] == '4') { 272 printSec_Byte(four); 273 } else if (Array[1] 274 == '5') { 275 printSec_Byte(five); 276 } else if (Array[1] == '6') { 277 printSec_Byte(six); 278 279 } else if (Array[1] == '7') { 280 printSec_Byte(seven); 281 } else if (Array[1] 282 == '8') { 283 printSec_Byte(eight); 284 } else if (Array[1] == '9') { 285 printSec_Byte(nine); 286 287 } else if (Array[1] == '0') { 288 printSec_Byte(zero); 289 } 290 291} 292 293void 294 printFir_Byte(byte fir_char[]) 295{ 296 int i = 0; 297 for (i = 0; i < 8; i++) 298 299 { 300 lc.setRow(0, i, fir_char[i]); 301 } 302} 303 304 305void printSec_Byte(byte 306 sec_char []) 307{ 308 int i = 0; 309 for (i = 0; i < 8; i++) 310 { 311 lc.setRow(1, 312 i, sec_char[i]); 313 } 314} 315 316//Theatre-style crawling lights. 317void theaterChase(uint32_t 318 c, uint8_t wait) { 319 for (int j = 0; j < 10; j++) { //do 10 cycles of chasing 320 321 for (int q = 0; q < 3; q++) { 322 for (int i = 0; i < strip.numPixels(); 323 i = i + 3) { 324 strip.setPixelColor(i + q, c); //turn every third pixel 325 on 326 } 327 strip.show(); 328 delay(wait); 329 for (int i = 330 0; i < strip.numPixels(); i = i + 3) { 331 strip.setPixelColor(i + q, 0); 332 //turn every third pixel off 333 334 } 335 } 336 } 337} 338 339// 340 Input a value 0 to 255 to get a color value. 341// The colours are a transition 342 r - g - b - back to r. 343uint32_t Wheel(byte WheelPos) { 344 WheelPos = 255 - 345 WheelPos; 346 if (WheelPos < 85) { 347 return strip.Color(255 - WheelPos * 3, 348 0, WheelPos * 3); 349 } 350 if (WheelPos < 170) { 351 WheelPos -= 85; 352 return 353 strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 354 } 355 WheelPos -= 170; 356 357 return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 358} 359
MCP3008 (Processing)
processing
put this file in the same folder of the file name User Interface (Processing)
1import processing.io.SPI; 2 3// MCP3008 is a Analog-to-Digital converter using SPI 4// other than the MCP3001, this has 8 input channels 5// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf 6 7class MCP3008 extends SPI { 8 9 MCP3008(String dev) { 10 super(dev); 11 settings(500000, SPI.MSBFIRST, SPI.MODE0); 12 } 13 14 float getAnalog(int channel) { 15 if (channel < 0 || 7 < channel) { 16 System.err.println("The channel needs to be from 0 to 7"); 17 throw new IllegalArgumentException("Unexpected channel"); 18 } 19 byte[] out = { 0, 0, 0 }; 20 // encode the channel number in the first byte 21 out[0] = (byte)(0x18 | channel); 22 byte[] in = transfer(out); 23 int val = ((in[1] & 0x03) << 8) | (in[2] & 0xff); 24 // val is between 0 and 1023 25 return val/1023.0; 26 } 27}
For Raspberry Pi
python
Code for a FSR sensor (Following feature) to Adafruit Neopixel and 16x2 LCD, and a micro switch (Follower feature) to 16x2 LCD. Run with Rpi terminal
1#!/usr/bin/python 2# Example using a character LCD connected to a Raspberry Pi or BeagleBone Black. 3import time 4import Adafruit_CharLCD as LCD 5from ScrollLCD import* 6#-----# 7import Adafruit_GPIO.SPI as SPI 8import MCP3008 9#-----# 10from neopixel import * 11import argparse 12import signal 13import sys 14 15# Raspberry Pi pin configuration: 16# Note this might need to be changed to 21 for older revision Pi's. 17lcd_rs = 27 #26 18lcd_en = 22 #19 19lcd_d4 = 25 #13 20lcd_d5 = 24 #6 21lcd_d6 = 23 #5 22lcd_d7 = 17 #11 23lcd_backlight = 4 24 25# Define LCD column and row size for 16x2 LCD. 26lcd_columns = 16 27lcd_rows = 2 28#Hardware SPI configuration: 29SPI_PORT = 0 30SPI_DEVICE = 0 31mcp = MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE)) 32 33# Initialize the LCD using the pins above. 34lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, 35 lcd_columns, lcd_rows, lcd_backlight) 36 37def signal_handler(signal, frame): 38 colorWipe(strip, Color(0,0,0)) 39 sys.exit(0) 40 41def opt_parse(): 42 parser = argparse.ArgumentParser() 43 parser.add_argument('-c', action='store_true', help='clear the display on exit') 44 args = parser.parse_args() 45 if args.c: 46 signal.signal(signal.SIGINT, signal_handler) 47 48def wheel(pos): 49 """Generate rainbow colors across 0-255 positions.""" 50 if pos < 85: 51 return Color(pos * 3, 255 - pos * 3, 0) 52 elif pos < 170: 53 pos -= 85 54 return Color(255 - pos * 3, 0, pos * 3) 55 else: 56 pos -= 170 57 return Color(0, pos * 3, 255 - pos * 3) 58 59# LED strip configuration: 60LED_COUNT = 48 # Number of LED pixels. 61LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!). 62#LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0). 63LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 64LED_DMA = 10 # DMA channel to use for generating signal (try 10) 65LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest 66LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 67LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53 68LED_STRIP = ws.WS2811_STRIP_GRB # Strip type and colour ordering 69#LED_STRIP = ws.WS2812_STRIP 70 71LED_i =0 72light = True 73aftertouch=False 74count=0 75aftertap=False 76following=0 77 78def tuang(strip,wait_ms=20,iterations=1): 79 """Draw 1 pixel at a time.""" 80 for j in range(1): 81 print(j) 82 for i in range(strip.numPixels()): 83 strip.setPixelColor(strip.numPixels()-i, wheel((int(i * 256 / strip.numPixels())+j) & 255)) 84 strip.show() 85 time.sleep(0.05) 86 # strip.show() 87 # time.sleep(0.05) 88 for i in range(strip.numPixels()): 89 strip.setPixelColor(strip.numPixels()-i, 0) 90 strip.show() 91 time.sleep(wait_ms/1000.0) 92 LED_i = i 93 print(LED_i) 94 95#text="Hi! I'm Tuang. I do cool things." 96#breaker=False 97#n = 16 98#rows = [text[i:i+n] for i in range(0, len(text), n)] 99#n_rows = len(rows) 100#scroll(lcd,text,False,False,1) 101 102print('Reading MCP3008 values, press Ctrl-C to quit...') 103# Print nice channel column headers. 104print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*range(8))) 105print('-' * 57) 106 107# Main program logic follows: 108if __name__ == '__main__': 109 #Process arguments 110 opt_parse() 111 # Create NeoPixel object with appropriate configuration. 112 strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP) 113 #Intialize the library (must be called once before other functions) 114 strip.begin() 115 while True: 116 #Read all the ADC channel values in a list. 117 values = [0]*8 118 for i in range(8): 119 #The read_adc function will get the value of the specified channel (0-7). 120 values[i] = mcp.read_adc(i) 121 #Pause for half a second. 122 print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values)) 123 time.sleep(0.2) 124 #lcd.clear() 125 if values[1]>800: 126 if aftertouch: 127 count=count+1 128 lcd.clear() 129 lcd.message('following: '+str(following)) 130 lcd.message('\ 131followers: '+str(count)+' ') 132 #scroll(lcd,text,count,breaker,False,False,0) 133 aftertouch=False 134 else: 135 aftertouch=True 136 #scroll(lcd,text,count,breaker,False,False,0) 137 lcd.message('following: '+str(following)) 138 lcd.message('\ 139followers: '+str(count)+' ') 140 if values[2]>600: 141 if aftertap: 142 #print('sholder tap!') 143 following=following+1 144 lcd.clear() 145 lcd.message('following: '+str(following)) 146 lcd.message('\ 147followers: '+str(count)+' ') 148 #scroll(lcd,text,count,breaker,False,False,0) 149 aftertap=False 150 else: 151 aftertap=True 152 #scroll(lcd,text,count,breaker,False,False,0) 153 lcd.message('following: '+str(following)) 154 lcd.message('\ 155followers: '+str(count)+' ') 156 if values[0]>600: 157 print("Hi5!") 158 light=True 159 else: 160 light=False 161 if light: 162 tuang(strip) 163 light=False 164 else: 165 for i in range(strip.numPixels()): 166 strip.setPixelColor(i,0) 167 strip.show() 168 #for x in range(n_rows): 169 # lcd.home() 170 # lcd.clear() 171 # nxt = x + 1 172 # lcd.message(rows[x]) 173 # lcd.message('\ 174Follower:'+str(count)+' ') #space 3 times to avoid any char on the first row drops 175 # if nxt == n_rows: 176 # sleep(2) 177 #break 178 #else: 179 # lcd.message(rows[nxt]) 180 # sleep(1) 181
User Interface (Processing)
processing
Save this file on Raspberry Pi, and run this file using Processing for Raspberry Pi. You will need to export font "ProcessingSanPro-Semibold-[SIZE].vlw" from the Processing program and put in the folder "data". Export this font in 3 sizes --48,70,250.
1import processing.io.*; 2MCP3008 adc; 3PFont font; 4int count=0; 5boolean readytoHit=true; 6boolean debugging =false; 7int scale =2; 8color[] colors; 9float a, b; 10int startTime; 11int totalTime=3000; 12int currentTime; 13boolean glitch=false; 14int smile=0, laugh=0, cry=0, kiss=0, confused=0; 15void settings() { 16 if (debugging) { 17 size(800/scale, 480/scale); 18 } else { 19 fullScreen(0); 20 } 21 colors = new color [3]; 22 colors[0] = color(255, 0, 0); 23 colors[1] = color(0, 255, 0); 24 colors[2] = color(0, 0, 255); 25} 26 27void setup() { 28 //printArray(SPI.list()); 29 adc = new MCP3008(SPI.list()[0]); 30 font = loadFont("ProcessingSansPro-Semibold-250.vlw"); 31 textFont(font, 250); 32} 33 34void draw() { 35 if (glitch) { 36 blendMode(BLEND); 37 a = random(100); 38 b = random(100, 255); 39 background(255); 40 fill(b, a, 0); 41 } else { 42 background(255, 0, 0); 43 fill(255); 44 } 45 textAlign(CENTER, CENTER); 46 //text("LIKES: "+count, width/2, height/2); 47 countHit(); 48 graphic(); 49 timer(); 50 println(adc.getAnalog(0)); 51} 52void countHit() { 53 if (adc.getAnalog(0)<0.75 && adc.getAnalog(0)>0.0) { 54 readytoHit=true; 55 } 56 57 if (readytoHit) { 58 if (adc.getAnalog(0)>=0.75) { 59 count++; 60 glitch=true; 61 readytoHit=false; 62 } 63 } 64 65 println("hit: "+readytoHit); 66 //println("glitch: "+glitch); 67 //println("FSR chan 0: "+adc.getAnalog(0)); 68 delay(200); 69} 70 71void graphic() { 72 //ProcessingSansPro-Semibold-48.vlw 73 pushMatrix(); 74 translate(0, height); 75 rotate(radians(-90)); 76 textSize(50); 77 text("LIKE ME!?", height/2, 50); 78 textSize(30); 79 text("my likes today:", height/2, 100); 80 textSize(200); 81 text(count, height/2, width/2-50); 82 textSize(35); 83 text(" X ", height-60, 150); 84 textSize(26); 85 text("--------------------------------------------", height/2, width-340); 86 text("how?", height/2, width-300); 87 textAlign(LEFT); 88 text(" ^_^ ", 50, width-250); 89 text(" ^D^ ", 50, width-200); 90 text(" T_T ", 50, width-150); 91 text(" v3v ", 50, width-100); 92 text(" *c* ", 50, width-50); 93 noFill(); 94 stroke(255, 255, 255); 95 strokeWeight(3); 96 ellipse(81, width-260, 60, 45); 97 ellipse(81, width-210, 60, 45); 98 ellipse(81, width-160, 60, 45); 99 ellipse(81, width-110, 60, 45); 100 ellipse(81, width-60, 60, 45); 101 ellipse(height-60, 150, 80, 65); 102 noStroke(); 103 textAlign(RIGHT); 104 text(smile, height-50, width-250); 105 text(laugh, height-50, width-200); 106 text(cry, height-50, width-150); 107 text(kiss, height-50, width-100); 108 text(confused, height-50, width-50); 109 textAlign(CENTER); 110 if (glitch) { 111 blendMode(EXCLUSION); 112 textSize(50); 113 text("i got a like now", (height/2)-5, width/2-50); 114 textSize(30); 115 text("my likes today:", height/2, 100); 116 textSize(200); 117 text(count, height/2, (width/2)-3); 118 textSize(52); 119 text("LIKE ME!", (height/2), width-250); 120 text("LIKE ME!", (height/2), width-200); 121 text("LIKE ME!", (height/2), width-150); 122 text("LIKE ME!", (height/2), width-100); 123 text("LIKE ME!", (height/2), width-50); 124 } else { 125 blendMode(BLEND); 126 } 127 popMatrix(); 128} 129 130void timer() { 131 currentTime=millis()-startTime; 132 133 if (currentTime>totalTime) { 134 glitch = false; 135 fill(255); 136 startTime = millis(); 137 //println("*******restart*********"); 138 } 139 // println("time: "+ round(currentTime)); 140} 141int i=0; 142void mousePressed() { 143 /*text("(^_^)",50,width-250); 144 text("(^D^)",50,width-200); 145 text("(T_T)",50,width-150); 146 text("(V3V)",50,width-100); 147 text("(*c*)",50,width-50);*/ 148 if (mouseY<425 && mouseY>363) { 149 if (mouseX >527 && mouseX<557) { 150 smile++; 151 count++; 152 glitch=true; 153 } else if (mouseX >577 && mouseX<607) { 154 laugh++; 155 count++; 156 glitch=true; 157 } else if (mouseX >627 && mouseX<657) { 158 cry++; 159 count++; 160 glitch=true; 161 } else if (mouseX >677 && mouseX<707) { 162 kiss++; 163 count++; 164 glitch=true; 165 } else if (mouseX >726 && mouseX<756) { 166 confused++; 167 count++; 168 glitch=true; 169 } 170 } else if (mouseY < height-50 && mouseY>0) { 171 if (mouseX >125&&mouseX<175) { 172 count--; 173 println("unlike"); 174 } 175 } 176 //i++; 177 //println(i+" x: "+mouseX+" y: "+mouseY); 178}
Downloadable files
Visual Diagram for connecting parts
It's a Fritzing flie to see all parts using in this program. But the PDB board does not really work with aesthetic design so for printing on CNC machine use a file called Z3_pcb only.
Visual Diagram for connecting parts
Visual Diagram for connecting parts
It's a Fritzing flie to see all parts using in this program. But the PDB board does not really work with aesthetic design so for printing on CNC machine use a file called Z3_pcb only.
Visual Diagram for connecting parts
For cutting PCB
This file is exactly what the designed pcb on the jacket but the visual plan on Fritzing does not show all parts.. Use this with your machine.
For cutting PCB
Comments
Only logged in users can leave comments
tuangt
0 Followers
•0 Projects
Table of contents
Intro
6
0