The SillyCyborg

by Shaqayeq Tahavvori in Circuits > Arduino

75 Views, 1 Favorites, 0 Comments

The SillyCyborg

PhotoRender.jpg
theSillyCyborg.jpg
theSillyCyborg (2).jpg
Tony the silly cyborg

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

Screenshot 2024-06-09 121157.png
  • Components:
  1. Arduino
  2. HC-05 Bluetooth module
  3. Speaker
  4. 9V Battery
  5. Battery connector
  6. LED
  7. 830 Tie-Points Breadboard
  8. LCD 1602 Module
  9. 2xServo motor
  10. DF player
  11. Jumper wires
  12. Resistor
  13. Potentiometer
  14. 3mm screws
  15. SD card
  • Materials:
  1. All-purpose glue
  2. PLA filament
  3. Electrical insulating tape
  • Tools:
  1. Desktop Printer
  2. Piler

The Circuit

Circuit diagram.jpg
01.jpg

Essential notes to keep in mind:

  1. for the DF player and Bluetooth module 3,3v, either a voltage divider or a 3,3v power pin can be used.
  2. the LED working voltage is 3-3.6v. either 220om resistor or 3.3v works here.
  3. LCD needs a potentiometer to adjust the contrast of the display.
  4. Bluetooth modules should be disconnected before uploading the code, this is used for serial communication.
  5. 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

Screenshot 2024-06-07 203104.png
Screenshot 2024-06-07 203449.png

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

Screenshot 2024-06-08 125904.png

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:

  1. Hi: Hi, I am Tony, I heard you keep scr**ing up, well congrats!
  2. You are wrong: Hey, Relax, even a broken clock is right twice a day!
  3. 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

Screenshot 2024-06-08 132213.png
  • 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

voice-app.png

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.

Body and Components Design

Screenshot 2024-06-07 210503.png

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

Screenshot 2024-06-07 210653.png

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.