The idea of the project is a "meet and treat" device that acts as a give-aways vending machine with a robot head. It will be used during events to do the following:
1- Grab attention to the booth so guests will come and check the robot.
2- Distribute giveaways to the guests (two different give-aways).
For designing the machine, I used Fusion 360.
1- Started by drawing the inclosure sketches of each face with tabs and T-Slots to be assembled by M3 screws and nuts, then extruded the sketchs to a 2.5D designs and did the assembly using joints to make sure it will fit correctly.
2- Designed the inside vending machine mechanizm, then extruded and assembled inside the enclosure.
3- Designed "the head" sketches, extruded and assembled. This includ parts that will be 3d printed (face and corners).
4- The last step is inserting the components to the design and mounting it to it's place.
5- Do a projection for each components to get the exact dimentions/holes of an exact assembly.
1- Started the fabrication process by extracting the files to be Laser cut. So I did a projection for each face to a new sketch to get the updated final holes and edits after mounting the components.
2- Exported the projected sketched to DXF files of each files for the enclosure, inside parts and the head.
3- On Laser works software started to import the DXF files one by one to srack it together on each sheet (30x50 cm) is the dimenrion of the 3mm thickens plywood we'll use as enclosure material.
Stalked all the parts to 6 sheets and saved the RLD files for the Laser Cutter.
4- On the Laser cutting machine, started to downlaod the files to the machine and stared the cutting process.
5- On the Laser machines I did adjusted the focus and tested the first sheet to be perfect. cheked the working time to report to the lap specialist.
1- Saved the parts that will be 3d printed as STL files.
2- On Cura opened the STL files of the head corners and the face. sliced the files and make sure this is the best orientation and settings for the 3D printer keeping in mind the materials quota limitations.
Saved the Cura project for later edits and saved the. GCODE files to be sent to the 3d printer.
3- For the 3D printing parts, I did copied the Gcode files to the printer memory card, insterted into the. printed, did a pre-heat to change the filament color, I used purple PLA+ from esun.
Did a run for the printer and recognized the first layers to make sure it is running great.
On the Machine, I did the following:
1- Set the focus.
2- Set the origin.
3- Track for the file to make sure it will fit the sheet.
4- Run the file.
And Here is the fabrication output.
Laser cut of 3mm plywood on a laser machine and assembled by M3 screws and nuts.
On the 3D Printer, I did the following:
1- Wipe the printer bed with alcohol.
2- Pre-heat to unload filament color.
3- Change filament & wipe the nozzle with paper towel.
4- Run the file.
And Here is the fabrication output.
3D Printed using Purple PLA.
After the machining, I did assembled the parts together.
1- Created the spiral out of 2mm steel wire.
2- Created the link parts between the spiral wire and the motor.
3- Installed hinges and a lock to the back-service door.
4- Mounted all the components.
5- Created a holder for the 8x8 matrix.
6- did the wiring.
Some wire management and handling.
The electronics circuit is illustrated by using Fritzing and then implemented using real components.
Here is the components list:
1- Inputs:
Keypad module (3x4)
Ultrasonic Sensor module
On/off Switch
2- Outputs:
4 (8x8) Matrix Led modules.
2 Geared DC motors (TT motor).
LED
3- Others:
Arduino Uno (mainboard)
H-Bridge module
Breadboard
2 adapter connector (female)
jumper wires (male-male, male-female)
The power source for the machine will be two adapters:
9V 2A Adapter: for powering the H-bridge DC motors, the Arduino board from the Vin pin.
5V 2A Adapter: for powering the LED Matrix modules and the Ultrasonic module.
I used multiple libraries for this code as we'll be using multiple components.
Also, I checked multiple tutorials online listed here:
Control 8x8 Matrix module:
https://www.instructables.com/Controlling-a-LED-Matrix-Array-With-Arduino-Uno/
3x4 Keypad module:
https://arduinogetstarted.com/tutorials/arduino-keypad
The main library for the LED matrix control is Parola, all info is found here: https://github.com/MajicDesigns/MD_Parola
Started the coding by using the divide and conquer methodology,
So I started by showing expressions to the robot head and after success, I did create another code for the keypad and motors code. then combined the two pieces of code into one under the "if" condition of the ultrasonic sensor.
I did comment my code to be descriptive so it can be readable.
The general idea of the code is big if the condition reads the ultrasonic sensor distance. and if the distance is lower or equal to 50 cm. the LED matrix screen will show a question to the guest if he needs 1- toys and 2-sweets. also, the keypad led will be high to let the guest know that he needs to add an input.
Once the guest pressed one the first motor will run and will vend a toy also a drawer led will light for 3 sec. to let the user get the toy.
The same thing for no.2 or the sweets.
Else from the big if condition (the distance is more than 50 cm), the screen will show some expressions on the machine head to grab some attention).
#include <MD_MAX72xx.h>
#include <MD_Parola.h>
#include <SPI.h>
#include "MD_RobotEyes.h"
#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW
#define MAX_DEVICES 4
#define NUM_ZONES 2
#define CLK_PIN 12
#define DATA_PIN 13
#define CS_PIN 11
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
MD_MAX72XX M = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
MD_RobotEyes E;
typedef struct
{
char name[7];
MD_RobotEyes::emotion_t e;
uint16_t timePause; // in milliseconds
} sampleItem_t;
const sampleItem_t eSeq[] =
{
{ "Nutral", MD_RobotEyes::E_NEUTRAL, 2000 },
{ "Blink" , MD_RobotEyes::E_BLINK, 1000 },
{ "Wink" , MD_RobotEyes::E_WINK, 1000 },
{ "Left" , MD_RobotEyes::E_LOOK_L, 1000 },
{ "Right" , MD_RobotEyes::E_LOOK_R, 1000 },
{ "Nutral", MD_RobotEyes::E_NEUTRAL, 2000 },
{ "Blink" , MD_RobotEyes::E_BLINK, 1000 },
{ "Up" , MD_RobotEyes::E_LOOK_U, 1000 },
{ "Down" , MD_RobotEyes::E_LOOK_D, 1000 },
{ "Nutral", MD_RobotEyes::E_NEUTRAL, 2000 },
{ "Blink" , MD_RobotEyes::E_BLINK, 1000 },
{ "Angry" , MD_RobotEyes::E_ANGRY, 1000 },
{ "Sad" , MD_RobotEyes::E_SAD, 1000 },
{ "Evil" , MD_RobotEyes::E_EVIL, 1000 },
{ "Evil2" , MD_RobotEyes::E_EVIL2, 1000 },
{ "Nutral", MD_RobotEyes::E_NEUTRAL, 2000 },
{ "Blink" , MD_RobotEyes::E_BLINK, 1000 },
{ "Squint", MD_RobotEyes::E_SQUINT, 1000 },
{ "Dead" , MD_RobotEyes::E_DEAD, 1000 },
{ "Nutral", MD_RobotEyes::E_NEUTRAL, 2000 },
{ "Blink" , MD_RobotEyes::E_BLINK, 1000 },
{ "ScanV" , MD_RobotEyes::E_SCAN_UD, 1000 },
{ "ScanH" , MD_RobotEyes::E_SCAN_LR, 1000 },
};
#define SPEED_TIME 50
#define PAUSE_TIME 1000
#define BUF_SIZE 75
char zone1Text[16] = "o";
char zone1Text1[16] = "O";
char zone1Text2[16] = "o";
bool zone1Swapper = true;
#include <Keypad.h>
const int ROW_NUM = 4; //four rows
const int COLUMN_NUM = 3; //three columns
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte pin_rows[ROW_NUM] = {A0, A1, A2, A3}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {7, 6, 5}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
long readUltrasonicDistance(int triggerPin, int echoPin)
{
pinMode(triggerPin, OUTPUT); // Clear the trigger
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
// Sets the trigger pin to HIGH state for 10 microseconds
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
pinMode(echoPin, INPUT);
// Reads the echo pin, and returns the sound wave travel time in microseconds
return pulseIn(echoPin, HIGH);
}
void setup()
{
// Serial.begin(9600);
pinMode (10, OUTPUT); //enable H-bridge Speed
pinMode(9, OUTPUT); //motor1
pinMode(8, OUTPUT); //motor2
pinMode(2, OUTPUT); //Keypad LED
pinMode(1, OUTPUT); //Gift LED
analogWrite(10, 130); // set Motor speed.
M.begin();
E.begin(&M);
P.begin(2);
P.setZone(0, 0, 3);
P.setZone(1, 2, 3);
P.setInvert(false);
// P.displayZoneText(0, zone0Text, PA_RIGHT, SPEED_TIME, PAUSE_TIME, PA_SCROLL_UP , PA_SCROLL_UP);
P.displayZoneText(1, zone1Text, PA_CENTER, SPEED_TIME, PAUSE_TIME, PA_OPENING, PA_OPENING);// , PA_SCROLL_DOWN);
}
void loop()
{
digitalWrite(1, LOW);
// This is the if condition of the ultrasonic sensor //
if (0.01723 * readUltrasonicDistance(3, 4) <= 50) {
E.setText("1 -> Toys 2 -> Sweets");
do {
// This is the if condition for the keypad //
digitalWrite(2, HIGH);
char key = keypad.getKey();
if (key) {
Serial.println(key);
}
if (key == '1') {
digitalWrite(9, HIGH);
delay(500);
digitalWrite(9, LOW);
digitalWrite(1, HIGH);
delay(3000);
digitalWrite(1, LOW);
} else if (key == '2') {
digitalWrite(8, HIGH);
delay(500);
digitalWrite(8, LOW);
digitalWrite(1, HIGH);
delay(3000);
digitalWrite(1, LOW);
} else {
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(1, LOW);
}
} while (!E.runAnimation());
} else {
digitalWrite(2, LOW);
digitalWrite(1, LOW);
// This is the code for diplaying the mouth //
if (P.displayAnimate()) {
if (P.getZoneStatus(1))
{
if (zone1Swapper)
{
strcpy(zone1Text, zone1Text1);
}
else
{
strcpy(zone1Text, zone1Text2);
}
zone1Swapper = !zone1Swapper;
P.displayReset(1);
}
}
static uint32_t timeStartDelay;
static uint8_t index = ARRAY_SIZE(eSeq);
static enum { S_IDLE, S_TEXT, S_ANIM, S_PAUSE } state = S_IDLE;
bool b = E.runAnimation(); // always run the animation
switch (state)
{
case S_IDLE:
index++;
if (index >= ARRAY_SIZE(eSeq))
index = 0;
if (b) // text animation is finished
{
E.setAnimation(eSeq[index].e, true);
state = S_ANIM;
}
break;
case S_ANIM: // checking animation is completed
if (b) // animation is finished
{
timeStartDelay = millis();
state = S_PAUSE;
}
break;
case S_PAUSE: // non blocking waiting for a period between animations
if (millis() - timeStartDelay >= eSeq[index].timePause)
state = S_IDLE;
break;
default:
state = S_IDLE;
break;
}
}
}
I asked for feedback and help a lot from my instructor Amany and I really want to take that chance to thank her for the great support and the amazing dedication.
My plan to 3D print the face part on Cura was the face down to the plate and she said it will not gonna have a good texture as the face is all curved so she mentioned the best practice is a 45-degree inclination angle and it came out great but it used a lot of material grams for the supports.
I asked for feedback about the volt regulator from our instructor Ibrahim and he explained the concept to me.
So I could have used only one Adapter 9V and a converter to 5V.
I did helped my coleague student Nihal in building the spiral and motor connector or coupling as she is also building a vending machine.
I did help my colleague student Mohamed Adel in settings the "cutter blade" angle to cut the paper with no trimming.
The first challenge was I designed the dimensions of the faces of the body 30 cm and the max sheets we can use on the Laser Cutting Machine is also 30 cm. So I did scaling the designs to 29 cm for all the parts and it worked great for the slots and taps but it didn't work for the holes for mounting the components so I had to re-drill the some holes and file some other slots.
The second challenge, when I was tying the two adapter inputs, I accidentally mixed the 5V with the 9V input, so that burned two ICs (MAX7219) of the 8x8 matrix module and I had to replace these ICs.
The last challenge is to be a maker with a 3 years old kid :D
I used a nails file to remove that disaster.
I Would have done a drawer with a servo to get the gift out for the guest.
I would have re-coded the Arduino code to accept mobile phone number from the user to vend the gift.
I would have added moving hands to the body.