First iPhone App

I am learning iOS  development as a full time subject at school like I did electronics last year. Yep, I go to school and learn programming. Pretty f$#^@&g awesome. We’d been doing terminal apps to learn the basics of objective c when we had a one-day workshop from apple engineers. Real apple people. The people emerged from the shadows with a holy white glow. No, they were really nice down to earth people actually. After they showed us iBooks author in the morning (it has a VERY hard to solve bug –  changing the background colour of a page) they moved on to some more advanced stuff – iOS dev. I was expecting some big thing where you have to code all this stuff to get it to display a black screen. It had to be harder than little terminal apps right? He dragged and dropped a text field, linked it up, pressed run and there was a hello world! I was like REALLY? Is it really that EASY?

This was awesome. I’d never seen anything this easy. So I mucked around for the rest of the workshop making some little things with the button and text outlets. We did a map example which everyone thought had a critical bug. It turned out to be that the simulator was set to simulate every single apple store location. So it was flying around before the map image was loaded. Making it look like the animation feature was stuffed.

I got home from the workshop and I was like, make something, anything, now! There’s some kids on my bus who talk about Minecraft EVERY day. And a lot of kids in the junior school robotics class that I teach are crazy about the stuff. I decided to make something minecrafty for them. I settled on making a little app that allows people to view all the splash texts and see what their meanings are. If you don’t know what the splash texts are go here: http://www.minecraftwiki.net/wiki/Splash . They’re basically just references to popular culture, games and in jokes. There’s 304 of them and one is randomnly displayed each time you load the game in a bright yellow flashing font.

So I set about making a little browser for these. Luckily all the splash texts are stored in a text file called splashes.txt found in minecraft.jar. So all I had to do was get the text file out, write some code to convert it to an array and print out the result. I also added the ability to view what each text means on the wiki page, and the text number. It was made as a project to learn how to make, debug, refine, submit and manage an iPhone app so I know what I’m doing when I want to make something good. The app is rated 17+ because apple has a silly rule that anything that has web access is highly dangerous. I think because it’s 17+ it’s banned in Korea or something. It’s a free app available for download from the app store.

It should top 50 downloads by the end of today. I don’t understand who would download it. Honestly.

Get the app here: http://itunes.apple.com/us/app/mc-splashes/id514227231?ls=1&mt=8

Some of my favourite reactions:

“So, what does this actually do?” Nothing really.

“Are you serious?” Yep. Vaguely.

“You’re going to charge people money for this aren’t you? Yes?” Um, no.

“Can’t you just view the wiki page?” Well, yeah but it doesn’t display them in the font and colour.

 

Advertisements

Bruce

I came up with this little guy when I was on a long car trip last weekend. I might make a game for him one day as a little project. Probably after I finish this big arduino competition entry I’ve got planned. Also, I’m still waiting for parts for my competition entry so not much is happening right now sadly. I think I’m beginning to become more of a software guy. Though this competition might bring back some of the excitement. Time will tell. I have just about had enough of the lack of control available in a wordpress.com blog. I’m thinking about maybe moving it over to a proper server sometime so I can put up files and other stuff and program the website how I like without having to stick to a pre-made theme.

Bruce

An update on some stuff

Okay so I went away for the weekend for a cycling race and on the car drive out I mostly just messed around with my new macbook air (more on that later). On the way back when I was extremely tired (as one is after racing the national champion) I remembered that I’d promised to write up some better behaviour code for that little robot I built.

The end result of that lazy little 20 minutes of code writing is pretty simple. Basically the program picks whether the robot is going to be happy, sad or neutral when the door is opened. Once it has determined that it simply shakes it’s head, blinks it’s eyes or plays a tune based on how happy it is. There are varying levels of action for each part of the robot to correspond with how happy or sad it is. Anyway, here’s the code so you can get a feel for what it’s like:

