Advertisement
the_pimaster

Little Computer with Battery Indicator

Jan 22nd, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.05 KB | None | 0 0
  1.  
  2. #include <Adafruit_GFX.h>
  3. #include <Adafruit_SharpMem.h>
  4.  
  5. // any pins can be used
  6. #define SHARP_SCK 24
  7. #define SHARP_MOSI 23
  8. #define SHARP_SS 22
  9.  
  10. #define IN01 A1
  11. #define IN02 A2
  12. #define IN03 A3
  13. #define IN04 A4
  14. #define IN05 A5
  15. #define IN06  0
  16. #define IN07  1
  17. #define IN08 11
  18. #define IN09  5
  19. #define IN10 21
  20. #define IN11 20
  21.  
  22. #define LED 13
  23. #define VBATPIN 9
  24.  
  25. // Set the size of the display here, e.g. 144x168!
  26. Adafruit_SharpMem display(SHARP_SCK, SHARP_MOSI, SHARP_SS, 144, 168);
  27.  
  28. #define BLACK 0
  29. #define WHITE 1
  30.  
  31.  
  32. typedef struct ButtonStates {
  33.   bool up, down, left, right;
  34.   bool opt, start, menu;
  35.   bool a, b, psi, omega;
  36. };
  37.  
  38. ButtonStates buttonInput = {};
  39. const int FRAME_LENGTH = 1000 / 60.0;
  40.  
  41. const int idleTimeSize = 3;
  42. int idleTime[idleTimeSize];
  43. int idleTimePos;
  44. ulong idleTimeLast = millis();
  45. float idleTimeUpdates = 1000;
  46.  
  47. void setup() {
  48.   Serial.begin(9600);
  49.  
  50.   Serial.println("Loading");
  51.   display.begin();
  52.   display.setRotation(3);
  53.   display.clearDisplay();
  54.   display.refresh();
  55.   display.fillScreen(BLACK);
  56.   display.refresh();
  57.   display.clearDisplay();
  58.   display.refresh();
  59.  
  60.   Serial.println("ScreenBlink");
  61.  
  62.  
  63.   pinMode(IN01, INPUT);
  64.   pinMode(IN02, INPUT);
  65.   pinMode(IN03, INPUT);
  66.   pinMode(IN04, INPUT);
  67.   pinMode(IN05, INPUT);
  68.   pinMode(IN06, INPUT);
  69.   pinMode(IN07, INPUT);
  70.   pinMode(IN08, INPUT);
  71.   pinMode(IN09, INPUT);
  72.   pinMode(IN10, INPUT);
  73.   pinMode(IN11, INPUT);
  74.  
  75. }
  76.  
  77. void loop() {
  78.   ulong startF = millis();
  79.   readInput();
  80.  
  81.   display.startWrite();
  82.   //display.clearDisplay();
  83.   display.fillScreen(WHITE);
  84.  
  85.   frameLoop(buttonInput);
  86.  
  87.   overlay(buttonInput);
  88.  
  89.   display.endWrite();
  90.   display.refresh();
  91.  
  92.   ulong endF = millis();
  93.   int waitTime = FRAME_LENGTH - (endF - startF);
  94.  
  95.   if (waitTime > 0) {
  96.     delay(waitTime);
  97.   }
  98.  
  99.   if (idleTimeLast + idleTimeUpdates < endF) {
  100.     idleTimePos = (idleTimePos + 1) % idleTimeSize;
  101.     idleTime[idleTimePos] = 0;
  102.     idleTimeLast = endF;
  103.   }
  104.   idleTime[idleTimePos] += waitTime;
  105.  
  106. }
  107.  
  108. void overlay(ButtonStates buttons){
  109.  
  110.   display.setTextSize(1);
  111.  
  112.   display.setCursor(0, 0);
  113.   display.setTextSize(1);
  114.   display.setTextColor(BLACK, WHITE);
  115.   display.print( (int)((idleTimeUpdates - idleTime[(idleTimePos - 1) % idleTimeSize]) / idleTimeUpdates  ));
  116.  
  117.   display.setCursor(110, 0);
  118.   display.print("B:");
  119.   display.print(batteryLevel());
  120. }
  121.  
  122. void readInput() {
  123.  
  124.   buttonInput.up = digitalRead(IN08);
  125.   buttonInput.down = digitalRead(IN11);
  126.   buttonInput.left = digitalRead(IN10);
  127.   buttonInput.right = digitalRead(IN09);
  128.  
  129.   buttonInput.opt = digitalRead(IN05);
  130.   buttonInput.start = digitalRead(IN07);
  131.   buttonInput.menu = digitalRead(IN06);
  132.  
  133.   buttonInput.a = digitalRead(IN01);
  134.   buttonInput.b = digitalRead(IN03);
  135.   buttonInput.psi = digitalRead(IN04);
  136.   buttonInput.omega = digitalRead(IN02);
  137.  
  138.  
  139. }
  140.  
  141. int gameMode = 0;
  142.  
  143. void frameLoop(ButtonStates buttons)
  144. {
  145.   if (buttons.menu)
  146.     gameMode++;
  147.   switch (gameMode) {
  148.     case 0:
  149.       buttonDisplay(buttons);
  150.       break;
  151.     case 1:
  152.       pong(buttons);
  153.       break;
  154.     default:
  155.       gameMode = 0;
  156.   }
  157. }
  158.  
  159. int ballX;
  160. int ballY;
  161. float ballXF;
  162. float ballYF;
  163. bool pongStarted = false;
  164. bool scored = false;
  165. int p1Y;
  166. int p2Y;
  167. int p1Points;
  168. int p2Points;
  169. bool bot = true;
  170. ulong endGameTime = 0;
  171.  
  172. const int pongBatSize = 20;
  173. const int pongBatMove = 3;
  174. const int pongBallSize = 4;
  175.  
  176. void pong(ButtonStates buttons)
  177. {
  178.   if (buttons.opt) {
  179.     bot = !bot;
  180.   }
  181.   if (buttons.start) {
  182.     pongStarted = false;
  183.   }
  184.   if (!pongStarted) {
  185.     randomSeed(analogRead(0));
  186.     p1Points = 0;
  187.     p2Points = 0;
  188.     scored = true; // cheating?
  189.     pongStarted = true;
  190.     p1Y = display.height() / 2;
  191.     p2Y = display.height() / 2 ;
  192.     endGameTime = 0;
  193.   }
  194.   if (scored)
  195.   {
  196.     ballX = display.width() / 2;
  197.     ballY = display.height() / 2;
  198.     ballXF = 0;
  199.     while (ballXF == 0) {
  200.       ballXF = random(-4, 4);
  201.     }
  202.     ballYF = 0;
  203.     while (ballYF == 0) {
  204.       ballYF = random(-3, 3);
  205.     }
  206.     scored = false;
  207.   }
  208.  
  209.   if (endGameTime)  {
  210.  
  211.     display.setCursor(display.width() / 2 - 20, display.height() / 2 - 15);
  212.     display.print("PLAYER");
  213.     if (millis() > endGameTime + 1500) {
  214.       display.setCursor(display.width() / 2 - 20, display.height() / 2);
  215.       display.print(p1Points > p2Points ? "ONE" : "TWO");
  216.     }
  217.     if (millis() > endGameTime + 3000) {
  218.       display.setCursor(display.width() / 2 - 20, display.height() / 2 + 15);
  219.       display.print("WINS!");
  220.     }
  221.   } else {
  222.     // Input
  223.     if (buttons.up && p1Y - pongBatSize / 2 > 0) {
  224.       p1Y -= pongBatMove;
  225.     } else if (buttons.down && p1Y + pongBatSize / 2 < display.height()) {
  226.       p1Y += pongBatMove;
  227.     }
  228.     if (bot) {
  229.       if (ballY - pongBallSize > p2Y) {
  230.         p2Y += 2;
  231.       } else if (ballY  + pongBallSize < p2Y) {
  232.         p2Y -= 2;
  233.       }
  234.     } else {
  235.       if (buttons.omega && p2Y - pongBatSize / 2 > 0) {
  236.         p2Y -= pongBatMove;
  237.       } else if (buttons.a && p2Y + pongBatSize / 2 < display.height()) {
  238.         p2Y += pongBatMove;
  239.       }
  240.     }
  241.     // Physics
  242.     ballX += ballXF;
  243.     ballY += ballYF;
  244.   }
  245.  
  246.  
  247.   // DRAW
  248.   display.fillRect(0, p1Y - pongBatSize / 2, pongBallSize, pongBatSize, BLACK);
  249.   display.fillRect(display.width() - pongBallSize, p2Y - pongBatSize / 2, pongBallSize, pongBatSize, BLACK);
  250.  
  251.   if (!endGameTime) {
  252.     display.fillCircle(ballX, ballY, pongBallSize, BLACK);
  253.     display.setTextSize(1);
  254.     display.setTextColor(BLACK, WHITE);
  255.     display.setCursor(display.width() / 2 - 20, display.height() / 2 - 10);
  256.     display.print(p1Points);
  257.     display.setCursor(display.width() / 2 + 20, display.height() / 2 - 10);
  258.     display.print(p2Points);
  259.   }
  260.  
  261.   // WALL
  262.   if (ballY <= pongBallSize) {
  263.     ballYF = -ballYF;
  264.     if (ballYF < pongBallSize) {
  265.       ballY = pongBallSize;
  266.     }
  267.   }
  268.   if (ballY >= display.height() - pongBallSize) {
  269.     ballYF = -ballYF;
  270.     if (ballYF > display.height() - pongBallSize) {
  271.       ballY = display.height() - pongBallSize;
  272.     }
  273.   }
  274.  
  275.   // Left side
  276.   if (ballX < pongBallSize && ballXF < 0) {
  277.     if (abs(p1Y - ballY) < pongBatSize / 2) {
  278.       paddleBounce();
  279.     } else {
  280.       p2Points++;
  281.       scored = true;
  282.     }
  283.   }
  284.   // Right side
  285.   if (ballX > display.width() - pongBallSize && ballXF > 0) {
  286.     if (abs(p2Y - ballY) < pongBatSize / 2) {
  287.       paddleBounce();
  288.     } else {
  289.       p1Points++;
  290.       scored = true;
  291.     }
  292.   }
  293.   if (max(p1Points, p2Points) >= 7 && !endGameTime) {
  294.     endGameTime = millis();
  295.   }
  296. }
  297.  
  298. const double PADDLE_POSITION_ADDITION = PI / 2;
  299. const double PADDLE_MAX_ANGLE = PADDLE_POSITION_ADDITION + HALF_PI;
  300. const double PADDLE_BOUNCE_MAGIC = HALF_PI / PADDLE_MAX_ANGLE;
  301.  
  302. void paddleBounce()
  303. {
  304.   // reflection=((angle +            (SQRT(ABS(offset))*offset*45))/135*90 +
  305.   // (((sqrt(ABS(angle/90))*angle) + (SQRT(ABS(offset))*offset*45))/135*90)) / 2
  306.   double incoming = atan2(ballYF, ballXF);
  307.   double offset = (ballY - p1Y) / (double)pongBatSize;
  308.   double offsetAngle = sqrt(abs(offset)) * offset * PADDLE_POSITION_ADDITION;
  309.   double reflection = ( (incoming + offsetAngle) * PADDLE_BOUNCE_MAGIC + //
  310.                         (((sqrt(abs(incoming / HALF_PI)) * incoming) + offsetAngle) * PADDLE_BOUNCE_MAGIC)) / 2;
  311.   double dist = sqrt(ballYF * ballYF + ballXF * ballXF);
  312.   ballXF = dist * cos(reflection);
  313.   ballYF = dist * sin(reflection);
  314. }
  315.  
  316. void buttonDisplay(ButtonStates buttons)
  317. {
  318.   if (buttons.up) {
  319.     display.fillCircle(30, 30, 5, BLACK);
  320.   } else {
  321.     display.drawCircle(30, 30, 5, BLACK);
  322.   }
  323.   if (buttons.down) {
  324.     display.fillCircle(30, 50, 5, BLACK);
  325.   } else {
  326.     display.drawCircle(30, 50, 5, BLACK);
  327.   }
  328.   if (buttons.left) {
  329.     display.fillCircle(20, 40, 5, BLACK);
  330.   } else {
  331.     display.drawCircle(20, 40, 5, BLACK);
  332.   }
  333.   if (buttons.right) {
  334.     display.fillCircle(40, 40, 5, BLACK);
  335.   } else {
  336.     display.drawCircle(40, 40, 5, BLACK);
  337.   }
  338.  
  339.  
  340.   if (buttons.opt) {
  341.     display.fillCircle(60, 30, 5, BLACK);
  342.   } else {
  343.     display.drawCircle(60, 30, 5, BLACK);
  344.   }
  345.   if (buttons.menu) {
  346.     display.fillCircle(60, 40, 5, BLACK);
  347.   } else {
  348.     display.drawCircle(60, 40, 5, BLACK);
  349.   }
  350.   if (buttons.start) {
  351.     display.fillCircle(60, 50, 5, BLACK);
  352.   } else {
  353.     display.drawCircle(60, 50, 5, BLACK);
  354.   }
  355.  
  356.  
  357.   if (buttons.b) {
  358.     display.fillCircle(100, 40, 5, BLACK);
  359.   } else {
  360.     display.drawCircle(100, 40, 5, BLACK);
  361.   }
  362.   if (buttons.a) {
  363.     display.fillCircle(90, 50, 5, BLACK);
  364.   } else {
  365.     display.drawCircle(90, 50, 5, BLACK);
  366.   }
  367.   if (buttons.psi) {
  368.     display.fillCircle(80, 40, 5, BLACK);
  369.   } else {
  370.     display.drawCircle(80, 40, 5, BLACK);
  371.   }
  372.   if (buttons.omega) {
  373.     display.fillCircle(90, 30, 5, BLACK);
  374.   } else {
  375.     display.drawCircle(90, 30, 5, BLACK);
  376.   }
  377.  
  378. }
  379.  
  380. float batteryLevel(void) {
  381.   float measuredvbat = analogRead(VBATPIN);
  382.   measuredvbat *= 2;    // we divided by 2, so multiply back
  383.   measuredvbat *= 3.3;  // Multiply by 3.3V, our reference voltage
  384.   measuredvbat /= 1024; // convert to voltage
  385.   return measuredvbat;
  386. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement