Build a Better Bear

About: I was acceptable in the 80's

Overview

This Instructable uses reasonably straight forward electronics to enhance a soft toy, but could potentially be used with any project.

It isn't an essay about sewing, just electronics and coding in C++ and MIT AI2.

Introduction

Some time ago I visited a well known high street retailer to buy a sound effect for a project. They refused, and made 'The List'. I won't use the retailers name, but let's call them 'Make-a-Bear' so no-one will guess their real name.

You don't have electronics as an interest without having set backs, so undeterred, I started looking at alternatives, and a plan started to form. I realised that I'd need a body and 'Team Girl' was unwilling to provide a volunteer from her vast collection of 'Make-a-Bears'.

Recovering from another set back, and proving the necessity is the engine of invention, I found an old monster slipper, an old dressing gown, an old dress, and a bow tie. Bobbs was made from all these bits and bobs, but he needed life, so I stuffed him with an Arduino style processor, FX sound board and tri-coloured LEDs for eyes.

Then things got out of hand (and expensive).

He needed a voice

How about some light up horns?

Tickley feet? Yep

Tilt sensor? Yep

Dark sensor? Yep

Control by an Andriod phone via HC06 bluetooth module? Damn right

There's only one Bobbs, but there's no reason why some of the ideas can't be used in your own projects. I find that using one or more of his abilities at the same time gives the best results though. For instance if Bobbs is knocked over, the tilt sensor set his eyes to red, the horns flash red, he growls and says 'Pick me up'.

Supplies:

I use Adafruit, Sparkfun and Arduino products where possible. I've tried a cheap knock-off components from Ebay; learn from my mistakes and buy the proper components. They might cost a few pounds/dollars more but you save so much aggravation. The support on the websites is excellent.

Spark fun pro micro controller (or any Arduino style microprocessor)

5v battery - Bobbs uses an old cut down radio controlled car power pack as they can deliver bucket loads of amps, but he will run on 4 x AA batteries

Adafruit FX board

Emic 2 Speech Chip

2 channel class D 3W amplifier

6v Motor

3 x tilt sensors

Tricolour LEDs

4017 decade counter

HC-06 bluetooth module

Vero board

Wires - I'm using Dupont connectors as they fit nicely onto the header pins, but they keep coming apart.

Resistors

Header pins and connectors

Power transistor

Photo diode

Solar panel

Diodes

A box to put it all in

Android device

Step 1: Brains

Bobbs brain (probably stretching the definition) is a Sparkfun Pro-micro processor, and these are available on eBay for a few £/$.

I'm assuming that you know how to program an Arduino. If not, learn! It's a great micro processor and your life will be much better. There's tons of support on the internet, and https://www.arduino.cc/ is the starting point.

Specific references are here;

https://learn.sparkfun.com/tutorials/pro-micro--fi...

It's a nice compact board with enough pins to keep us happy for now. It has 32k of memory so we're a bit limited there, but still enough for a reasonable amount of code as C++ is fairly efficient.

If you're using Arduino Create, the Sparkfun Pro-Micro likes to think it's an Arduino Leonardo.

Step 2: Power

Fully loaded Bobbs uses a lot of juice, so we're going to need something fairly hefty to provide the amps. I've used an old Nimh RC car battery which has been cut down to give 4.8v.

In an effort to be environmentally acceptable, Bobbs has a 6v solar panel attached to his back. Bobbs battery is recharged a bit by a solar power. A diode prevents the battery discharging through the solar panel at night.

In this configuration he runs for about a day.

Step 3: Eyes

Let's start with something easy. We're using 2 x tri colour LEDs, the microprocessor, a 50 ohm resistor and some wires.

The red leg is connected to pin 5, green to pin 6 and blue to pin 9. The negative leg is connected to ground via a 50 ohm resistor. The brightness is controlled by the Arduino using pulse width modulation. Having separate pins means that a wide range of colours can be created.

Here's a few comments on the code.

The void eyes routine uses analogWrite to send pulses (Pulse Width Modulation) to the LEDs depending on the values of the integers r, g and b. In turn, the LEDs switch on.

