Andrew R Gross
Published © CC BY

Arduino Baby Mobile (Marvel Inspired)

I built my baby a mobile for entertainment, soothing, and to help him learn to track objects.

AdvancedFull instructions providedOver 1 day4,699
Arduino Baby Mobile (Marvel Inspired)

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
SparkFun Slip Ring
Slip rings allowed the semi-circle arcs to turn infinitely without tangling the wires that powered the LEDs.
×1
Perma-Proto Breadboard Half Size
Perma-Proto Breadboard Half Size
×1
PTS 645 Series Switch
C&K Switches PTS 645 Series Switch
Four buttons provided simple inputs for changing the mobile behavior during operation.
×1
Rocker Switch, Non Illuminated
Rocker Switch, Non Illuminated
A simple power switch
×1
USB Li Ion Battery Charger
Adafruit USB Li Ion Battery Charger
This simple USB power supply powered the Arduino and the downstream lights and motors.
×1
SparkFun Servo - Generic High Torque Continuous Rotation (Standard Size)
Two servos turned the semi-circle arcs. I chose this item because it was in a drop-down list, but in reality the servos used were not high in torque, the were deliberately weak.
×1
EVA foam - Interlocking Fitness Mat
This was used to build the semi-circle arcs, which were the rotating members of the mobile.
×1
Arduino Proto Shield
Arduino Proto Shield
I didn't use this and I should've.
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Contact cement
Craft Knife

Story

Read more

Custom parts and enclosures

Baby Mobile Parts

All the 3D printed parts

Schematics

System diagram

This is the total system diagram. It's the same as the version in the text above.

Code

Mobile run code

Arduino
This Arduino code controls the mobile
/* Andrew R Gross - Mobile v1
 *  
 */

#include <Servo.h>

const int button1Pin = A0;     // the number of the pushbutton pin
const int button2Pin = A1;
const int button3Pin = A2;
const int button4Pin = A3;

const int led0 = 0;
const int led1 = 1;
const int led2 = 2;
const int led3 = 3;
const int led4 = 4;

const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

//Parameters
int maxSpeedL = 120;
int minSpeedL = 60;
int maxSpeedR = 110;
int minSpeedR = 80;
int leftSpeed = 88;
int slDelay = 50;
int slDelayDelay = 5000;
int adjuster = -1;
int pauseButton = 0;
int cycleNumber = 50;
int lightDelay = 1000;
int timer = 13000;

int currentLed = 0;

Servo servoLeft;  // create servo object to control a servo
Servo servoRight;

unsigned long currentMillis;
unsigned long slMillis;
unsigned long slDelayMillis;
unsigned long lightMillis;

void setup() {      ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  servoLeft.attach(10);  // attaches the servo on pin 9 to the servo object
  servoRight.attach(11);

  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);     
  pinMode(led0, OUTPUT);   
  pinMode(led1, OUTPUT); 
  pinMode(led2, OUTPUT); 
  pinMode(led3, OUTPUT); 
  pinMode(led4, OUTPUT); 
  
  // initialize the pushbutton pin as an input:
  pinMode(button1Pin, INPUT);     
  pinMode(button2Pin, INPUT); 
  pinMode(button3Pin, INPUT); 
  pinMode(button4Pin, INPUT); 

          
  digitalWrite(led0, LOW); 
  digitalWrite(led1, LOW); 
  digitalWrite(led2, LOW); 
  digitalWrite(led3, LOW); 
  digitalWrite(led4, LOW); 
        

}