//Servo robot behaviour program
//Created by Lochie Ferrier to control a small robot
//the servo control information
#include <Servo.h>
Servo head;
//the mood of the robot when the program runs for the first time
String mood=”happy”;
//initiate variables
int selector, speakerPin, lastReading, pos,range,ledPin,lastPitch,pitch,additive,timeAfterAction=60000;
void setup(){
head.attach(9);
Serial.begin(9600);
}
//HEAD FUNCTIONS
//function to shake the head slowly
void headShakeSlow(){
pos= random(0,180);
head.write(pos);
delay(3000);
head.write(0);
delay(3000);
}
//function to shake the head moderately
void headShakeMedium(){
pos= random(0,180);
head.write(pos);
delay(2000);
head.write(0);
delay(2000);
}
//function to shake the head fast
void headShakeFast(){
pos= random(0,180);
head.write(pos);
delay(1000);
head.write(0);
delay(1000);
}
//LIGHT FUNCTIONS
void eyeBlinkSlow(){
digitalWrite(ledPin,HIGH);
delay(1000);
digitalWrite(ledPin,LOW);
}
void eyeBlinkFast(){
digitalWrite(ledPin,HIGH);
delay(500);
digitalWrite(ledPin,LOW);
}
//SOUND FUNCTIONS
void melodyLow(){
pitch=200;
int count=0;
if(count<10){
range=50;
additive=random(-range,range);
pitch = pitch+additive;
tone(speakerPin, pitch);
pitch=lastPitch;
count++;
delay(500);
noTone(speakerPin);
}
}
void melodyHigh(){
pitch=400;
int count=0;
if(count<10){
range=50;
additive=random(-range,range);
pitch = pitch+additive;
tone(speakerPin, pitch);
pitch=lastPitch;
count++;
delay(500);
noTone(speakerPin);
}
}
void loop(){
if((lastReading+2)>analogRead(0)){
selector=random(0,2);
if(selector==0){
mood=”sad”;
//perform sad behaviour for the robot
Serial.write(“:(“);
eyeBlinkSlow();
headShakeSlow();
melodyLow();
//this function ensures the robot does not continue to bug me once it has finished
//it’s little hello
delay(timeAfterAction);
}
if(selector==1){
mood=”neutral”;
//perform neutral behaviour for the robot
Serial.write(“:|”);
eyeBlinkSlow();
headShakeMedium();
melodyLow();
//this function ensures the robot does not continue to bug me once it has finished
//it’s little hello
delay(timeAfterAction);
}
if(selector==2){
mood=”happy”;
//perform happy behaviour for the robot
Serial.write(“:)”);
eyeBlinkFast();
headShakeFast();
melodyLow();
//this function ensures the robot does not continue to bug me once it has finished
//it’s little hello
delay(timeAfterAction);
}
//end of robot action
}
}

The other cool thing that has happened recently is I have received on loan for a year a Macbook Air from my school for learning iOS development. Aside from all the pretty Mac graphics and hardware design I think one of the main cool things about this computer is it’s flash hard drive. This means it’s boots up REALLY fast making it a much more useful device than my slower booting (but to be fair, faster overall Dell). Also it’s weight and size is quite impressive. I’m going to be pretty tempted to buy it from the school at the end of the year.

I was also asked by my iOS dev teacher to share my thoughts on objective-c. Well seeing as I really haven’t done that much in it already I thought I’d just make a meme about it instead.

The one annoying thing about the iPad. No programming!

The iPad is awesome. You can create artwork, music, videos and write blog posts on it. You can also use hundreds of thousands of pre-made apps available for download at apple’s app store. However, it does have one major downfall. You need a Mac computer to code for it.

There are some ways around this. None of them result in a fully-fledged app store app though.

My favorite choice is an app called codea. It costs $1 and is very easy to use. You program in the Lua programming language and there is an included code reference and sprites that are well made. It is very easy to program for the iPad with this. I had a cool accelerometer graphics thingy running in about half an hour after looking through the examples to find what I needed here and there. It even makes having adjustable parameters in your program easy with pre made sliders. It also has a text output window that you can easily write to using the print function. It’s by far the best and is great for testing out a coding idea. It doesn’t produce anything that looks like normal iPad apps as it doesn’t have support for all the fancy UI elements.

The other option that I’ve read about quite a bit is using JavaScript and other web technologies to develop for mobile devices. This means that you can code web based apps for the iPad using an on board web code editor like textastic. However, this has it’s issues as textastic doesn’t support server side technologies like php in its previews. Also, this is often quite a messy solution relying on complex libraries and extensions.

This is a problem that apple needs to solve if it wants people to chuck out their laptops for iPads.

Chipkit Uno 32 Review

The Arduino electronics prototyping platform is one of the most successful electronics hobbyist products in the world. It has introduced thousands of ordinary people to digital electronics and is probably the most famous open source hardware project ever. One of the reasons it is so popular is it’s simplicity. It does without things like 32 bit computing and fancy features and sticks to a simple, small 8 bit processor. For most hobbyist’s electronics projects an Arduino Uno board will give all the computing power they could ever need. However, there are some projects that require a bit more grunt or some more pins without having to splash large amounts of cash on an Arduino Mega. Like building a servo humanoid robot for example. Or a 3D printer, or some big LED display. Then the Arduino hobbyist is faced with a problem. They can buy an expensive Arduino Mega with more power or try and learn a whole new platform like the PIC32. Both of those options can be daunting and expensive. Enter the chipKit line of Arduino compatible development boards for the PIC32.

