Get Schwifty With Text: the Markov-Driven Rick Face

by Hirond_l in Circuits > Raspberry Pi

50 Views, 0 Favorites, 0 Comments

Get Schwifty With Text: the Markov-Driven Rick Face

title.jpg

A while back I watched the super video by CodeBullet on AI-generated Rick & Morty episodes, I was super hyped and willing to make some kind of Rick chatbot too. From some random Stack Overflow post, I knew that Markov Chains could be useful to make this kind of chatbot. So here is what I got:

A 3D printed face of Rick Sanchez, with a LCD screen that displays Rick-like sentences based on a Markov Chain I've built using the transcripts of the sitcom.

You can watch it and enjoy weird sentences being generated, sometimes absolutely boring, sometimes magnificient SciFi madness...

I'll start this instructables directly with the build (steps up to 7) and add more details (steps from 8) in the end on the process to build the Markov chain from the transcripts, you may find it useful if you plan to make a Morty Face too!

Supplies

Components:

Raspberry Pi 2B (newer should work too) + its power supply

SD card (got 32GB)

I2C LCD1602: 16x2 LCD display with a I2C backpack

4 * buttons (10mm diameter)

classic electric wire

random screws and washers

Tools:

3D printer + filament

soldering iron + tin

drill + 1 or 2mm drill bit

Extra fanciness:

5 + 2 * 2 female header connectors (2.54mm)

heat shrink tubing

