Introduction: Powered Mobility Training Device for Toddlers

Young children with disabilities are often not afforded the opportunity to move about independently. This Instructable describes the steps required for building a powered mobility training device for young children. The device consists of a 4 wheel platform, two drive wheels and two casters. It was designed to accommodate children ranging in age from about 18 months to 4 years. Two approaches are described. One approach requires the fabrication of a simple platform and the other uses an off-the-shelf Travelmate Baby Cruizer as the platform. The main drive and power unit mounted on a plywood base can be used in either build. The DIY approach is the focus of this Instructable. Both approaches require a standard car seat and one or multiple switches to control the Trainer.

Step 1: ​Parts List

Please find the parts list attached.

Do note that the parts list is not exhaustive. Things that are NOT listed include:

1. Tools and equipment that you might require to assemble the parts, such as soldering irons and screwdrivers.

2. Standard fasteners such as screws, bolts and nuts.

The following steps are a guideline to construct this device. Please feel free to modify the size and design of the device to fit your purpose.

Step 2: Electronics: Introduction

The electronics are crucial to the operation of the device, and this is likely the most complicated step of the entire Instructable. To begin this step, please ensure that you have a good soldering iron, as well as a roll of solder. Other equipment you might find useful includes desoldering braids to help remove bad solders, and a set of vices to help you hold the part in place.

We will be using an Arduino Uno as the main microcontroller with two motor shields providing the interface between the Arduino board and the motors. The reason why they are called "shields", is because they were designed to be stacked on top of the Arduino Uno, or on each other;

Look at the motor shields. You should see two sets of two-column pins in the middle of the board, labelled DIR and PWM.

1. For the first board, place a jumper connector (circled red in the image above) at row labelled D2 for DIR, and row labelled D3 for PWM.

2. For the second board, place a jumper connector (circled red in the image above) at row labelled D4 for DIR, and row labelled D5 for PWM.

Step 3: Electronics: Circuit Board

In this step, we will be constructing our own

"shield" to wire up the electronics. Before you begin, cut the copper prototyping board to size, i.e. 22 holes x 35 holes.

Follow the illustrations for soldering the components and wires on the copper prototyping board. The placement of the components are shown on the illustration of the bottom of the board, while the points to solder are indicated by the illustration of the top of the board with the white pill shapes. Ensure that the areas indicated by the pill shapes are soldered together.

Use the solid core wires for all wiring, with the exception of the wires going to the battery.

This are the connections that we will establish:

1. D8, D9, D10, D11, Ground to Controller electronics box.

2. Current Sensor A: Ground to Ground, VCC to 5V, Out to A1.

3. Current Sensor B: Ground to Ground, VCC to 5V, Out to A0.

4. Potentiometer: Left pin to Ground, Right pin to 5V, Middle pin to A3.

Step 4: Electronics: Direction Buttons

The device was designed for two types of user inputs: individual switches to control each direction, and either a DB9 or 1/8" jack interfaces to accept certain adaptive switches

Four 1/8” female jacks were mounted onto the housing to accept individual switches

A DB9-to-terminal block or USB-to-terminal block can be used as an alternative input

Enabling Devices and Ablenet are two companies that offer a variety of switch controls:

https://enablingdevices.com/catalog/capability_switches

https://www.ablenetinc.com/technology/switches

Connections between the switch jacks and Arduino should be configured to reflect the following convention

1. Arduino D8 controls Forward

2. Arduino D9 controls Reverse

3. Arduino D10 controls Right

4. Arduino D11 controls Left

5. Arduino GND is Ground/Common

Step 5: Electronics: Power

Connect the voltage regulator to the circuit board as per the illustration in step 3. Plug the battery to the circuit using the battery cable provided, and switch on the circuit. You should see the voltage regulator's display light up, indicating the input voltage (see image). Press the "O" button on the voltage regulator, this displays the output voltage. Press either "+" or "-" to add or subtract the number till the display reads 9.0. This ensures that 9V is supplied to the Arduino Board.

Turn off the circuit.

