Featured

Interactive Object

Phase 1: Getting RFID working

We started by getting the all the parts needed and prioritized getting the RFID to work. We started with a simple RFID id-3LA and a break out board, but while we soldered it onto the breakout board we ran into a problem of not working. It had previously worked before soldering but in the end it stopped working for us, everyone was baffled because they didn’t know why it stopped working it looked fined. In the end we ended up getting another RFID this time we got the ID-12LA with its compatible board and that ended up working for us a lot better. We took a sample program from our online Arduino sources to get the RFID working to scan in our card IDs. We were able to get the cards read in and use their ASCII ID to implement it into the rest of the project.

/******* RFID Test Code *********/
/*****************************
RFID-powered lockbox
Written by: acavis, 3/31/2015
Modified: Ho YUN "Bobby" Chan @ SparkFun Electronics Inc., 11/10/2017
Inspired by & partially adapted from
http://bildr.org/2011/02/rfid-arduino/
Description: This sketch will move a servo when
a trusted tag is read with the
ID-12/ID-20 RFID module
———-HARDWARE HOOKUP———-
PINOUT FOR SERVO MOTOR
Servo Motor —– Arduino
GND GND
Vcc 5V
SIG D9
PINOUT FOR SPARKFUN RFID USB READER
Arduino —– RFID module
5V VCC
GND GND
D2 TX
PINOUT FOR SPARKFUN RFID BREAKOUT BOARD
Arduino —– RFID module
5V VCC
GND GND
GND FORM
D2 D0
Optional: If using the breakout, you can also
put an LED & 330 ohm resistor between
the RFID module's READ pin and GND for
a "card successfully read" indication.
Note: Make sure to GND the FORM pin to enable the ASCII output format.
————————————————–
******************************/
#include <SoftwareSerial.h>
//#include <Servo.h>
// Choose two pins for SoftwareSerial
SoftwareSerial rSerial(5, 3); // RX, TX
// Make a servo object
//Servo lockServo;
// Pick a PWM pin to put the servo on
//const int servoPin = 9;
// For SparkFun's tags, we will receive 16 bytes on every
// tag read, but throw four away. The 13th space will always
// be 0, since proper strings in Arduino end with 0
// These constants hold the total tag length (tagLen) and
// the length of the part we want to keep (idLen),
// plus the total number of tags we want to check against (kTags)
const int tagLen = 16;
const int idLen = 13;
const int kTags = 4;
// Put your known tags here!
char knownTags[kTags][idLen] = {
"111111111111",
"5500080E8FDC",
"550008004A17"
};
// Empty array to hold a freshly scanned tag
char newTag[idLen];
void setup() {
// Starts the hardware and software serial ports
Serial.begin(9600);
rSerial.begin(9600);
}
void loop() {
// Counter for the newTag array
int i = 0;
// Variable to hold each byte read from the serial buffer
int readByte;
// Flag so we know when a tag is over
boolean tag = false;
// This makes sure the whole tag is in the serial buffer before
// reading, the Arduino can read faster than the ID module can deliver!
if (rSerial.available() == tagLen) {
tag = true;
}
if (tag == true) {
while (rSerial.available()) {
// Take each byte out of the serial buffer, one at a time
readByte = rSerial.read();
/* This will skip the first byte (2, STX, start of text) and the last three,
ASCII 13, CR/carriage return, ASCII 10, LF/linefeed, and ASCII 3, ETX/end of
text, leaving only the unique part of the tag string. It puts the byte into
the first space in the array, then steps ahead one spot */
if (readByte != 2 && readByte!= 13 && readByte != 10 && readByte != 3) {
newTag[i] = readByte;
i++;
}
// If we see ASCII 3, ETX, the tag is over
if (readByte == 3) {
tag = false;
}
}
}
// don't do anything if the newTag array is full of zeroes
if (strlen(newTag)== 0) {
return;
}
else {
int total = 0;
for (int ct=0; ct < kTags; ct++){
total += checkTag(newTag, knownTags[ct]);
}
// If newTag matched any of the tags
// we checked against, total will be 1
if (total > 0) {
// Put the action of your choice here!
// I'm going to rotate the servo to symbolize unlocking the lockbox
Serial.println("Success!");
}
else {
// This prints out unknown cards so you can add them to your knownTags as needed
Serial.print("Unknown tag! ");
Serial.print(newTag);
Serial.println();
}
}
// Once newTag has been checked, fill it with zeroes
// to get ready for the next tag read
for (int c=0; c < idLen; c++) {
newTag[c] = 0;
}
}
// This function steps through both newTag and one of the known
// tags. If there is a mismatch anywhere in the tag, it will return 0,
// but if every character in the tag is the same, it returns 1
int checkTag(char nTag[], char oTag[]) {
for (int i = 0; i < idLen; i++) {
if (nTag[i] != oTag[i]) {
return 0;
}
}
return 1;
}
view raw RFIDCode.ino hosted with ❤ by GitHub

Phase 2: Getting RFID to work with MP3 Shield

After we had worked on getting the RFID to work we needed to get the mp3 player shield to connect with the RFID so it played a song when the card was scanned in. We started first by testing out the mp3 player using its library we found sample code that would allow us to control the player through the serial monitor. After plugging in the mp3 player we tested the songs on the micro card and played with it for a little while to figure out how it worked.