void loop() {        ///////////////////////////////////////////////////////////////////////////////////////////////////////////

  currentMillis = millis();


  //// Run through Routine
  
  if(currentMillis < timer){                          // If the cycle hasn't run down, proceed
    
    if(pauseButton == 0){                       // Check if pause is on. If it isn't, proceed

      if(currentMillis - slMillis > slDelay) {  // Check if it's time to adjust servoLeft based on delay
        slMillis = currentMillis;
        leftSpeed = leftSpeed + adjuster;
        servoLeft.write(leftSpeed);
        //servoRight.write(leftSpeed);

        if(leftSpeed <= minSpeedL) {
          adjuster = 1;
          slMillis = slMillis - slDelay;
          } // If the servo speed hits its minimum, reverse accelleration direction
        else if(leftSpeed >= maxSpeedL) {
          adjuster = -1;
          slMillis = slMillis - slDelay;
          }// If the servo speed hits its max, reverse acceleration direction. I think I need else if
      }

      else if(currentMillis - slDelayMillis > slDelayDelay) { // Check if it's time to adjust the delay
        slDelayMillis = currentMillis;
        slDelay = slDelay + 1;
//        cycleNumber = cycleNumber -1;
      }


      if(currentMillis - lightMillis > lightDelay) {
        lightMillis = currentMillis;
        
        digitalWrite(led0, LOW); 
        digitalWrite(led1, LOW); 
        digitalWrite(led2, LOW); 
        digitalWrite(led3, LOW); 
        digitalWrite(led4, LOW); 
        
        if(currentLed == 0){
          digitalWrite(led0, HIGH);
          currentLed = 1;
        }
        else if(currentLed == 1){
          digitalWrite(led1, HIGH);
          currentLed = 2;
        }
        else if(currentLed == 2){
          digitalWrite(led2, HIGH);
          currentLed = 3;
        }
        else if(currentLed == 3){
          digitalWrite(led3, HIGH);
          currentLed = 4;
        }
        else if(currentLed == 4){
          digitalWrite(led4, HIGH);
          currentLed = 0;
        }

        
      }

/*
  digitalWrite(led0, HIGH); delay(500); digitalWrite(led0, LOW); 
//  digitalWrite(led1, HIGH); delay(500); digitalWrite(led1, LOW); 
//  digitalWrite(led2, HIGH); delay(500); digitalWrite(led2, LOW); 
//  digitalWrite(led3, HIGH); delay(500); digitalWrite(led3, LOW); 
//  digitalWrite(led4, HIGH); delay(500); digitalWrite(led4, LOW); 


  if(leftSpeed <= minSpeed){adjuster = 1;} // If the left speed is less than the minimum speed, reverse speed 
  if(leftSpeed >= maxSpeed){               // If the left speed is greater than the max: 
    adjuster = -1;                         // the adjuster flips...
    leftDelay = leftDelay + 5;             // ... the 
    cycleNumber = cycleNumber - 1;
    }

  //servoLeft.attach(11);
  servoLeft.write(leftSpeed);
  delay(leftDelay);
  leftSpeed = leftSpeed + adjuster;
*/

    }
    else {                                      // If pause button is ON:
      servoLeft.detach();                       // Stop the servo
      //leftDelay = 10;
      }
  }
  
  else {                                        // If the cycle has run down
    servoLeft.detach();                         // Shut the servos off
    //servoRight.detach(10);
    }

  //// Button programs
  
  if (digitalRead(button1Pin) == HIGH) {                    // turn LED on:    
    digitalWrite(ledPin, HIGH); delay(200); digitalWrite(ledPin, LOW); delay(500); 
    slDelay = 10;
    slDelayDelay = 1000;
  }  

  else if (digitalRead(button2Pin) == HIGH) {                    // turn LED on: 
    timer = currentMillis + 3000;   
    digitalWrite(ledPin, HIGH); delay(200); digitalWrite(ledPin, LOW); delay(200); 
    digitalWrite(ledPin, HIGH); delay(200); digitalWrite(ledPin, LOW); delay(200); 
  }  

  else if (digitalRead(button3Pin) == HIGH) {                    // turn LED on:    
    digitalWrite(ledPin, HIGH); delay(200); digitalWrite(ledPin, LOW); delay(200); 
    digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); delay(100); 
    digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); delay(100); 
    pauseButton = 0;
    cycleNumber = cycleNumber + 10;
    servoLeft.attach(10);
  }  

  else if (digitalRead(button4Pin) == HIGH) {                    // turn LED on:    
    digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); delay(50); 
    digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); delay(50); 
    digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); delay(50); 
    digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); delay(50); 
   // servoRight.write(85);
    pauseButton = 1;
    servoLeft.detach();
   // if (pauseButton == 0){pauseButton = 1}
   // else if (pauseButton == 1){pauseButton = 0;}
    }
    
  else {    // turn LED off:
    digitalWrite(ledPin, LOW); 
  }
  //servoLeft.detach();
}

Credits

Andrew R Gross

Andrew R Gross

7 projects • 19 followers
Biomedical engineer by profession, wanna-be roboticist on the weekends
Thanks to Calvin McGinn (age 0).

Comments