Introduction: The Touch Module - a Robotic Dog Toy.

About: I'm a grad student studying abroad at the Swiss Institute of Technology in Lausanne.
The idea was to invent an Arduino-based, robotic toy that my dog could interact and play with. One that could record scores, automatically deliver treats, and grow more advanced as the dog learns to play with it. I wanted to find a task to test my dog's intelligence, so I chose a simple system with three 'levers.'

At first, as soon as the dog touches one of the levers, treats are delivered. Eventually the dog should begin to associate the action of pushing the levers with the rewarding stimulus, a tasty treat. Depending on your dog and what really gets him going, you can use light storebought treats, chopped up hot dogs, shredded chicken, or you can use this as a way to make mealtime more interesting for dogs with problems eating. At its most advanced, an LED lights up above one of the three levers and the dog must touch the correct lever in order to get a treat. It is designed to get more and more complex during a single playing event, and after every reset, the dog has to start over. A small counter would track his overall high-score of levers in-a-row, if he could ever actually hit two in-a-row...

There are some pretty widely-accepted theories on the intelligence of dogs generally used to classify dogs. The theory identifies three types of intelligence: instinctive intelligence which describes the activities the dog was bred for, adaptive intelligence, a metric for problem-solving, and working intelligence, or the ability to learn from human interaction. I wanted to come up with a robot that could work with all three types of intelligence for some mental stimulation. Plus, tossing treats at Henry was getting a bit boring and we needed to spice it up.

The larger scheme for the idea of robotic dog toys is to have a centralized treat-delivery system that wirelessly communicates with several toys of varying design, so this 'Touch' module with the levers could just be a single toy in a group. Before I get into the specifics, check out this video of my dog Henry, playing with the finished prototype, so you can get an idea of how it works.



This is the current stage of Henry's interaction with the toy, and now I am working on him using the machine without me around.

The last and most important advice is to SUPERVISE YOUR DOG and do not leave them unattended with any of the items in this instructable. It is not meant to be an autonomous robot that wakes up and plays with your dog, but a game with which you both interact. The fun part for me was teaching Henry how to play with it, watching him systematically improve at the game, only to completely forget everything the next day. 

The whole thing took about two months to complete and in the meantime I was able to spend some quality time with my dog and learn that he was pretty quick to pick up how to work the toy!

Step 1: Training the Dog

Training:
The dog has to be very comfortable around the toy for it to have any success. At the stage before I added any electronics I handfed Henry his dinner over and under and the around the beams for a few nights.



Yet he is completely motivated by food and after a few days he would be excited as soon as he saw the toy.
So first I just worked with him on touching the levers:
Since Henry already knew how to shake, I put the machine between us and tried to make him 'shake' my hand under the area of the scaffolding where the levers would go. Eventually I put my hand further and further back until he was slapping the postcards just by accident. Anytime his paw touched a postcard I gave him a tasty treat. I worked like that for a few nights and eventually just could tap the levers for him to 'touch' them. After a few times like that, all I had to do was hold the treat up and he would slap the levers.

Check it out:



You can watch Henry in the video to get a good idea of some of the challenges for this project. At one point he just double slaps two levers and leaves his paws resting on them while the Flex Sensors underneath are fully strained. So that's when I decided to separate the treat dispenser from the toy itself, so that after a tap on the levers the dog has to move a bit to collect the food.

Eventually Henry graduated to the first level of difficulty on the game. That is where we are at now because he has some trouble grasping that he should push a certain lever under whichever light was on, so I am trying to think of a way to get him to learn how to do that.

If you want to give a shot at making one yourself, there are detailed instructions and code. If you want to borrow some aspects of the module and creating something new, all I ask is that you keep it open-source!

Step 2: Materials

All of the design choices I made were based on what I had lying around, most if not all from SparkFun. I think there is enough information on all of these pieces available (in this instructable and hyperlinked throughout) so that a complete beginner could assemble a piece like this, with absolutely no prior robotics/electronics experience.

The body of the toy is made with MakerBeam, a fantastic open-source t-slot hardware which is perfect for prototyping small designs like this. Of course an eventual improvement for a commercial robotic dog toy would be to use dog safe materials, or just plain larger materials for any dog bigger than my guy Henry.

Nearly complete list of stuff:

