AI Chatbot
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
Raspberry Pi 4B
7" Touchscreen Display
Microphone
Bluetooth Speaker
3D Printed Case for touchscreen/Raspberry Pi
Attach Case & Electronics
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
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
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.