element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum Deciphering Arduino Code
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Verified Answer
  • Replies 19 replies
  • Answers 4 answers
  • Subscribers 391 subscribers
  • Views 2164 views
  • Users 0 members are here
  • help
  • arduino mkr zero
  • ceramics
  • arduino coding
Related

Deciphering Arduino Code

dlnxdaman
dlnxdaman over 4 years ago

Hey everyone,

 

I am new to this community and was hoping I could work with someone (or a few people) in helping me to understand a program that was written. I am new to Arduino, and have done around 30 lesson from Paul Mcwhorter on Youtube, but there is a lot of differences in the terms used and the commands used that weren't brought up in the tutorials I watched. So I was wondering if anyone would be willing to meet via Zoom and talk the code through with me so I can understand what controls what? Or, if more preferable, we could discuss the code here in a thread!

 

The code is actually a program written by one of the main contributors to this website, DJ Harrigan, and the program is for his Tomodachi (Tamagotchi spin-off) project. I came across his YouTube video while searching how to start creating the very same type of code in Arduino that he already had developed, but I need to understand all of the components so I can rework the entire thing into a project I am trying to combine with my ceramic artwork. I am a graduate student working toward my MFA in ceramics in the US and am trying to implement some new ways of incorporating technology with clay/ceramics.

 

If anyone is interested in helping me on this endeavor let me know! I would really appreciate it! Of course, we won't need to go over the entire code in one sitting, but just knowing someone could help guide me in this process would be an immense relief!

 

The code is attached at the bottom!

 

Thanks for your time!

-Dylan F.

 

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Bounce2.h>
#include <armus.h>


#define PIN_PIEZO 5
#define PIN_BTN_LEFT 6
#define PIN_BTN_RIGHT 9
#define PIN_BTN_OK 10


#define X_WIDTH 128
#define Y_HEIGHT 64
#define TEMPO 400
#define MAX_LEVEL 3
#define MAX_POWER 8


U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 11, /* dc=*/ 13, /* reset=*/ 12);
Bounce btnLeft = Bounce();
Bounce btnRight = Bounce(); 
Bounce btnOk = Bounce();
ArMus piezo(PIN_PIEZO, TEMPO);
  
enum gamestate {
  home,
  viewTomo,
  minigame,
  stats
};


gamestate curState = home;
gamestate lastState = viewTomo;
boolean displayInverted = false;


int curSelection = 0;
int lastSelection = -1;
char mIntro[] = "-3C -2C -1C C";
char mBeep[] = "C*";
char mOk[] = "2C 3C*";
char mBack[] = "3C 2C*";
char mSuccess[] = "2C 2C 2C 3C*";
char mLevelUp[] = "C C C 1C* 2C 2C 2C 3C*";
char mFailure[] = "F F -2F2";


char *tomoText[] = {"charging up...", "leveling up!", "missing!", "tired.", "strong."};
int tomoAction = 0; // placeholder for future
boolean tomoIsLevelingUp = false;
int tomoLevel = 0;
int tomoPower = 6; // experience
int tomoFrame = 0; // frame of animation
unsigned long curTime = 0;
unsigned long lastTime = -1;
int animationInterval = 800;


// Minigame vars
boolean minigameAvailable = true;
int minigameLives = 3;
int minigameScore = 0;
int curMinigame = 0;
int minigameCountdown = 9;
boolean minigameCountdownActive = false;
//u8g2 u8g2_font_open_iconic_all_2x_t
int symbolList[] = {104, 152, 223, 175, 168, 259, 96, 193}; // bug, drop, moon, earth, fire, suns, bolt, key 




// ******************************** PowerGo ******************************** 
int powerGoPresses = 0;
int powerGoCountdownInterval = 70;
boolean powerGoLocation = 0;