There are two versions of the chipKit development boards much like the arduino boards. There’s the chipKit Uno32 and the chipKit Mega 32. The chipKit Uno32 is the lower end board and lacks some of the features of the chipKit Mega 32 like Ethernet, USB and 83 I/O pins. However, the chipKit Uno is a very powerful board anyway. It has:

  • 42 I/O pins
  • 80 Mhz 32 bit processing power
  • 128K of Flash and 16K of SRAM
  • Arduino form factor and compatibility

Out of the box

I received my chipKit Uno32 board from element 14  Australia about a week ago. The chipKit Uno 32 comes in a box very similar to the one the official Arduino Uno comes in. A nice addition is some anti static foam for the board to rest on so it isn’t fried during it’s journey to your front door. I’m not exactly sure how that would happen but it’s a nice touch nonetheless. The Arduino Uno board doesn’t come with this foam. However, the chipKit Uno 32 packaging lacks a nice booklet like the one the Arduino Uno comes with.

First impressions are that this thing is pretty cool. It has a LOT of input and output pins-  42 in total. It looks very similar to the Freetronics Etherten with the flat chip and mini USB connector. Everything is laid out carefully in the same layout as the Arduino Uno so there is no need to worry about shield compatibility (apart from the 3.3V issue, more on that later).

At the core of the development board is PIC32MX320F128 processor. Now this is where the two chipKit boards differ. The chipKit Mega 32 has a PIC32MX795F512 processor which has advanced communications capabilities such as USB, Ethernet and a high number of I/O built in. The chipKit Uno’s PIC32MX320F128 processor does not have these features built in. It is still a powerful processor with 128K of flash and 16K of SRAM. Here’s a comparison between the chipKit Uno32 and the Arduino Uno:

chipKit Uno32 (Microchip 32 bit PIC32MX320F128) vs Arduino Uno (AVR 8 bit ATMega328):

  • Flash: 128K vs 32KB
  • SRAM: 16K vs 2KB
  • I/O: 42 vs 14
  • Speed: 80Mhz vs 16Mhz
  • Operating voltage: 3.3V vs 5V

So I think it’s pretty clear to see that this thing is a powerhouse out of the box compared to the official Arduino Uno. And it even runs at a lower voltage than the standard Arduino Uno. Let’s look at what it takes to get a blink sketch up and running.

Getting off the ground

To get started with a chipKit Uno32 you’ll need to download a special modified Arduino IDE from here: https://github.com/chipKIT32/chipKIT32-MAX/downloads . I downloaded the 3rd one down – the windows zip package. I’m pretty sure that the chipKit board does not work with the official Arduino IDE as I tried to program it straight up with that and it didn’t work.

Once you have the modified IDE downloaded and extracted you can start the MPIDE. You’re presented with what looks like the normal Arduino IDE with a message in the splash box saying it’s a modified version. Have a look at the boards menu though. It has a multitude of other PIC32 boards along with the standard arduino boards.

I loaded the blink sketch from the examples in mpide no problems. Don’t forget to select the UNO32 board from the menu. Hit the upload button and the pin 13 LED flashes just like on a standard Arduino.

So setting up the chipKit Uno32 is just as easy as setting up an Arduino Uno. Let’s do a speed comparison between the two.

Speed test!

The main differences between the chipKit Uno32 and a standard Arduino Uno are the amount of I/O pins and the computing speed. It’s pretty obvious the difference in pins so I decided to do a computing test.

I used serial to do a basic speed comparison between the chipKit Uno32 and an Arduino Duemilanove. My Arduino Uno wasn’t working so I couldn’t test it with that. However, the Arduino Uno and Duemilanove are very similar in computing power. I wrote this simple program to count to a million and report how long it took by printing out the time in milliseconds to the serial monitor. Once it has printed out the time it has taken in milliseconds it prints it out every 5 seconds as a sort of test to see whether the value was true. Here’s the code:

void setup() {
  Serial.begin(9600);
}
unsigned long number;
int time;
void loop(){
number++;
if(number > 1000000){
time = millis();
Serial.println(time);
delay(5000);
}
}

