AI Chatbot

by TrayHRC in Circuits > Raspberry Pi

607 Views, 7 Favorites, 0 Comments

AI Chatbot

AI ShakespeareBot
AI Nursebot

I created an AI chatbot that you can actually talk with!

I have created three modes: William Shakespeare, Blackbeard the Pirate, and Nurse.

A Microphone is used to capture your audio questions or requests.

OpenAI (ChatGPT) is utilized to created the response.

Supplies

speakbot Pic.jpg

Raspberry Pi 4B

7" Touchscreen Display

Microphone

Bluetooth Speaker

3D Printed Case for touchscreen/Raspberry Pi

Attach Case & Electronics

IMG_2220.JPEG
IMG_2221.JPEG

Attach the 3D printed case to the Raspberry Pi. Hooked-up the touchscreen wires to the pi. Attached the backplate to keep the electronics protected.

Python Libraries & Variables

First we must download the necessary libraries. I tried multiple different audio and speech libraries, but I found that espeak gave the most customizability for the different voices I wanted to create.


import speech_recognition as sr
import openai
import pyttsx3
import tkinter as tk
from threading import *
from espeak import espeak
import os
import pyaudio
import time



Next I initialize some key variables.

openai.api_key: I set my OpenAI key, which I have omitted here. You can attain your own key for free by creating an account with OpenAI (the company that make ChatGPT)

engine & recognizer are the functions that allow text-to-speech and speech-to-text respectively.


The rest of the variables identify key characteristics about the audio qualities. I set the default to 'William Shakespeare' but this will change with user inputs.

# Set your OpenAI API key
openai.api_key = "Your OPEN AI KEY HERE"


# Initialize the text-to-speech engine
engine = pyttsx3.init()


# Initialize the recognizer
recognizer = sr.Recognizer()


character = "William Shakespeare"
VoiceInfo = 'espeak -ven+m2 -s150 -p750 "' 
user_input = "I am an AI Robot"
bot_reply = "My Response"
talkcheck = False

Functions

I defined multiple functions including:

AskRobot: Prompts the robot to listen via the microphone. Sends the user inputs to chatGPT and stores chatGPT's response.

def AskRobot():
    global user_input
    global bot_reply
    global talkcheck
    with sr.Microphone() as source:
        recognizer.adjust_for_ambient_noise(source)
        audio = recognizer.listen(source, timeout=10)
        #print("Testing")
        try:
            user_input = recognizer.recognize_google(audio)
        except sr.UnknownValueError:
            user_input = ""
        except sr.RequestError as e:
            user_input = ""


    # Send user input to ChatGPT
    response = openai.Completion.create(
        model="text-davinci-002",
        prompt=("Let's rollplay. You are" + character + 
        "Answer all questions as they would. My question is " + user_input),
        max_tokens=100 # Adjust the response length as needed
    )
    bot_reply = response.choices[0].text
    
    if user_input.lower() == "exit":
        bot_reply = "Thank you and have a good day"
        #print("You said exit")
    #print("Bot:", bot_reply)


    # Use the text-to-speech engine to play the response
    talkcheck = True
    bot_reply=bot_reply.replace('"','')
    os.system(VoiceInfo+bot_reply+'"')

    button["text"] = "Ask the AI a question"  


    # Clean up the engine
    engine.stop()


Listening: Updates the GUI so that it displays that is waiting for the user to ask a question

def Listening():
    button["text"] = "Listening... Ask Me a Question"


Display Text: Updates the GUI with the user request and chatGPT's response


def DisplayText():
    global user_input
    global bot_reply
    global talkcheck
    while not talkcheck:
        time.sleep(0.1)
        
    print("Testing got here")
    labeluser["text"] = "I Heard you say: " + user_input
    labelbot["text"] = "AI Response: " + bot_reply
    talkcheck = False 


Buttonpress: controls the flow of which functions should be run when the user clicks the 'ask a question' button

def buttonpress():
    t1=Thread(target=AskRobot).start()
    t2=Thread(target=Listening).start()
    t3=Thread(target=DisplayText).start()


