Magic 8 Ball on a Breadboard!

by ihavebraindamage in Circuits > Arduino

1820 Views, 20 Favorites, 0 Comments

Magic 8 Ball on a Breadboard!

IMG_20231117_231433206.jpg

I have recently been exploring accelerometer modules, specifically the GY521 (MPU6050 module), and I had been thinking for some time about creating something fun that might put the module to good use. I then decided to scroll on my phone for a while, only to find streamers on YouTube using the Magic 8-Ball for content.

Then it hit me that I can build a simple circuit that uses the accelerometer module and try to recreate a Magic 8-Ball. Well, the circuitry, at least. The process seemed very simple and straightforward, and it's something I would recommend for people starting off with electronics to explore as well!

The project uses a microcontroller (doesn't necessarily have to be an Arduino) that monitors the acceleration values across the axes of the MPU6050 module. When the values from the acceleration module surpass the threshold value (feel free to experiment and change the sensitivity :) ), a random value is generated between 0 and 20 (as the Magic 8-Ball has 21 possible outcomes). The generated value is then used as the index for the array that stores all the possible outcomes. Since indexing for arrays starts from 0, we generate numbers between 0 and 20.

I found all the outcomes to the Magic 8 Ball here : https://magic-8ball.com/magic-8-ball-answers/ . After getting all the outcomes I randomised their order and stored them in an Array. I decided to randomise the Array as well to get better outputs.

Supplies

IMG_20231118_021235047.jpg

Things you will need include:

  1. 16X2 LCD (Liquid Crystal Display)
  2. GY51 Accelerometer Module (MPU6050)
  3. I2C Module for the LCD
  4. Breadboard
  5. Jumper Wires
  6. Arduino Uno

Arrange All the Components on the Breadboard

IMG_20231117_225334819.jpg

We start by arranging all the components on the breadboard like so. Feel free to arrange them in any other way. I decided to use a medium-sized breadboard for this, as it seemed like a convenient size for handheld use.

Wire Up All the Components

IMG_20231117_225537592.jpg

Now, begin wiring the components. To avoid confusion, I suggest using different colored wires to easily navigate the components. This step is crucial as it helps prevent incorrect connections, which could be potentially dangerous for the components used in the project.

It also adds a pop of colour to your circuit :)

Connect the Components to the Arduino

IMG_20231117_225938424.jpg

Now the connections to the Arduino are as follows :

For the Accelerometer (GY521):

  • VCC ---> 3.3V on the Arduino
  • GND ---> GND on the Arduino
  • SDA ---> A4 on the Arduino
  • SCL ---> A5 on the Arduino

For The I2C Module :

  • VCC ---> 5V on the Arduino
  • GND ---> GND on the Arduino
  • SDA ---> SDA on the Arduino
  • SCL ----> SCL on the Arduino

I suggest to use an Arduino Uno or Mega for this project as the board has pins for both 5V and 3.3V, making it significantly easier to conenct.

Alternatively should you wish to use boards like Arduino nano, ESP8266 or EP32, you can use a 5V powersupply for the I2C Module with a common ground with the board of choice.

Upload the Code to Project

VID_20231117_231345600 (1).gif

Now Upload the code to the Board and Enjoy!

(You can find the file consisting the code below this step.)

The section below explains the parts of the code that might not be clear to a beginner :)

This part of the code is used for creating characters for the special animations in the project that makes these components come to life.

byte unloaded_1[8]={ 
  B01111,
  B11000,
  B10000,
  B10000,
  B10000,
  B10000,
  B11000,
  B01111
};
byte unloaded_2[8]={
  B11111,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111
};
byte unloaded_3[8]={
  B11110,
  B00011,
  B00001,
  B00001,
  B00001,
  B00001,
  B00011,
  B11110
};
//Loaded Characters
byte loaded_1[8]={
  B01111,
  B11000,
  B10011,
  B10111,
  B10111,
  B10011,
  B11000,
  B01111
};
byte loaded_2[8]={
  B11111,
  B00000,
  B11111,
  B11111,
  B11111,
  B11111,
  B00000,
  B11111
};
byte loaded_3[8]={
  B11110,
  B00011,
  B11001,
  B11101,
  B11101,
  B11001,
  B00011,
  B11110
};
byte first_half[8]={
  B00011,
  B00110,
  B01101,
  B01110,
  B01101,
  B01110,
  B00111,
  B00011
};
byte second_half[8]={
  B11000,
  B01100,
  B10110,
  B01110,
  B10110,
  B01110,
  B11100,
  B11000
};


The 'accelThresh' is a variable that sets sensitivity of the module, feel free to experiment with the value and change it to whatever suits you the best.


const int MPU_addr = 0x68;  
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
int accelThresh = 8000;

Now we create characters using previously declared variables to accomodate animations and a more interactive feel for the project over all.


  //Creating all the custom characters
  lcd.createChar(0,unloaded_1);
  lcd.createChar(1,unloaded_2);
  lcd.createChar(2,unloaded_3);
  lcd.createChar(3,loaded_1);
  lcd.createChar(4,loaded_2);
  lcd.createChar(5,loaded_3);
  lcd.createChar(6,first_half);
  lcd.createChar(7,second_half)


now the acceleration of values from the accelerometer, in order to detect shake we're only interested in the acceleration values from accelerometer.


  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);
  AcX=Wire.read()<<8|Wire.read();  
  AcY=Wire.read()<<8|Wire.read();
  AcZ=Wire.read()<<8|Wire.read();
  Tmp=Wire.read()<<8|Wire.read();  
  GyX=Wire.read()<<8|Wire.read();  
  GyY=Wire.read()<<8|Wire.read();
  GyZ=Wire.read()<<8|Wire.read();  


This part is crucial as the 'if' condition here only returns true when the acceleration on both the X and Y axis exceeds the threshold acceleration set at the beginning of the program.

  if((abs(AcX) > accelThresh) && (abs(AcY) > accelThresh)){
    lcd.clear();
    int randomNumber = random(0,20); //generating a Random number
    delay(200);

this explains most of the logic for the project and I hope this discription was sufficient in explaining the significant parts of the code. Have a wonderful day ahead. :)