// ******************************** MemoSym ********************************
 enum memoSymState {
  msRevealed, msHidden, msIncorrect, msCorrect
};
const char memoSymSelMax = 8;
int memoSymIcons[] = {104, 152, 223, 175, 168, 259, 96, 193}; // bug, drop, moon, earth, fire, suns, bolt, key 
int memoSymIconsOrder[] = {0, 1, 2, 3, 4, 5, 6, 7};
memoSymState memoSymStates[] = {msRevealed, msRevealed, msRevealed, msRevealed, msRevealed, msRevealed, msRevealed, msRevealed}; 
//99 = box, 120=correct button, 121=incorrect button
int memoSymGuessCount = 0;
int memoSymIconToGuess = 0;


// ******************************** StackIt ********************************
int stackItBallRad = 4;
int stackItBallDir = -1;
int stackItBallXPos = 64;
int stackItLastBallXPos = -1;
int stackItBallYPos = 59;
int stackItBallYOffset = 0;
int stackItUpdateInterval = 65;
int stackItHeight = 0;


// ******************************** StackIt ********************************
int lucky64ReelIcons[] = {224, 228, 232, 236};
int lucky64ReelOffset = 0;
int lucky64ReelsStopped = 0;
int lucky64UpdateInterval = 333;


void setup(void){ // **************************************************************** BEGIN SETUP ****************************************************************


  Serial.begin(115200);
  u8g2.begin();
  u8g2_prepare();
  u8g2.setFont(u8g2_font_nokiafc22_tf); 
  drawStrCentered(0, "Element14 Presents");
  u8g2.setFont(u8g2_font_sticker_mel_tr);
  drawStrCentered(20, "TOMODACHI");
  u8g2.setFont(u8g2_font_nokiafc22_tf);
  drawStrCentered(48, "Digital friend!");
  u8g2.sendBuffer();
  piezo.playMelody(mIntro);
  pinMode(PIN_BTN_LEFT, INPUT_PULLUP);
  pinMode(PIN_BTN_RIGHT, INPUT_PULLUP);
  pinMode(PIN_BTN_OK, INPUT_PULLUP);
  btnLeft.attach(PIN_BTN_LEFT);
  btnLeft.interval(8);
  btnRight.attach(PIN_BTN_RIGHT);
  btnRight.interval(8);
  btnOk.attach(PIN_BTN_OK);
  btnOk.interval(8);
  while(true){ // hang in the splash screen
    btnOk.update();
    if (btnOk.fell()){
      piezo.playMelody(mOk);
      flashDisplay(8);
      break; 
    }
  }
  
  
}


void flashDisplay(int flashes){
  for (int ii = 0; ii < flashes; ii++){
    invertDisplay();
    delay(100);
  }
}


void getInput(){
  btnLeft.update();
  btnRight.update();
  btnOk.update();
  if (btnOk.fell() || btnLeft.fell() || btnRight.fell()) piezo.playMelody(mBeep); //enable sound
}


void u8g2_prepare(void) {
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}


void drawStrCentered(int yVal, const char *text){
  u8g2.drawStr((X_WIDTH - u8g2.getStrWidth(text)) >> 1, yVal, text);
}


void drawTomo(int xPos, int yPos, int curLevel, int frame){
  
  // Body
  u8g2.drawBox(xPos-2, yPos, 4, 8+(6*curLevel)); // vertical line
  u8g2.drawBox(xPos-12, yPos-6, 24, 6); // horizontal line
  
  // Upgrades
  if (curLevel >= 1){ // +antennae
    u8g2.drawVLine(xPos-11, yPos-11, 5); // L
    u8g2.drawVLine(xPos+10, yPos-11, 5); // R
  }
  if (curLevel >= 2){ // +fancy antennae
    u8g2.drawCircle(xPos-11, yPos-13, 2); // L
    u8g2.drawCircle(xPos+10, yPos-13, 2); // R
  }
  if (curLevel >= 3){ // +arms
    u8g2.drawLine(xPos-3, yPos+10, xPos-8, yPos+7); // L
    u8g2.drawLine(xPos+2, yPos+10, xPos+7, yPos+7); // R
  }
  
  // Eyes
  u8g2.setDrawColor(0);
  if (frame){
    u8g2.drawVLine(xPos-9, yPos-4, 2); // left eye
    u8g2.drawVLine(xPos+10, yPos-4, 2); // right eye
  } else {
    u8g2.drawVLine(xPos-10, yPos-4, 2); // left eye
    u8g2.drawVLine(xPos+9, yPos-4, 2); // right eye
  }
  u8g2.setDrawColor(1);
}