-- Three Flex Sensors (2.2")
-- Super Bright LEDs - Red, Blue, and Green 10mm
-- breadboards for testing
-- Arduino MEGA 2560 (also tested with Arduino UNO which worked exactly the same)
-- ArduMoto Shield
-- Arduino ProtoShield 
-- Zevro Smartspace Cereal Dispenser
--12 V DC geared motor  and coupling shaft
-- MakerBeam kit
-- lots of wire, jumper wire, resistors, etc.
-- some postcards and electrical tape
-- the hardware pictured above for clamping down the motor
-- a dog...

Step 3: Dog Treat Delivery System

I have to give credit for the dog treat delivery idea to a guy Matt Newton at this site.

He had the idea to use the Zevro cereal dispense with this particular motor connected. He also goes in a different direction that might be interesting for some people reading this instructable, an internet-enabled pet feeder.

He talks about the problems with turning the rubber blade and how he decided to take the geared motor route, for high torque and low speed. His idea works perfectly and the slow turning of the blade enables you to deliver a nice little batch of treats at a time. He also designed and posted a design for a custom made coupling and shaft to connect the motor to the Zevro dry food dispenser, which I also made. But the similarities end after the type of motor and the Zevro, because I used the Arduino MEGA and the ArduMoto shield to run the motor.

For the wood piece and hardware:

I went to the local hardware store and purchased several pieces. The pictures included in this step pretty clearly illustrate what I did. I first bought a cheap wooden shelf and a saw and a few L-brackets to make a stand to connect the motor to. Then I found a 'mast clamp,' a piece to fix the motor to the board. You will have to find one that matches the size of the motor you buy. (I used a high torque gearbox motor for reasons discussed above). Once you make the coupling and shaft or find an alternate solution, you can screw everything together.

For the motor and the Arduino setup/code:

First, I followed this very detailed Sparkfun tutorial to test the ArduMoto shield. Once you have completed it, you should have a working idea of the sheild. At the time I had no screw terminals to connect to the ArduMoto so I just soldered two wires directly into the B terminal 3 and 4. Then I then connected those two wires by jumper cable to the 12 V 4 RPM DC motor. The order of the wires never matters because swapping them only changes direction of the motor, which can control through the ArduMoto shield. For the ArduMoto terminal B, the direction pin is hard-wired to Pin 13 and the pulse-width modulation pin is on Pin 11.



In the image you can see the ArduMoto shield in action on top of the Arduino Mega 2560 in a little project case. The plastic case on the bottom is absolutely necessary if you are working with the Ardumoto shield, because the motor can be easily shorted by touching the exposed pins on the bottom of the arduino.

This motor is a 12V DC geared motor which can turn in either direction. I chose this one because of the torque it provides to be able to turn this rubbery silicone blade, but it comes at the cost of RPM of which this motor which is rated at a slow 4 RPM.

Because the motor takes 12 V to get going, the 5 V power from the Arduino board is not enough, so I soft wired a terminal socket to the arduMoto here in order to connect it to a 12V wall wart.

You can see that the Ardumoto board has a few status LEDs which blink at a change in direction or by sending a pulse-modulated signal through the power output. 

This is the code I used in order to run the motor:

/* ArudoMoto Test */
/* Randy Carney */

int PWM_B = 11; //These two pins are reserved already on the arduMoto shield
int DIR_B = 13;

void setup()
{

  pinMode(PWM_B, OUTPUT); //Set control pins to be outputs
  pinMode(DIR_B, OUTPUT);
}

void loop()
{

 // This program which turn on and off the motor every second.

  delay(1000);

  digitalWrite(DIR_B, HIGH); //Can be used reverse motor direction, 1 - HIGH, 2 - LOW

  analogWrite(PWM_B, 255); //set the motor to run at 255/255 = 100% duty cycle to obtain the required torque.

  delay(1000);

  analogWrite(PWM_B,0); //turn of the motor
}



You can upload this sketch into the Arduino IDE and upload it to the board after making all the connections, and see if it works! If it does, you can move on to the next step, if not, put a description of what's going on in the comments and we can try to figure out the problem.

Step 4: Scaffolding, LEDs, Flex Sensors

Scaffolding: 
I used the MakerBeam to construct a rectangular piece to hold the three lever arms. The pictures for this step show the general design pretty clearly.

The only consideration is to make the base deep, so that when the dog slams the levers, the toy doesn't fall over. Note the mini L-brackets on the front placed in order to connect the LEDs. Those weren't included in the MakerBeam set, just had them around from a server motor.

Arduino ProtoShield:
The arduino ProtoShield kit is a nice package to get started on this project. It gives you a little prototyping area to connect the LEDs and Flex Sensors very conveniently. Like the arduMoto shield, there is a very nice quick start guide available for the ProtoShield. It shows you how to set it up and test it when you receive it in the mail. I used the ProtoShield to easily hook up three bright LEDs and three Flex Sensors, as described below.


Flex Sensors:
I used some little 2.2" flex sensors that I purchased from Sparkfun. The resistance of the flex sensor changes when it is bent. Here is an excellent little explanation of the technology with a quick start guide to test out your sensors. These sensors are really the key to this entire project.

I hooked up three to the scaffolding on three little arms sticking out from the top. Basically I soldered the ends to a bit of wire, covered it with some heat shrink to protect/hide the wires, and then taped each one to the scaffolding. I wrapped the excess wire up to the top of the module in order to connect it to the arduino. 

One of the sensors goes to the GND and the other is connected both to an Analog In pin and also through a 10K resistor to +5V. You don't have to keep track of which wire is connected to the pins on the flex sensor because they are interchangeable. The program I wrote is activated by a change in the resistance value, positive or negative. 

The flex sensors actually are connected to the analog inputs, so you don't have to define the 'pinMode' in the Arduino code. I used Analog pins 0, 1, and 2 from left to right for the flex sensors. 

On top of the flex sensor I just folded up some rigid postcards and taped them like crazy to the scaffolding. I folded the postcard over and cut a small hole to make a little pocket for the sensor to go into. The sensor is slipped into the straight part of the postcard protected back in the toy. The dog should be taught to slap the folded down part of the postcard. This way the flex sensor is triggered without being directly slapped by the dog, which might result in it snapping off. Actually the warning on the box for these flex sensors is that they can easily break at the point where the pins connect to the sensor. Even though my dog is a small guy, he ended up hitting these things pretty hard on occasion or leaving his paw to rest while bending the sensor. For that reason I set the sensors pretty deep on the metal arm and taped it heavily just above the weak pivot point on the flex sensor, to give it some support. Each sensor has been hit roughly 100 times so far with my dog while prototyping, and none of them have broken yet. The postcards are also nice because you can replace them quite easily when they get bent up or your dog chews them up, but it would be nice to find some kind of tough elastic material that wouldn't need to be swapped out.

Super Bright LEDs:
I used three Super Bright LEDs for this project, red, green, and blue. I soldered wire to the terminals (this time you have to keep track of the pins). The positive lead (longer pin) is connected to a Digital In pin on the protoShield, and the negative terminal is connected through a 470 Ohm resistor to the ground.

On the front-top of the scaffolding I had put some small L-brackets I had lying around from an old servo motor kit and straddled the legs of the LEDs through them, threading the wire around back and up to the top like the flex sensors. 

For the LEDS I used digital pins 4, 6, and 8, because they didn't interfere with the arduMoto shield.


Now you can check the images for this step and you should have everything setup as pictured before going on to test the Touch module so far.


Step 5: Arduino Code - Test Machine

Here is a video of the basic functionality, all of the levers are wired together so that if any of the levers is pressed, the motor turns and treats can be delivered:



Before integrating the motor, the LEDs and flex sensors can be tested:

There are two modes of difficulty for the Touch module.

First, all 3 LEDs light up and the dog can hit any lever they choose to deliver a treat from the dispenser.
Second, a single LED lights up and the dog must hit the lever corresponding to the light to deliver a treat from the dispenser.
 
Second level of difficulty:
The second level of difficulty is actually the easiest to program and the code is as follows:

#include <TrueRandom.h>

/*
// HARDWARE:
//
// For Flex Sensors (not that the flex sensor pins are interchangeable)
// Sensor pin = GND
// Sensor pin = Analog In, with 10K resistor to +5V

// For LEDs
// + pin = Digital In pin
// - pin = 470 resistor to GND

*/

int ledPinG = 7; // PIN 7 is a green LED
int ledPinR = 6; // PIN 6 is a red LED
int ledPinB = 5; // PIN 6 is a blue LED
int ledPin;
int analogPin;
int del = 1000;
int x;


void setup() {
Serial.begin(9600);
pinMode(ledPinG, OUTPUT); //Set all of the LED pins to OUTPUT
pinMode(ledPinR, OUTPUT);
pinMode(ledPinB, OUTPUT);
pinMode(ledPin, OUTPUT);

}

void loop()
{
digitalWrite(ledPinG, HIGH); // Initial LED flash to indicate input ready
digitalWrite(ledPinR, HIGH);
digitalWrite(ledPinB, HIGH);
delay(del);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, LOW);
digitalWrite(ledPinB, LOW);

x = TrueRandom.random(1, 4); // I used this TrueRandom library I found online,
// because of a known error with Arduino's random function being non-random
Serial.println(x);

int sens;
sens = SensorRead(); // Call the SensorRead() function

}