The chipKit Uno32 achieved a time of 250 milliseconds every time.

A stock standard Arduino Duemilanove achieved a time of  2263 milliseconds every time.

Ouch. That’s quite a big difference if your Arduino sketches commonly include large calculations.

Some features

The chipKit Uno32 has some nifty little features built in. Here’s some of the cool ones:

  • Mini USB connector. Just like an etherten’s so it doesn’t short against shields. A criticism of the Arduino boards that hasn’t been addressed.
  • Open source. Always a cool thing. Get the schematics and everything else you could ever need here:http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,892,893&Prod=CHIPKIT-UNO32
  • 2 User LEDs. On pin 13 and 43. They are placed on the outer edge of the board so they can still be clearly seen when a shield is plugged in. There’s 2 of them so you can have twice the super fast trippy blinking LED fun than before. What, isn’t that what you did when you first got an Arduino?
  • Lots of input and output pins. 42 in fact. 12 analog pins. Enough to drive just about enough LEDs for any christmas project.
  • 32 bits and 80 Mhz of grunt.
  • ICSP PIC programming header holes. If you own a PICkit 3 you can use that to program it.
  • Heaps of program space. So you can program in all the Christmas tree animations you could ever imagine.

So those are the good bits. Here’s the bad stuff:

  • The chip can’t be removed. Unless you’re a Jedi at soldering. This means you can’t program the chip like with the Arduino Uno and then put it in a socket on your custom project circuit board.
  • No AVR ICSP programming header. So you can’t program this with an AVR ICSP.
  • 3.3V operating voltage means that some shields won’t work. Most should though.
  • There’s no atmega8u2 chip like in the Arduino Uno. No emulating HID USB devices (keyboards, mice etc) for you. Not that anyone seems to have figured out how to do that anyway….
  • I think there’s some code that doesn’t work. For example, I was going to use some of the Arduino Test Suite code on the board and it didn’t work. See here for more on the issue of code compatibility: http://www.chipkit.cc/wiki/index.php?title=ChipKIT%E2%84%A2_Support_Resources#chipKIT.E2.84.A2_Development_Environment.2C_functions_and_libraries

But that’s about all that’s wrong with it. It’s a great board for those who love the Arduino concept but need something a bit more powerful. It’s easy to get started with and is extremely powerful (especially the Mega model). It’s probably not the best choice if you’re just starting out in Arduino though. It’s definitely the way to go if you want some more grunt in your Arduino projects. I highly recommend it. Pick one up now at element 14 for $35.

Also have a look at some of their other digilent boards while you’re there.

 

 

 

Well, well, well

A lot has happened recently. And I mean a lot.

So what have I been up to? Well a lot of stuff as mentioned above.

One of the most important things that has happened recently for me is I’ve been hired. No, not by Macdonalds like half of my school it seems. No, I’ve been hired to create the new website for uavs australia. If you don’t know who they are here’s their current website: http://www.uavsaustralia.com/ . Trust me, I’m making a better one than that. So I’ve been dusting off my web coding skills and hitting the aptana studio editor hard. So I haven’t had much time to write stuff for this blog as frequently as I normally do.

The other thing I have been doing is building a spacecraft. The avionics are nearly done (I’ll write something up on them when they’re finished) and I have figured out the whole government approval thing. All I have to do know is get a balloon and some helium. Kids at school just laugh when they ask me what I’m doing on the weekend. “I’m working on a spacecraft”.”Bulls**t you are”.

Yesterday I did some testing of the balloon video camera by strapping it to a kite for a high speed test run. Here’s a still from the flight.

I'm the little dude in the white jumper.

I’ll upload the full video some time. It makes for interesting viewing. The kite can get a pretty high perspective.

I also flew some water rockets using a hose and some bottles with a friend. We got a bit bored on a Sunday afternoon. Here’s a couple of pics from that adventure:

The rocket could fly to about the distance of the car in the background. I mean it was just a bottle shoved on a hose.

The rocket could fly to about the distance of the car in the background.

That's my friend kicking a dud one to get it to launch.

That's my friend kicking a stubbourn one to get it to launch.

Sorry the rocket pictures are so low res. My friend has go pro footage of the launches. I’ll have to get it off him. It was fun and wet launching those things. You pinch the hose as a throttle and gradually build up the pressure in the bottle until it can’t take it any more and blasts off.

So there’s my hastily written update on what I’ve been doing. I’ll keep you posted.

Fun with retro gaming sounds and airwick air fresheners.

You know, inspiration can come from the strangest of places.

About a year ago, I spotted at my local supermarket an airwick automatic air freshener unit. It cost about $10 and I bought it right away thinking that it could be used to keep our toilet smelling nice and fresh and limit the amount of matches that are chucked in there to keep it from stinking the house out. So I arrived home from the shops with the brand new $10 automatic air freshener under my arm. And, predictably, my Mum wasn’t happy about me spending money on robotic air fresheners. I ended up having to pay for it myself. Oh well. It was still cool.

My airwick freshener thingy.

My airwick freshener thingy.

So I put in the freshener cartridge that came with the device, set it to the right mode, and left it alone. The little air freshener went off every time you walked into the toilet keeping it smelling nice. But airwick (the company that makes these) are just as bad as the printer companies. They get you on the toner, or in this case the cartridges. The cartridges cost about $10 and only last about a week or so. Needless to say, the freshener sat and collected dust with an empty cartridge just blinking its little light.  Until yesterday when I noticed it had a PIR detector mounted in the front for detecting motion.

The PIR sensor

The PIR sensor

For more on what a PIR sensor is and how it’s used see here: http://www.ladyada.net/learn/sensors/pir.html

So what am I going to build with this? A super mario brothers room greeting robot.

Let’s start by taking the freshener apart.

The back of the freshener. It looks like some sort of crashed spaceship.

The back of the freshener. It looks like some sort of crashed spaceship.

The gas cartridge in position.

The gas cartridge in position.

The gas cartridge.

The gas cartridge.

The back cover with the batteries out exposing two screws.

The back cover with the batteries out exposing two screws.

The circuit board and it's plugs. The PIR is on the other side of the PCB.

The circuit board and it's plugs. The PIR is on the other side of the PCB.

A very nice looking PCB with the PIR, switches and some handy connectors.

A very nice looking PCB with the PIR, switches and some handy connectors.

After disassembling the device I wanted to find out how the PIR is wired up on this particular device. To do this I used this tutorial on hacking the airwick fresheners found here:

http://www.instructables.com/id/Re-purposing-an-Air-Wick-Freshmatic-Compact-i-Moti/step3/Approach-1-Digitized-Sensor-Output-Simplest-way/

It was a very simple procedure and worked straight away. Thanks for posting your method Doug! Here’s a picture of my finished hack.

The white wire is the modification.

The white wire is the modification.

I tested it using the code found on the ladyada PIR tutorial mentioned above. It worked fine and was surprisingly good at detecting people. So now I have the sensor and I’m ready to put a little music into this project. Here’s what I used for the music: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253920105 (the RTTTL example). The music sounded surprisingly good and is pretty easy to modify. I shortened the mario song by referencing the sheet music found here: http://www.mariopiano.com/mario-sheet-music-overworld-main-theme.html . Once I had figured out which bit of the song I wanted I simply lopped off the bit I didn’t need and was left with this RTTTL text:

char *song = “smb:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,”;

It’s much shorter than the original code from the arduino forum. You can load any RTTTL ringtone into it so it’s not like this thing is limited to playing super mario bros. Cool. Now to bring it all together.

I did this by modifying the bottom section of the RTTTL example to this:

void loop(void)
{
//I chose pin 2 to read the PIR signal
  if (digitalRead(2) == (LOW)){
      play_rtttl(song);
      delay(5000); //delay to make sure it doesn't go off too often.
  }
}

Now that I have the code so that it only plays the song when the sensor detects motion, I can show you a video of it working. This a pretty cool project and is a fun addition to any room. Here’s the hastily made video (made on my mobile phone because my HD webcam isn’t working with youtube):

It could also be used for something like this: http://www.youtube.com/watch?v=cbEKAwCoCKw .

A very retro one-day project:

The finished project with the PIR in it's case.

The finished project with the PIR in its case.

Cool. My room is now complete with retro gaming noises.

Here’s the full version of the code because it was requested:

//Below is a modified version of the example RTTTL sketch that I used to power the project.
//You need to have the tone library installed. 

// A fun sketch to demonstrate the use of the Tone library.

// To mix the output of the signals to output to a small speaker (i.e. 8 Ohms or higher),
// simply use 1K Ohm resistors from each output pin and tie them together at the speaker.
// Don't forget to connect the other side of the speaker to ground!

// You can get more RTTTL (RingTone Text Transfer Language) songs from
// http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation

#include <Tone.h>

Tone tone1;

#define OCTAVE_OFFSET 0

int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};

//char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6";
//char *song = "Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6";
//char *song = "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5";
//char *song = "Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6";
//char *song = "Muppets:d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c";
//char *song = "Xfiles:d=4,o=5,b=125:e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,g6,f#6,e6,d6,e6,2b.,1p,g6,f#6,e6,d6,f#6,2b.,1p,e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,e6,2b.";
//char *song = "Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f";
//char *song = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b";
//char *song = "Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6";
//char *song = "MASH:d=8,o=5,b=140:4a,4g,f#,g,p,f#,p,g,p,f#,p,2e.,p,f#,e,4f#,e,f#,p,e,p,4d.,p,f#,4e,d,e,p,d,p,e,p,d,p,2c#.,p,d,c#,4d,c#,d,p,e,p,4f#,p,a,p,4b,a,b,p,a,p,b,p,2a.,4p,a,b,a,4b,a,b,p,2a.,a,4f#,a,b,p,d6,p,4e.6,d6,b,p,a,p,2b";
//char *song = "StarWars:d=4,o=5,b=45:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6";
//char *song = "GoodBad:d=4,o=5,b=56:32p,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,d#,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,c#6,32a#,32d#6,32a#,32d#6,8a#.,16f#.,32f.,32d#.,c#,32a#,32d#6,32a#,32d#6,8a#.,16g#.,d#";
//char *song = "TopGun:d=4,o=4,b=31:32p,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,16f,d#,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,g#";
//char *song = "A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#";
//char *song = "Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6";
//char *song = "Jeopardy:d=4,o=6,b=125:c,f,c,f5,c,f,2c,c,f,c,f,a.,8g,8f,8e,8d,8c#,c,f,c,f5,c,f,2c,f.,8d,c,a#5,a5,g5,f5,p,d#,g#,d#,g#5,d#,g#,2d#,d#,g#,d#,g#,c.7,8a#,8g#,8g,8f,8e,d#,g#,d#,g#5,d#,g#,2d#,g#.,8f,d#,c#,c,p,a#5,p,g#.5,d#,g#";
//char *song = "Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#";
//char *song = "Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#";
//char *song = "MahnaMahna:d=16,o=6,b=125:c#,c.,b5,8a#.5,8f.,4g#,a#,g.,4d#,8p,c#,c.,b5,8a#.5,8f.,g#.,8a#.,4g,8p,c#,c.,b5,8a#.5,8f.,4g#,f,g.,8d#.,f,g.,8d#.,f,8g,8d#.,f,8g,d#,8c,a#5,8d#.,8d#.,4d#,8d#.";
//char *song = "LeisureSuit:d=16,o=6,b=56:f.5,f#.5,g.5,g#5,32a#5,f5,g#.5,a#.5,32f5,g#5,32a#5,g#5,8c#.,a#5,32c#,a5,a#.5,c#.,32a5,a#5,32c#,d#,8e,c#.,f.,f.,f.,f.,f,32e,d#,8d,a#.5,e,32f,e,32f,c#,d#.,c#";
//har *song = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d";
//char *song = "SMBUndergr:d=16,o=6,b=100:c,c5,a5,a,a#5,a#,2p,8p,c,c5,a5,a,a#5,a#,2p,8p,f5,f,d5,d,d#5,d#,2p,8p,f5,f,d5,d,d#5,d#,2p,32d#,d,32c#,c,p,d#,p,d,p,g#5,p,g5,p,c#,p,32c,f#,32f,32e,a#,32a,g#,32p,d#,b5,32p,a#5,32p,a5,g#5";
char *song = "smb:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,";
 void setup(void)
{
  Serial.begin(9600);
  tone1.begin(13);
}

#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here

  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)

  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }

  Serial.print("ddur: "); Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

  Serial.print("doct: "); Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

  Serial.print("bpm: "); Serial.println(bpm, 10);

  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

  Serial.print("wn: "); Serial.println(wholenote, 10);


  // now begin note loop
  while(*p)
  {
    // first, get note duration, if available
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    
    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

    // now get the note
    note = 0;

    switch(*p)
    {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }
  
    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note

    if(note)
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
    {
      Serial.print("Pausing: ");
      Serial.println(duration, 10);
      delay(duration);
    }
  }
}

void loop(void)
{
//I chose pin 2 to read the PIR signal
  if (digitalRead(2) == (LOW)){
      play_rtttl(song);
      delay(5000); // wait 50 seconds for me so it doesn't endlessly loop.
  }
}