Gesso (a primer we'll use on the 3D face)

Acrylic paint + brush

Black marker

Get the Chassis

20250119_103630_resied.jpg
20250202_104158.jpg
20250210_223630.jpg

Important: If you don't have a 3D printer, you can simply go with the good old tin box!

First, I got the excellent model by UHPM, and drew some basic shapes of the screen, the buttons, screws, supports... Then I processed the face to "substract" the screen and the buttons by using Blender's "boolean modifiers". I put my files here if you want to use them.

NB: I had to lower my model resolution to comply with the 25MB size limit, but it should work perfectly fine (I hope).

Then I sliced the Rick_full.stl with supports, 3-layer walls and printed it. It took a bit more than 7 hours.

In the end, I had to use the drill to remove excess support, especially in the holes for the screws.

Once you have your print, you can apply the gesso, paint it... A nice touch was the black marker on the edges that added a very sketchy effect.

At some point, you'll have to glue the supports. I recommend doing it at the very end of your build, when everything works. (Maybe I put a support in front of the HDMI port and had to unstick it to make the tutorial, wooooops)

Get the Pi Ready

I won't go into to much details about setting up a Raspberry for the first time, here is a quick description of the process:

Go visit the official website to get the Raspberry Pi Imager.

On the imager, select the correct model of your board, the OS you want (I went for the full desktop version), your SD card and follow the instructions.

Usually, once started, username, password and all, you need to update your system, you can run in a terminal:

sudo apt update
sudo apt upgrade

I don't remember installing any Python packages, but maybe the OS you chose don't have them.

Then you can create a folder for your project.

To mount the Pi on the chassis, I used small rubber washers and screws.

Give Rick a Screen

LCD1602pi.jpg
20250818_201723.jpg

I spent quite some time browsing before finding a way to connect the screen to the Pi. Finally, NerdCave saved the day.

Following his instructions, you can wire the screen to the Pi (see 1st picture, Image credit: [SunFounder](https://docs.sunfounder.com/projects/davinci-kit/en/latest/python_pi5/pi5_1.1.1_blinking_led_python.html)).

At first you can use wires with 2.54mm headers, but in the end I decided to make a 2x2 2.54mm connectors by gluing connectors, soldering wires and securing with heat shrink tubing.

Put the LCD.py in your project folder.

Then run:

i2cdetect -y 1

It should give you something like:

yourname@pi:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
yourname@pi:~ $

Then put demo.py in your folder, open it and modify the address of your screen in the following line, for example:

lcd = LCD(2, 0x27, True)

Finally, run demo.py, you should see something on the screen. If you get any trouble or want additional explanation, please go visit NerdCave's website. You can tweak the potentiometer on the I2C backpack to get the background brightness you like the most.

When you'll put the screen on the chassis, it's tricky to put the screws correctly, I put only 2 out of the 4.

Downloads

Give Rick Buttons

20250818_201813.jpg
20250818_201840.jpg
20250213_173515.jpg

For the buttons, we can directly use the recipe from the doc: we wire one side of each buttons respectively to the pins 6, 13, 19, 26 and all the other sides to GND (see pictures). I did a similar custom connector too. I put a quick hand-written note I just found, it shows the wiring on the Pi in case it may help some of you.

In case of trouble, go check pinout.xyz website.

NB: in my build, I cannot take the buttons out of the chassis because of the soldering. Maybe you can find a better system than mine!

Let Rick Speaks for Himself

Now, make sure to put the following files in your project folder:

  1. MM2.json
  2. LCD.py
  3. Rick_Box_Screen_Button.py

Then you can run Rick_Box_Screen_Button.py and press the "NEW" button, it should give you a Rick-like sentence!

The "AUTO" button gives you sentences until you press it again, the "KILL" button restarts the Rick_Box_Screen_Button.py code, and the "OFF" button turns the Pi off.

Autorun

I'm quite sure you don't want to need a keyboard, a mouse, a screen... everytime you want to show your Rick around. So let's make the Rick_Box_Screen_Button.py code run automatically when the Pi starts.

This was by far the most technical part I faced, so it may not be the best method, and it may not work for every Pi, but I used the excellent video of Grace Xing. However, I have to say it still takes some time to start.

Open the file manager, you should be in "/home/yourname"

Left-click and tick "Show Hidden"

Go in the ".config" folder

Create a new folder called "autostart"

Create a new file called "WhateverYouWant.desktop"

In that file, write:

[Desktop Entry]

Exec=sudo bash /home/yourname/on_reboot.sh

Go back to "/home/yourname" and using text editor, create a file "on_reboot.sh" with the code:

#!bin/bash
cd /home/yourname/Documents/yourproject/
python3 Rick_Box_Screen_Button.py

Next time you boot the Pi, your Rick code should start too. I wish you the best and hope it will work!

Enjoy the Show

vid dark.gif
vid loop cut.gif

Dear readers and makers, I hope you made it successfully this far! Let me know how it went, I would love to see some of your Ricks in the "I made it" section!

I'll now add more sections to put details on the process to build the Markov Chain from the transcripts of the sitcom, feel free to try it on other characters than Rick or for other projects!

Get the Data, Clean Them

I started with the data I've found on Kaggle by Prarabdha Srivastava. Then I run a code to select only the lines by Rick and format them a littlebit: "csv sorting.py". It gave me a new file that I cleaned: removed typos, homogenized belching marks, musics... I also added some more lines I found following the links given by Prarabdha. And finally, I got: ": "BY HAND rick_only_nb.csv".

Start to Belch

proba burps.png

One feature I really loved in the video of Code Bullet was to mimic Rick's belching style. So I started how to do it based on my data at hand. I ended up with a nice categorical law (I guess) depending on the length of the genrated line, with nicely fitted curves: that's the numbers you can find in the list "r_fit" in the Rick_Box_Screen_Button.py" file. In my notes, I just found: "a 'categorical draw' with the probability 'parametrized' by the length of the generated line". Yummy.

From there, the idea was to generate the line with the Markov Chain, then draw the number of *burps* based on the length of the line, and finally insert them randomly in the sentence.

Enter the Markov Chain

START.png

Then plan here was to use a Markov Chain to represent all the data we got. Let's take a super simple example: "The dog saw the cat and the cat saw the dog, but the dog chased the cat.". If we do not care about the case ("t" is the same as "T"), then we can represent this as a simple graph. Here transition had the same probability, but it can vary, you can use not only the word before, but the two previous words, etc.

Thus I wrote a function "generate_MMn" that encodes that kind of graph into a .json file. You will find it in the build_MM.py file.

This function gives files like "data_MM2.json". Feel free to try other orders to see the effect!