Category Archives: Week 9

LOLshield–wave

I made a pattern about wave with the LOL shield. It’s lucky that all the leds worked perfectly.

Here is the code:

/*
Basic LoL Shield Test

Writen for the LoL Shield, designed by Jimmie Rodgers:

http://jimmieprodgers.com/kits/lolshield/

This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/

Created by Jimmie Rodgers on 12/30/2009.
Adapted from: http://www.arduino.cc/playground/Code/BitMath

History:
December 30, 2009 – V1.0 first version written at 26C3/Berlin

This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <avr/pgmspace.h> //AVR library for writing to ROM
#include <Charliplexing.h> //Imports the library, which needs to be
//Initialized in setup.

//Sets the time each frame is shown (milliseconds)
const unsigned int blinkdelay = 1000 / 50;

/*
The BitMap array is what contains the frame data. Each line is one full frame.
Since each number is 16 bits, we can easily fit all 14 LEDs per row into it.
The number is calculated by adding up all the bits, starting with lowest on
the left of each row. 18000 was chosen as the kill number, so make sure that
is at the end of the matrix, or the program will continue to read into memory.

Here PROGMEM is called, which stores the array into ROM, which leaves us
with our RAM. You cannot change the array during run-time, only when you
upload to the Arduino. You will need to pull it out of ROM, which is covered
below. If you want it to stay in RAM, just delete PROGMEM
*/
PROGMEM const uint16_t BitMap[][9] = {
//Diaganal swipe across the screen
{0,0,514,1285,10376,4176,32,0,0},
{0,0,257,8834,5188,2088,16,0,0},
{0,0,8320,4417,2594,1044,8,0,0},
{0,0,4160,10400,1297,522,4,0,0},
{0,0,2080,5200,8840,261,2,0,0},
{0,0,1040,2600,4420,8322,1,0,0},
{0,0,520,1300,2210,4161,8192,0,0},
{0,0,260,650,1105,10272,4096,0,0},
{0,0,130,325,8744,5136,2048,0,0},
{0,0,65,8354,4372,2568,1024,0,0},
{0,0,8224,4177,2186,1284,512,0,0},
{0,0,4112,10280,1093,642,256,0,0},
{0,0,2056,5140,8738,321,128,0,0},
{0,0,1028,2570,4369,8352,64,0,0},
{18000}
};

void setup() {
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE); //Initializes the screen
}
void loop() {
for (uint8_t gray = 1; gray < SHADES; gray++)
DisplayBitMap(gray); //Displays the bitmap
}

void DisplayBitMap(uint8_t grayscale)
{
boolean run=true; //While this is true, the screen updates
byte frame = 0; //Frame counter
byte line = 0; //Row counter
unsigned long data; //Temporary storage of the row data
unsigned long start = 0;

while(run == true) {

for(line = 0; line < 9; line++) {

//Here we fetch data from program memory with a pointer.
data = pgm_read_word_near (&BitMap[frame][line]);

//Kills the loop if the kill number is found
if (data==18000){
run=false;
}

//This is where the bit-shifting happens to pull out
//each LED from a row. If the bit is 1, then the LED
//is turned on, otherwise it is turned off.
else for (byte led=0; led<14; ++led) {
if (data & (1<<led)) {
LedSign::Set(led, line, grayscale);
}
else {
LedSign::Set(led, line, 0);
}
}
}
LedSign::Flip(true);

unsigned long end = millis();
unsigned long diff = end – start;
if ( start && (diff < blinkdelay) )
delay(200);
start = end;

frame++;
}
}

Step Sequencer for Generative art and music

step sequencer

step insides

It consists of 2 oscillators (40106), frequency divider (4040), shift register(4015), multiplexer (4051) and a teensy.

I found this really helpful: http://milkcrate.com.au/_other/sea-moss/

CODE:

const int numInputs = 12;
const int teensyPins[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
const int scaleMods[][numInputs] = {
{0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19}, // major
{0, 2, 3, 5, 7, 8, 10, 12, 14, 15, 17, 19}, // minor
{0, 1, 3, 5, 7, 8, 10, 12, 13, 15, 17, 19}, // phrygian
{0, 1, 3, 5, 6, 8, 10, 12, 13, 15, 17, 18}, // locrian
};

int MIDIchannel = 1;
int velocity = 110;
boolean lastReadings[numInputs];
int lastNotes[numInputs];

void setup() {
for (int i=0; i<numInputs; i++) {
pinMode(teensyPins[i], INPUT);
}
}

void loop() {
int scaleSel = 0;
if (digitalRead(3) == HIGH) scaleSel += 1;
if (digitalRead(4) == HIGH) scaleSel += 1;

int octaveMod = 0;
if (digitalRead(17) == HIGH) octaveMod += 12;
if (digitalRead(18) == HIGH) octaveMod += 12;

for (int i=0; i<numInputs; i++) {
int note = 36+scaleMods[scaleSel][i]+octaveMod;
boolean reading = digitalRead(teensyPins[i]);
if (reading == HIGH && lastReadings[i] == LOW) {
usbMIDI.sendNoteOn(note, velocity, MIDIchannel);
lastNotes[i] = note;
}
if (reading == LOW && lastReadings[i] == HIGH) {
usbMIDI.sendNoteOff(lastNotes[i], 0, MIDIchannel);
}
lastReadings[i] = reading;
}
}

Midterm – Autonomous Car

IMG_20141018_205558926 copy IMG_20141018_205622674_HDR copy
Inputs: distance sensor and photocell
Outputs: motors and LED headlights.
The distance sensor looks ahead of the car and if it senses something too close it backs up and turns and then continues on it’s way.
The photocell senses when it is too dark and turns on the headlights on the car.
Here is a link to my documentation: http://youtu.be/LsgcDeVzgE0
CODE:
//code edited from Arduino documentation about motors, h-bridges, and distance sensorsconst int motor1Pin = 9; //back motor
const int motor2Pin = 8; //back motor
const int motor3Pin = 11; //front motor
const int motor4Pin = 10; //front motor
const int enablePin = 7;
const int photocellPin = A0;
int photocellReading;
const int ledPin1 = 5;
const int ledPin2 = 3;

int LEDbrightness;

#define echoPin 13 // Echo Pin
#define trigPin 12 // Trigger Pin
long duration, distance; // Duration used to calculate distance
int minRange = 30; // min range before reverse

void setup() {
Serial.begin(9600);
pinMode(motor1Pin, OUTPUT);
pinMode(motor2Pin, OUTPUT);
pinMode(motor3Pin, OUTPUT);
pinMode(motor4Pin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(photocellPin, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);

pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}

void loop() {

photocellReading = analogRead(photocellPin);
LEDbrightness = constrain(map(photocellReading, 500, 300, 0, 255), 0, 255);
analogWrite(ledPin1, LEDbrightness);
analogWrite(ledPin2, LEDbrightness);

// set enablePin high so that motor can turn on:
digitalWrite(enablePin, HIGH);
/* The following trigPin/echoPin cycle is used to determine the
distance of the nearest object by bouncing soundwaves off of it. */
digitalWrite(trigPin, LOW);
delayMicroseconds(2);

digitalWrite(trigPin, HIGH);
delayMicroseconds(10);

digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);

//Calculate the distance (in cm) based on the speed of sound.
distance = duration/58.2;
Serial.println(distance);

if (distance >= minRange){
fwd();
straight();
}
else {
bkwd();
right();
delay(2000);
}
delay(10);

}

void fwd() {
digitalWrite(motor1Pin, LOW);
digitalWrite(motor2Pin, HIGH);
}
void bkwd() {
digitalWrite(motor1Pin, HIGH);
digitalWrite(motor2Pin, LOW);
}
void left() {
digitalWrite(motor3Pin, LOW);
digitalWrite(motor4Pin, HIGH);
}
void right() {
digitalWrite(motor3Pin, HIGH);
digitalWrite(motor4Pin, LOW);
}
void straight() {
digitalWrite(motor3Pin, LOW);
digitalWrite(motor4Pin, LOW);
}

Schematic

midterm

1 2


#include <NewPing.h>
#include <Servo.h>

#define MAX_DISTANCE 200
#define TRIG_PIN  4
#define ECHO_PIN  2

#define LEFT 0
#define CENTER 90
#define RIGHT 180
#define ENABLE1 3
#define INPUT1 9
#define INPUT2 8
#define ENABLE2 11
#define INPUT3 7
#define INPUT4 6

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
Servo ultrasonicServo;

float dangerThreshold = 40.0;

int currentPos = 0;

#define LEFT_FORWARD_RIGHT_FORWARD {HIGH, HIGH, LOW, HIGH, HIGH, LOW}
#define LEFT_OFF_RIGHT_FORWARD {LOW, HIGH, LOW, LOW, HIGH, LOW}
#define LEFT_FORWARD_RIGHT_OFF {HIGH, LOW, LOW, HIGH, LOW, LOW}
#define LEFT_REVERSE_RIGHT_FORWARD {HIGH, HIGH, HIGH, LOW, HIGH, LOW}
#define LEFT_FORWARD_RIGHT_REVERSE {HIGH, HIGH, LOW, HIGH, LOW, HIGH}
#define LEFT_REVERSE_RIGHT_REVERSE {HIGH, HIGH, HIGH, LOW, LOW, HIGH}
#define LEFT_OFF_RIGHT_OFF {HIGH, HIGH, LOW, LOW, LOW, LOW}
#define LEFT_FREEWHEEL_RIGHT_FREEWHEEL {LOW, LOW, LOW, LOW, LOW, LOW}

#define FORWARD LEFT_FORWARD_RIGHT_FORWARD
#define REVERSE LEFT_REVERSE_RIGHT_REVERSE
#define LEFT_TURN LEFT_OFF_RIGHT_FORWARD
#define RIGHT_TURN LEFT_FORWARD_RIGHT_OFF
#define ROTATE_LEFT LEFT_REVERSE_RIGHT_FORWARD
#define ROTATE_RIGHT LEFT_FORWARD_RIGHT_REVERSE
#define BRAKE LEFT_OFF_RIGHT_OFF
#define FREEWHEEL LEFT_FREEWHEEL_RIGHT_FREEWHEEL

#define SLOW 130;
#define MEDIUM 195;
#define FAST 255;

int throttle = MEDIUM;

void setup() {

pinMode(ENABLE1, OUTPUT);
pinMode(ENABLE2, OUTPUT);
pinMode(INPUT1, OUTPUT);
pinMode(INPUT2, OUTPUT);
pinMode(INPUT3, OUTPUT);
pinMode(INPUT4, OUTPUT);

ultrasonicServo.attach(5);

servo_position(CENTER);
}

void loop() {

float distanceForward = ping();

if (distanceForward > dangerThreshold)
{
drive_forward();
}
else
{
brake();

servo_position(LEFT);
float distanceLeft = ping();

servo_position(RIGHT);
float distanceRight = ping();

if (distanceLeft > distanceRight && distanceLeft > dangerThreshold)       //if left is less obstructed
{

rotate_left();
}
else if (distanceRight > distanceLeft && distanceRight > dangerThreshold) //if right is less obstructed
{

rotate_right();
}
else
{

u_turn();
}

servo_position(CENTER);
}
}

void freewheel(){
const int driveControl[] = FREEWHEEL;
drive(driveControl);
delay(25);

void brake(){
const int driveControl[] = BRAKE;
drive(driveControl);
delay(25);
}

void drive_forward(){
const int driveControl[] = FORWARD;
drive(driveControl);
}

void drive_backward(){
const int driveControl[] = REVERSE;
drive(driveControl);
}

void turn_left(){
const int driveControl[] = LEFT_TURN;
drive(driveControl);
delay(600);

}

void turn_right(){
const int driveControl[] = RIGHT_TURN;
drive(driveControl);
delay(600);

}

void rotate_left(){
const int driveControl[] = ROTATE_LEFT;
drive(driveControl);
delay(300);
}
void rotate_right(){
const int driveControl[] = ROTATE_RIGHT;
drive(driveControl);
delay(300);
}

void u_turn(){
const int driveControl[] = ROTATE_RIGHT;
drive(driveControl);
delay(600);
}

void drive(const int settings[6]){

if (settings[0] == HIGH)
analogWrite(ENABLE1, throttle);
else
digitalWrite(ENABLE1, LOW);

if (settings[1] == HIGH)
analogWrite(ENABLE2, throttle);
else
digitalWrite(ENABLE2, LOW);

digitalWrite(INPUT1, settings[2]);
digitalWrite(INPUT2, settings[3]);
digitalWrite(INPUT3, settings[4]);
digitalWrite(INPUT4, settings[5]);
}

void servo_position(int newPos){

if (newPos > currentPos){
for(int pos=currentPos; pos < newPos; pos += 1)
{
ultrasonicServo.write(pos);
delay(15);
}
currentPos = newPos;
}
else if (newPos < currentPos){
for(int pos=currentPos; pos > newPos; pos -= 1)
{
ultrasonicServo.write(pos);
delay(15);
}
currentPos = newPos;
}
}

float ping(){
delay(50);

unsigned int seconds = sonar.ping();

if (seconds == 0)
return MAX_DISTANCE;
else
return seconds / US_ROUNDTRIP_CM;
}

Midterm–Qianjing_Liu

 

 

I made a doll with arduino for midterm. There is a light sensor and a distance sensor in this doll. The eyes of the doll is the distance sensor while the nose of it is the light sensor.  The brightness of the two leds on the doll’s face will change with the light sensor. If the room is dark, the doll will get a red face. I also put a buzzer in the doll’s body, so if the distance sensor get that you are in a short distance, the buzzer will make sound. There is a servo in its tail, so if you are put something near the doll, its tail will move.

8  9 7 6 2  4 1  Photo on 10-12-14 at 18.36

 

 

 

Here is the code:

/*
Multiple tone player

Plays multiple tones on multiple pins in sequence

circuit:
* 3 8-ohm speaker on digital pins 6, 7, and 11

created 8 March 2010
by Tom Igoe
based on a snippet from Greg Borenstein

This example code is in the public domain.

http://arduino.cc/en/Tutorial/Tone4

*/
#include <Servo.h>

Servo myservo;

int pos = 0;
int lightsensor = A0;
const int echopin=2;
const int trigpin=3;
int led = 5;

void setup() {
Serial.begin(9600);
myservo.attach(9);
pinMode(lightsensor,INPUT);
pinMode(echopin,INPUT);
pinMode(trigpin,OUTPUT);
pinMode(led,OUTPUT);
}

void loop() {
int light = analogRead(lightsensor);
digitalWrite(trigpin,LOW);
delayMicroseconds(2);
digitalWrite(trigpin,HIGH);
delayMicroseconds(10);
digitalWrite(trigpin,LOW);
float distance = pulseIn(echopin,HIGH);
distance = distance/58.0;
delay(100);

if(distance<=15){
int sound = map(distance,0,15,1000,100);
for(pos = 0; pos < 180; pos += 1)
{
myservo.write(pos);
tone(4, sound, 200);
delay(5);
}
for(pos = 180; pos>=1; pos-=1)
{
myservo.write(pos);
tone(4, sound, 200);
delay(5);
}
}
int brightness = map(light,0,170,255,0);
if(brightness<0){
brightness=0;
}
analogWrite(led,brightness);
Serial.println(light);
}

 

MIDTERM_LUOBIN

Glove Instrument with Arduino and SuperCollider 

An music instrument using 4 flex sensors and an Arduino board. The readings from flex sensors are being sent to SuperCollider at real time. Firmata support is outdated on SuperCollider, so I’m using serial port instead. The signals strings are first sent to SC, separated by commas, then split function is used to separate them into array, the values in the array are assigned to variables one by one.

The data returned from flex sensor are values that is altered by its resistance. Some of the sensor was not that sensitive anymore so every mapping value should be adjusted manually.

4 buses are used in SC, 3 of them based on SinOsc(sine wave), one is based on RLPF(low pass filter). Codes in Arduino are simply reading and mapping out the value for SC to use.

Note that SC is a real time audio synthesis program, it could only possible to generate sound be initiated by starting the server and run the coding, which cannot be done automatically. It could be fun if SC behave like MaxMSP that is much more user friendly.

All codes are on Github: https://github.com/peterobbin/glove_instrument.git

 

Arduino code____________________________________________________________

void setup()
{
Serial.begin(9600);
}

void loop()
{
int sensor, sensor2, sensor3, sensor4, degrees, degrees2, degrees3, degrees4;
sensor = analogRead(0);
sensor2 = analogRead(1);
sensor3 = analogRead(2);
sensor4 = analogRead(3);

degrees = map(sensor, 768, 853, 400, 500);
degrees2 = map(sensor2, 768, 853, 380, 500);
degrees3 = map(sensor3, 790, 853, 0.001, 20);
degrees4 = map(sensor4, 768, 853, 400, 800);

// Serial.print(“[“);
Serial.print(degrees,DEC);
Serial.print(“,”);
Serial.print(degrees2,DEC);
Serial.print(“,”);
Serial.print(degrees3,DEC);
Serial.print(“,”);
Serial.print(degrees4,DEC);
Serial.println();

//Serial.println(“]”);
delay(100);

}

 

SuperCollider code _____________________________________________

(
SynthDef(“tones”,{
arg freq = 300,freq2 = 400, freq3 =20, freq4 = 400 ;
var out;
var out2;
var out3;
var out4;
var freqMap;
out = SinOsc.ar([freq,freq4], 0,0.3);
out2 = SinOsc.ar(freq4, 0,0.3);
out3 = {RLPF.ar(LFPulse.ar([25,35].midicps, 0.15),SinOsc.kr(freq3, 0, 10, 72).midicps, 0.1, 0.1)};
out4 = SinOsc.ar(OnePole.ar(Mix(
LFSaw.ar([1,0.40],[0,0.6],freq2*2,freq2*3).trunc([200,600])*[1,-1]
),0.98)).dup*0.1;

//courtesy to Lance Putnam
//”http://supercollider.sourceforge.net/audiocode-examples/”

Out.ar(0, out);
Out.ar(0, out2);
Out.ar(0, out3);
Out.ar(0, out4);
}).play
)

//a = Synth(“tones”, [“freq”,600,”freq2″,500,”freq3″,20, “freq4”,700]);

(

SerialPort.listDevices;
p = SerialPort(
“/dev/tty.usbmodemfa131”,
baudrate: 9600,
crtscts: true);
a = Synth(“tones”, [“freq”,400,”freq2″,400,”freq3″,20, “freq4”,400]);
r= Routine({

var byte, str, res, tone1, tone2, tone3, tone4;
99999.do{|i|
if(p.read==10, {
str = “”;
while({byte = p.read; byte !=13 }, {
str= str++byte.asAscii;
});
res= str.split($,).asInteger;
tone1 = res.at(0).postln;
tone2 = res.at(1).postln;
tone3 = res.at(2).postln;
tone4 = res.at(3).postln;

(“test value:”+res).postln;
(“tone1:”+tone1).postln;
(“tone2:”+tone2).postln;
(“tone3:”+tone3).postln;
(“tone4:”+tone4).postln;

a.set(“freq”,tone1,”freq2″, tone2,”freq3″,tone3, “freq4”,tone4);

});
};
}).play;

)
r.stop;
p.close;

_________________________________________________

 

 

Midterm: Milkweed

2014-10-23 18.12.09

 

No video, just a photo, because the motors I used aren’t strong enough to turn the butterfly wings. =(

I was inspired by butterflies such as Monarchs who perch on plants such as butterfly milkweed. When they’re perched on these plants, they’re hard to spot, until they move. So I wanted to create little robotic butterflies that were camouflaged against mechanical pieces that would flutter when there were no people moving around them, and would stop and hide themselves when there are people. I used two motion sensors to control the butterflies, and two stepper motors to make the butterflies flutter. Unfortunately, the motors I used weren’t strong enough to turn the butterflies and kept getting jammed and so can only move very, very subtly.

=(

Continue reading

Midterm_DarkGivesMeLife

My work for Midterm is a toy. The concept is, “Dark Gives Me Life”.

It’s a ghost toy for Halloween. When night (dark) comes, the ghost will be alive.

There is a photocell sensor to detect the light. If the light is weak, it can give signal to Arduino. Then, Arduino will turn on the LEDs, piezo speaker and servo. So the ghost can shake, scream and blink his green evil eyes.

There are 1 photocell for detecting the light, 1 force sensor for detecting people pressing his hand. And 2 LEDs (for blinking eyes), 1 servo (for shaking head) and 1 piezo speaker (for screaming) as outputs.

IMG_1521 IMG_1523 IMG_1524 IMG_1526 IMG_1527 IMG_1528 IMG_1529 IMG_1530 IMG_1531 IMG_1532 IMG_1535 IMG_1542 IMG_1580 IMG_1581 IMG_1582

 

 

 

code is here,

 

#include <Servo.h>

Servo myservo;

int speaker = 9;
int ledPin1 = 6;
int ledPin2 = 5;

void setup(){
Serial.begin(9600);
myservo.attach(3);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(speaker, OUTPUT);
}

void loop(){
noTone;
int sensorValue = analogRead(A0);
int sensorValue2 = analogRead(A1);
// Serial.println(sensorValue);
// Serial.println(sensorValue2);

delay(10);

//turn off the light
if(sensorValue < 50){
// myservo.write(180);
int thisPitch = map(sensorValue, 0, 100, 1000, 1500);
tone(speaker, thisPitch, 800);
for(int fadeValue = 0; fadeValue <= 255; fadeValue +=1){
int i = 0;
myservo.write(i++);
analogWrite(ledPin1, fadeValue);
// delay(3);
}
for(int fadeValue = 255; fadeValue >= 0; fadeValue -=1){
int i = 90;
myservo.write(i–);
analogWrite(ledPin1, fadeValue);
// delay(3);
}
}

//press
if(sensorValue2 > 200){
int powerValue = map(sensorValue2, 400, 900, 1000, 2000);
tone(speaker, powerValue, 800);
}

}

 

LoL Shield Animation

 

/*
Basic LoL Shield Test

Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/

This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/

Created by Jimmie Rodgers on 12/30/2009.
Adapted from: http://www.arduino.cc/playground/Code/BitMath

History:
December 30, 2009 – V1.0 first version written at 26C3/Berlin

This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <avr/pgmspace.h> //AVR library for writing to ROM
#include <Charliplexing.h> //Imports the library, which needs to be
//Initialized in setup.

//Sets the time each frame is shown (milliseconds)
const unsigned int blinkdelay = 1000 / 50;

/*
The BitMap array is what contains the frame data. Each line is one full frame.
Since each number is 16 bits, we can easily fit all 14 LEDs per row into it.
The number is calculated by adding up all the bits, starting with lowest on
the left of each row. 18000 was chosen as the kill number, so make sure that
is at the end of the matrix, or the program will continue to read into memory.

Here PROGMEM is called, which stores the array into ROM, which leaves us
with our RAM. You cannot change the array during run-time, only when you
upload to the Arduino. You will need to pull it out of ROM, which is covered
below. If you want it to stay in RAM, just delete PROGMEM
*/
PROGMEM const uint16_t BitMap[][9] = {
//Diaganal swipe across the screen
{0,0,0,128,448,128,0,0,0},
{0, 0, 128, 320, 544, 320, 128, 0, 0},
{0, 128, 320, 544, 1040, 544, 320, 128, 0},
{128, 320, 544, 1040, 2056, 1040, 544, 320, 128},
{320, 544, 1040, 2056, 4100, 2072, 1072, 608, 320},
{544, 1040, 2056, 4100, 8194, 4100, 2056, 1040, 544},
{1040, 2056, 4100, 8194, 1, 8194, 4100, 2056, 1040},
{2056, 4100, 8194, 1, 0, 1, 8194, 4100, 2056},
{4100, 8194, 1, 0, 0, 0, 1, 8194, 4100},
{8194, 1, 0, 0, 0, 0, 0, 1, 8194},
{1, 0, 0, 0, 0, 0, 0, 0, 1},
{18000}
};

void setup() {
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE); //Initializes the screen
}
void loop() {
for (uint8_t gray = 1; gray < SHADES; gray++)
DisplayBitMap(gray); //Displays the bitmap
}

void DisplayBitMap(uint8_t grayscale)
{
boolean run=true; //While this is true, the screen updates
byte frame = 0; //Frame counter
byte line = 0; //Row counter
unsigned long data; //Temporary storage of the row data
unsigned long start = 0;

while(run == true) {

for(line = 0; line < 9; line++) {

//Here we fetch data from program memory with a pointer.
data = pgm_read_word_near (&BitMap[frame][line]);

//Kills the loop if the kill number is found
if (data==18000){
run=false;
}

//This is where the bit-shifting happens to pull out
//each LED from a row. If the bit is 1, then the LED
//is turned on, otherwise it is turned off.
else for (byte led=0; led<14; ++led) {
if (data & (1<<led)) {
LedSign::Set(led, line, grayscale);
}
else {
LedSign::Set(led, line, 0);
}
}
}

LedSign::Flip(true);

unsigned long end = millis();
unsigned long diff = end – start;
if ( start && (diff < blinkdelay) )
delay( 5*blinkdelay – diff );
start = end;

frame++;
}
}

Midterm Project: Spiritual Pumpkins

See Spiritual Pumpkins in action.

IMG_20141024_105053

Here is my midterm project. I call them Spiritual Pumpkins. The midterm project was due in October, Halloween time, so I thought it would be fun to do a Halloween-themed project. I love carving pumpkins, and I love the Legend of Zelda.

Zelda_Spiritual_Stones_Pack_by_GGRock70

The idea of Spiritual Pumpkins came from the Spiritual Stones in the Legend of Zelda video game. While working on this project I took the opportunity to share the process with the kids that I teach programming to. They had a blast learning about LED’s.

kids leds

Watch my student’s having fun with LED’s.

Spiritual PumpkinsIMG_20141024_105505  IMG_20141024_105517

Close-ups for details of the carving and light shining from the LED’s.

IMG_20141024_105407 IMG_20141024_105424 IMG_20141024_105432 IMG_20141024_105419 IMG_20141024_105416

SO MUCH SOLDERING.

IMG_20141024_105023 

I don’t even understand how I got burnt there.

//FADE////////////////////////////////////////////////////////////
int led = 9; // the pin that the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by

//CHASE////////////////////////////////////////////////////////////
// Simple macros to remember which direction to shift LEDs
#define UP true
#define DOWN false
// Will be used to track how long since last event “fired”
unsigned long previousMillis=0;
// Delay to determine when we see the next LED
unsigned long interval = 250;
// Array with Arduino pins containing LEDs in sequence
byte LEDpins[] = {2,3,4,5,6};
// Variable to track which LED to turn on, start at 000001
int LEDstate=0x01;
// State variable to know which direction to shift
boolean direction=UP;

//FLICKER////////////////////////////////////////////////////////////
int ledPin3 = 11;

//////////////////////////////////////////////////////////////////////
//////////////////////////////VOID_SETUP//////////////////////////////
//////////////////////////////////////////////////////////////////////

void setup() {
//FADE////////////////////////////////////////////////////////////
// declare pin 9 to be an output:
pinMode(led, OUTPUT);

//CHASE////////////////////////////////////////////////////////////
// Set Pins with LEDs to OUTPUT
for (int x=0; x < 5; x++)
pinMode(LEDpins[x], OUTPUT);

//FLICKER////////////////////////////////////////////////////////////
pinMode(ledPin3, OUTPUT);
}

//////////////////////////////////////////////////////////////////////
//////////////////////////////VOID_LOOP///////////////////////////////
//////////////////////////////////////////////////////////////////////

void loop() {
//FADE////////////////////////////////////////////////////////////
// set the brightness of pin 9
analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);

//CHASE////////////////////////////////////////////////////////////
// Set the pins of each LED during each iteration
// You’ll only see something change when “LEDpins” gets updated
for (int x=0; x < 5; x++)
digitalWrite(LEDpins[x], bitRead(LEDstate,x));
// Get current time and determine how long since last check
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis – previousMillis) >= interval) {
// We’ve waited “interval” amount of time, so let’s do some stuff!
// “Reset” our clock
previousMillis = currentMillis;
if (direction==UP) {
// Use “<<” to “bit-shift” everything to the left once
LEDstate = LEDstate << 1;
// 0x20 is the “last” LED, another shift makes the value 0x40
if (LEDstate == 0x40) {
// turn on the one before “0x20” and reverse direction
LEDstate = 0x10;
direction = DOWN;
}
} else {
// use “>>” to “bit-shift” all bits in LEDstate once to the right
LEDstate = LEDstate >> 1;
// This means we ran out of bits!
if (LEDstate == 0x00) {
// set one ahead so no extra delay
LEDstate = 0x02;
direction = UP;
}
}
}
//FLICKER////////////////////////////////////////////////////////////
analogWrite(ledPin3, random(120)+135);
delay(random(100));
}