int SensorRead(){
if (x == 1) // This if-elseif stamement links the random number (1, 2, or 3) with a lever.
{
analogPin = 0; // analog PIN 0 is activated
ledPin = 7; // This LED corresponds with the lever connected to analogPin 0
}
else if (x == 2)
{
analogPin = 1;  // This LED corresponds with the lever connected to analogPin 1
ledPin = 6;
}
else if (x == 3)
{
analogPin = 2; // This LED corresponds with the lever connected to analogPin 2
ledPin = 5;
}

digitalWrite(ledPin, HIGH); //Turns on one of the LED's over the level which was randomly chosen.

int sensor;

sensor = analogRead(analogPin); // Reads the current lever's flex sensor value and sets a threshold of 3
int initVal = sensor;
int initValHigh = 6 + sensor;
int initValLow = sensor - 6;

while (sensor < initValHigh && sensor > initValLow)     // As long as the sensor value read within +/- 6 of the initial value, the analog pin
// continues to be read. Breaking the while loop means that the correct lever has been pressed.
{
sensor = analogRead(analogPin);
Serial.println(sensor);
Serial.println(initVal);

}
digitalWrite(ledPin, LOW); // The LED is shut off.

delay(del);
}


END OF CODE

Here are a few notes about the code:
-- I used the TrueRandom library instead of the built-in Arduino random command due to a known bug in which the built-in random actually isn't random at all. The website for the library is very clear on how to implement it.

-- You can follow the pin readings on the Serial Monitor with this code. You can see the constantly updating readings for the current sensor pin. If your pin is fluctuating more than +/- 6 from the initial value without being touched, you might need to increase the value. Play around with it to find the right pressure, where it doesn't go off randomly, but also responds to the slightest touch. We want the dog to get a treat any time it happens to run against the correct lever.

 

First level of difficulty:
The first level of difficulty works as long as any of the three levers is pressed down. You can achieve this by taping all three levers together and using the following code (which basically triplicates the second level code above). The TrueRandom function is no longer needed.

I've also added in the MOTOR functionality at the end of code so that the motor turns for 1 second, enough for one dose of treats to be delivered.

/*

// HARDWARE:
//
// For Flex Sensors (not that the flex sensor pins are interchangeable)
// Sensor pin = GND
// Sensor pin = Analog In, with 10K resistor to +5V

// For LEDs
// + pin = Digital In pin
// - pin = 470 resistor to GND

*/

int ledPinG = 7; // PIN 7 is a green LED
int ledPinR = 6; // PIN 6 is a red LED
int ledPinB = 5; // PIN 5 is a blue LED
int analogPin0;
int analogPin1;
int analogPin2;
int del = 1000;
int PWM_B = 11; //These two pins are reserved already on the arduMoto shield
int DIR_B = 13;

void setup() {
Serial.begin(9600);
pinMode(ledPinG, OUTPUT); //Set all of the LED pins to OUTPUT
pinMode(ledPinR, OUTPUT);
pinMode(ledPinB, OUTPUT);
pinMode(PWM_B, OUTPUT); //Set control pins to be outputs
pinMode(DIR_B, OUTPUT);

}

void loop()
{
digitalWrite(ledPinG, HIGH); // Initial LED flash to indicate input ready
digitalWrite(ledPinR, HIGH);
digitalWrite(ledPinB, HIGH);
delay(del);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, LOW);
digitalWrite(ledPinB, LOW);


int sens;
sens = SensorRead(); // Call the SensorRead() function

}

int SensorRead(){

digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, HIGH);
digitalWrite(ledPinB, HIGH);

int sensor1;
int sensor2;
int sensor3;

sensor1 = analogRead(analogPin0);
sensor2 = analogRead(analogPin1);
sensor3 = analogRead(analogPin2);

int initVal1 = sensor1;
int initVal2 = sensor2;
int initVal3 = sensor3;

int initValHigh1 = 6 + sensor1;
int initValHigh2 = 6 + sensor2;
int initValHigh3 = 6 + sensor3;

int initValLow1 = sensor1 - 6;
int initValLow2 = sensor2 - 6;
int initValLow3 = sensor3 - 6;

while (sensor1 < initValHigh1 && sensor1 > initValLow1)
{
sensor1 = analogRead(analogPin0);
sensor2 = analogRead(analogPin1);
sensor3 = analogRead(analogPin2);

Serial.println(sensor1);
Serial.println(initVal1);
}

digitalWrite(ledPinG, LOW);
delay(100);
digitalWrite(ledPinR, LOW);
delay(100);
digitalWrite(ledPinB, LOW);
delay(100);
digitalWrite(ledPinB, HIGH);
delay(100);
digitalWrite(ledPinR, HIGH);
digitalWrite(ledPinB, LOW);
delay(100);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, LOW);
delay(100);
digitalWrite(ledPinG, LOW);
delay(100);


digitalWrite(DIR_B, HIGH); //Can be used reverse motor direction, 1 - HIGH, 2 - LOW

analogWrite(PWM_B, 255); //set the motor to run at 255/255 = 100% duty cycle to obtain the required torque.

delay(1000);

analogWrite(PWM_B,0); //turn of the motor

delay(1000);

}  


END CODE



Step 6: Final

Hope you enjoyed the instructable, here is Henry playing with the machine again: