Tamanooki - an Arduino Based Virtual Pet (tamagotchi and Animal Crossing Inspired)

by Jerietje in Circuits > Arduino

242 Views, 0 Favorites, 0 Comments

Tamanooki - an Arduino Based Virtual Pet (tamagotchi and Animal Crossing Inspired)

IMG_8504.jpg
happy_tom_ani.gif
money_tom_ani.gif
neutral_tom.png
shocked_tom_ver3.png

Hi my name's Jae, I'm a game art student from the netherlands currently in my first year. The Tamanooki is a project I made for a class named "If this then that" (ITTT) where we got to make whatever we wanted with an arduino as long as it had an interaction.

The Tamanooki is a simple virtual pet inspired by Tom Nook from animal crossing and Tamagotchi.

You can interact with Tom by pressing one of the two buttons or shaking him. The interactions include: giving him money, showing some love and shaking him.

You probably think why? why would I design a project with the sole purpose to shake Tom Nook?

Well it all started in the spring of 2020 where little old me was tempted to live on a desserted island by a lovely tanuki and his little nephews called Tom, Timmy and Tommy. It was a beautiful escape into nature until he came knocking, I wasn't aware of the horrors that were about to follow... The bill. I was now indebted to the wannabe raccoon and with that came a life time of trying to clear my debt.

So... long story short, I'm broke! I'm mad! and now I just want to shake him. So I built this Tamanooki to still my anger.

Now that i've finished this project i've learned that a lot can go wrong and that i should constantly test and check if it works before moving on to the next step

Supplies

IMG_8393.jpg
IMG_8227.jpg

Arduino Components:

  • 1 Arduino uno
  • 1 Oled screen
  • I used the Seeed Studio Grove OLED Display (0.96 inch 128*64 pixels| SSD1315 Driver)
  • 1 3-axis accelerometer
  • I used the Seeed Studio grove 3-axis acelerometer
  • 2 Buttons
  • 2 Button caps
  • 3 Resistors (330 Ω)

Soldering Components:

  • 1 PCB Board of your choosing
  • Soldering wires (I use around 14 wires)
  • Soldering tin
  • Soldering iron

3D Components:

  • PLA in the colour of your choosing (I used a wood based PLA)
  • A 3d printer
  • The model
  • Tools to clean the model (pliers, sanding paper)
  • Acrylic paint for the details

The Idea and 3D Modelling

IMG_4342.JPG
Schermafbeelding_2024-03-09_203359.png
Schermafbeelding_2024-03-09_203509.png
Schermafbeelding_2024-03-09_203604.png
Schermafbeelding_2024-03-09_203711.png

I started the project wondering what I wanted to make, I wanted to create something that was fun to make and I wanted to be able to use it after the project too.

While coming up with an idea I was obsessed with tamagotchi's so I figured pretty fast that I wanted to make a little pet. A week later I also picked up the game Animal Crossing again and the idea to include Tom nook grew slowly.

Suddenly I had the idea to combine the two and make a Tom Nook inspired virtual pet, but I couldn't make it a love letter! The mobster raccoon look-a-like stole all my money and I wanted to make something a little devious to show how I felt about him. That's where the idea started to shake the Nookster. I was so excited about the idea that I started sketching and modelling pretty much right away.

Coding

The next step was coding!

I had a little of experience before this but was basically a noob with any sort of programming (Still am to be honest).

I was able to figure out most of the code on my own but couldn't figure out how the accelerometer worked so I asked my friend Jorn Uffing for some help (Visit his site!). He wrote the code for the accelerometer and explained it too me thoroughly so i could make it my own.

Here's the code needed to make your own Tamanooki! I've included some comments to explain how it works.

I've included the code and Nook.h file (all the images I used) I made as downloadable files.

//Tamanooki code and pixel art by Jae van den Heuvel With help by Jorn Uffing


//With include you can use an existing library in your code so you don't have to write everything yourself
#include "Arduino_SensorKit.h" //This library is needed for the accelerometer I used
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> // wire.h and both adafruit libraries are used by my screen
#include "pitches.h" //This library is used by the buzzer and makes it easy to use notes
#include <CuteBuzzerSounds.h> //This library has a bunch of cute sounds that I used as reactions
#include "nook.h" //This is the file I made to contain all my images

#define SCREEN_WIDTH 128  // OLED display width,  in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels
#define button1 4
#define button2 2
#define BUZZER 5


// declare an SSD1306 display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

//for reading the pushbutton status
int button_state = 0;
int button_money = 0;


//xyz axis floats for accelerometer
float xNow;
float xPrev;
float yNow;
float yPrev;
float zNow;
float zPrev;
float threshold = 1; // The threshold looks at the difference between the readings of Now and Prev, if the difference is equal to 1 Tom reacts


void setup() {
  Serial.begin(9600);
  Accelerometer.begin(); //This is used to activate the accelerometer


  // initialize the pushbutton pin as an input:
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(BUZZER, OUTPUT);
  cute.init(BUZZER);


  xNow = Accelerometer.readX();
  xPrev = Accelerometer.readX();


  yNow = Accelerometer.readY();
  yPrev = Accelerometer.readY();


  zNow = Accelerometer.readZ();
  zPrev = Accelerometer.readZ();


  // initialize OLED display with address 0x3C for 128x64
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true)
      ;
  }


  delay(2000);  // wait for initializing
  oled.setCursor(0, 0);
}


//neutral animation
void tomNorm() {


  oled.clearDisplay(); //Clears the display so the images always work


  // display neutral tom
  oled.drawBitmap(0, 0, NeutralTom, 128, 64, WHITE); //Draws the bitmap of the image
  oled.display();
  delay(100); //The delay is used to make the animations flow correctly
  oled.clearDisplay();
}


// happy animation
void tomHappy() {


  // display normal tom
  oled.drawBitmap(0, 0, NormalTom, 128, 64, WHITE);
  oled.display();
  delay(100);
  cute.play(S_HAPPY);  //plays a happy sound on the buzzer


  oled.clearDisplay();


  // display happy tom
  oled.drawBitmap(0, 0, HappyTom, 128, 64, WHITE);
  oled.display();
  delay(500);
}


//this button plays the happy animation
void happyButton() {


  button_state = digitalRead(button1);
  oled.clearDisplay();


  //if the button is pressed (button_state is high) an animation will play
  if (button_state == HIGH) {
    tomHappy();


  } else {
    tomNorm();
  }
}
//money animation
void money() {


  button_money = digitalRead(button2);
  oled.clearDisplay();


  //If this button is pressed tom will recieve some money
  if (button_money == HIGH) {


    // display coins_appear
    oled.drawBitmap(0, 0, CoinsV1, 128, 64, WHITE);
    oled.display();
    delay(10);
    oled.clearDisplay();


    // Play coin sound
    tone(5, NOTE_B5, 100);
    delay(100);
    tone(5, NOTE_E6, 850);
    delay(600);
    noTone(5);


    // display coins_appear_2
    oled.drawBitmap(0, 0, CoinsV2, 128, 64, WHITE);
    oled.display();
    delay(50);
    oled.clearDisplay();


    // display money_falling
    oled.drawBitmap(0, 0, CoinsV3, 128, 64, WHITE);
    oled.display();
    delay(50);
    oled.clearDisplay();


    // display money_falling
    oled.drawBitmap(0, 0, CoinsV4, 128, 64, WHITE);
    oled.display();
    delay(200);
    oled.clearDisplay();


    tomHappy();


  } else {
    tomNorm();
  }
}
//shook animation
void tomShook() {


  oled.clearDisplay();


  // displays Shocked tom start
  oled.drawBitmap(0, 0, ShockTomStart, 128, 64, WHITE);
  oled.display();
  cute.play(S_SURPRISE);
  delay(50);


  oled.clearDisplay();


  // display shocked tom 1
  oled.drawBitmap(0, 0, ShockTom1, 128, 64, WHITE);
  oled.display();
  //delay(50);
  oled.clearDisplay();
}


//tom gets shaken when the difference between now and prev is above the threshold
void xMove() {
  xNow = Accelerometer.readX();
  yNow = Accelerometer.readY();
  zNow = Accelerometer.readZ();


  if (abs(xNow - xPrev) > threshold || abs(yNow - yPrev) > threshold || abs(zNow - zPrev) > threshold) {
    tomShook();


  } else {
    tomNorm();
  }


  xPrev = xNow;
  yPrev = yNow;
  zPrev = zNow;
}
void loop() {
  happyButton();
  money();
  xMove();
}

3D Printing

IMG_8410.jpg
IMG_8363.jpg
IMG_8360.jpg
IMG_8474.jpg
IMG_8461.jpg

In this step I will be talking about the printing process! I love making 3D models so I figured this step would be easy, but like with any project there will always be suprises and failures. I haven't really made any models specifically meant for printing before so I only realised the flaws in my model after starting this phase.

The walls of the model were originally way too thin, which made the print fail. So I tried making them a little thicker which also brought some problems but after a lot of trial and error i've ended up with a pretty nice case.

Unfortunately while making the walls a little thicker I forgot to include the ears I originally designed (But I did include them just in case).

We tried printing the case standing up so the front would be nice and smooth but the edges ended up really fragile, the next time we printed it with the face of the model down, it looks a little more homemade now but the case is really sturdy when shaking the device.

The coin pouch and money bag accesoires were easy and fast to print, around 10 and 30 min.

I think this step requires a little experimenting for everyone, so have some fun with it!

I've included my models so you can make your own tamanooki, but you can also customise it or make your own case if you got experience with 3D modelling.

Building the Tamanooki

circuit schematic.png
IMG_8449.jpg
IMG_8446.jpg
IMG_8467.jpg
IMG_8457.jpg
IMG_8463.jpg
Tamanooki Breadbord test

If been using the arduino sensor kit for most of my testing which worked great, but now it was time for the real stuff!

To actually fit all my components in my 3D print, I needed to make a schematic and figure out where i needed to connect every piece. To make the schematic I used the online simulator of wokwi (note that I used the oled display and accelerometer from my sensor kit, which uses a grove pin connection).

You can test it for yourself with this link!

Unfortunatly i did run into some problems with my modules, the screen did not want to work without the grove base shield.

Solution 1: Take the grove base shield out of the sensor kit.

Add first we thought the shield might have stopped working, so we tried a lot of things to fix it. It turned out that it was the screen that stopped working and that the shield only worked when the accelerometer was attached.

We ended up not using the shield and getting a new screen and now everything works like its supposed to!


Soldering:

Once the circuit was fully working it was time to solder everything that needed soldering so it was secure and usable.

I planned what PCB board to use and where to put everything with the help of my dad, we ended up fitting everything on a small double sided board of 2cm*8cm.

We put the 2 buttons, 2 resistors, the pin wires and a ground wire on the front so they would fit nicely in the 3D print. On the back of the board was still space left so the buzzer, pin wires and the wire that would connect to 5V fit nicely there.

If you plan on making this yourself I would reccomend either a different placement for the buzzer or holes in the model so the sound can come through more clearly!

Lastly the screen and accelerometer. Since I wanted to be able to reuse them we decided not to solder them both instead use a grover plug.

The Tamanooki

IMG_8504.jpg
IMG_8506.jpg
The Tamanooki (Finished arduino project)

Here is the finished product!

With this little virtual pet you can interact with Tom nook by shaking him, and giving him some love or money by pressing the buttons!