Introduction: Spark.io Build Night Rex-o-Phone Wifi Xylophone

Our Spark Build Nights on November 13 and 15th 2014 at Blooming-labs were a lot of fun thanks to Spark.io and Instructables for making the Build Night possible! I was building a glockenspiel played by solenoids from a player piano so why not make it wireless, too?

The following steps necessary to successfully build a WiFi controlled interactive xylophone are listed below and will give you a starting point for building your own versions.

  • source for xylophone tone bars formulas and ideas from nerd Kits.
  • initial project using hand built solenoids not discussed any further here.
  • acquiring player piano solenoids happenstance of visiting cousins piano shop
  • the 74ls595 serial tri state shift register
  • drive circuitry schematic
  • testing software with Arduino
  • the serial shift command
  • how to shift 16 bit unsigned integer words
  • the web interface *hacked from rtttl remote player http://spark.io
  • multiple buttons on web interface
  • the spark io side also from rttl remote player
  • project photos
  • circuit schematics
  • etching the board
  • populating the board and other problems with tip120 darlington pair NPN transistors Be mindfull of proper testing of power supplies and resistor values. Each project requires meticulous testing.
  • Inkscape files and design
  • design spark pcb design software.
  • other projects. http://microrexrobotics.com


Conclusions Don't rush and Don't procrastinate ...

continuation of project. never done and always being modified. never satisfied.

Step 1: Step 1 Source for Xylophone Tone Bars Formulas and Ideas From Nerdkits.

frequency in hertz
length inches note inches from each end of bar

..Please see reference table..

For the tenacious builder please note : The project tone bars were cut from 1" x 1/4" aluminum bar stock. Each bar

cut to a slightly longer length allowing for pitch adjustment. There is an android phone application called

chromatic piano tuner which can be used to measure the bar frequency. To sharpen the tone file excess

off of ends of the bars. To flatten the tone grove "grind" material from the center of bar between nodes.

Step 2: Step 2 . Initial Project Used Hand Built Solenoids However There Was a Better Solution

The better solution if you can find them are player piano solenoids.

Step 3: Step 3. Mounting the Solenoids for Rex-O-Phone

There is a major advantage of being a member of a Hacker Space particularly Bloominglabs is access to the Full Spectrum laser cutter. Using InkScape I drew up plans for the case and mounting holes and brackets for the xylophone.

Step 4: Step 4. the Input Output Solution... 74ls595 Tristate Octal Serial Shift Register

A total 16 chromatic tone bars and solenoids were mounted on the xylophone case. For driving the solenoids from

the spark .io I used (2) 74ls595 tri state octal serial shift registers to expand the output pins. The 74ls595

requires a data input Spark.io D3, a serial shift clock spark.io D4, a data latch clock Spark.io D5, a

data latch tristate control line Spark.io D6 and a clear shift register data latch pin Spark.io D7. Note that

according to your code the pins may be reassigned. Data sheets presented in this instructable were

downloaded from Jameco.com or Digikey.com. The schematic depicts using a network of 2n2222 and a tip120

darlington pair however one could also consider using the uln2804 driver ic simplifying the design if 500 ma drive

current is sufficient for the solenoids.

Step 5: Step 5. Code Development Spark.io Side

Preliminary hardware was laid out with point to point soldering . Initial code development was done with

an arduino 328 clone .shiftOut(dataPin, clockPin, LSBFIRST, j); was the first intstruction used and it

was found that it would only shift out an a bit word.

/*************************************************************/
/* Spark.io functions for processing webpage interaction */

/* Bloominglabs Spark.io build night november 13 and 15 2013 */

/* by Rex M Marling */

/* Currently a project in progress for a microcontrolled */

/* glockenspiel (xylophone). The Spark.io enables wireless */

/* interfacing with the associated file Play RexOphone html file */

/* Two 74ls595 shift registers are being utilized to expand */

/* the output data from the spark.io. Jan 3 2015 */

/* INITIALIZE DATA TYPES AND TRIGGER INTERRUPT FUNCTION /* /* character data type */

//char *songPtr;

/* BOOL DATA TYPE */

//bool songDone = false;

bool remoteTriggered = false; // global state variable for remoteTrigger() function

/* BYTE DATA TYPE *

/byte default_dur = 4;

byte default_oct = 6;

byte lowest_oct = 3;

byte note; byte scale;

/* INT DATA TYPE */

int x; int pointer;

int result;

int bpm = 63;

int num;

int clr = 7;

int data = 3;

int clock = 4;

int latch = 5;

int enable = 6;

int counter;

/* UNSIGNED INT DATA TYPE */

unsigned int note;

unsigned int mask;

/* the following unsigned int are assigned for 16 notes*/

unsigned int a1 = 0x0001;

unsigned int b1 = 0x0002;

unsigned int c1 = 0x0004;

unsigned int c1p = 0x0008;

unsigned int d1 = 0x0010;