Plug the barrel jack from the voltage regulator into the Arduino Board. Following the illustration in step 3, connect the ground (black) cables from the circuit board to the - (negative) input on the motor shields, and the power (red) cables from the circuit board to the + (positive) input on the motor shields.

Turn on the circuit.

Press the A button on the motor shields, you should see a red LED labelled A light up. Do the same for the B button, you should see a red LED labelled B light up. You have now successfully powered the electronics!

Step 6: Electronics: Current Sensors & Motors

We will now prepare the wiring to connect the motor shield to the motors. To ensure that the 2 drive motors drive consistently, we will run one of the wires going to each motor through a current sensor.

Prepare 2 x 4" length of 16 gauge red primary wire. Connect them to the A outputs on the motor shields. Next, we will solder them to the corresponding current sensors:

1. Solder the wire from the motor shield with D2 connected to DIR to the hole at the start of the arrow on Current Sensor A.

2. Solder the wire from the motor shield with D4 connected to DIR to the hole at the start of the arrow on Current Sensor B.

Prepare 2 x 2 feet length of 16 gauge red primary wire, and 2 x 2 feet length of 16 gauge black primary wire. Solder the ends of the red primary wire to the holes at the end of the arrow for each current sensor. Connect the black primary wire to the B outputs on each motor shield. At the ends of these long primary wires, attach the female spade connectors. These will connect to the motors.

Insert the shields and circuit board on top of one another. The Arduino Uno board forms the bottom layer, followed by the two motor shields, and lastly the circuit board goes on top. Ensure that you push the male header pins into the female headers, and make sure that all the pins are aligned.

Make sure that you group the correct pair of wires together. Ensure that the red wire from Current Sensor A is paired with the black wire from the motor shield with D2 connected to DIR, and that the red wire from Current Sensor B is paired with the black wire from the motor shield with D4 connected to DIR.

Step 7: Electronics: Upload Code

Upload the following code to the Arduino Uno board. You can find instructions on how to set up your arduino here:https://www.arduino.cc/en/Guide/HomePage

//start of code

const int DIR_A = 2, //Motor Shield A DIR pin

DIR_B = 4, //Motor Shield B DIR pin

PWM_A = 3, //Motor Shield A PWM pin

PWM_B = 5, //Motor Shield A PWM pin

POT = A3, //Potentiometer pin

FORWARD = 8, //Forward pin

REVERSE = 9, //Reverse pin

LEFT = 11, //Left pin

RIGHT = 10, //Right pin

CURRENT_A = A1, //Current Sensor A pin

CURRENT_B = A0; //Current Sensor B pin

int DIR, OLD_DIR; // Controller Input and Input history

boolean stop_all = false; //Decrease speed to 0

//Declaring variables

int MAX_SPEED = 230, MIN_SPEED = 60;

float acc = 0;

float LEFT_SPEED = 0;

float RIGHT_SPEED = 0;

float COMP_A = 0;

float COMP_B = 0;

int LEFT_MOTOR_DIR = 0;

int RIGHT_MOTOR_DIR = 0;

double TIME_TO_MAX_SPEED = 5000;

int DELAY = 100;

void setup() {

//Defining Input and Output pins

pinMode(DIR_A, OUTPUT);

pinMode(DIR_B, OUTPUT);

pinMode(PWM_A, OUTPUT);

pinMode(PWM_B, OUTPUT);

pinMode(RIGHT, INPUT_PULLUP);

pinMode(LEFT, INPUT_PULLUP);

pinMode(FORWARD, INPUT_PULLUP);

pinMode(REVERSE, INPUT_PULLUP);

pinMode(POT, INPUT);

pinMode(CURRENT_A, INPUT);

pinMode(CURRENT_B, INPUT);

//Initializes serial port for monitoring if necessary

Serial.begin(9600);

DIR = (digitalRead(FORWARD) << 3)

+ (digitalRead(REVERSE) << 2)

+ (digitalRead(LEFT) << 1)

+ (digitalRead(RIGHT));

OLD_DIR = DIR;

//Decrease PWM frequency to reduce motor whine

setPwmFrequency(3,1);

setPwmFrequency(5,1);

}

void loop() {

//Reads the controller input

//FORWARD: B0111

//REVERSE: B1011

//LEFT: B1101

//RIGHT: B1110

DIR = (digitalRead(FORWARD) << 3)

+ (digitalRead(REVERSE) << 2)

+ (digitalRead(LEFT) << 1)

+ (digitalRead(RIGHT));

//READS THE POTENTIOMETER AND MAPS IT TO THE MINIMUM AND MAXIMUM SPEED

int SPEED = map(analogRead(POT), 0, 1023, MIN_SPEED, MAX_SPEED);

//READS THE CURRENT SENSOR TO BALANCE THE LOAD GOING INTO BOTH MOTORS

double I_A = ((((double)analogRead(CURRENT_A)) * 5/ 1023.0) - 2.5) / 0.1;

double I_B = ((((double)analogRead(CURRENT_B)) * 5/ 1023.0) - 2.5) / 0.1;

//IF NO BUTTONS PRESSED, STOP THE MOTORS

if (DIR==B1111) {

stop_all = true;

}

if (stop_all) {

LEFT_SPEED = (LEFT_SPEED <= 0) ? 0 : LEFT_SPEED-(SPEED/TIME_TO_MAX_SPEED*DELAY*2);

RIGHT_SPEED = (RIGHT_SPEED <= 0) ? 0 : RIGHT_SPEED-(SPEED/TIME_TO_MAX_SPEED*DELAY*2);

}

if (LEFT_SPEED==0 && RIGHT_SPEED==0 && B1111) {

stop_all = false;

OLD_DIR = DIR;

}

//IF MOTORS ARE INACTIVE, LISTEN FOR CONTROLLER INPUT

if (stop_all==false) {

if (DIR != OLD_DIR && digitalRead(FORWARD) != B0) {

DIR = OLD_DIR;

}

switch(DIR) {

case B0111: //FORWARD

// current sensor compensation

if (abs(I_A-I_B) > 0.1) {

if (I_A>I_B) {

COMP_A = (I_A-I_B)*SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

COMP_B = (I_A-I_B)*-SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

}

else {

COMP_A = (I_A-I_B)*-SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

COMP_B = (I_A-I_B)*SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

}

}

else {

COMP_A = 0;

COMP_B = 0;

}

// calculate acceleration

acc = (SPEED-LEFT_SPEED)*0.1;

acc = (acc >= 6) ? 6 : acc;

acc = (acc <= 1) ? 1 : acc;

// add acceleration and compensation to the left and right motors

LEFT_SPEED = LEFT_SPEED+acc+COMP_B;

RIGHT_SPEED = RIGHT_SPEED+acc+COMP_A;

LEFT_SPEED = (LEFT_SPEED >= SPEED) ? SPEED : LEFT_SPEED;

RIGHT_SPEED = (RIGHT_SPEED >= SPEED) ? SPEED : RIGHT_SPEED;

//Set motor directions, 1=forward, -1=reverse

LEFT_MOTOR_DIR = 1;

RIGHT_MOTOR_DIR = 1;

break;

case B0101: //steer left when moving forward

LEFT_SPEED = LEFT_SPEED*0.9;

RIGHT_SPEED = RIGHT_SPEED;

break;

case B0110: //steer right when moving forward

LEFT_SPEED = LEFT_SPEED;

RIGHT_SPEED = RIGHT_SPEED*0.9;

break;

case B1011: //REVERSE

// current sensor compensation

if (abs(I_A-I_B) > 0.1) {

if (I_A>I_B) {

COMP_A = (I_A-I_B)*SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

COMP_B = (I_A-I_B)*-SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

}

else {

COMP_A = (I_A-I_B)*-SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

COMP_B = (I_A-I_B)*SPEED/TIME_TO_MAX_SPEED*DELAY*0.1;

}

}

else {

COMP_A = 0;

COMP_B = 0;

}

// calculate acceleration

acc = (SPEED-LEFT_SPEED)*0.1;

acc = (acc >= 6) ? 6 : acc;

acc = (acc <= 1) ? 1 : acc;

// add acceleration and compensation to the left and right motors

LEFT_SPEED = LEFT_SPEED+acc+COMP_B;

RIGHT_SPEED = RIGHT_SPEED+acc+COMP_A;

LEFT_SPEED = (LEFT_SPEED >= SPEED) ? SPEED : LEFT_SPEED;

RIGHT_SPEED = (RIGHT_SPEED >= SPEED) ? SPEED : RIGHT_SPEED;

//Set motor directions, 1=forward, -1=reverse

LEFT_MOTOR_DIR = -1;

RIGHT_MOTOR_DIR = -1;

break;

case B1101: //LEFT

// calculate acceleration

acc = (SPEED-LEFT_SPEED)*0.1;

acc = (acc >= 15) ? 8 : acc;

acc = (acc <= 1) ? 1 : acc;

// add acceleration and compensation to the left and right motors

LEFT_SPEED = LEFT_SPEED+acc;

RIGHT_SPEED = RIGHT_SPEED+acc;

LEFT_SPEED = (LEFT_SPEED >= SPEED) ? SPEED : LEFT_SPEED;

RIGHT_SPEED = (RIGHT_SPEED >= SPEED) ? SPEED : RIGHT_SPEED;

//Set motor directions, 1=forward, -1=reverse

LEFT_MOTOR_DIR = -1;

RIGHT_MOTOR_DIR = 1;

break;

case B1110: //RIGHT

// calculate acceleration

acc = (SPEED-LEFT_SPEED)*0.1;

acc = (acc >= 15) ? 8 : acc;

acc = (acc <= 1) ? 1 : acc;

// add acceleration and compensation to the left and right motors

LEFT_SPEED = LEFT_SPEED+acc;

RIGHT_SPEED = RIGHT_SPEED+acc;

LEFT_SPEED = (LEFT_SPEED >= SPEED) ? SPEED : LEFT_SPEED;

RIGHT_SPEED = (RIGHT_SPEED >= SPEED) ? SPEED : RIGHT_SPEED;

//Set motor directions, 1=forward, -1=reverse

LEFT_MOTOR_DIR = 1;

RIGHT_MOTOR_DIR = -1;

break;

}

}

//set motor directions

if (RIGHT_MOTOR_DIR > 0) {

digitalWrite(DIR_A, LOW);

}

else {

digitalWrite(DIR_A, HIGH);

}

if (LEFT_MOTOR_DIR > 0) {

digitalWrite(DIR_B, LOW);

}

else {

digitalWrite(DIR_B, HIGH);

}

//set motor speed

LEFT_SPEED = LEFT_SPEED <= 0 ? 0 : LEFT_SPEED;

RIGHT_SPEED = RIGHT_SPEED <= 0 ? 0 : RIGHT_SPEED;

analogWrite(PWM_A, RIGHT_SPEED);

analogWrite(PWM_B, LEFT_SPEED);

OLD_DIR = DIR;

Serial.print(SPEED);

Serial.print(" | ");

Serial.print("LEFT:");

Serial.print(LEFT_SPEED);

Serial.print(" | ");

Serial.print("RIGHT:");

Serial.println(RIGHT_SPEED);

delay(DELAY);

}

// Sets the frequency of the PWM

void setPwmFrequency(int pin, int divisor) {

byte mode;

if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {

switch(divisor) {

case 1:

mode = 0x01;

break;

case 8:

mode = 0x02;

break;

case 64:

mode = 0x03;

break;

case 256:

mode = 0x04;

break;

case 1024:

mode = 0x05;

break;

default:

return;

}

if(pin == 5 || pin == 6) {

TCCR0B = TCCR0B & 0b11111000 | mode;

}

else {

TCCR1B = TCCR1B & 0b11111000 | mode;

}

}

else if(pin == 3 || pin == 11) {

switch(divisor) {

case 1:

mode = 0x01;

break;

case 8:

mode = 0x02;

break;

case 32:

mode = 0x03;

break;

case 64:

mode = 0x04;

break;

case 128:

mode = 0x05;

break;

case 256:

mode = 0x06;

break;

case 1024:

mode = 0x7;

break;

default:

return;

}

TCCR2B = TCCR2B & 0b11111000 | mode;

}

}

//end of code

Step 8: Electronics Box

If you want, you can package the electronics in a box. Attached is a pdf file for a box design that you can laser cut out of a 0.12" acrylic sheet. Remember to insulate any metal parts near the electronics to minimize the chance of short circuiting.

Step 9: Cart: Overview of the Cart

The Trainer design is based upon two modules, a platform and a drive module. This resulted from our desire to investigate two different platforms and we wanted to utilize the same drive module. The platform is configured with front casters and a means to mount a child's car seat. The drive module consists of a 3/4" plywood sheet upon which the motors, electronics and batteries are mounted. This plywood module was designed to mount to either platform, the Travelmate Deluxe Cruizer and the DIY platform. These are minimal designs and there is much room for variation based on specific additional needs.

The 3/4" plywood drive module was cut to approximately 14"x31". The length of 31" was used to utilize fastening to plastic holes on the bottom of the Travelmate Deluxe Cruizer and overhang approximately 7" to accommodate the electronics box and battery. The image above provides an overview of the assembly and each component for the 2x4 platform.

Step 10: Cart Underside Assembly

Starting with four 2x4's (step 1) attach a small plywood piece to mount the front casters (step 2). Next attach the plywood drive modeule with the motor assemblies (step 3). Finally attach the front casters inset at least a few inches to allow for clearance of the PVC tray holder in a later stage (step 4). This may be a good time to connect and test the wires to the motors that will run to the green current sensors in the step 3 graphic of the bottom circuit diagram. Once tested label the wires since the connection order will affect the controller input for direction commands to the motors. For instance, if the controller inputs for forward and reverse are opposite you will need to switch the connections on the motor wire terminals. The cut pipe holders (described in next step) can be attached at this point as well.

Step 11: Cart: Attaching the Car Seat

To secure the cart seat we attached four eye lag screws to the top and sides of the 2x4 base. The existing car seat connections were used when possible but an adjustable strap secured with karabiners had to be made for securing the front of the seat. With the seat secured you can determine the proper size for next step making the PVC tray holder and footrests. The battery and electronics box can be added and secured with Velcro, Polylock or straps.

Step 12: Cart: PVC Tray Holder

We built a few variations of the tray holders out of 1" PVC plumbing pipe and standard T and 45/90 degree joints. The lengths and configurations depend on the size of the child and any specific accommodations for limitations of mobility or body support. A tray holder is used to support the enabling device controller that will be used for directional input to the cart. The PVC structure is connected to the cart with pipe holders modified to allow for a friction fit. This allowed a relatively easy attachment and detachment from the cart to allow entry into the car seat. We added a footrest for larger children or to attach a foot pedal input on one of the PVC tray holders.

Step 13: Lap Tray

We used a kid’s Travel Tray as a base to support the control switches. This is a small, lightweight tray that is designed to mount onto a car seat, so met our needs for the Trainer. An alternative is to fabricate a tray and mount it permanently onto the PVC frame

Step 14: Alternative Platform: Travelmate Baby Cruizer

The construction of the Trainer is similar using the Baby Cruizer but with increased cost. The Baby Cruiser offers car seat attachment straps and a handle to assist in steering and moving the trainer around. To configure the Baby Cruizer as the platform, the rear wheels must be removed and the plywood platform (with motors, controller and battery) must be screwed into the underside of the Baby Cruizer. Once the rear wheels are removed, use chalk or a wax pencil to coat the existing holes on the underside of the Cruiser (as shown). Press the plywood against the underside to transfer the hole locations. These can be used to predrill the plywood for mounting. Hand tighten the screws to avoid stripping the plastic.