void invertDisplay(){ // default to flash
  displayInverted = !displayInverted;
  if (displayInverted){
    u8g2.sendF("c", 0x0a7); // inverse
  } else {
    u8g2.sendF("c", 0x0a6); // normal
  }
}


void drawLives(int tempLives){
  u8g2.setDrawColor(0);
  u8g2.drawBox(0, 13, 25, 10);
  u8g2.setDrawColor(1);
  u8g2.setFont(u8g2_font_nokiafc22_tf);
  u8g2.setCursor(0, 13);
  for (int ii = 0; ii < tempLives; ii++){
    u8g2.print("T"); // full battery
  }
  u8g2.sendBuffer();
}


void drawScore(int tempScore){
  u8g2.setDrawColor(0);
  u8g2.drawBox(128-10, 13, 16, 16);
  u8g2.setDrawColor(1);
  u8g2.setFont(u8g2_font_nokiafc22_tf);
  u8g2.setCursor(128-7, 13);
  u8g2.print(tempScore);
  u8g2.sendBuffer();
}


void drawPowerGo(){
  u8g2.setFont(u8g2_font_freedoomr25_mn);
  u8g2.setDrawColor(0);
  u8g2.drawBox(18, 25, 30, 39);
  u8g2.setDrawColor(1);
  u8g2.setCursor(64-9, 32-6);
  u8g2.print(powerGoPresses);
  u8g2.sendBuffer();
  u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
}


void memoSymNewPattern(){
  randomSeed(analogRead(A1));
  int tempIcon = 0;
  for (int ii = 0; ii < 8; ii++){ // shuffled the symbols in place
    tempIcon = memoSymIcons[ii];
    long randIndex = random(8);
    memoSymIcons[ii] = memoSymIcons[randIndex];
    memoSymIcons[randIndex] = tempIcon;
  }
  for (int ii = 0; ii < 8; ii++){ // create a random list of indexes for the current symbol to find
    tempIcon = memoSymIconsOrder[ii];
    long randIndex = random(8);
    memoSymIconsOrder[ii] = memoSymIconsOrder[randIndex];
    memoSymIconsOrder[randIndex] = tempIcon;
  }


}


void memoSymDrawPattern(){


  int iconToDraw = 0;
  u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
  //clear area
  u8g2.setDrawColor(0);
  if (!minigameCountdownActive)u8g2.drawBox(56, 13, 16, 16); // clear prompt symbol
  u8g2.drawBox(0, 32, 128, 16); // clear prompt symbol
  u8g2.setDrawColor(1);
  if (!minigameCountdownActive)u8g2.drawGlyph(56, 13, memoSymIcons[memoSymIconsOrder[memoSymGuessCount]]); // show a random index of the symbol array
  for (int ii = 0; ii < 8; ii++){
    switch (memoSymStates[ii]){
      case msRevealed:
        iconToDraw = memoSymIcons[ii];
      break;
      case msHidden:
        iconToDraw = 99; // box
      break;
      case msIncorrect:
        iconToDraw = 121; // x button
      break;
      case msCorrect:
        iconToDraw = 120; // check button
      break;
    }
    u8g2.drawGlyph(ii*16, 32, iconToDraw);
  }
  u8g2.sendBuffer();
}


void memoSymClearCursor(){
  u8g2.setDrawColor(0);
  u8g2.drawBox(16*curSelection, 50, 16, 16);
  u8g2.setDrawColor(1);
}


void memoSymDrawCursor(){
  u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
  u8g2.drawGlyph(16*curSelection, 50, 82); // up arrow symbol
  u8g2.sendBuffer();
}


void memoSymSetPattern(memoSymState tempState){
  for (int ii = 0; ii < 8; ii++){
    memoSymStates[ii] = tempState;
  }
}


void memoSymUpdateCounter(){
  u8g2.setFont(u8g2_font_freedoomr10_tu);
  u8g2.setDrawColor(0);
  u8g2.drawBox(56, 13, 17, 17);
  u8g2.setDrawColor(1);
  u8g2.setCursor(61, 15);
  u8g2.print(minigameCountdown);
  u8g2.sendBuffer();
  u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
}


void minigameScoreIncrease(int pts, int maxLevel){
  minigameScore+=pts;
  if (minigameScore > maxLevel){
    piezo.playMelody(mSuccess);
    tomoPower++; 
    checkTomoLevel();// test for level up!
    curState = stats;
    getInput(); // avoid triggering menu 
  } else {
    drawScore(minigameScore);
    piezo.playMelody(mOk); 
  }
}


void minigameLoseLife(){
  minigameLives--;
  if (minigameLives < 1){
    piezo.playMelody(mFailure);
    curState = home;
    getInput();
    delay(600);
  } else {
    piezo.playMelody(mBack);
    drawLives(minigameLives);                      
  }
}


void stackItClearBall(){
  u8g2.setDrawColor(0);
  u8g2.drawBox(stackItBallXPos-stackItBallRad, stackItBallYPos-stackItBallRad-stackItBallYOffset, 9, 9);
  u8g2.setDrawColor(1);
}


void stackItDrawBall(){
  u8g2.drawCircle(stackItBallXPos, stackItBallYPos - stackItBallYOffset, stackItBallRad);
}


void stackItReset(){
  stackItBallXPos = 64;
  stackItLastBallXPos = -1;
  stackItBallYPos = 59;
  stackItBallYOffset = 0;
  stackItUpdateInterval = 80;
  stackItHeight = 0;
}


void lucky64ClearReels(){
  u8g2.setDrawColor(0);
  u8g2.drawBox(20+(24*lucky64ReelsStopped), 24, 128, 17);
  u8g2.setDrawColor(1);
}


void lucky64DrawReels(){
  u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
  for (int ii = 0; ii < 4; ii++){
    u8g2.drawGlyph(20+(24*ii), 24, lucky64ReelIcons[ii]);
  }
  u8g2.sendBuffer();
}


void lucky64Reset(){
  for (int ii = 0; ii < 4; ii++){
    lucky64ReelIcons[ii] = 224 + (4 * ii);
  }
  lucky64ReelOffset = 0;
  lucky64ReelsStopped = 0;
}


void checkTomoLevel(){
  if (tomoPower >= MAX_POWER && tomoLevel < MAX_LEVEL){
    tomoIsLevelingUp = true;
    curState = viewTomo;
  } else {
    tomoPower = MAX_POWER;
  }
}