unsigned int d1p = 0x0020;

unsigned int e1 = 0x0040;

unsigned int f1 = 0x0080;

unsigned int f1p = 0x0100;

unsigned int g1 = 0x0200;

unsigned int g1p = 0x0400;

unsigned int a2 = 0x0800;

unsigned int ap2 = 0x1000;

unsigned int b2 = 0x2000;

unsigned int c2 = 0x4000;

unsigned int n[]= {0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002,0x0001};

/* LONG DATA TYPE */

long wholenote;

long duration;

/* DEFINES */

#define DEBUG = false;

/* SETUP DATA PORTS AND TRIGGER INTERRUPT */

void setup(void) {

// if(DEBUG) Serial1.begin(115200);

pinMode(D6,OUTPUT);

pinMode(D7,OUTPUT);

pinMode(data,OUTPUT);

pinMode(clock,OUTPUT);

pinMode(latch,OUTPUT);

pinMode(enable,OUTPUT);

digitalWrite(clock,HIGH);

digitalWrite(data,HIGH);

digitalWrite(latch,HIGH);

digitalWrite(enable,LOW);

digitalWrite(clr,HIGH);

Spark.function("remote",remoteTrigger); }

/* END SETUP DATA PORTS AND TRIGGER INTERRUPT */

/* MAIN LOOP */ void loop(void) {

/* The main loop() processes the web button click one note at a time. */

/* avoid blocking the background tasks for too long */

/* or else the Spark Core would disconnect from the Cloud. */

if(remoteTriggered) {

digitalWrite(D7,HIGH);

// Light the onboard Blue LED while the song plays };

delay(600);

digitalWrite(D7,LOW);

// Turn off the onboard Blue LED.

remoteTriggered = false;

// if(DEBUG) Serial1.println("Done!");

delay(2000); }

{

// the following code was designed to clock a 16 bit

// unsigned int "note data above " through 2 x 74ls595

// shift registers the shiftOut function only transfers

// 8 bits of data

//syntax

//shiftOut(dataPin, clockPin, bitOrder, value)

//Parameters

//dataPin: the pin on which to output each bit (int)

//clockPin: the pin to toggle once the dataPin has been set to the correct value (int)

//bitOrder: which order to shift out the bits; either MSBFIRST or LSBFIRST.

//(Most Significant Bit First, or, Least Significant Bit First)

//value: the data to shift out. (byte)

// Serial.println ("begin"); for( pointer = 0;pointer<=15;pointer++) { mask = 0x8000; //&B1000000000000000 note = n[pointer]; Serial.println(note); for( x = 0;x<=16;x++){ result = note & mask; mask = mask>>1; if (result > 0) {digitalWrite(data,HIGH); Serial.println(" high"); }

if(result == 0) {digitalWrite(data,LOW); Serial.println(" low");} digitalWrite(clock,LOW); delay( 15); digitalWrite(clock,HIGH); };

// end inner loop

digitalWrite(latch,LOW);

delay(15);

digitalWrite(latch,HIGH);

delay(15);

digitalWrite(enable,LOW);

delay(15);

digitalWrite(enable,HIGH);

delay(250); };

//end outer loop

// activate output enable for 74ls595 play note "drive output darlington transistors" then return to tristate

}

/**************************************************************/ /* */ /* END MAIN LOOP */ /**************************************************************

**************************************************************/ /* REMOTE TRIGGER FOR SPARK.IO DEVICE */ /**************************************************************/ int remoteTrigger(String args) { if(args == "1"){ counter = 1; };

if(args == "2"){ counter = 2; };

if(args == "3"){ counter = 3; };

if(args == "4"){ counter = 4; };

if(args == "5"){ counter = 5; };

if(args == "6"){ counter =6; };

if(args == "7"){ counter = 7; };

if(args == "8"){ counter =8; };

if(args == "9"){ counter = 9; };

if(args == "10"){ counter =10; };

if(args == "11"){ counter = 11; };

if(args == "12"){ counter =12; };

if(args == "13"){ counter = 13; };

if(args == "14"){ counter =14; };

if(args == "15"){ counter = 15; };

if(args == "16"){ counter =16; };

// the argument passed from the webpage buttons is

// loaded into counter for controlling the for loop

// visual test for proper functioning of webpage data

// passed on mouse button click

for(counter;counter>0;counter--)

{ digitalWrite(D7,LOW);

delay(200);

digitalWrite(D7,HIGH);

delay(200);

digitalWrite(D7,LOW); }

remoteTriggered = true; return 200; }

/* END WEB PAGE HANDLER */

Step 6: Step 6: Code Development Web Page for Spark.io

see attached code

To see spark.io being controlled by this web page click here...http://microrexrobotics.com/rexophone.mp4

Wood Contest

Participated in the
Wood Contest

Homemade Gifts Contest

Participated in the
Homemade Gifts Contest

Let's Party! Challenge

Participated in the
Let's Party! Challenge