void rollseye uses three for loops to change the values of r, g and b to produce a range of colours

void setup defines pins 5, 6 and 9 as outputs

void loop is the main code which calls the rollseyes routine repeatedly

His eyes look better in real life than in the video.

// initialise variables and constants
// Arduino pins 

#define redpin  5
#define greenpin 6 
#define bluepin  9
void eyes(int r, int g, int b)
{ 
// writes to pins to change eye colours
analogWrite(redpin, r);
analogWrite(greenpin, g);
analogWrite(bluepin, b); 
}
void rollseyes()
{
// loops to change eye colours

int colour;
eyes(0, 0, 0);

for (colour = 0; colour < 255; colour++)
 { 
// blue fades, red brightens
 eyes(colour, 0, 255 - colour);
 delay(10);
}

for (colour = 0; colour < 255; colour++)
{
// red fades, green brightens    
eyes(255 - colour, colour, 0); 
delay(10);
}

for (colour = 0; colour < 255; colour++)
{
// green fades, blue brightens    
eyes(0, 255 - colour, colour);
delay(10);
 }
}
void setup() 
{
/* output pins */
pinMode(redpin, OUTPUT);
pinMode(greenpin, OUTPUT);
pinMode(bluepin, OUTPUT);
}
void loop() 
{

rollseyes();

}

Step 4: Sounds

The Adafruit Sound board is a good thing, but relatively expensive at around £20, and they only hold about 10 sounds. Check the link below for heaps of info about it.

https://www.adafruit.com/product/2133

If you're not going the fully loaded Bobbs route, the board will work without a microprocessor, but you'll have to play the sounds using the trigger pins. Either way, it's time to break out the amp and speakers.

You can run this by setting up to 10 triggers, or by serial communication with the Software Serial library (settle down haters). I'm going to be describing the Software Serial (UART) method below. I accept there are issues with it but nothing that'll affect us here.

I'm not going to repeat the detailed instructions on the Adafruit site, but in brief;

Firstly, find some sounds to copy onto the board. Soundbible's a good place to start

http://soundbible.com/

Download them and convert to OGG or WAV if necessary. The board doesn't use MP3 format but converting the files is easy. I like the Audacity application as you can edit the file to get exactly the noise you want.

https://www.audacityteam.org/

The files will need to be named T00, T01, etc

Next transfer them to the board using a USB lead. That's the set up done

Installation. Pins 7 (RX) and 8 (TX) go to TX and RX on the Adafruit FX board. Connect the UG pin to ground to enable UART mode. Also connect up the amp, speaker and power.

Bobbs has his speakers positioned just behind his mouth.

The code. Adafruit have their own libraries which I haven't used but expect they're good. I've written my own for Bobbs

Some notes on the code;

Include the software serial library and create an instance called FXserial using pins 7 and 8 and TX and TX.

Start the serial communication using FXserial.begin in void setup()

Playing a sound is by calling FXserial.println("#x");

where x is replaced with the track number, so for track 0, x is zero, etc

#include <softwareserial.h>
SoftwareSerial FXserial(7, 8); // RX | TX


void growl()
{
// Use software serial to tell Adafruit FX card
// to play a sound
  FXserial.println("#03");
  delay(500);
}

void fart()
{
// Use software serial to tell Adafruit FX card
// to play a sound
  FXserial.println("#02");
  delay(500);
}

void burp()
{
// Use software serial to tell Adafruit FX card
// to play a sound
  FXserial.println("#04");
  delay(500);
}

void laugh()
{
// Use software serial to tell Adafruit FX card
// to play a sound 
  FXserial.println("#00");
  delay(500);
}

void setup() {
// Initialise Bobbs on start up</p><p>// Serial communications with  
// sound card
  FXserial.begin(9600);
}

void loop(){
	fart();
	burp();
	laugh();
	growl();
}</p>

Step 5: Alternative Sounds

As a cheaper alternative to the Adafruit board, a DFplayer mini MP3 with an SD card is a possibility. Be warned - they are a pain. It does play MP3 files whereas the FX board won't, and you can hold many more noises. Like the Adafruit board it will also run without a microprocessor.

eBay sells them for about £4, which is mucho less dosh than £20 for the FX board and £60 for the speech chip. There's more about it here.

https://www.dfrobot.com/blog-277.html

I couldn't get the libraries to work properly, and unless I took steps 1 and 2 below it wouldn't play the files I wanted. Forget about directories as well.

The steps I followed to make it work are;

1) Download sound files from a site like Sound Bible or make some voice files and edit them as necessary with Audacity.

1.5) Transfer them to an SD card. Name the files 0001.MP3, 0002.MP3 etc

2) Find a fat 32 file sorter (http://www.luisrios.eti.br/public/en_us/projects/y...) and sort the files by name. Each time you add a sound, clear the SD card, and repeat points 1.5 and 2.

3) Hook up the DFplayer as in the diagram.

4) Time for some code

/*  New file order - clear SD, download new files, YAFS */

#include "SoftwareSerial.h"

# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]

SoftwareSerial MP3player(10, 9); // RX, TX</

void setVolume(int volume)
{
  execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
  delay(2000);
}

void play(int file)
{
  int state = LOW;
while (state == LOW)
  {
    state = digitalRead(busy);
  }

  execute_CMD(0x03, 0, file);
  delay(100);
}

void execute_CMD(byte CMD, byte Par1, byte Par2)
// Execute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
                            Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte
                          };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++)
  {
    MP3player.write( Command_line[k]);
  }

  delay(100);

}

void setup() {

  MP3player.begin(9600);
  setVolume(21);
  play(34);
}