shakespear_button, Blackbear_button, currie_button: Update the name, personality, and voice characteristics of the chatbot. Note that originally I was planning to utilize Marie Currie, but her profile changed to a generic nurse for medical applications.

def Shakespeare_Button():
    global character
    global VoiceInfo
    character = "William Shakespeare"
    VoiceInfo = 'espeak -ven+m2 -s150 -p750 "' 
    button_Shakespeare["bg"] = "green"
    button_Blackbeard["bg"] = "gray"
    button_Curie["bg"] = "gray"
def Blackbeard_Button():
    global character
    global VoiceInfo
    character = "Blackbeard the Pirate"
    VoiceInfo = 'espeak -ven+m2 -s100 -p10 "' 
    button_Shakespeare["bg"] = "gray"
    button_Blackbeard["bg"] = "green"
    button_Curie["bg"] = "gray"
def Curie_Button():
    global character
    global VoiceInfo
    character = "Medical Nurse Assistant"
    VoiceInfo = 'espeak -ven+f5 -s125 -p75 "'
    button_Shakespeare["bg"] = "gray"
    button_Blackbeard["bg"] = "gray"
    button_Curie["bg"] = "green"
    


GUI

I utilized Tkinter to create the GUI. First I adjust the screensize and textbox length to fit my 7" touchscreen.

screensize = "800x500"
mylength = 500


root = tk.Tk()
root.title("AI Chatbot")
root.geometry(screensize)


Next I create all the buttons and labels

labelchoices = tk.Label(root, text="Choose a Personality:", font=("Helvetica", 12), wraplength=mylength)
labelchoices.place(relx=0, rely=.05, anchor="nw")


button_Shakespeare = tk.Button(root, text="William Shakespeare", command=Shakespeare_Button)
button_Shakespeare.place(relx=.05, rely=.15, anchor="nw")


button_Blackbeard = tk.Button(root, text="Blackbeard the Pirate", command=Blackbeard_Button)
button_Blackbeard.place(relx=.05, rely=.25, anchor="nw")


button_Curie = tk.Button(root, text="Nurse", command=Curie_Button)
button_Curie.place(relx=.05, rely=.35, anchor="nw")


labelPress= tk.Label(root, text="Press here to ask a question: ", font=("Helvetica", 12), wraplength=mylength)
labelPress.place(relx=.0, rely=.5, anchor="nw")


button = tk.Button(root, text="Ask the AI a question", command=buttonpress)
button.place(relx=.05, rely=.6, anchor="nw")


labeluser = tk.Label(root, text="Welcome to AI Chatbot", font=("Helvetica", 12), wraplength=mylength)
labeluser.place(relx=.35, rely=.05, anchor="nw")


labelbot = tk.Label(root, text="Push the button to ask a question", font=("Helvetica", 12), wraplength=mylength)
labelbot.place(relx=.35, rely=.15, anchor="nw")
button_Shakespeare["bg"] = "gray"
button_Blackbeard["bg"] = "gray"
button_Curie["bg"] = "gray"


root.mainloop()


Full Python Code

aipic.jpg
import speech_recognition as sr
import openai
import pyttsx3
import tkinter as tk
from threading import *
from espeak import espeak
import os
import pyaudio
import time


# Set your OpenAI API key
openai.api_key = "Your OPEN AI KEY HERE"


# Initialize the text-to-speech engine
engine = pyttsx3.init()


# Initialize the recognizer
recognizer = sr.Recognizer()


character = "William Shakespeare"
VoiceInfo = 'espeak -ven+m2 -s150 -p750 "' 
user_input = "I am an AI Robot"
bot_reply = "My Response"
talkcheck = False


def AskRobot():
    global user_input
    global bot_reply
    global talkcheck
    with sr.Microphone() as source:
        recognizer.adjust_for_ambient_noise(source)
        audio = recognizer.listen(source, timeout=10)
        #print("Testing")
        try:
            user_input = recognizer.recognize_google(audio)
        except sr.UnknownValueError:
            user_input = ""
        except sr.RequestError as e:
            user_input = ""


    # Send user input to ChatGPT
    response = openai.Completion.create(
        model="text-davinci-002",
        prompt=("Let's rollplay. You are" + character + 
        "Answer all questions as they would. My question is " + user_input),
        max_tokens=100 # Adjust the response length as needed
    )
    bot_reply = response.choices[0].text
    
    if user_input.lower() == "exit":
        bot_reply = "Thank you and have a good day"
        #print("You said exit")
    #print("Bot:", bot_reply)


    # Use the text-to-speech engine to play the response
    talkcheck = True
    bot_reply=bot_reply.replace('"','')
    os.system(VoiceInfo+bot_reply+'"')

    button["text"] = "Ask the AI a question"  


    # Clean up the engine
    engine.stop()


def Listening():
    button["text"] = "Listening... Ask Me a Question"


def DisplayText():
    global user_input
    global bot_reply
    global talkcheck
    while not talkcheck:
        time.sleep(0.1)
        
    print("Testing got here")
    labeluser["text"] = "I Heard you say: " + user_input
    labelbot["text"] = "AI Response: " + bot_reply
    talkcheck = False    
    
def buttonpress():
    t1=Thread(target=AskRobot).start()
    t2=Thread(target=Listening).start()
    t3=Thread(target=DisplayText).start()


def Shakespeare_Button():
    global character
    global VoiceInfo
    character = "William Shakespeare"
    VoiceInfo = 'espeak -ven+m2 -s150 -p750 "' 
    button_Shakespeare["bg"] = "green"
    button_Blackbeard["bg"] = "gray"
    button_Curie["bg"] = "gray"
def Blackbeard_Button():
    global character
    global VoiceInfo
    character = "Blackbeard the Pirate"
    VoiceInfo = 'espeak -ven+m2 -s100 -p10 "' 
    button_Shakespeare["bg"] = "gray"
    button_Blackbeard["bg"] = "green"
    button_Curie["bg"] = "gray"
def Curie_Button():
    global character
    global VoiceInfo
    character = "Medical Nurse Assistant"
    VoiceInfo = 'espeak -ven+f5 -s125 -p75 "'
    button_Shakespeare["bg"] = "gray"
    button_Blackbeard["bg"] = "gray"
    button_Curie["bg"] = "green"
    
screensize = "800x500"
mylength = 500


root = tk.Tk()
root.title("AI Chatbot")
root.geometry(screensize)


labelchoices = tk.Label(root, text="Choose a Personality:", font=("Helvetica", 12), wraplength=mylength)
labelchoices.place(relx=0, rely=.05, anchor="nw")


button_Shakespeare = tk.Button(root, text="William Shakespeare", command=Shakespeare_Button)
button_Shakespeare.place(relx=.05, rely=.15, anchor="nw")


button_Blackbeard = tk.Button(root, text="Blackbeard the Pirate", command=Blackbeard_Button)
button_Blackbeard.place(relx=.05, rely=.25, anchor="nw")


button_Curie = tk.Button(root, text="Nurse", command=Curie_Button)
button_Curie.place(relx=.05, rely=.35, anchor="nw")


labelPress= tk.Label(root, text="Press here to ask a question: ", font=("Helvetica", 12), wraplength=mylength)
labelPress.place(relx=.0, rely=.5, anchor="nw")


button = tk.Button(root, text="Ask the AI a question", command=buttonpress)
button.place(relx=.05, rely=.6, anchor="nw")


labeluser = tk.Label(root, text="Welcome to AI Chatbot", font=("Helvetica", 12), wraplength=mylength)
labeluser.place(relx=.35, rely=.05, anchor="nw")


labelbot = tk.Label(root, text="Push the button to ask a question", font=("Helvetica", 12), wraplength=mylength)
labelbot.place(relx=.35, rely=.15, anchor="nw")
button_Shakespeare["bg"] = "gray"
button_Blackbeard["bg"] = "gray"
button_Curie["bg"] = "gray"


root.mainloop()


Testing the Chatbot

F9ZXNH3LOFRPY93.jpg

Finally, I test the chatbot's William Shakespeare and Nurse modes. I utilized a USB-microphone and bluetooth speaker that I had laying around. Wee the videos at the top for the initial tests.