Introduction: Arduino Based Toy for Children
The goal of my first project was to create an interactive toy for children that would help them develop their motor skills, and interact with their environment.
The toy will play musical notes for each unique action the child makes and can be reprogrammed as the child grows to teach musical patterns and colour recognition.
Interactive components will be controlled by an Arduino Uno.
1 - Arudino Uno
1 - 74HC595 Shift Register for Led Outputs
2 - CD4021BE Shift Registers for Joystick and Push Button inputs
1 - Piezo speaker
13 - 10K ohm resistors
8 - 330 ohm resistors
2 - full size arcade joysitcks
5 - arcade LED Push buttons - various colours
Several pieces of Styrofoam or construction paper decorate project box
wood or plastic box to hold project. I used wood as it was more accessible at the time of this project.
Connecting wires of different colours. You can cut to the desired size.
The toy will play musical notes for each unique action the child makes and can be reprogrammed as the child grows to teach musical patterns and colour recognition.
Interactive components will be controlled by an Arduino Uno.
1 - Arudino Uno
1 - 74HC595 Shift Register for Led Outputs
2 - CD4021BE Shift Registers for Joystick and Push Button inputs
1 - Piezo speaker
13 - 10K ohm resistors
8 - 330 ohm resistors
2 - full size arcade joysitcks
5 - arcade LED Push buttons - various colours
Several pieces of Styrofoam or construction paper decorate project box
wood or plastic box to hold project. I used wood as it was more accessible at the time of this project.
Connecting wires of different colours. You can cut to the desired size.
Step 1: Box Design and Colour Scheme
Created button holes for the side panels of box.
Added styrofoam colour panels to each of the sides.
Added styrofoam colour panels to each of the sides.
Step 2: Arduino and Connections
Arduino connections
I tested my connections using a mini bread board and arduino.
Goal was to get one Shift in and one shift out register functioning.
Shift in register would handle the inputs from the joystick/buttons, and the shift out register would handle the lighting of the LED's.
Shift registers were used in this project due to the limitation of outputs/inputs on the Arduino Uno. It also provided an opportunity to learn how shift registers can be connected together, increasing the number of inputs and outputs, while reducing the number of connections to the micro-controller.
I tested my connections using a mini bread board and arduino.
Goal was to get one Shift in and one shift out register functioning.
Shift in register would handle the inputs from the joystick/buttons, and the shift out register would handle the lighting of the LED's.
Shift registers were used in this project due to the limitation of outputs/inputs on the Arduino Uno. It also provided an opportunity to learn how shift registers can be connected together, increasing the number of inputs and outputs, while reducing the number of connections to the micro-controller.
Step 3: Soldering to the Breadboard
1 Shift in Register 74HC595 and 2 Shift Out registers (CD4021BE) were soldered to a breadboard, along with the appropriate resistors to limit current and for grounding.
I followed the guide on the the page for the shift in registers.
http://arduino.cc/en/Tutorial/ShiftIn
For the Shift out registers (LED Outputs) I followed the guide of the website below.
http://arduino.cc/en/Tutorial/ShiftOut
I followed the guide on the the page for the shift in registers.
http://arduino.cc/en/Tutorial/ShiftIn
For the Shift out registers (LED Outputs) I followed the guide of the website below.
http://arduino.cc/en/Tutorial/ShiftOut
Step 4: Arudino Code
Below is my Arduino code for this project.
#include "pitches.h" // contains the notes referenced in this code.
int tonepin = 3; // to play musical tones
int loadpin = 9;
int clockpin = 7;
int SOpin = 8;
unsigned long idle_time;
byte registerContent = 0;
byte registerContent2 = 0;
long loWord; //previously was an integer
int bitContent = 0;
long idle_millseconds =0;
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin_595 = 10; // previously 10
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin_595 = 12; //previously 12
////Pin connected to Data in (DS) of 74HC595
const int dataPin_595 = 11; // previously 11
int bitToSet; // bit on 595 shift register to set
int button_Switch1=2;
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_E7, NOTE_A3, NOTE_G3,NOTE_A4, NOTE_D8, NOTE_B6};
#define white_button 8
#define yellow_button 32
#define blue_button 1
#define red_button 2
#define green_button 16
#define red_led 0 // bit to write on 595 register
#define white_led 4
#define blue_led 1
#define green_led 2
#define yellow_led 3
long joy1_up = 32768;
long joy1_down = 2048;
long joy1_left = 8192;
long joy1_right = 512;
long joy2_up = 4096;
long joy2_down = 1024;
long joy2_left = 16384;
long joy2_right = 256;
void setup ()
{
pinMode (loadpin, OUTPUT);
pinMode (clockpin, OUTPUT);
pinMode (SOpin, INPUT);
//set pins to output because they are addressed in the main loop
pinMode(latchPin_595, OUTPUT);
pinMode(dataPin_595, OUTPUT);
pinMode(clockPin_595, OUTPUT);
pinMode (button_Switch1, INPUT); //5 button switches with leds
digitalWrite (loadpin, LOW);
digitalWrite (clockpin, HIGH);
// digitalWrite (button_Switch1, LOW);
led_check(1); // light up Leds and play a single note ..random
Serial.begin(9600);
idle_time=millis();
}
void loop ()
{
for (int idx = 0; idx < 16; idx++)
{
if (idx == 0)
{
pulseload();
}
bitContent = digitalRead (SOpin);
if (bitContent == 1 && idx < 8)
{
bitWrite(registerContent,idx,1);
}
else if (bitContent == 1 && idx >= 8)
{
bitWrite (registerContent2,idx-8,1);
}
else if (bitContent == 0 && idx < 8)
{
bitWrite (registerContent,idx,0);
}
else if (bitContent == 0 && idx >= 8)
{
bitWrite (registerContent2,idx-8,0);
}
pulseclock();
}
// end of clock cycle for 2 shift registers.
loWord = word(registerContent, registerContent2); //convert two bytes into a word
Serial.print("Output Value:");
Serial.println(loWord,DEC); // print the word as a decimal
switch(loWord) {
case 36864:
Serial.println("Both Up");
bitToSet=red_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 3072:
Serial.println("Both Down");
bitToSet=green_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 24576:
Serial.println("Both Left");
bitToSet=white_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 768:
Serial.println("Both Right");
bitToSet=blue_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 8:
Serial.println("White Button");
bitToSet=white_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 32:
Serial.println("Yellow Button");
bitToSet=yellow_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 1:
Serial.println("Blue Button");
bitToSet=blue_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 2:
Serial.println("Red Button");
bitToSet=red_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 16:
Serial.println("Green Button");
bitToSet=green_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
default:
// nothing pushed or unrecognized sequence
for (int thisPin = 0; thisPin < 16; thisPin++) {
registerWrite(thisPin, LOW);
}
registerContent=0;
registerContent2=0;
} // end of case / switch
//capture current time
check_idle_time(); //check inactivity time
Serial.print("Register 1:");
Serial.println (registerContent, BIN);
Serial.print("Register 2:");
Serial.println (registerContent2, BIN);
//Serial.println (byte(10));
//registerContent = 0;
delay (250);
}
void pulseload ()
{
digitalWrite (loadpin, HIGH);
delay (5);
digitalWrite (loadpin, LOW);
}
void pulseclock ()
{
digitalWrite (clockpin, LOW);
delay (5);
digitalWrite (clockpin, HIGH);
}
void registerWrite(int whichPin, int whichState) {
// the bits you want to send
byte bitsToSend = 0;
// turn off the output so the pins don't light up
// while you're shifting bits:
digitalWrite(latchPin_595, LOW);
// turn on the next highest bit in bitsToSend:
bitWrite(bitsToSend, whichPin, whichState);
// shift the bits out:
shiftOut(dataPin_595, clockPin_595, MSBFIRST, bitsToSend);
// turn on the output so the LEDs can light up:
digitalWrite(latchPin_595, HIGH);
}
void playtone(int num_of_tones) {
// play a random note from melody
for (int i=0; i < num_of_tones ; i++) {
int rand_note = random(0,7); // choose one note from melody array
int rand_duration = (random(1,2))* 4; //either 4 or 8
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/rand_duration;
tone(tonepin, melody[rand_note],noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(tonepin);
idle_time=millis();
}
}
void led_check(int tone_count)
{
for (int led_bit=0 ; led_bit <5; led_bit++) {
registerWrite(led_bit, HIGH);
playtone (tone_count);
delay (250);
registerWrite(led_bit, LOW);
idle_time=millis(); //reset idle timer
}
}
void check_idle_time() {
if (millis() > idle_time + 600000) {
// 10 minutes of inactivity
led_check(2); // light leds play 2 notes
idle_time=millis();
}
}
#include "pitches.h" // contains the notes referenced in this code.
int tonepin = 3; // to play musical tones
int loadpin = 9;
int clockpin = 7;
int SOpin = 8;
unsigned long idle_time;
byte registerContent = 0;
byte registerContent2 = 0;
long loWord; //previously was an integer
int bitContent = 0;
long idle_millseconds =0;
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin_595 = 10; // previously 10
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin_595 = 12; //previously 12
////Pin connected to Data in (DS) of 74HC595
const int dataPin_595 = 11; // previously 11
int bitToSet; // bit on 595 shift register to set
int button_Switch1=2;
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_E7, NOTE_A3, NOTE_G3,NOTE_A4, NOTE_D8, NOTE_B6};
#define white_button 8
#define yellow_button 32
#define blue_button 1
#define red_button 2
#define green_button 16
#define red_led 0 // bit to write on 595 register
#define white_led 4
#define blue_led 1
#define green_led 2
#define yellow_led 3
long joy1_up = 32768;
long joy1_down = 2048;
long joy1_left = 8192;
long joy1_right = 512;
long joy2_up = 4096;
long joy2_down = 1024;
long joy2_left = 16384;
long joy2_right = 256;
void setup ()
{
pinMode (loadpin, OUTPUT);
pinMode (clockpin, OUTPUT);
pinMode (SOpin, INPUT);
//set pins to output because they are addressed in the main loop
pinMode(latchPin_595, OUTPUT);
pinMode(dataPin_595, OUTPUT);
pinMode(clockPin_595, OUTPUT);
pinMode (button_Switch1, INPUT); //5 button switches with leds
digitalWrite (loadpin, LOW);
digitalWrite (clockpin, HIGH);
// digitalWrite (button_Switch1, LOW);
led_check(1); // light up Leds and play a single note ..random
Serial.begin(9600);
idle_time=millis();
}
void loop ()
{
for (int idx = 0; idx < 16; idx++)
{
if (idx == 0)
{
pulseload();
}
bitContent = digitalRead (SOpin);
if (bitContent == 1 && idx < 8)
{
bitWrite(registerContent,idx,1);
}
else if (bitContent == 1 && idx >= 8)
{
bitWrite (registerContent2,idx-8,1);
}
else if (bitContent == 0 && idx < 8)
{
bitWrite (registerContent,idx,0);
}
else if (bitContent == 0 && idx >= 8)
{
bitWrite (registerContent2,idx-8,0);
}
pulseclock();
}
// end of clock cycle for 2 shift registers.
loWord = word(registerContent, registerContent2); //convert two bytes into a word
Serial.print("Output Value:");
Serial.println(loWord,DEC); // print the word as a decimal
switch(loWord) {
case 36864:
Serial.println("Both Up");
bitToSet=red_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 3072:
Serial.println("Both Down");
bitToSet=green_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 24576:
Serial.println("Both Left");
bitToSet=white_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 768:
Serial.println("Both Right");
bitToSet=blue_led;
registerWrite(bitToSet, HIGH);
playtone(2);
break;
case 8:
Serial.println("White Button");
bitToSet=white_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 32:
Serial.println("Yellow Button");
bitToSet=yellow_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 1:
Serial.println("Blue Button");
bitToSet=blue_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 2:
Serial.println("Red Button");
bitToSet=red_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
case 16:
Serial.println("Green Button");
bitToSet=green_led;
registerWrite(bitToSet, HIGH);
playtone(1);
break;
default:
// nothing pushed or unrecognized sequence
for (int thisPin = 0; thisPin < 16; thisPin++) {
registerWrite(thisPin, LOW);
}
registerContent=0;
registerContent2=0;
} // end of case / switch
//capture current time
check_idle_time(); //check inactivity time
Serial.print("Register 1:");
Serial.println (registerContent, BIN);
Serial.print("Register 2:");
Serial.println (registerContent2, BIN);
//Serial.println (byte(10));
//registerContent = 0;
delay (250);
}
void pulseload ()
{
digitalWrite (loadpin, HIGH);
delay (5);
digitalWrite (loadpin, LOW);
}
void pulseclock ()
{
digitalWrite (clockpin, LOW);
delay (5);
digitalWrite (clockpin, HIGH);
}
void registerWrite(int whichPin, int whichState) {
// the bits you want to send
byte bitsToSend = 0;
// turn off the output so the pins don't light up
// while you're shifting bits:
digitalWrite(latchPin_595, LOW);
// turn on the next highest bit in bitsToSend:
bitWrite(bitsToSend, whichPin, whichState);
// shift the bits out:
shiftOut(dataPin_595, clockPin_595, MSBFIRST, bitsToSend);
// turn on the output so the LEDs can light up:
digitalWrite(latchPin_595, HIGH);
}
void playtone(int num_of_tones) {
// play a random note from melody
for (int i=0; i < num_of_tones ; i++) {
int rand_note = random(0,7); // choose one note from melody array
int rand_duration = (random(1,2))* 4; //either 4 or 8
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/rand_duration;
tone(tonepin, melody[rand_note],noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(tonepin);
idle_time=millis();
}
}
void led_check(int tone_count)
{
for (int led_bit=0 ; led_bit <5; led_bit++) {
registerWrite(led_bit, HIGH);
playtone (tone_count);
delay (250);
registerWrite(led_bit, LOW);
idle_time=millis(); //reset idle timer
}
}
void check_idle_time() {
if (millis() > idle_time + 600000) {
// 10 minutes of inactivity
led_check(2); // light leds play 2 notes
idle_time=millis();
}
}
Step 5: Completed Project
Picture and video of completed project.
The power source is the built in USB connection for the Arduino Uno.
The power source is the built in USB connection for the Arduino Uno.
Attachments
Step 6: Advanced Product Testing of Completed Project
A toy expert tests and gives their review of my project.