The SillyCyborg
The SillyCyborg is a project done by "Shaqayeq Tahavvori, Jiuyuan Liu, and Guangyu Wang" under the curriculum of the ITECH program at the University of Stuttgart. As useless as can be, the robot is sensitive to negativity and tends to make the situation even more negative by responding with a silly sentence. This idea arises from the negativity that every student may go through as part of their studies, both cognitively and unconsciously, which affects one's productivity in a significant way. In that sense, the SillyCyborg is ironically a reminder of negative talk, a signal to bring us back on track. to achieve this, the robot’s reaction starts with moving its ears (as a sign that it is hearing you) and continues by shooting back ironic sentences at you.
Supplies
- Components:
- Arduino
- HC-05 Bluetooth module
- Speaker
- 9V Battery
- Battery connector
- LED
- 830 Tie-Points Breadboard
- LCD 1602 Module
- 2xServo motor
- DF player
- Jumper wires
- Resistor
- Potentiometer
- 3mm screws
- SD card
- Materials:
- All-purpose glue
- PLA filament
- Electrical insulating tape
- Tools:
- Desktop Printer
- Piler
The Circuit
Essential notes to keep in mind:
- for the DF player and Bluetooth module 3,3v, either a voltage divider or a 3,3v power pin can be used.
- the LED working voltage is 3-3.6v. either 220om resistor or 3.3v works here.
- LCD needs a potentiometer to adjust the contrast of the display.
- Bluetooth modules should be disconnected before uploading the code, this is used for serial communication.
- The range of the servomotor rotation is 180 degrees, we consider the initial position 90 degrees, and it should be noted that they are mirrored.
https://fritzing.org/ is a good start for circuit design.
The Logic Diagram
The workflow delineates the comprehensive logic underlying the robot's operation. At the initial stage, the Google voice recognition engine installed on a mobile device is utilized to detect negative keywords spoken by the user to the robot. These identified keywords are subsequently transmitted to the Arduino board via an HC-05 Bluetooth module. In response, the robot activates an LED, moves its ears utilizing a servomotor, and plays an ironic line.
Response Design & Ai Sound Generation
Since the robot is designed to respond, both the stimuli and the response should be designed. in this project, we have used simple samples, a few of which are listed below:
- Hi: Hi, I am Tony, I heard you keep scr**ing up, well congrats!
- You are wrong: Hey, Relax, even a broken clock is right twice a day!
- You are terrible: That’s just my warm-up act:)
to generate an Ai Sound, we have used the https://ttsmp3.com website in which you write down the text and the voice is downloadable in mp3 format. for ease of use, some of the formerly generated sounds are attached below.
Code Logic
- Including libraries:
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <LiquidCrystal.h>
#include <Servo.h>
- Custom Character Creation:
byte one[8] = {0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100};
byte two[8] = {0b00000, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100};
byte three[8] = {0b00000, 0b00000, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100};
byte four[8] = {0b00000, 0b00000, 0b00000, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100};
byte five[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00100, 0b00100, 0b00100, 0b00100};
byte six[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00100, 0b00100, 0b00100};
byte seven[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00100, 0b00100};
byte zero[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};
- LCD, Servo motors and DFplayer Initialization:
LiquidCrystal lcd(8, 9, 7, 6, 5, 4);
Servo servo1;
Servo servo2;
SoftwareSerial mySerial(10, 11); // RX, TX for DFPlayer
DFRobotDFPlayerMini myDFPlayer;
String voice; // Variable to store incoming command
- Trigger words definition:
struct Command {
const char *trigger;
int fileIndex;
};
Command commands[] = {
{"*you suck", 1},
{"*life is hopeless", 3},
{"*hi", 2},
{"*my heart is broken", 4},
{"*i feel so bad", 5},
{"*i f***** up", 6},
{"*you are wrong", 7},
{"*i am stupid", 8},
{"*you are terrible", 9},
{"*shut up", 10},
{"*i am confused", 11},
{"*shoot", 12},
{"*i am getting mad", 13},
// Add more commands here
};
- the initial state of LCD, Servo motors, LEDs & DFplayer setup:
void setup() {
lcd.begin(16, 2);
lcd.createChar(0, zero);
lcd.createChar(1, one);
lcd.createChar(2, two);
lcd.createChar(3, three);
lcd.createChar(4, four);
lcd.createChar(5, five);
lcd.createChar(6, six);
lcd.createChar(7, seven);
servo1.attach(2);
servo2.attach(3);
delay(1000); // Add a delay to ensure everything is powered and stable
servo1.write(90); // Initial position at 90 degrees
servo2.write(90); // Initial position at 90 degrees
pinMode(12, OUTPUT); //LED
pinMode(13, OUTPUT);
Serial.begin(9600); // Start serial communication for HC-05
mySerial.begin(9600); // Start communication for DFPlayer
if (!myDFPlayer.begin(mySerial)) { // Use softwareSerial for DFPlayer
Serial.println("Unable to begin:");
Serial.println("1. Please recheck the connection!");
Serial.println("2. Please insert the SD card!");
while(true);
}
if (!servo1.attached() || !servo2.attached()) {
Serial.println("Servo not attached");
return false;
}
Serial.println("Servo online");
myDFPlayer.volume(30); // Set volume
Serial.println("DFPlayer Mini online.");
Serial.println("LCD online");
randomSeed(analogRead(0));
displayNeutralFace();
}
- Looping actions:
void setup() {
lcd.begin(16, 2);
lcd.createChar(0, zero);
lcd.createChar(1, one);
lcd.createChar(2, two);
lcd.createChar(3, three);
lcd.createChar(4, four);
lcd.createChar(5, five);
lcd.createChar(6, six);
lcd.createChar(7, seven);
servo1.attach(2);
servo2.attach(3);
delay(1000); // Add a delay to ensure everything is powered and stable
servo1.write(90); // Initial position at 90 degrees
servo2.write(90); // Initial position at 90 degrees
pinMode(12, OUTPUT); //LED
pinMode(13, OUTPUT);
Serial.begin(9600); // Start serial communication for HC-05
mySerial.begin(9600); // Start communication for DFPlayer
if (!myDFPlayer.begin(mySerial)) { // Use softwareSerial for DFPlayer
Serial.println("Unable to begin:");
Serial.println("1. Please recheck the connection!");
Serial.println("2. Please insert the SD card!");
while(true);
}
if (!servo1.attached() || !servo2.attached()) {
Serial.println("Servo not attached");
return false;
}
Serial.println("Servo online");
myDFPlayer.volume(30); // Set volume
Serial.println("DFPlayer Mini online.");
Serial.println("LCD online");
randomSeed(analogRead(0));
displayNeutralFace();
}
- Function of actions:
void play(int index) {
//turn on LED
analogWrite(12, 255);
analogWrite(13, 255);
//move the ears
for(int i = 90, j = 90; i >= 0 && j <= 180; i--, j++){
servo1.write(i);
servo2.write(j);
delay(50);
}
// play the voice
Serial.print("Playing random file: ");
Serial.println(index);
myDFPlayer.playMp3Folder(index);
delay(200);
//get the duration of the voice, jitter the ear and display voice visulization on LCD
unsigned long duration = getAudioDuration(index);
Serial.print("playing time(ms): ");
Serial.println(duration);
unsigned long startMillis = millis();
unsigned long currentMillis = startMillis;
delay(500);
while (currentMillis - startMillis < duration) {
currentMillis = millis();
int jitter1 = random(-20, 20); // Random jitter between -20 and 20 degrees
int jitter2 = random(-20, 20);
servo1.write(0 + jitter1);
servo2.write(180 + jitter2);
displayPattern();
delay(200); // Small delay for both jitter and display update
}
displayNeutralFace();
// ears move to default position
for(int i = 0, j = 180; i <= 90 && j >= 90; i++, j--){
servo1.write(i);
servo2.write(j);
delay(50);
}
// turn off LED
analogWrite(12, 0);
analogWrite(13, 0);
}
the function of displaying patterns:
void displayNeutralFace(){
lcd.clear();
for(int i =0; i < 16; i++){
lcd.setCursor(i, 0);
lcd.print("_");
}
}
- Function of displaying pattern:
void displayNeutralFace(){
lcd.clear();
for(int i =0; i < 16; i++){
lcd.setCursor(i, 0);
lcd.print("_");
}
}
void displayPattern() {
lcd.clear();
for (int x = 0; x < 16; x++) {
int bottomRowValue = random(1, 7);
int topRowValue = (bottomRowValue != 1) ? 0 : random(0, 7);
lcd.setCursor(x, 0);
lcd.write(byte(topRowValue));
lcd.setCursor(x, 1);
lcd.write(byte(bottomRowValue));
}
}
- Function of audio duration:
unsigned long getAudioDuration(int fileIndex) {
switch (fileIndex) {
case 1:
return 3500;
case 2:
return 5500;
case 3:
return 3500;
case 4:
return 7500;
case 5:
return 2500;
case 6:
return 4500;
case 7:
return 3500;
case 8:
return 6500;
case 9:
return 1500;
case 10:
return 2500;
case 11:
return 2500;
case 12:
return 2500;
case 13:
return 2500;
default:
return 2000;
}
}
Downloads
Robot-Android App Connection
We can control the robot with ease using the BT Voice Control for the Arduino app. This is a free utility and tool application developed by SimpleLabsIN for Android devices. It is equipped with voice recognition technology, enabling you to use voice commands. The app is compatible with a variety of platforms, including Arduino, ARM, PICAXE, MSP430, 8051-based, and many more.
The program is easy to use, and it is a versatile tool for developers and hobbyists alike. All you have to do is download the app. Then, connect the app to your robot device using Bluetooth. To give a command, simply tap the microphone button and start speaking.
Downloads
Body and Components Design
Here is an exploded diagram, which shows the placement of the pieces, how we used a servo motor for ear movements, a speaker in the body for the robot’s sound, and all the other parts that are put into the head.
the Stl files of each part are added for G-code generation in desktop printer slicers.
Fabrication and Assembly
The assembly process for the robot is relatively straightforward. The body components are designed to accommodate the internal parts with minimal complexity. The only potentially challenging aspect is the assembly of the servo motor within the ear. Nevertheless, with the aid of the design specifications in Rhino for each ear, this task can also be accomplished with relative ease.
Outlook
- To tackle the problem of response limitations, the Bluetooth module can be replaced by a wifi module. This provides the opportunity of connecting the robot to chat GPT which makes the robot more flexible in spontaneous responses.
- Robot’s movement can be enhanced. Ears are the current movable parts using a servo motor, other parts can be included in these movements using various sensors of the desirable action.
- LCD is used to illustrate the mouth movement, demonstrating the very basic usage of this component. This can also be explored based on one’s creativity.