void loop() {
// play a random track between 1 and 49
      track = random(1, 50;

}

Yep, it's a pain. If you can cope with a few sound effects, stick with Adafruit.

Step 6: Ampifier and Speakers

I'm guessing that you can wire up an amp and speakers. The amp's another Adafruit product, but that's only because they tend to work without any trouble.

https://www.adafruit.com/product/987

If you want sounds and speech, you'll need two channels as you can't have two inputs going into a mono amp.

Step 7: Speech Synthesiser

This is the good bit. Bring your toy to life with speech. I'm amazed that there aren't more hobby priced speech chips - there must be a demand for them. Perhaps it's the price - it's relatively expensive at around £60.

If you can stand the pain, you could record some voice files onto MP3 and then use the DFplayer mentioned earlier for speech.

https://www.adafruit.com/product/924

https://www.parallax.com/product/30016

It has several voices and they all sound like Stephen Hawkins. I'm using Software Serial again (I can hear teeth grinding). Again, I'm not going to repeat what's already available on the web, just cover what I've done.

Installing the chip is easy; Hook up the RX (pin 2 on Arduino) to TX on the board and pin 3 on the Arduino (TX) to the RX pin on the board. Outputs go to the amp as usual. The code can be a bit more involved - see the websites for more details. My example below is probably as simple as it gets.

#include <softwareserial.h>
<SoftwareSerial emicserial(2, 3); // RX | TX

void speak(String message)
{
// Send message to speech chip 
  emicserial.print("S");
  emicserial.print(message);
  emicserial.write("\n");

}

void setup() {

// Serial communications with speech chip
  emicserial.begin(9600);

// Set volume for speech
  emicserial.print('V16');
  emicserial.print('\n');

void loop() 
{
   speak("Hello");
}

Step 8: Bluetooth

Control your toy by Android phone using Bluetooth and just for once, a cheap knock off from eBay and, amazingly, it actually works!. This time we're not just using C++ with the Arduino, but MIT AI2 as well.

https:\\ai2.appinventor.mit.edu/

MIT AI2 is just amazing. You don't need to know anything about the Andriod operating system - just drag the components to make the screen layout and then program it using blocks.

You can make the MIT AI2 bit as complicated as you like. For simplicity I'm going to explain noises and speech, but there are guys out there that do all kinds of craziness.

This gets a bit involved but to keep this mostly simple we're using classic Bluetooth instead of BLE. I'm not sure if BLE's supported by the HC06 anyway.

Let's start with the Andriod side first.

In keeping with my policy about not repeating everything already on the internet, this Instructable explains the Arduino / Andriod interaction nicely.

https://www.instructables.com/id/Connecting-stuff-...

Step 9: Bluetooth Andriod Code

Open up the MIT AI2 website and create a new project. The window opens on the designer page, and on the left side of the screen you should be able to find 'Button' under user interface. Drag 2 buttons onto the blank screen.

Also on the left side of the screen under connectivity is an icon called Bluetooth client. Drag this onto the screen.

Under Sensors is Accelerator Sensor. Drag the to the screen as well.

The right hand side of the screen allows to customise the buttons.

At the top right hand side of the screen is a button which reads 'Blocks'. Click it, and we'll start programing. I've put images on the code above. It's not ideal but the Instructable editor won't let me do anything else.

The first thing to do is create the Bluetooth connection which is done by getting a list picker and making the elements equal to the list of Bluetooth connections in the Andriod device. See diagram 1

After the user has chosen a connection we call the Bluetooth instance to contact the HC06 module - diagram 2.

Buttons are event driven; they don't do anything until clicked. When clicked the Andriod device sends a character to the Bluetooth instance which sends it onto the HC06. Ignore the 'Set Global repeat' bit. See diagrams 3 and 4

I've also added the accelerometer as it's cool. Shaking the phone activates this bit of code and sends another character to Bobbs - diagram 5.

Build the code and either save the apk file to your computer or use the QR code. Your Andriod device must have the developer option switched on.

Go to Settings > About phone > Build number. (might be different for Samsungs)

Tap Build number seven times.

Return to Settings, where you'll find a Developer options entry in the menu.

Once the file has been transferred to the Andriod device, install it, and pair the phone with the HC 06. Unless the HC06 has been messed with, the PIN is 1234.

Step 10: Bluetooth Arduino Code

It's Arduino time.

The code below isn't complete as it's only meant to illustrate what's going on. It's very likely your project isn't going to another Bobbs and I expect you'll modify it anyway for your own need.

The Andriod device is sending characters to the HC06, but for reasons of it's own, the ASCII code is being detected by the Aduino. This is stored in the 'command' string then converted to an integer for use with the switch function.

#include <SoftwareSerial.h>

SoftwareSerial BTserial(14, 15); // RX | TX

void instruction()
{
// Decode instructions from BT device and
// take action

  command = BTserial.read();
  int commandvalue = command.toInt();
  switch (commandvalue)
  {
    case 71: // G
      growl();
      break;
    case 84: // T
      getmessage();
      break;
    case 70: // F
      fart();
      break;
    case 66: //B
      burp();
      delay(500);
      speak("Better out than in");
      break;
    case 69: // E
      speak("All the colours of the bow man");
      rollseyes();
      break;
    case 83: // S
      shake();
      break;
    case 76: // L
      laugh();
      break;
  }

void setup() {

// Initialise Bobbs on start up
// Serial communications with BT device 
  BTserial.begin(9600);
}

void loop() {
// BT device instruction received?


  if (BTserial.available())
  {
    instruction();
  }

Step 11: Shake It Off

It's not just Taylor Swift that can shake it off, Bobbs has the moves too. The setup for Bobbs is he shakes when the Andriod device is shaken, or when called in conjunction with other interactions like high five or tickly feet.

The motor is firmly fixed to the box using big screws and wood. The shaking is caused by an off centre weight.

A transistor is used to handle the current and save damaging the Arduino.

#define motorpin  10

void motor(int turns)

{
// Active motor pin to turn on motor briefly
  for (int i = 0; i < turns; i++)
  {
    digitalWrite(motorpin, HIGH);
    delay(2);
    digitalWrite(motorpin, LOW);
  }
}

void setup() {

pinMode(motorpin, OUTPUT);

digitalWrite(motorpin, LOW);

}

void loop() {

motor(10);

}

Step 12: Tilt Sensor

Bobbs doesn't enjoy being tipped over - cue bad words and growling.

The hardware for this is dead easy - a tilt switch and a resistor. Arduino pin 21 measures the voltage and jumps to the tilt actions routine if Bobbs isn't upright. I've de-sensitised Bobbs by counting 500 first otherwise he thinks he's constantly falling over.

The tilt actions routine picks a random phrase and flashes eyes and horns.

#define tiltpin  21

void tiltactions()
{
// Randomly select an action when Bobbs in tilted

  choice = random(6);
  eyes(255, 0, 0);
  growl();
  delay(750);
  switch (choice)
  {
    case 0:
      speak("Whats happening");
      delay(750);
      break;
    case 1:
      speak("This is not cool");
      delay(750);
      break;
    case 2:
      speak("Human I need help");
      delay(750);
      break;
    case 3:
      speak("This sucks");
      delay(750);
      break;
    case 4:
      speak("I'm going to puke");
      delay(750);
      break;
    case 5:
      speak("Make it stop");
      delay(750);
      break;
  }
  horns(1, 10, 5); // colour, repeat, speed
}

void setup() {
pinMode(tiltpin, INPUT);
}

void loop() {

// Is Bobbs tilited?

  if (tilt > 500)
  {
    tiltcount += 1;
    if (tiltcount > 500)
    {
      tiltactions();
      delay(1000);
      timethen = timenow;
    }
  }
  else
  {
    tiltcount = 0;
  }

}

Step 13: Dark Sensor

Bobbs is a wuss when it gets dark.

I'm using a photo diode as I had a spare one, but I expect an LDR would work just as well. Like the high five and tickly feet routines, this is another voltage change detection exercise. As it gets dark, the value measured by pin 20 changes setting off the dark actions routine.

#define lightpin  20
int light = 0;

void darkactions()

{
// Randomly select an action to perform when it's dark

  choice = random(5);
  eyes(0, 0, 255);

  switch (choice)
  {
    case 0:
      speak("Is that the moon");
      delay(1500);
      FXserial.println("#06");
      break;
    case 1:
      sleepnoise();
      sleepnoise();
      break;
    case 2:
      speak("Who turned off the lights");
      delay(1500);
      break;
    case 3:
      speak("Ooh creepy");
      delay(750);
      break;
    case 4:
      speak("It's dark");
      delay(750);
      break;
  }
  horns(3, 10, 5); // colour, repeat, speed
}

void setup() {

pinMode(lightpin, INPUT);

}

void loop() {

light = analogRead(lightpin);

// Is it dark?

  if (light > 900) // dark
  {
    darkactions();
    delay(1000);
    timethen = timenow;
  }

}

Step 14: Tickley Feet

Bobbs laughs, eyes and horns light up when he gets his feet tickled.

A piece of Veroboard is wired so that alternate strips are connected (as per diagram). When a figure is run over the strips a small amount of current flows causing pin 19 to register a change in value. Bobbs has a sensor in each foot.

#define feetpin 19

void feet()

{
// Interactive feet
// Bobbs asks for his feet to be tickled
// user must respond within a set period of
// time to activate eyes, horns and make Bobbs laugh</p><p>  int feetnow = 0;</p><p>  speak("Tickle my feet");
  eyes (0, 0, 0);</p><p>  timethen = millis();</p><p>  while ( millis() < timethen + 5000)
  {
    for (int i = 0; i < 200; i++)
    {
      feetnow = feetnow + analogRead(feetpin);
    }
    feetnow = feetnow / 200;</p><p>    if ( feetnow < 0)
    {
      FXserial.println("#00"); // play the laugh sound on the Adafruit board
      eyes(255, 215, 0);
      motor(100);
      horns(1, 10, 5); // colour, repeat, speed
    }
  }
}
void setup(){

pinMode(feetpin, INPUT);

}
void loop(){

feet();

}

Step 15: High Five

Yes, high fives as well.

This is a development of the tilt routine but with a tilt sensor in each paw. In this set up Bobbs asks for a high five and starts purring if he gets one. To save pins on the Arduino board I'm using one pin to measure both paw sensors. Lifting either paw sets of the routine.

#define pawpin  18

void pawthing()

{
// Interactive paws
// Bobbs asks for his hands to be shaken
// The user must respond in time to activate
// motor, eyes and horns

  int paw = 0;
  speak("Give me high five");
  eyes (0, 0, 0);

  timethen = millis();
  while ( millis() < timethen + 5000)
  {
    paw = analogRead(pawpin);

   if (paw < 650)
    {

        speak("Purrr");
        horns(2, 5, 5);
      }

      eyes(255, 215, 0);
      delay(500);
      motor(100);
    }
  }


void setup() {

pinMode(pawpin, INPUT);
}

Step 16: Horns

Team Girl's 'Make-a-bear' dragon has light up horns. Bobbs can beat that, but we're going to need some electronics.

I wanted 6 tricolour LEDs in his horns but this meant 18 pins would be required (plus 0v), and I only had two spare pins on the Arduino. Provided we don't object to the same colour LED turning on in both horns at the same time, I can wire the LEDs so that I only need 9 states plus off. This sounds like a job for a decade counter.

The Arduino sends a pulse from pin 16 to the clock pin on the 4017 to change the output pins and switch on the LEDs in each horn. Arduino pin 4 is connected to reset. Sending 10 pulses will cycle through the colours and positions.

4017 pin - LED pair

0 - Off

1 - Red bottom

2 - Red middle

3 - Red top

4 - Green bottom

5 - Green middle

6 - Green top

7 - Blue bottom

8 - Blue middle

9 - Blue top

Supposing we wanted a particular colour, say green. If we skip through the red LEDs really quickly, say a few milli seconds, the user won't notice them switching on, and will only see the green LEDs. We then reset the 4017 so the blue lights don't activate.

Here's the subroutine to do it.

#define hornpin 16
#define hornresetpin 4

void setup{
pinMode(hornpin, OUTPUT);
pinMode(hornresetpin, OUTPUT);

digitalWrite(hornresetpin, LOW);

}


void resethorns(){
// Reset decade counter chip to turn off horn lights
  digitalWrite(hornresetpin, HIGH);
  delay(10);
  digitalWrite(hornresetpin, LOW);
}

void horns(int col, int repeat, int speed)
{
// Sets the colour of the horn lights by
// cycling through the decade counter pins
// really quickly and stopping at the 
// chosen colour
// parameters are colour, number of times to
// repeat the sequence and speed</p><p>  int start;
  int end;
  int limit;

 for (int i = 0; i < repeat; i++)
  {
    resethorns();

    switch (col)
    {
      case 0:
        limit = 10;
        break;
      case 1: //red
        limit = 3;
        break;
      case 2: //green
        limit = 3;
        for (int k = 0; k < 3; k++) // skip red
        {
          digitalWrite(hornpin, LOW);
          delay(1);
          digitalWrite(hornpin, HIGH);
          delay(1);
        }
        break;
      case 3: // blue
        limit = 3;
        for (int k = 0; k < 7; k++) // skip red and green
        {
          digitalWrite(hornpin, LOW);
          delay(1);
          digitalWrite(hornpin, HIGH);
          delay(1);
        }
        break;
    }

   for (int j = 0; j < limit; j++)
    {
      digitalWrite(hornpin, LOW);
      delay(speed);
      digitalWrite(hornpin, HIGH);
      delay(speed);
    }
  }

 resethorns();
}

Step 17: The End?

Bobbs is a big 8 bit Atari fan - check out his other Instructables.

Unfortunately his brain is fairly full. I can't add too much more code as there's only a handful of bytes left for variables. He's also out of pins.

An upgrade to an Arduino Mega is an option. It has loads and loads of pins and much more memory, but size could be an issue.

There is another possibility; we can shift some of the work to the Android device using the Bluetooth connection. MIT AI2 is a seriously powerful tool with hook ups to the internet.

How about an RSS feed reader?

Speech recognition?

GPS?

Loads of stuff in available to Android devices, depending on your phone.

Something I'm looking at is a modern version of the Eliza program (https://en.wikipedia.org/wiki/ELIZA). Conversations with a toy could be more than just imaginary!

Bonus points for figuring out which film I nicked the end from.

Share

    Recommendations

    • Sensors Contest

      Sensors Contest
    • Planter Challenge

      Planter Challenge
    • Sew Tough Challenge

      Sew Tough Challenge

    Discussions