void loop() { // **************************************************************** BEGIN MAIN LOOP ****************************************************************
  
  getInput();
  curTime = millis();
  // u8g2.clear();
  // First switchcase handles one-time drawing
  if (curState != lastState){
    u8g2.clear();
    u8g2.setFont(u8g2_font_nokiafc22_tf);      
    switch (curState){
      case home:
        //print menu        
        minigameScore = 0;
        curSelection = 0;
        curMinigame = 0;
        minigameCountdown = 9; 
        minigameLives = 3;
        u8g2.setFont(u8g2_font_sticker_mel_tr);
        u8g2.drawStr(18, 1, "PowerGo");
        u8g2.drawStr(18, 33, "MemoSym");
        u8g2.drawStr(18, 17, "StackIt");
        u8g2.drawStr(18, 49, "Lucky64");
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
        u8g2.drawGlyph(0, 16*curSelection, 75); // right arrow button
        //select menu
        if (lastState == minigame){
          minigameAvailable = false;
        }
      break;
      case viewTomo:
        minigameAvailable = true;
        drawStrCentered(0, "Tomo is:");
        drawStrCentered(12, tomoText[tomoAction]);
        drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
        while (tomoIsLevelingUp){
          u8g2.clear();
          u8g2.setFont(u8g2_font_nokiafc22_tf); 
          drawStrCentered(0, "Tomo is:");
          delay(700);
          u8g2.sendBuffer();
          u8g2.setFont(u8g2_font_sticker_mel_tr);
          drawStrCentered(14, "MAXED OUT!");
          piezo.playMelody(mLevelUp); 
          delay(200);
          u8g2.sendBuffer();
          flashDisplay(18);
          for (int ii = 0; ii < 10; ii++){
            u8g2.clear();
            drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
            u8g2.sendBuffer();            
            flashDisplay(1);
            delay(100);            
            u8g2.clear();
            drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel+1, tomoFrame);
            flashDisplay(1);
            delay(100);            
            u8g2.sendBuffer();
          }
          tomoLevel+=1;
          delay(1000);
          u8g2.clear();
          drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
          u8g2.sendBuffer();
          tomoIsLevelingUp = false;
          curState = stats;
          tomoPower = 0;
        }
      break;
      case minigame:
        u8g2.drawHLine(0, 11, X_WIDTH);
        drawLives(minigameLives);
        drawScore(minigameScore);
        switch (curMinigame){
          case 0: // PowerGo
            drawStrCentered(0, "PowerGo: win 1 battery");
            drawPowerGo(); 
          break;
          case 1: // StackIt
            drawStrCentered(0, "StackIt: win 2 batteries");
            u8g2.drawVLine(32, 12, 52); // Borders
            u8g2.drawVLine(91, 12, 52);
            stackItReset();
            stackItDrawBall();
          break;
          case 2: // MemoSym
            drawStrCentered(0, "MemoSym: win 3 batteries");
            memoSymNewPattern();
            memoSymSetPattern(msRevealed);
            memoSymUpdateCounter();
            memoSymDrawPattern();
            curSelection = 0;
            memoSymGuessCount = 0;
            minigameCountdownActive = true;
            memoSymDrawCursor();
          break;
          case 3: // Lucky64
            drawStrCentered(0, "Lucky64: win X batteries");
            lucky64Reset();
            lucky64DrawReels();
          break;
        }
        // on game end, gain power and level up
      break;
      case stats:
        drawStrCentered(0, "Statistics");
        u8g2.setFont(u8g2_font_sticker_mel_tr);
        // Level
        u8g2.drawStr(0, 20, "LVL;"); // semicolon is swapped with colon in this font
        u8g2.setCursor(42, 20);
        u8g2.print(tomoLevel);
        u8g2.drawStr(0, 46, "PWR;");
        u8g2.setFont(u8g2_font_battery19_tn);
        u8g2.setCursor(46, 42);
        for (int ii = 0; ii < MAX_POWER; ii++){
          if (tomoPower >= ii){
            u8g2.print("5"); // full battery
          } else {
            u8g2.print("0"); // empty battery
          }  
        }
      break;
      default:
      break;
    }
    lastState = curState;
    u8g2.sendBuffer();
  }


  // Second switchcase processes input events
  switch (curState){ // **************************************************************** HANDLE INPUT ****************************************************************
    case home:
      if (btnOk.rose()){
        u8g2.setDrawColor(0);
        u8g2.drawBox(0, 16*curSelection, 16, 16+(16*curSelection));
        curSelection++;
        if (curSelection>3)curSelection = 0;
        u8g2.setDrawColor(1);
        u8g2.drawGlyph(0, 16*curSelection, 75);
        u8g2.sendBuffer();
      }
      if (btnOk.read() == 0 && btnOk.duration() > 1200 && minigameAvailable){
        curState = minigame;
        curMinigame = curSelection;
        piezo.playMelody(mOk);
      }
      if (btnLeft.fell()){
        curState = viewTomo;
      }
      if (btnRight.fell()){
        curState = stats;
      }
    break;
    case viewTomo:
      if (btnOk.fell()){
        // play with Tomo?
        minigameAvailable = true;
        piezo.playMelody(mOk);
      }
      if (btnLeft.fell()){
        curState = stats;
      }
      if (btnRight.fell()){
        curState = home;
      }
      if (curTime - lastTime > animationInterval){
        tomoFrame = !tomoFrame;
        drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
        u8g2.sendBuffer();
        lastTime = curTime;
      }
    break;
    case minigame:
      
      switch (curMinigame){
          case 0: // PowerGo
            if (btnOk.fell()){
              if (minigameCountdownActive == false){
                powerGoPresses++;
                drawPowerGo();
              }
              if (powerGoPresses >= 9 && minigameCountdownActive == false){
                minigameCountdownActive = true;
                drawPowerGo();
                //choose random symbol
                randomSeed(analogRead(0));
                long randomSide = random(100);
                Serial.print("randomSide ");
                Serial.println(randomSide);
                if (randomSide<50){ // draw left side
                  powerGoLocation = 0;
                  u8g2.drawGlyph(0, 28, 104); // bug
                  u8g2.drawGlyph(X_WIDTH-16, 28, 96); // bolt
                } else {
                  powerGoLocation = 1;
                  u8g2.drawGlyph(X_WIDTH-16, 28, 104); // bug
                  u8g2.drawGlyph(0, 28, 96); // bolt
                }
                u8g2.sendBuffer();
              }
            }
            if (minigameCountdownActive){
              if (btnLeft.fell() && powerGoLocation){ // Did you press on a lightning bolt on the correct side?
                if (powerGoLocation){
                  powerGoPresses = 0;
                  minigameCountdownActive = false;
                  u8g2.setDrawColor(0);
                  u8g2.drawBox(0, 25, X_WIDTH, 39);
                  u8g2.setDrawColor(1);
                  minigameScore++;
                  if (minigameScore > 9){
                    piezo.playMelody(mSuccess);
                    tomoPower++;
                    checkTomoLevel();
                    flashDisplay(6);
                    curState = home; 
                  } else {
                    drawScore(minigameScore);
                    piezo.playMelody(mOk); 
                    drawPowerGo();  
                  }              
                } else { 
                  minigameLoseLife();
                }
                minigameCountdownActive = false;
              }
              if (btnRight.fell()){ // Did you press on a lightning bolt on the correct side?
                if (!powerGoLocation){
                  powerGoPresses = 0;
                  minigameCountdownActive = false;
                  u8g2.setDrawColor(0);
                  u8g2.drawBox(0, 25, X_WIDTH, 39);
                  u8g2.setDrawColor(1);
                  minigameScore++;
                  if (minigameScore > 9){
                    piezo.playMelody(mSuccess);
                    tomoPower++;
                    checkTomoLevel();
                    curState = home; 
                  } else {
                    drawScore(minigameScore);
                    piezo.playMelody(mOk); 
                    drawPowerGo();  
                  }
                } else { 
                  minigameLoseLife();
                }
                minigameCountdownActive = false;
              }


              if (curTime - lastTime > powerGoCountdownInterval && minigameCountdownActive){ // seems redundant, but can lose two lives quickly otherwise
                powerGoPresses--;
                if (powerGoPresses < 0){
                  powerGoPresses = 0;
                  minigameCountdownActive = false;
                  u8g2.setDrawColor(0);
                  u8g2.drawBox(0, 25, X_WIDTH, 39);
                  u8g2.setDrawColor(1);
                  minigameLoseLife();
                }
                drawPowerGo();
                lastTime = curTime;
              }
            }
          break;
          case 2: // MemoSym
            if (btnOk.fell() && !minigameCountdownActive){
              if (memoSymIcons[curSelection] == memoSymIcons[memoSymIconsOrder[memoSymGuessCount]]){
                memoSymStates[curSelection] = msCorrect;
                minigameScoreIncrease(1, 8); 
              } else {
                memoSymStates[curSelection] = msIncorrect;
                minigameLoseLife();
              }
              // guesses increase
              memoSymGuessCount++;
              if (memoSymGuessCount > 7){
                piezo.playMelody(mSuccess);
                tomoPower+=3;
                curState = home; 
                checkTomoLevel();
                flashDisplay(6);
                
              }
              memoSymDrawPattern();
            }
            if (btnLeft.fell()){
              memoSymClearCursor();
              curSelection--;
              if (curSelection < 0) curSelection = 7;
              memoSymDrawCursor();
            }
            if (btnRight.fell()){
              memoSymClearCursor();
              curSelection++;
              if (curSelection > 7) curSelection = 0;
              memoSymDrawCursor();
            }
            if (curTime - lastTime > 1000 && minigameCountdownActive){
              minigameCountdown--;
              if (minigameCountdown < 0){
                // hide boxes
                memoSymSetPattern(msHidden);                
                minigameCountdownActive = false;
              } else {
                memoSymUpdateCounter();
              }
              memoSymDrawPattern();
              lastTime = curTime;
            }
            
          break;
          case 1: // StackIt
            if (curTime - lastTime > stackItUpdateInterval){
              stackItClearBall();
              stackItBallXPos += stackItBallDir;
              if (stackItBallXPos < 38 || stackItBallXPos > 85){ 
               stackItBallDir *= -1;
              }
              stackItDrawBall();
              u8g2.sendBuffer();
              lastTime = curTime;
            }
            if (btnOk.fell()){
              //test stackable
              if (stackItHeight == 0){
                stackItLastBallXPos = stackItBallXPos;
                stackItBallYOffset += 9;
                stackItUpdateInterval -= 16;
                stackItHeight++;
              } else if (stackItBallXPos > (stackItLastBallXPos-3) && stackItBallXPos < (stackItLastBallXPos+3)){
                stackItLastBallXPos = stackItBallXPos;
                stackItBallYOffset += 9;
                stackItUpdateInterval -= 16;
                stackItHeight++;
                if (stackItHeight > 4){
                  piezo.playMelody(mSuccess); // turn into generic minigame success threshold function
                  tomoPower+=2;
                  flashDisplay(4);
                  curState = home;
                  checkTomoLevel();// test level up
                }
              } else {
                minigameLoseLife();
                delay(400);
              }
            }
            if (btnLeft.fell()){ // placeholder
            }
            if (btnRight.fell()){ // placeholder
            }
            
          break;
          case 3: // Lucky64
            if (curTime - lastTime > lucky64UpdateInterval){
              lucky64ClearReels();
              for (int ii = lucky64ReelsStopped; ii < 4; ii++){ // update the active reels
                lucky64ReelIcons[ii]++;
                
                if (lucky64ReelIcons[ii] > 239) lucky64ReelIcons[ii] = 224;
              }
              lucky64DrawReels();
              lastTime = curTime;
            }
            if (btnOk.fell()){
              lucky64ReelsStopped++;
              if (lucky64ReelsStopped > 3){ // test matches
                if (lucky64ReelIcons[0] == lucky64ReelIcons[1]){                  
                  minigameScoreIncrease(1, 4);
                  if (lucky64ReelIcons[0] == lucky64ReelIcons[2]){
                    minigameScoreIncrease(1, 4);
                    if (lucky64ReelIcons[0] == lucky64ReelIcons[3]){
                      minigameScoreIncrease(2, 4);
                    }
                  }
                } else {
                  minigameLoseLife();
                  lucky64Reset();
                }
              }              
            }
            if (btnLeft.fell()){ // placeholder
            }
            if (btnRight.fell()){ // placeholder
            }
          break;
        }
        // on game end, check for level up
    break;
    case stats:
      if (btnOk.fell()){
        // interact with stats? different view?
        //piezo.playMelody(mBack);
      }
      if (btnLeft.fell()){
        curState = home;
      }
      if (btnRight.fell()){
        curState = viewTomo;
      }
    break;
  }
  //

  
}

  • Sign in to reply
  • Cancel