/******* MP3 Shield Player Code *********/
/**
* \file FilePlayer.ino
*
* \brief Example sketch of using the MP3Shield Arduino driver, with flexible list of files and formats
* \remarks comments are implemented with Doxygen Markdown format
*
* \author Bill Porter
* \author Michael P. Flaga
*
* This sketch listens for commands from a serial terminal (such as the Serial
* Monitor in the Arduino IDE). Listening for either a single character menu
* commands or an numeric strings of an index. Pointing to a music file, found
* in the root of the SdCard, to be played. A list of index's and corresponding
* files in the root can be listed out using the 'l' (little L) command.
*
* This sketch allows the various file formats to be played: mp3, aac, wma, wav,
* fla & mid.
*
* This sketch behaves nearly identical to MP3Shield_Library_Demo.ino, but has
* extra complicated loop() as to recieve string of characters to create the
* file index. As the Serial Monitor is typically default with no CR or LF, this
* sketch uses intercharacter time out as to determine when a full string has
* has been entered to be processed.
*/
#include <SPI.h>
//Add the SdFat Libraries
#include <SdFat.h>
#include <FreeStack.h>
//and the MP3 Shield Library
#include <SFEMP3Shield.h>
// Below is not needed if interrupt driven. Safe to remove if not using.
#if defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Timer1
#include <TimerOne.h>
#elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer
#include <SimpleTimer.h>
#endif
/**
* \brief Object instancing the SdFat library.
*
* principal object for handling all SdCard functions.
*/
SdFat sd;
/**
* \brief Object instancing the SFEMP3Shield library.
*
* principal object for handling all the attributes, members and functions for the library.
*/
SFEMP3Shield MP3player;
int16_t last_ms_char; // milliseconds of last recieved character from Serial port.
int8_t buffer_pos; // next position to recieve character from Serial port.
//——————————————————————————
/**
* \brief Setup the Arduino Chip's feature for our use.
*
* After Arduino's kernel has booted initialize basic features for this
* application, such as Serial port and MP3player objects with .begin.
* Along with displaying the Help Menu.
*
* \note returned Error codes are typically passed up from MP3player.
* Whicn in turns creates and initializes the SdCard objects.
*
* \see
* \ref Error_Codes
*/
char buffer[6]; // 0-35K+null
void setup() {
uint8_t result; //result code from some function as to be tested at later time.
Serial.begin(115200);
Serial.print(F("F_CPU = "));
Serial.println(F_CPU);
Serial.print(F("Free RAM = ")); // available in Version 1.0 F() bases the string to into Flash, to use less SRAM.
Serial.print(FreeStack(), DEC); // FreeRam() is provided by SdFatUtil.h
Serial.println(F(" Should be a base line of 1017, on ATmega328 when using INTx"));
//Initialize the SdCard.
if(!sd.begin(SD_SEL, SPI_FULL_SPEED)) sd.initErrorHalt();
// depending upon your SdCard environment, SPI_HAVE_SPEED may work better.
if(!sd.chdir("/")) sd.errorHalt("sd.chdir");
//Initialize the MP3 Player Shield
result = MP3player.begin();
//check result, see readme for error codes.
if(result != 0) {
Serial.print(F("Error code: "));
Serial.print(result);
Serial.println(F(" when trying to start MP3 player"));
if( result == 6 ) {
Serial.println(F("Warning: patch file not found, skipping.")); // can be removed for space, if needed.
Serial.println(F("Use the \"d\" command to verify SdCard can be read")); // can be removed for space, if needed.
}
}
#if (0)
// Typically not used by most shields, hence commented out.
Serial.println(F("Applying ADMixer patch."));
if(MP3player.ADMixerLoad("admxster.053") == 0) {
Serial.println(F("Setting ADMixer Volume."));
MP3player.ADMixerVol(-3);
}
#endif
help();
last_ms_char = millis(); // stroke the inter character timeout.
buffer_pos = 0; // start the command string at zero length.
parse_menu('l'); // display the list of files to play
}
//——————————————————————————
/**
* \brief Main Loop the Arduino Chip
*
* This is called at the end of Arduino kernel's main loop before recycling.
* And is where the user's serial input of bytes are read and analyzed by
* parsed_menu.
*
* Additionally, if the means of refilling is not interrupt based then the
* MP3player object is serviced with the availaible function.
*
* \note Actual examples of the libraries public functions are implemented in
* the parse_menu() function.
*/
void loop() {
// Below is only needed if not interrupt driven. Safe to remove if not using.
#if defined(USE_MP3_REFILL_MEANS) \
&& ( (USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer) \
|| (USE_MP3_REFILL_MEANS == USE_MP3_Polled) )
MP3player.available();
#endif
char inByte;
if (Serial.available() > 0) {
inByte = Serial.read();
if ((0x20 <= inByte) && (inByte <= 0x126)) { // strip off non-ASCII, such as CR or LF
if (isDigit(inByte)) { // macro for ((inByte >= '0') && (inByte <= '9'))
// else if it is a number, add it to the string
buffer[buffer_pos++] = inByte;
} else {
// input char is a letter command
buffer_pos = 0;
parse_menu(inByte);
}
buffer[buffer_pos] = 0; // update end of line
last_ms_char = millis(); // stroke the inter character timeout.
}
} else if ((millis() – last_ms_char) > 500 && ( buffer_pos > 0 )) {
// ICT expired and have something
if (buffer_pos == 1) {
// look for single byte (non-number) menu commands
parse_menu(buffer[buffer_pos – 1]);
} else if (buffer_pos > 5) {
// dump if entered command is greater then uint16_t
Serial.println(F("Ignored, Number is Too Big!"));
} else {
// otherwise its a number, scan through files looking for matching index.
int16_t fn_index = atoi(buffer);
SdFile file;
char filename[13];
sd.chdir("/",true);
uint16_t count = 1;
while (file.openNext(sd.vwd(),O_READ))
{
file.getName(filename, sizeof(filename));
if ( isFnMusic(filename) ) {
if (count == fn_index) {
Serial.print(F("Index "));
SerialPrintPaddedNumber(count, 5 );
Serial.print(F(": "));
Serial.println(filename);
Serial.print(F("Playing filename: "));
Serial.println(filename);
int8_t result = MP3player.playMP3(filename);
//check result, see readme for error codes.
if(result != 0) {
Serial.print(F("Error code: "));
Serial.print(result);
Serial.println(F(" when trying to play track"));
}
char title[30]; // buffer to contain the extract the Title from the current filehandles
char artist[30]; // buffer to contain the extract the artist name from the current filehandles
char album[30]; // buffer to contain the extract the album name from the current filehandles
MP3player.trackTitle((char*)&title);
MP3player.trackArtist((char*)&artist);
MP3player.trackAlbum((char*)&album);
//print out the arrays of track information
Serial.write((byte*)&title, 30);
Serial.println();
Serial.print(F("by: "));
Serial.write((byte*)&artist, 30);
Serial.println();
Serial.print(F("Album: "));
Serial.write((byte*)&album, 30);
Serial.println();
break;
}
count++;
}
file.close();
}
}
//reset buffer to start over
buffer_pos = 0;
buffer[buffer_pos] = 0; // delimit
}
delay(100);
}
uint32_t millis_prv;
//——————————————————————————
/**
* \brief Decode the Menu.
*
* Parses through the characters of the users input, executing corresponding
* MP3player library functions and features then displaying a brief menu and
* prompting for next input command.
*/
void parse_menu(byte key_command) {
uint8_t result; // result code from some function as to be tested at later time.
// Note these buffer may be desired to exist globably.
// but do take much space if only needed temporarily, hence they are here.
char title[30]; // buffer to contain the extract the Title from the current filehandles
char artist[30]; // buffer to contain the extract the artist name from the current filehandles
char album[30]; // buffer to contain the extract the album name from the current filehandles
Serial.print(F("Received command: "));
Serial.write(key_command);
Serial.println(F(" "));
//if s, stop the current track
if(key_command == 's') {
Serial.println(F("Stopping"));
MP3player.stopTrack();
//if 1-9, play corresponding track
} else if(key_command >= '1' && key_command <= '9') {
//convert ascii numbers to real numbers
key_command = key_command – 48;
#if USE_MULTIPLE_CARDS
sd.chvol(); // assign desired sdcard's volume.
#endif
//tell the MP3 Shield to play a track
result = MP3player.playTrack(key_command);
//check result, see readme for error codes.
if(result != 0) {
Serial.print(F("Error code: "));
Serial.print(result);
Serial.println(F(" when trying to play track"));
} else {
Serial.println(F("Playing:"));
//we can get track info by using the following functions and arguments
//the functions will extract the requested information, and put it in the array we pass in
MP3player.trackTitle((char*)&title);
MP3player.trackArtist((char*)&artist);
MP3player.trackAlbum((char*)&album);
//print out the arrays of track information
Serial.write((byte*)&title, 30);
Serial.println();
Serial.print(F("by: "));
Serial.write((byte*)&artist, 30);
Serial.println();
Serial.print(F("Album: "));
Serial.write((byte*)&album, 30);
Serial.println();
}
//if +/- to change volume
} else if((key_command == '-') || (key_command == '+')) {
union twobyte mp3_vol; // create key_command existing variable that can be both word and double byte of left and right.
mp3_vol.word = MP3player.getVolume(); // returns a double uint8_t of Left and Right packed into int16_t
if(key_command == '-') { // note dB is negative
// assume equal balance and use byte[1] for math
if(mp3_vol.byte[1] >= 254) { // range check
mp3_vol.byte[1] = 254;
} else {
mp3_vol.byte[1] += 2; // keep it simpler with whole dB's
}
} else {
if(mp3_vol.byte[1] <= 2) { // range check
mp3_vol.byte[1] = 2;
} else {
mp3_vol.byte[1] -= 2;
}
}
// push byte[1] into both left and right assuming equal balance.
MP3player.setVolume(mp3_vol.byte[1], mp3_vol.byte[1]); // commit new volume
Serial.print(F("Volume changed to -"));
Serial.print(mp3_vol.byte[1]>>1, 1);
Serial.println(F("[dB]"));
//if < or > to change Play Speed
} else if((key_command == '>') || (key_command == '<')) {
uint16_t playspeed = MP3player.getPlaySpeed(); // create key_command existing variable
// note playspeed of Zero is equal to ONE, normal speed.
if(key_command == '>') { // note dB is negative
// assume equal balance and use byte[1] for math
if(playspeed >= 254) { // range check
playspeed = 5;
} else {
playspeed += 1; // keep it simpler with whole dB's
}
} else {
if(playspeed == 0) { // range check
playspeed = 0;
} else {
playspeed -= 1;
}
}
MP3player.setPlaySpeed(playspeed); // commit new playspeed
Serial.print(F("playspeed to "));
Serial.println(playspeed, DEC);
/* Alterativly, you could call a track by it's file name by using playMP3(filename);
But you must stick to 8.1 filenames, only 8 characters long, and 3 for the extension */
} else if(key_command == 'f' || key_command == 'F') {
uint32_t offset = 0;
if (key_command == 'F') {
offset = 2000;
}
//create a string with the filename
char trackName[] = "track001.mp3";
#if USE_MULTIPLE_CARDS
sd.chvol(); // assign desired sdcard's volume.
#endif
//tell the MP3 Shield to play that file
result = MP3player.playMP3(trackName, offset);
//check result, see readme for error codes.
if(result != 0) {
Serial.print(F("Error code: "));
Serial.print(result);
Serial.println(F(" when trying to play track"));
}
/* Display the file on the SdCard */
} else if(key_command == 'd') {
if(!MP3player.isPlaying()) {
// prevent root.ls when playing, something locks the dump. but keeps playing.
// yes, I have tried another unique instance with same results.
// something about SdFat and its 500byte cache.
Serial.println(F("Files found (name date time size):"));
sd.ls(LS_R | LS_DATE | LS_SIZE);
} else {
Serial.println(F("Busy Playing Files, try again later."));
}
/* Get and Display the Audio Information */
} else if(key_command == 'i') {
MP3player.getAudioInfo();
} else if(key_command == 'p') {
if( MP3player.getState() == playback) {
MP3player.pauseMusic();
Serial.println(F("Pausing"));
} else if( MP3player.getState() == paused_playback) {
MP3player.resumeMusic();
Serial.println(F("Resuming"));
} else {
Serial.println(F("Not Playing!"));
}
} else if(key_command == 't') {
int8_t teststate = MP3player.enableTestSineWave(126);
if(teststate == -1) {
Serial.println(F("Un-Available while playing music or chip in reset."));
} else if(teststate == 1) {
Serial.println(F("Enabling Test Sine Wave"));
} else if(teststate == 2) {
MP3player.disableTestSineWave();
Serial.println(F("Disabling Test Sine Wave"));
}
} else if(key_command == 'S') {
Serial.println(F("Current State of VS10xx is."));
Serial.print(F("isPlaying() = "));
Serial.println(MP3player.isPlaying());
Serial.print(F("getState() = "));
switch (MP3player.getState()) {
case uninitialized:
Serial.print(F("uninitialized"));
break;
case initialized:
Serial.print(F("initialized"));
break;
case deactivated:
Serial.print(F("deactivated"));
break;
case loading:
Serial.print(F("loading"));
break;
case ready:
Serial.print(F("ready"));
break;
case playback:
Serial.print(F("playback"));
break;
case paused_playback:
Serial.print(F("paused_playback"));
break;
case testing_memory:
Serial.print(F("testing_memory"));
break;
case testing_sinewave:
Serial.print(F("testing_sinewave"));
break;
}
Serial.println();
} else if(key_command == 'b') {
Serial.println(F("Playing Static MIDI file."));
MP3player.SendSingleMIDInote();
Serial.println(F("Ended Static MIDI file."));
#if !defined(__AVR_ATmega32U4__)
} else if(key_command == 'm') {
uint16_t teststate = MP3player.memoryTest();
if(teststate == -1) {
Serial.println(F("Un-Available while playing music or chip in reset."));
} else if(teststate == 2) {
teststate = MP3player.disableTestSineWave();
Serial.println(F("Un-Available while Sine Wave Test"));
} else {
Serial.print(F("Memory Test Results = "));
Serial.println(teststate, HEX);
Serial.println(F("Result should be 0x83FF."));
Serial.println(F("Reset is needed to recover to normal operation"));
}
} else if(key_command == 'e') {
uint8_t earspeaker = MP3player.getEarSpeaker();
if(earspeaker >= 3){
earspeaker = 0;
} else {
earspeaker++;
}
MP3player.setEarSpeaker(earspeaker); // commit new earspeaker
Serial.print(F("earspeaker to "));
Serial.println(earspeaker, DEC);
} else if(key_command == 'r') {
MP3player.resumeMusic(2000);
} else if(key_command == 'R') {
MP3player.stopTrack();
MP3player.vs_init();
Serial.println(F("Reseting VS10xx chip"));
} else if(key_command == 'g') {
int32_t offset_ms = 20000; // Note this is just an example, try your own number.
Serial.print(F("jumping to "));
Serial.print(offset_ms, DEC);
Serial.println(F("[milliseconds]"));
result = MP3player.skipTo(offset_ms);
if(result != 0) {
Serial.print(F("Error code: "));
Serial.print(result);
Serial.println(F(" when trying to skip track"));
}
} else if(key_command == 'k') {
int32_t offset_ms = -1000; // Note this is just an example, try your own number.
Serial.print(F("moving = "));
Serial.print(offset_ms, DEC);
Serial.println(F("[milliseconds]"));
result = MP3player.skip(offset_ms);
if(result != 0) {
Serial.print(F("Error code: "));
Serial.print(result);
Serial.println(F(" when trying to skip track"));
}
} else if(key_command == 'O') {
MP3player.end();
Serial.println(F("VS10xx placed into low power reset mode."));
} else if(key_command == 'o') {
MP3player.begin();
Serial.println(F("VS10xx restored from low power reset mode."));
} else if(key_command == 'D') {
uint16_t diff_state = MP3player.getDifferentialOutput();
Serial.print(F("Differential Mode "));
if(diff_state == 0) {
MP3player.setDifferentialOutput(1);
Serial.println(F("Enabled."));
} else {
MP3player.setDifferentialOutput(0);
Serial.println(F("Disabled."));
}
} else if(key_command == 'V') {
MP3player.setVUmeter(1);
Serial.println(F("Use \"No line ending\""));
Serial.print(F("VU meter = "));
Serial.println(MP3player.getVUmeter());
Serial.println(F("Hit Any key to stop."));
while(!Serial.available()) {
union twobyte vu;
vu.word = MP3player.getVUlevel();
Serial.print(F("VU: L = "));
Serial.print(vu.byte[1]);
Serial.print(F(" / R = "));
Serial.print(vu.byte[0]);
Serial.println(" dB");
delay(1000);
}
Serial.read();
MP3player.setVUmeter(0);
Serial.print(F("VU meter = "));
Serial.println(MP3player.getVUmeter());
} else if(key_command == 'T') {
uint16_t TrebleFrequency = MP3player.getTrebleFrequency();
Serial.print(F("Former TrebleFrequency = "));
Serial.println(TrebleFrequency, DEC);
if (TrebleFrequency >= 15000) { // Range is from 0 – 1500Hz
TrebleFrequency = 0;
} else {
TrebleFrequency += 1000;
}
MP3player.setTrebleFrequency(TrebleFrequency);
Serial.print(F("New TrebleFrequency = "));
Serial.println(MP3player.getTrebleFrequency(), DEC);
} else if(key_command == 'E') {
int8_t TrebleAmplitude = MP3player.getTrebleAmplitude();
Serial.print(F("Former TrebleAmplitude = "));
Serial.println(TrebleAmplitude, DEC);
if (TrebleAmplitude >= 7) { // Range is from -8 – 7dB
TrebleAmplitude = -8;
} else {
TrebleAmplitude++;
}
MP3player.setTrebleAmplitude(TrebleAmplitude);
Serial.print(F("New TrebleAmplitude = "));
Serial.println(MP3player.getTrebleAmplitude(), DEC);
} else if(key_command == 'B') {
uint16_t BassFrequency = MP3player.getBassFrequency();
Serial.print(F("Former BassFrequency = "));
Serial.println(BassFrequency, DEC);
if (BassFrequency >= 150) { // Range is from 20hz – 150hz
BassFrequency = 0;
} else {
BassFrequency += 10;
}
MP3player.setBassFrequency(BassFrequency);
Serial.print(F("New BassFrequency = "));
Serial.println(MP3player.getBassFrequency(), DEC);
} else if(key_command == 'C') {
uint16_t BassAmplitude = MP3player.getBassAmplitude();
Serial.print(F("Former BassAmplitude = "));
Serial.println(BassAmplitude, DEC);
if (BassAmplitude >= 15) { // Range is from 0 – 15dB
BassAmplitude = 0;
} else {
BassAmplitude++;
}
MP3player.setBassAmplitude(BassAmplitude);
Serial.print(F("New BassAmplitude = "));
Serial.println(MP3player.getBassAmplitude(), DEC);
} else if(key_command == 'M') {
uint16_t monostate = MP3player.getMonoMode();
Serial.print(F("Mono Mode "));
if(monostate == 0) {
MP3player.setMonoMode(1);
Serial.println(F("Enabled."));
} else {
MP3player.setMonoMode(0);
Serial.println(F("Disabled."));
}
#endif
/* List out music files on the SdCard */
} else if(key_command == 'l') {
if(!MP3player.isPlaying()) {
Serial.println(F("Music Files found :"));
SdFile file;
char filename[13];
sd.chdir("/",true);
uint16_t count = 1;
while (file.openNext(sd.vwd(),O_READ))
{
file.getName(filename, sizeof(filename));
if ( isFnMusic(filename) ) {
SerialPrintPaddedNumber(count, 5 );
Serial.print(F(": "));
Serial.println(filename);
count++;
}
file.close();
}
Serial.println(F("Enter Index of File to play"));
} else {
Serial.println(F("Busy Playing Files, try again later."));
}
} else if(key_command == 'h') {
help();
}
// print prompt after key stroke has been processed.
Serial.print(F("Time since last command: "));
Serial.println((float) (millis() – millis_prv)/1000, 2);
millis_prv = millis();
Serial.print(F("Enter s,1-9,+,-,>,<,f,F,d,i,p,t,S,b"));
#if !defined(__AVR_ATmega32U4__)
Serial.print(F(",m,e,r,R,g,k,O,o,D,V,B,C,T,E,M:"));
#endif
Serial.println(F(",l,h :"));
}
//——————————————————————————
/**
* \brief Print Help Menu.
*
* Prints a full menu of the commands available along with descriptions.
*/
void help() {
Serial.println(F("Arduino SFEMP3Shield Library Example:"));
Serial.println(F(" courtesy of Bill Porter & Michael P. Flaga"));
Serial.println(F("COMMANDS:"));
Serial.println(F(" [1-9] to play a track"));
Serial.println(F(" [f] play track001.mp3 by filename example"));
Serial.println(F(" [F] same as [f] but with initial skip of 2 second"));
Serial.println(F(" [s] to stop playing"));
Serial.println(F(" [d] display directory of SdCard"));
Serial.println(F(" [+ or -] to change volume"));
Serial.println(F(" [> or <] to increment or decrement play speed by 1 factor"));
Serial.println(F(" [i] retrieve current audio information (partial list)"));
Serial.println(F(" [p] to pause."));
Serial.println(F(" [t] to toggle sine wave test"));
Serial.println(F(" [S] Show State of Device."));
Serial.println(F(" [b] Play a MIDI File Beep"));
#if !defined(__AVR_ATmega32U4__)
Serial.println(F(" [e] increment Spatial EarSpeaker, default is 0, wraps after 4"));
Serial.println(F(" [m] perform memory test. reset is needed after to recover."));
Serial.println(F(" [M] Toggle between Mono and Stereo Output."));
Serial.println(F(" [g] Skip to a predetermined offset of ms in current track."));
Serial.println(F(" [k] Skip a predetermined number of ms in current track."));
Serial.println(F(" [r] resumes play from 2s from begin of file"));
Serial.println(F(" [R] Resets and initializes VS10xx chip."));
Serial.println(F(" [O] turns OFF the VS10xx into low power reset."));
Serial.println(F(" [o] turns ON the VS10xx out of low power reset."));
Serial.println(F(" [D] to toggle SM_DIFF between inphase and differential output"));
Serial.println(F(" [V] Enable VU meter Test."));
Serial.println(F(" [B] Increament bass frequency by 10Hz"));
Serial.println(F(" [C] Increament bass amplitude by 1dB"));
Serial.println(F(" [T] Increament treble frequency by 1000Hz"));
Serial.println(F(" [E] Increament treble amplitude by 1dB"));
#endif
Serial.println(F(" [l] Display list of music files"));
Serial.println(F(" [0####] Enter index of file to play, zero pad! e.g. 01-65534"));
Serial.println(F(" [h] this help"));
}
void SerialPrintPaddedNumber(int16_t value, int8_t digits ) {
int currentMax = 10;
for (byte i=1; i<digits; i++){
if (value < currentMax) {
Serial.print("0");
}
currentMax *= 10;
}
Serial.print(value);
}
view raw MP3Shield.ino hosted with ❤ by GitHub

We then moved on to connecting it with the RFID to try getting them to work with each other, at this point we found it difficult to get both codes working with each other, we searched online to find examples in order to help us get the communication we needed. In the end we couldn’t find anything that was similar to our project without it having buttons to help play or stop songs. We looked at the project with buttons and as guidance we used their code to turn the RFID into a button so it would work similarly, we made another void to connect both the RFID and the shield player. We added a bool variable in order to tell if it was playing something we called it runSound, and added it to our mp3 code in the IF statement. That would be triggered in our ReadTag function when the RFID scanner was used, if the card was read and it matched one of the codes it would play the song assigned to it.

/******** RFID&MP3******/
#include <Arduino.h>
#line 1 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
#line 1 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
/**
\file MP3ButtonPlayer2.ino
\brief Example sketch of using the MP3Shield Arduino driver using buttons,
with arduino recommended(simpler) debounce library
\remarks comments are implemented with Doxygen Markdown format
\author Michael P. Flaga
This sketch demonstrates the use of digital input pins used as buttons as
NEXT, PLAY and STOP to control the tracks that are to be played.
Where PLAY or STOP will begin or cancel the stream of track000.mp3 through
track999.mp3, as indexed by NEXT, begining with 0.
\note Use this example uses the bounce2 library to provide debouncing fuctions. Advocated by Arduino's website at http://playground.arduino.cc/code/bounce
*/
// libraries
#include <SPI.h>
#include <SdFat.h>
#include <SFEMP3Shield.h>
#include <SoftwareSerial.h>
SoftwareSerial rSerial(5, 3); // RX, TX
SdFat sd;
SFEMP3Shield MP3player;
int8_t current_track = 0;
const int tagLen = 16;
const int idLen = 13;
const int kTags = 4;
// Put your known tags here!
char knownTags[kTags][idLen] = {
"5500080E8FDC",//Track 0
"550008004A17",//Track 1
"111111111111"
};
char newTag[idLen];
bool runSound = false;
//——————————————————————————
#line 47 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
void setup();
#line 61 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
void loop();
#line 101 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
void readTag();
#line 181 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
int checkTag(char nTag[], char oTag[]);
/#line 47 "C:\\Users\\EOLuser\\AppData\\Local\\Temp\\arduino_modified_sketch_325931\\MP3ButtonPlayer2.ino"
void setup() {
Serial.begin(115200);
rSerial.begin(9600);
if (!sd.begin(9, SPI_HALF_SPEED)) sd.initErrorHalt();
if (!sd.chdir("/")) sd.errorHalt("sd.chdir");
MP3player.begin();
MP3player.setVolume(10, 10);
Serial.println(F("Looking for Buttons to be depressed…"));
}
//——————————————————————————
void loop() {
// Below is only needed if not interrupt driven. Safe to remove if not using.
#if defined(USE_MP3_REFILL_MEANS) \
&& ( (USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer) \
|| (USE_MP3_REFILL_MEANS == USE_MP3_Polled) )
MP3player.available();
#endif
readTag();
if (runSound == true) {
Serial.print(F("B_PLAY pressed, Start Playing Track # "));
Serial.println(current_track);
MP3player.playTrack(current_track);
delay(1000);
runSound = false;
}
}
void readTag() {
// Counter for the newTag array
int i = 0;
// Variable to hold each byte read from the serial buffer
int readByte;
// Flag so we know when a tag is over
boolean tag = false;
// This makes sure the whole tag is in the serial buffer before
// reading, the Arduino can read faster than the ID module can deliver!
if (rSerial.available() == tagLen) {
tag = true;
}
if (tag == true) {
while (rSerial.available()) {
// Take each byte out of the serial buffer, one at a time
readByte = rSerial.read();
/* This will skip the first byte (2, STX, start of text) and the last three,
ASCII 13, CR/carriage return, ASCII 10, LF/linefeed, and ASCII 3, ETX/end of
text, leaving only the unique part of the tag string. It puts the byte into
the first space in the array, then steps ahead one spot */
if (readByte != 2 && readByte != 13 && readByte != 10 && readByte != 3) {
newTag[i] = readByte;
i++;
}
// If we see ASCII 3, ETX, the tag is over
if (readByte == 3) {
tag = false;
}
}
}
// don't do anything if the newTag array is full of zeroes
if (strlen(newTag) == 0) {
return;
}
else {
int total = 0;
for (int ct = 0; ct < kTags; ct++) {
total += checkTag(newTag, knownTags[ct]);
if(total >0){
current_track = ct;
break;
}
}
// If newTag matched any of the tags
// we checked against, total will be 1
if (total > 0) {
runSound = true;
// Put the action of your choice here!
// I'm going to rotate the servo to symbolize unlocking the lockbox
Serial.println("Success!");
}
else {
// This prints out unknown cards so you can add them to your knownTags as needed
Serial.print("Unknown tag! ");
runSound = false;
Serial.print(newTag);
Serial.println();
}
}
// Once newTag has been checked, fill it with zeroes
// to get ready for the next tag read
for (int c = 0; c < idLen; c++) {
newTag[c] = 0;
}
}
int checkTag(char nTag[], char oTag[]) {
for (int i = 0; i < idLen; i++) {
if (nTag[i] != oTag[i]) {
return 0;
}
}
return 1;
}
view raw RFID&MP3.ino hosted with ❤ by GitHub

Phase 3: Adding an interrupt to the code

After getting the RFID and MP3 player working together we wanted to have a way to change songs while other songs were being played. At this point we have a song playing but you would have to wait for it to finish playing and then play the next song, but we wanted users to have the freedom of changing the song in at any point. In order to do this we had to go searching for some kind of code that would let the user change the song, what we found was an interrupt code. I had a hard time trying to figure out how to implement the code I had found into our working code, I tried adding a function that would allow me to interrupt the music playing or at least stop it while the user scanned the next card. After some time working on the interrupt I found that it didn’t want to work along with the rest of the code, so I had to find a way to make it work using the other code I looked out from the samples of the hardware. The mp3 shield player has a line of code as “MP3player.stopTrack();” which allowed me to stop the song when I need it too, I added that line to our RFID code. When a card is scan the song would start playing and if you scan a card again it would stop the song and start whatever song would be assigned to that card, even if it was the same song. In the end we only needed a couple lines of code to get the project working the way we wanted.

/******* Final Project Code *********/
// libraries
#include <SPI.h>
#include <SdFat.h>
#include <SFEMP3Shield.h>
#include <SoftwareSerial.h>
SoftwareSerial rSerial(5, 3); // RX, TX
SdFat sd;
SFEMP3Shield MP3player;
int8_t current_track = 0;
const int tagLen = 16;
const int idLen = 13;
const int kTags = 6;
const byte interruptPin = 10;
volatile byte state = LOW;
// Put your known tags here!
char knownTags[kTags][idLen] = {
"5500080E8FDC",//Track 0
"550008004A17",//Track 1
"6500E7385DE7", //Track 2
"6800901D7E9B", //Track 3
"67009C0DEE18", //Track 4
"111111111111"
};
char newTag[idLen];
bool runSound = false;
//——————————————————————————
int checkTag(char nTag[], char oTag[]);
void setup() {
Serial.begin(115200);
Serial.println(F("Looking for Buttons to be depressed 2 …"));
rSerial.begin(9600);
Serial.println(F("Looking for Buttons to be depressed 3 …"));
if (!sd.begin(9, SPI_HALF_SPEED)) sd.initErrorHalt();
if (!sd.chdir("/")) sd.errorHalt("sd.chdir");
MP3player.begin();
MP3player.setVolume(10, 10);
Serial.println(F("Looking for Buttons to be depressed…"));
pinMode(interruptPin, INPUT_PULLUP);
//attachInterrupt(digitalPinToInterrupt(interruptPin),rfidInterrupt,CHANGE);
}
//——————————————————————————
void loop() {
// Below is only needed if not interrupt driven. Safe to remove if not using.
#if defined(USE_MP3_REFILL_MEANS) \
&& ( (USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer) \
|| (USE_MP3_REFILL_MEANS == USE_MP3_Polled) )
MP3player.available();
#endif
readTag();
if (runSound == true) {
Serial.print(F("B_PLAY pressed, Start Playing Track # "));
Serial.println(current_track);
MP3player.playTrack(current_track);
delay(1000);
Serial.println(F("Looking for Buttons to be depressed 44 …"));
runSound = false;
}
//digitalWrite(rSerial, state);
}
void rfidInterrupt(){
MP3player.stopTrack();
Serial.println(F("Looking for Buttons to be depressed… 22"));
runSound = false;
}
void readTag() {
// Counter for the newTag array
int i = 0;
// Variable to hold each byte read from the serial buffer
int readByte;
// Flag so we know when a tag is over
boolean tag = false;
// This makes sure the whole tag is in the serial buffer before
// reading, the Arduino can read faster than the ID module can deliver!
if (rSerial.available() == tagLen) {
tag = true;
}
if (tag == true) {
while (rSerial.available()) {
// Take each byte out of the serial buffer, one at a time
readByte = rSerial.read();
/* This will skip the first byte (2, STX, start of text) and the last three,
ASCII 13, CR/carriage return, ASCII 10, LF/linefeed, and ASCII 3, ETX/end of
text, leaving only the unique part of the tag string. It puts the byte into
the first space in the array, then steps ahead one spot */
if (readByte != 2 && readByte != 13 && readByte != 10 && readByte != 3) {
newTag[i] = readByte;
i++;
}
// If we see ASCII 3, ETX, the tag is over
if (readByte == 3) {
tag = false;
}
}
}
// don't do anything if the newTag array is full of zeroes
if (strlen(newTag) == 0) {
return;
}
else {
int total = 0;
for (int ct = 0; ct < kTags; ct++) {
total += checkTag(newTag, knownTags[ct]);
if(total >0){
current_track = ct;
break;
}
}
// If newTag matched any of the tags
// we checked against, total will be 1
if (total > 0) {
runSound = true;
MP3player.stopTrack();
// Put the action of your choice here!
// I'm going to rotate the servo to symbolize unlocking the lockbox
Serial.println("Success!");
}
else {
// This prints out unknown cards so you can add them to your knownTags as needed
Serial.print("Unknown tag! ");
runSound = false;
Serial.print(newTag);
Serial.println();
}
}
// Once newTag has been checked, fill it with zeroes
// to get ready for the next tag read
for (int c = 0; c < idLen; c++) {
newTag[c] = 0;
}
}
int checkTag(char nTag[], char oTag[]) {
for (int i = 0; i < idLen; i++) {
if (nTag[i] != oTag[i]) {
return 0;
}
}
return 1;
}

Phase 4: Final project and adding lights

Our final project turned out as best as we can could make it with our limited hardware and knowledge. The overall goal for our project was to make a music box that was easy for anyone to use, originally we wanted to attach songs with objects but due to our time we had we weren’t able to do that. But we ended up having the main goal become a reality, the box is easy to use and people enjoyed being able to change the song at any point. We added a couple of LEDs to the side as an add on with a button you can press to change the color, but in the future I would like to develop them more so they will change on their own depending on the mood of the song. We lazer but the box with finger joints for easy assembly and stained the wood to make it look nice, as well as painting the front where the card slot is with chalk board paint. We added two holes in the back for the power wires and the aux cord that went to the speaker for easy access. In the end we had a working music box that I was proud of presenting and will be using in the future.

//Sarah MacDonald, Monica Chairez, Dureti Ahmed
//INTERACTIVE OBJECT: LED Button Code
//initialize led pins
//green led
int ledPin1 = 5;
//yellow led
int ledPin2 = 4;
//red led
int ledPin3 = 3;
//button
int switchPin = 7;
int count = 0;
boolean lastButton;
boolean currentButton = false;
boolean ledOn = false;
void setup() {
pinMode(switchPin, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
count = 0;
}
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
//change between lights based on button push
if (last != current)
{
delay(5);
current = digitalRead(switchPin);
}
return current;
}
void loop() {
lastButton = currentButton;
currentButton = debounce(lastButton);
if (lastButton == false && currentButton == true)
{
if (count == 0)
{
count++;
//turn on green light
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
}
else if (count == 1)
{
//turn on yellow light
count++;
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, LOW);
}
else if (count == 2)
{
//turn on red light
count++;
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, HIGH);
}
else if (count == 3)
{
//turn off all lights
count = 0;
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
}
}
}
view raw Lights.ino hosted with ❤ by GitHub

Music Box Schematics

LED light schematics

Photos

We were required to keep the RFID on the breadboard because that was the only way we could make it work, the LED was were soldered to a breakout board.

Video

Lab 5 – Motors

Part 1: DC Motor

For this lab we worked with two different motors one DC motor and one Stepper motor. The first part of this lab was to build a circuit that that would tell a DC motor to turn clockwise or counterclockwise. By using an H-bridge we are able to make the DC motor work with the Arduino. We used a 10k ohm resistor for the switch and connected everything with the bread board, I also connected the switch to digital input 2.

The wiring looks slightly complicated but using the schematic I was able to connect everything correctly and make the motor work.

The code for this motor was a lot easier than I though it was going to be, in order to make the motor switch direction I used a simple if and else statement that would switch the amount of power going to parts of the H-bridge.

const int switchPin = 2; //switch input
const int motor1Pin = 3; // H-bridge leg 1 (pin2, 1A)
const int motor2Pin = 4; // H-bridge leg 2 (pin 7, 2A)
const int enablePin = 9; // H-bridge enable pin
void setup() {
//set the switch as an input:
pinMode(switchPin, INPUT);
//set all the oether pins you're using as outputs:
pinMode(motor1Pin, OUTPUT);
pinMode(motor2Pin, OUTPUT);
//set enablePin high so that motor can turn on:
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, HIGH);
}
void loop() {
// if the switch is heigh, motor will turn on one direction
if(digitalRead(switchPin) == 1)
{
//set leg 1 of the H-bridge low
digitalWrite(motor1Pin, LOW);
//set leg 2 of the H-bridge high
digitalWrite(motor2Pin, HIGH);
}
//else (which means the switch is low), motor will turn in the other direction
else{
//set leg 1 of the H-bridge high
digitalWrite(motor1Pin, HIGH);
//set leg 2 of the H-bridge low
digitalWrite(motor2Pin, LOW);
}
}
view raw DC_Motor.ino hosted with ❤ by GitHub

Part 2: Stepper Motor

The second part to this lab was using a stepper motor and have it go one whole revolution then stop and make it go the other way. The stepper motor was a little more complicated to make work compared to the DC motor. When trying to make it rotate I ran into a problem where I would try to make it do a full rotation but it did not move, instead it would get stuck. So in order to fix that I changed the connection of the cable that went to VIN and connected it directly to the 5V power.

The wiring was simple due to the schematics we used the only problem I ran into was that wire that goes from VIN, but after figuring that out the motor started running smoothly. All the changes that needed to be made was in the code and not the wiring.

The code for this motor was a little more difficult than the one for the DC motor. Using the Stepper motor library I was able to make it work, and the examples in the Arduino library helped a lot in order to get the correct amount of revolutions for the motor I had.

#include <Stepper.h>
const int stepsPerRevolution = 480; // change this to fit the number of steps per revolution
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(9600);
}
void loop() {
// step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}

Lab 4-Serial Game or Audio Controller

Part 1: The Arduino side

The first part of the lab was to establish connection between Arduino and P5 using the web editor with serial port library. First I started by testing out the connection by using the code we were given in class, that code gives you a simple message that tells you if you have connected to the port or not. We also have to make sure that we include the file serialport.js into our projects because that is part of what allows us to connect into ports.

/*
This P5 sketch is a template for getting started with Serial Communication.
The SerialEvent callback is where incoming data is received
By Arielle Hein, adapted from ITP Phys Comp Serial Labs
Edited March 12 2019
*/
var serial; //variable to hold an instance of the serial port library
var portName = 'YOUR-PORT'; //fill in with YOUR port
function setup() {
createCanvas(400, 300);
serial = new p5.SerialPort(); //a new instance of serial port library
//set up events for serial communication
serial.on('connected', serverConnected);
serial.on('open', portOpen);
serial.on('data', serialEvent);
serial.on('error', serialError);
serial.on('close', portClose);
//open our serial port
serial.open(portName);
//let's figure out what port we're on – useful for determining your port
// serial.on('list', printList); //set a callback function for the serialport list event
// serial.list(); //list the serial ports
}
function draw() {
background('dodgerblue');
}
//all my callback functions are down here:
//these are useful for giving feedback
function serverConnected(){
console.log('connected to the server');
}
function portOpen(){
console.log('the serial port opened!');
}
//THIS IS WHERE WE RECEIVE DATA!!!!!!
//make sure you're reading data based on how you're sending from arduino
function serialEvent(){
//receive serial data here
}
function serialError(err){
console.log('something went wrong with the port. ' + err);
}
function portClose(){
console.log('the port was closed');
}
// get the list of ports:
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
}
}
view raw sketch.js hosted with ❤ by GitHub

This is the serialport.js

https://raw.githubusercontent.com/vanevery/p5.serialport/master/lib/p5.serialport.js

After I establish connection I started with getting an input from the Arduino to change something on the P5 screen, as well as light up one LED when the potentiometer was turned. When I got that working I moved on to having to potentiometers changing elements of the P5 screen. On the P5 side I used the code that was provided by our Professor and worked on the Arduino side myself.

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(6, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorValue = analogRead(A0);
int sensorValue2 = analogRead(A1);
int val = analogRead(0);
int val2 = analogRead(1);
int mappedval = map(val, 0, 1023, 0, 255);
int mappedval2 = map(val2, 0, 1023, 0, 255);
Serial.write(mappedval);
Serial.write(mappedval2);
Serial.print(mappedval1);
Serial.print(",");
Serial.println(mappedval2);
analogWrite(6, mappedval);
delay(1);
}
view raw Lab4_input2.ino hosted with ❤ by GitHub

The code was simple to make I took part of my code from last lab and added code so that there would be serial communication between p5 and the Arduino. Below is a video of the two potentiometers working and the light turning on as the dot color changes.

Part 2: The P5 Side

The second part to this lab was getting connection between P5 and the Arduino but focusing on getting P5 to make something on the Arduino light up. I started by looking at the P5 code that was in the Github repo in order to get a sense of what the code in Arduino should look like. I had to google a couple of things to get a full understanding of what it was doing but in the end I got the right code to work and get an input from P5.

const int ledPin = 5; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
void setup() {
Serial.begin(9600); // initialize serial communication
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
}
void loop() {
//RECEIVE ASCII
if (Serial.available() > 0) { // see if there's incoming serial data
incomingByte = Serial.read(); // read it
if (incomingByte == 'H') { // if it's a capital H (ASCII 72),
digitalWrite(ledPin, HIGH); // turn on the LED
}
if (incomingByte == 'L') { // if it's an L (ASCII 76)
digitalWrite(ledPin, LOW); // turn off the LED
}
}
}
view raw Lab4_P5.ino hosted with ❤ by GitHub

Part 3: Simple Interactive Game

For the last part of the lab we had to create a interactive game that had inputs and outputs. I made a Space Shooter game where I implemented a potentiometer to move the player in the x direction and then a FSR sensor to shoot the enemy’s. I also added two LEDS to the FSR sensor as a output when your shooting they turn on, and if you hold down the sensor the LEDS stay on. The link below is the full game code and all the images.

https://github.com/Mch117/SerialGame

I did a simple circuit that connects one potentiometer and one FRS to Analog inputs 0 and 1. I had the LEDS connected to pin 6.

The fallowing code is the Arduino code I used to make sure my sensors were working and to write serial inputs into P5.

int LEDpin = 6;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDpin, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorVal = analogRead(A0);
int sensor = analogRead(A1);
// int mappedval = map(sensorVal, 0, 1023, 0, 255);
//int pressure = map(sensor, 0, 1023, 0, 6);
//Serial.write(mappedval);
//Serial.write(pressure);
Serial.print(sensorVal);
Serial.print(",");
Serial.println(sensor);
if(sensor > 1)
{
digitalWrite(LEDpin, HIGH);
}
else
{
digitalWrite(LEDpin, LOW);
}
delay(1);
}

There wasn’t a lot that I had to change in my game code to make it usable with Arduino, I had to add the Serial port connection and add a map code so the sensors took the input and where usable. The fallowing three lines is the code that adds the ability to move the player and shoot with the sensors.

var newValue = map(sensor1, 0, 1023, 0, width -40);
player.x = newValue;

var button = map(sensor2, 0, 1023, 0, 6);

The fallowing video is the game working with the sensors.

var serial; //variable to hold an instance of the serial port library
var portName = 'COM4'; //fill in with YOUR port
var inData; //a variable to store incoming data
var sensor1, sensor2; //variables for each of my incoming sensor values – name these whatever you want
function setup() {
serial = new p5.SerialPort(); //a new instance of serial port library
//set up events for serial communication
serial.on('connected', serverConnected);
serial.on('open', portOpen);
serial.on('data', serialEvent);
serial.on('error', serialError);
//open our serial port
serial.open(portName);
createCanvas(canvasWidth, canvasHeight);
noCursor();
}
/////////////////////////////////////////////// Game Part
var canvasWidth = 600;
var canvasHeight = 400;
var score = 0;
//player
var player = {
color : "#FFF",
x : 280,
width : 40,
y : 355,
height: 40,
draw : function(){
image(img_player, this.x, this.y, this.width, this.height);
},
}
//bullet
var bullets = [];
function Bullet(I){
I.active = true;
I.x = player.x + player.width/2;
I.y = player.y + player.height/2;
I.width = 3;
I.height = 6;
I.yVelocity = 5;
I.inBounds = function(){
return I.x >= 0 && I.y >= 0 && I.x < canvasWidth – I.width && I.y < canvasHeight – I.height;
}
I.update = function(){
I.active = I.active && I.inBounds();
I.y -= I.yVelocity;
}
I.draw = function(){
image(img_bullet, I.x, I.y, I.width, I.height);
}
return I;
}
//enemies
var enemies = [];
function Enemy(I){
I.active = true;
I.x = Math.random() * canvasWidth;
I.y = 0;
I.width = 30;
I.height = 30;
I.yVelocity = 2;
I.inBounds = function(){
return I.x >= 0 && I.y >= 0 && I.x < canvasWidth – I.width && I.y < canvasHeight – I.height;
}
I.draw = function(){
image(img_enemy, I.x, I.y, I.width, I.height);
}
I.update= function(){
I.active = I.active && I.inBounds();
I.y += I.yVelocity;
}
return I;
}
//collision function
function collision(enemy, bullet){
return bullet.x + bullet.width >= enemy.x && bullet.x < enemy.x + enemy.width &&
bullet.y + bullet.height >= enemy.y && bullet.y < enemy.y + enemy.height;
}
//canvas functions
var img_enemy, img_player, img_bullet;
var sound_enemy_dead, sound_player_dead, sound_bullet, sound_game_start;
function preload(){
//load images
img_enemy = loadImage("images/enemy.png");
img_player = loadImage("images/player.png");
img_bullet = loadImage("images/bullet.png");
//load sounds
sound_enemy_dead = loadSound("sounds/enemy_dead.wav"); //Creative Commons 0 License – https://freesound.org/people/qubodup/sounds/332056/
sound_bullet = loadSound("sounds/bullet.wav"); //Creative Commons 0 License – https://freesound.org/people/cabled_mess/sounds/350924/
sound_player_dead = loadSound("sounds/player_dead.wav"); //Creative Commons 0 License – https://freesound.org/people/n_audioman/sounds/276362/
sound_game_start = loadSound("sounds/game_start.wav") //Creative Commons 0 License – https://freesound.org/people/GameAudio/sounds/220209/
//adjust sounds volumes if necessary
sound_bullet.setVolume(0.2);
}
//Sensor Value Input from Arduino
//var sensor1; // variables for each of my incoming sensor values
//var sensor2;
function draw(){
fill(255);
clear();
background("#000");
text("score : " + score, 10, 10);
fill(player.color);
var newValue = map(sensor1, 0, 1023, 0, width -40);
player.x = newValue;
var button = map(sensor2, 0, 1023, 0, 6);
/*
//Movement of player ////////////////////////////////////
if(newValue){
if(player.x-5 >= 0)
player.x -= 5;
else
player.x = 0;
}
if(keyIsDown(RIGHT_ARROW)){
if(player.x + 5 <= canvasWidth-player.width)
player.x += 5;
else
player.x = canvasWidth – player.width;
}*/
if(button){
bullets.push(Bullet({}));
sound_bullet.play();
print("I am shooting");
}
player.draw();
bullets = bullets.filter(function(bullet){
return bullet.active;
});
bullets.forEach(function(bullet){
bullet.update();
bullet.draw();
});
if(Math.random()<0.05){
enemies.push(Enemy({}));
}
enemies = enemies.filter(function(enemy){
return enemy.active;
});
enemies.forEach(function(enemy){
enemy.update();
enemy.draw();
});
bullets.forEach(function(bullet){
enemies.forEach(function(enemy){
if(collision(enemy, bullet)){
enemy.active = false;
bullet.active = false;
score++;
sound_enemy_dead.play();
}
});
});
enemies.forEach(function(enemy){
if(collision(enemy, player)){
enemy.active = false;
noLoop();
sound_player_dead.play();
textSize(40);
text("GAME OVER", 180, 200);
}
});
}
///////////////////////////////////////////Serial stuff
//all my callback functions here:
//callback functions are useful for giving feedback
function serverConnected(){
console.log('connected to the server');
}
function portOpen(){
console.log('the serial port opened!');
}
//THIS IS WHERE WE ACTUALLY RECEIVE DATA!!!!!!
//make sure you're reading data based on how you're sending from arduino
function serialEvent(){
//THIS READS BINARY – serial.read reads from the serial port, Number() sets the data type to a number
// inData = Number(serial.read()); //reads data as a number not a string
//THIS READS ASCII
inData = serial.readLine(); //read until a carriage return
//best practice is to make sure you're not reading null data
if(inData.length > 0){
//split the values apart at the comma
var numbers = split(inData, ',');
//var numbers = inData;
//set variables as numbers
sensor1 = Number(numbers[0]);
sensor2 = Number(numbers[1]);
console.log(sensor1 + ", " + sensor2);
}
}
function serialError(err){
console.log('something went wrong with the port. ' + err);
}
// get the list of ports:
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
}
}
view raw Game.js hosted with ❤ by GitHub

Hiroshi Ishii Talk

After attending Hiroshi Ishii’s talk I was really fascinated by everything he is apart of, when I hear about MIT I think about more of a scientific approach to things instead of an artistic way to look at things. I was really fascinated by the early project had which was the ClearBoard, it was an idea that a lot of people have thought of but never executed. I always wondered how a board like that would work and it was really interesting to hear how it was created and how tangible bits became a reality because of these kinds of projects. It was very inspiring to hear about all the other projects he has helped to develop along the way, like I/O Brush. I was really amazed by this project and how they came up with the idea of being able to paint with real world inputs, and it was created with one of his students. Its amazing how the idea of tangible bits became something that has created a whole new world, there has been amazing projects that have come out of this idea of human-computer interactions. When he started explaining about the award he had won which was the SIGCHI Lifetime Research Award I wasn’t too sure what it was about or why it was a big deal but I did some research and I was amazed, only those that have made a major contribution to their field of research can be nominated. Not only do they have to make a contribution but also be recognized by others as an influence for those research projects and that means you have a major affect on the people around you. Its hard to reach that kind of level with new innovative human-computer interaction. A lot of the world is still scared of what we can create with new technology so having that acknowledgment from the community is amazing to me. Through out the presentation I was so fascinated by all the projects and the perspective he had in of each project, because he saw materials that could be used to make something for the world and a lot of people cant even see a shape in a cloud. To be able to turn materials into useful formats using computers is very intelligent, for example the TRANSFORM project it shapes the material to conform to objects or patterns that you have used to hold things. Its intelligent furniture that we have dreamed of but has been made through research and the brilliance of Hiroshi Ishii. It was really inspiring to have gone to this talk it made me think of new ways we can create different interactions with the world, I have even though of ideas that could possibly work but would need some research. I never thought that something so futuristic would have started from a long time ago and it was interesting to see how human ideas have evolved over time to become tangible bits and radical atoms.

Lab 3 Analog Sensor Box

Part 1: Variable Input & Output

For the first part of the lab was to make a circuit with one potentiometer and one other variable resistor as an input, then have two LEDs as the output. First I started by testing out the potentiometer in order to identify the sensor value in order to map the code for the rest of the project. I started by connecting one simple turn nob into the Arduino and the breadboard.

The above picture shows how I initially started connecting the potentiometer. Then I connected 2 LED to the board so we can manipulate it with the potentiometer, using code we are able to change the brightness of the LED turning it on and off. The next picture shows how the potentiometer changes the brightness of the LEDS with one nob.

From there we added another potentiometer and each LED was individually connected to one, that way we are able to manipulate each one. Everything was connected in series so in order to work each part individually I had to code each analog input in order to get the LED to work individually.

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorValue = analogRead(A0);
int sensorValue1 = analogRead(A1);
int val = analogRead(0);
int val2 = analogRead(1);
val = map(val, 0, 1023, 0, 255);
val2 = map(val2, 517, 1023, 0, 255);
analogWrite(9, val);
analogWrite(10, val2);
//Serial.println(sensorValue);
Serial.println(sensorValue1);
delay(1);
}
view raw LED_TURN2.ino hosted with ❤ by GitHub

Part 2: Tone Output

For the second part of the lab we had to create a circuit that connects two photoresistors and one 8-ohm speaker in order to create an input by using your hands and an output to the speaker. I connected the two photoresistors and the spealer in a series like the picture below.

In the circuit I added a 100 ohm resistor to the speaker and connected the two photoresistors to A0. The speaker is connected to pin 8 and the other cable is connected to ground.

The video shows how it works and how one photoresistor makes the noise louder and the other stops it completely.

//starts at 588
//declafe float variable for our frequency value
//declare float variable for our frequency value
void setup() {
// initialize serial communication
Serial.begin(9600);
}
void loop() {
//read analog input on A0, set sensorReading to this value
//map sensorReacing to a an output between 100 and 1000, sst frequency to this
//change the pitch, play for 10ms – use tone()
int sensorReading = analogRead(A0);
int Pitch = map(sensorReading, 588, 1000, 100, 1000);
tone(8, Pitch, 10);
delay(1);
}
view raw Sound.ino hosted with ❤ by GitHub

Part 3: Laser Cut Sensor Box

For the third part of the project we had to create a sensor box that took two analog inputs and had two analog outputs. I choose to do a potentiometer and a softpot sensor. The potentiometer connected to the speaker and changed the volume of the sound coming from it. The softpot sensor changed how many lights were turned on base on where your finger is putting pressure on. If its closer to the connection it turns off the lights the farther you go out the more lights turn on.

This is my schematic for my box with all the holes for the analog input and outputs. Below is the schematic for the wiring to the box.

Below is the code that takes in the sensor inputs and outputs to the analog interaction. I had to figure out how to input both sensors since I hadn’t used the softpot sensor, and I also learned that the softpot sensor take a lot more power than the other sensor. I had to connect my outside power so it would all work correctly. In the end I was able to wire and code everything to work how I wanted and the lazer cut box came out looking really good.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
const int SOFT_POT_PIN = A0; // Pin connected to softpot wiper
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, 6, NEO_GRB + NEO_KHZ800); // number of pixels, pin number
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
strip.begin();
strip.show();
pinMode(SOFT_POT_PIN, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorReading = analogRead(A1);
int Pitch = map(sensorReading, 517, 1000, 0, 1000);
tone(8, Pitch, 10);
analogWrite(8, Pitch);
Serial.println(Pitch);
// Read in the soft pot's ADC value
int softPotADC = analogRead(SOFT_POT_PIN);
// Map the 0-1023 value to 0-40
int softPotPosition = map(softPotADC, 0, 1023, 0, 6);
for(int i = 0; i < softPotPosition; i++){
strip.setPixelColor(i, 128, 0, 128);
}
for(int i = softPotPosition; i<5; i++){
strip.setPixelColor(i, 0, 0, 0);
}
if (softPotADC == 0){
strip.clear();
}
strip.show();
delay(1);
}
view raw Box.ino hosted with ❤ by GitHub

Lab 2: Digital I/O Breakout Boards

Part 1 Digital Input Breakout Board:

For this part of lab we were told to use break out boards to solder a button with its correct resistor. I choose a momentary switch (button) for my breakout board with a pull-down resistor of 10K ohm. I connected a red wire for power, a blue wire as the digital i/o pin, and a white wire as the ground wire.

I laid out all my wires and components first on the board before beginning to solder. I then soldered each connection making sure that it was just a right amount and that they didn’t connect with one another, then I cut off any extra wire.

I made two input boards for the later part of this lab but they both have the same layout as the first breakout board.

Part 2 Digital Output Board:

For this part of the lab we had to solder two LEDs onto a board as an output. I solder them in series and have a red wire connecting to one of the LEDs as ground, a 100 ohm resistor, and a dark green wire that it the digital i/o pin.

I aligned the wires and the other connections together and then soldered them just like the other breakout boards, I cut any excess connection.

I then tested out my connection by plugging in one of the input buttons to the Arduino board and the output board. I connected the button to pin 7 and the LEDs to pin 8, I also connected the power and ground from the Arduino to the bread board to complete the circuit. Under the picture there is the code I used to make the circuit work, its a simple if statement that turns on the lights if the button is pressed.

int buttonPin = 7; // Button connected to pin 7
int LEDPin = 8; // LED connected to pin 8
void setup() {
// set digital pins as inputs or outputs
pinMode(buttonPin, INPUT);
pinMode(LEDPin, OUTPUT);
}
void loop() {
// read a digital input = digitalRead(pin, VALUE)
// write to a digital output = digitalWrite(pin, VALUE)
//if button is pressed, turn LEDs on, otherwise off
if (digitalRead(buttonPin) == 1)
{
digitalWrite(LEDPin, HIGH);
}
else{
digitalWrite(LEDPin, LOW);
}
}
view raw LEDbutton.ino hosted with ❤ by GitHub

Here is a video of the button and LED working.

Digital I/O Circuit

For this part I used the neopixels we practiced soldering in lab, and the two buttons we made for the earlier part of this lab. But first I made sure that the neopixels worked so I connected it to my Arduino to test example code on them.

After I had the neopixels working I then connected them with the two buttons made from the earlier part of the lab. I connected the LEDS to pin 6 and the two buttons to pins 7 and 8.

After research on the neopixel library I found code that would help me in having the buttons do what I wanted. I made one button change the color to blue and the other button change the color to red, and when both buttons are pressed the color would change to purple. You can see a video of it working at the bottom of the blog.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
// strip connected to pin 6
#define PIN 6
// defining strip as instance of neopixel library
Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, 6, NEO_GRB + NEO_KHZ800); // number of pixels, pin number
// button 1 connected to pin 7
const int button1 = 7;
// button 2 connected to pin 8
const int button2 = 8;
// both button states starts at 0 (off)
int button1State = 0;
int button2State = 0;
void setup() {
// initialize strip
strip.begin();
// sets pixels to 0 (off)
strip.show();
// sets buttons as input
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
// reads button state
button1State = digitalRead(button1);
button2State = digitalRead(button2);
if((button1State == HIGH) && (button2State == LOW)){ // if button 1 is on (and button 2 is off)
for(uint16_t i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 255, 0, 0); // sets LED colors to red
strip.show(); // shows pixel color
delay(100); //delay of showing
}
}
else if((button2State == HIGH) && (button1State == LOW)){ // if button 2 is on (and button 1 is off)
for(uint16_t i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 0, 0, 255); // sets LED colors to blue
strip.show();
delay(100);
}
}
else if((button1State == HIGH) && (button2State == HIGH)){
for(uint16_t i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 180, 0, 180); // sets LED colors to purple
strip.show();
delay(100);
}
}
else if((button1State == LOW) && (button2State == LOW)){ // if button 1 is off and button 2 is off
for(uint16_t i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 0, 0, 0); // sets LEDs to off
strip.show();
delay(100);
}
}
}
view raw LED_Lab2.ino hosted with ❤ by GitHub

Lab 1 – Basic Electronics

Part 1: LED’s in Series and Parallel

The first part of lab was to build out two different circuits and both circuits incorporate a switch. Each circuit is built with two LED’s and a voltage regulator that will let the power going through the current be 5V.

The first circuit I built to start off was a simple LED with no switch in order to get an idea of how to start off the lab. It had one resister and two red LED’s.

Then I continued with adding a switch to my circuit to complete the series. The fallowing diagram shows my series circuit and its labeled with both voltage and resistor power.

As you can see in the schematic I calculated the resistor base on what kind of LED I had and the amount of volts in the current. I had two red LED’s which both have 2V forward voltage, which according to my calculation should result in needing to use a 50 ohm resistor to complete the circuit. I used a power regulator in my circuit in order to take the 9V input and convert it into 5V so it would overload the power going to the LED’s.

As you can see the two lights lid up which means that my circuit was complete and my calculation was correct. The electric current flows through the wires set up in the way that is drawn out in the schematic leading to the lights to light up in the end.

The next circuit I made was the parallel circuit where I have two LED’s in the same power circle but if one of them stops working the other continues to work, unlike in a series circuit. For this circuit I calculated that with an input of 5V and current having to go through two different LED’s I would need to use a resister of 75 ohms for each light.

As you can see my circuit worked and each light turned on and were wired according to my schematic. When I unplugged on the other light would stay on because they are not depended on each other, each one gets its own flow of current.

Part 2: DIY Switch

For the second part we had to make our own switch using whatever we liked. I ended up using two pieces of copper tape to make a press together kind of switch, when you press the two copper pieces together it makes the lights switch on. I continued to use my circuit in a parallel because I wanted to make sure that in the future if one LED didn’t work it wouldn’t stop my project from working completely.

After connecting the new switch into the circuit I tested it out by pressing the two pieces of copper tape together and the two LED’s turned on. When the copper pieces don’t touch at all they break the electrical current of the circuit, so when you touch the pieces together it creates a closed circuit and the lights turn on.

Part 3: Creative Enclosure

For the last part of the lab we had to make a creative enclosure for our DIY switch and because I had a switch you had to press together I had to think of a creative way to use it. I noticed a lot of other people making similar enclosures so I thought of making something completely different but simple. I decided to make a happy box, that went along with the song “If your happy and you know it”, it might be simple but it did make me happy when I saw the lights turn on when the two hands clapped together.

This is how it looked from both the side and the top.

The fallowing is a short video of how my enclosure and switch look and worked as you pressed the hands together.