Top Replies

  • cstanton
    cstanton over 4 years ago +6 suggested
    The code is actually a program written by one of the main contributors to this website, Tariq Ahmad, and the program is for his Tomodachi (Tamagotchi spin-off) project. I came across his YouTube video…
  • kmikemoo
    kmikemoo over 4 years ago +4 verified
    dlnxdaman DJ Harrington recently added some bonus content on his code for the tamagotchi. Bonus Content: Tamagotchi Code He does a great job of going through the code.
  • mrvolt
    mrvolt over 4 years ago in reply to kmikemoo +4 suggested
    Thanks Mike! Also, Dylan I'm happy to answer any specific questions about my code. Bear in mind, this was the first working version and was never refactored, so it's quite sloppy by my standards, but workable…
  • hugohu
    0 hugohu over 4 years ago

    Could you unzip the ZIP package and send the text only? Don't feel comfortable downloading a ZIP, also you could DM me as I have quite some experience in Arduino.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • dlnxdaman
    0 dlnxdaman over 4 years ago in reply to hugohu

    Oh shoot, sorry I should have considered that! But yes I can totally do that!

     

    I will also DM!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • cstanton
    0 cstanton over 4 years ago in reply to hugohu

    edited.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • hugohu
    0 hugohu over 4 years ago

    Thanks!

    I'm quite unfamiliar with some of these libraries, I'll research them in a bit.

    Could you tell me what this project makes?

    Appears to be a robot of sorts, or some gaming device.


    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • beacon_dave
    0 beacon_dave over 4 years ago in reply to hugohu

    "...Could you tell me what this project makes?..."

     

    A virtual pet by the looks of it

    Episode 449: DIY Tamagotchi - Build a Virtual Pet

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • cstanton
    0 cstanton over 4 years ago

     

    The code is actually a program written by one of the main contributors to this website, Tariq Ahmad, and the program is for his Tomodachi (Tamagotchi spin-off) project. I came across his YouTube video while searching how to start creating the very same type of code in Arduino that he already had developed, but I need to understand all of the components so I can rework the entire thing into a project I am trying to combine with my ceramic artwork. I am a graduate student working toward my MFA in ceramics in the US and am trying to implement some new ways of incorporating technology with clay/ceramics.

     

     

    VCP Biography: DJ is one of our element14 presents video content creators, Episode 449: DIY Tamagotchi - Build a Virtual Pet and created the project and code.

     

    Did you watch the episode? Do you believe DJ could go over the code differently so as to help you understand it? Have you tried looking up the functions and sections of the code? Does the code need more comments?

     

    Let us know, as DJ does also frequent the community, mrvolt

    • Cancel
    • Vote Up +6 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • hugohu
    0 hugohu over 4 years ago in reply to beacon_dave

    Thanks, I didn't read through it.

     

    I skipped through the video at 2x speed, looks like a handheld gaming pet?

     

    Or rather, a virtual pet with gaming capability.

     

    It has an Adafruit Monochrome OLED, which I'd assume is controlled over SPI, since there is no I2C library.

     

    U8G2 appears to be a library to control the OLED as well?

     

    I'd reckon Bounce2 is for the buttons, ArMus is for the buzzer...

     

    Lines 119-123:

     

    That should be how you print on the screen.

     

    Sorry, I'm not being very helpful, honestly, I don't get 60% of what's happening here without reading deeply.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kmikemoo
    0 kmikemoo over 4 years ago

    dlnxdaman  DJ Harrington recently added some bonus content on his code for the tamagotchi.  Bonus Content: Tamagotchi Code  He does a great job of going through the code.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • mrvolt
    0 mrvolt over 4 years ago in reply to kmikemoo

    Thanks Mike!

     

    Also, Dylan I'm happy to answer any specific questions about my code. Bear in mind, this was the first working version and was never refactored, so it's quite sloppy by my standards, but workable.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • dlnxdaman
    0 dlnxdaman over 4 years ago in reply to hugohu

    Hey Hugo!

     

    Yes, it creates a small digital character, or virtual pet!

     

    So my main problem is not knowing what each term does/how it activates a program/action. For example, I learned to use "Int" to "attach" particular definitions to specific pins on the Arduino and things, and the creator uses "define" which makes sense on the surface, but realistically I don't know how that is different from "int". As for the other terms used, I don't recognize a lot honestly, so it's just really overwhelming trying to figure it all out! (why I am here hahaha).

     

    While I would like to really take the time to learn this all in a regular progressive fashion, I do need to figure out how to read and manipulate the current code for a body of ceramic works in my MFA program.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube