Guest User

Untitled

a guest
Apr 8th, 2025
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.89 KB | None | 0 0
  1. #include <LiquidCrystal.h>
  2. LiquidCrystal lcd(4, 6, 10, 11, 12, 13);
  3.  
  4. int xPin = A0;
  5. int yPin = A1;
  6. int buttonPin = 2;
  7. int xVal;
  8. int yVal;
  9. int buttonState;
  10. int lastButtonState = HIGH;
  11.  
  12. // Constants for modes
  13. const int MODE_GRID = 0;
  14. const int MODE_OPERATOR = 1;
  15. const int MODE_RESULT = 2;
  16.  
  17. // Current mode
  18. int currentMode = MODE_GRID;
  19.  
  20. // Variables for cursor position
  21. int cursorX = 0;
  22. int cursorY = 0;
  23.  
  24. // Grid of values (0 or 1) for each position
  25. int grid[2][8] = {
  26.   {0, 0, 0, 0, 0, 0, 0, 0},
  27.   {0, 0, 0, 0, 0, 0, 0, 0}
  28. };
  29.  
  30. // Backup of original values
  31. int gridBackup[2][8] = {
  32.   {0, 0, 0, 0, 0, 0, 0, 0},
  33.   {0, 0, 0, 0, 0, 0, 0, 0}
  34. };
  35.  
  36. // Operator selection
  37. int currentOperator = 0;
  38. int selectedOption = 0; // 0 for REVERT, 1 for RESET
  39. String operators[] = {"AND", "OR ", "XOR", "NAND", "NOR ", "XNOR"};
  40.  
  41. // State tracking
  42. bool isCalculated = false;
  43.  
  44. // Debounce variables
  45. unsigned long lastMoveTime = 0;
  46. unsigned long lastButtonTime = 0;
  47. const int moveDelay = 200;    // ms between cursor movements
  48. const int buttonDelay = 300;  // ms between button presses
  49.  
  50. byte charXor[8] = {
  51.   0b00000,
  52.   0b01110,
  53.   0b10101,
  54.   0b11111,
  55.   0b10101,
  56.   0b01110,
  57.   0b00000,
  58.   0b00000
  59. };
  60.  
  61. byte charOr[8] = {
  62.   B00000,
  63.   B10001,
  64.   B01010,
  65.   B00100,
  66.   B00000,
  67.   B00000,
  68.   B00000,
  69.   B00000
  70. };
  71.  
  72. byte charNot[8] = {
  73.   B00000,
  74.   B00000,
  75.   B00000,
  76.   B11111,
  77.   B10000,
  78.   B00000,
  79.   B00000,
  80.   B00000
  81. };
  82.  
  83.  
  84. void setup() {
  85.   lcd.begin(16, 2);
  86.   pinMode(xPin, INPUT);
  87.   pinMode(yPin, INPUT);
  88.   pinMode(buttonPin, INPUT_PULLUP);
  89.   Serial.begin(9600);
  90.  
  91.   lcd.createChar(0, charOr);
  92.   lcd.createChar(1, charXor);
  93.   lcd.createChar(2, charNot);
  94.  
  95.   updateDisplay(); // Display initial grid and UI elements
  96.   lcd.setCursor(cursorX, cursorY); // Set initial cursor position
  97.   lcd.cursor(); // Show the cursor
  98. }
  99.  
  100. void loop() {
  101.   xVal = analogRead(xPin);
  102.   yVal = analogRead(yPin);
  103.   buttonState = digitalRead(buttonPin);
  104.  
  105.   // Handle input based on current mode
  106.   switch (currentMode) {
  107.     case MODE_GRID:
  108.       handleGridMode();
  109.       break;
  110.     case MODE_OPERATOR:
  111.       handleOperatorSelectMode();
  112.       break;
  113.     case MODE_RESULT:
  114.       handleResultMode();
  115.       break;
  116.   }
  117.  
  118.   lastButtonState = buttonState;
  119. }
  120.  
  121. void resetBlink() {
  122.   lcd.cursor();
  123.   lcd.noBlink();
  124. }
  125.  
  126. void handleGridMode() {
  127.   // Only move the cursor if enough time has passed
  128.   if (millis() - lastMoveTime > moveDelay) {
  129.     // Check X-axis (left/right)
  130.     if (xVal < 100) { // Moving left
  131.       if (cursorX == 10) {
  132.         cursorX = 7;
  133.       } else if (cursorX > 0) {
  134.         cursorX--;
  135.       }
  136.       lastMoveTime = millis();
  137.       lcd.setCursor(cursorX, cursorY);
  138.     } else if (xVal > 924) { // Moving right
  139.       if (cursorX == 7) {
  140.         cursorX = 10;  // Jump from 7 to 10
  141.       } else if (cursorX < 7) {  
  142.         cursorX++;
  143.       }
  144.       lastMoveTime = millis();
  145.       lcd.setCursor(cursorX, cursorY);
  146.     }
  147.    
  148.     // Check Y-axis (up/down)
  149.     if (yVal < 100 && cursorY == 0 && !isCalculated) {
  150.       cursorY++;
  151.       lastMoveTime = millis();
  152.       lcd.setCursor(cursorX, cursorY);
  153.     } else if (yVal > 924 && cursorY == 1) {
  154.       cursorY--;
  155.       lastMoveTime = millis();
  156.       lcd.setCursor(cursorX, cursorY);
  157.     }
  158.  
  159.     if (cursorX == 10 && cursorY == 1) {
  160.       lcd.noCursor();
  161.       lcd.blink();
  162.     } else {
  163.       lcd.cursor();
  164.       lcd.noBlink();
  165.     }
  166.   }
  167.  
  168.  
  169.   // Check button press with debounce
  170.   if (buttonState == LOW && lastButtonState == HIGH &&
  171.       (millis() - lastButtonTime > buttonDelay)) {
  172.    
  173.     // If at position (10,0), switch to operator mode
  174.     if (cursorX == 10 && cursorY == 0) {
  175.       currentMode = MODE_OPERATOR;
  176.       updateDisplay(); // renders selection arrows
  177.       lcd.noCursor();
  178.       lcd.blink();
  179.     } else if (cursorX == 10 && cursorY == 1) {
  180.       executeOperation();
  181.  
  182.     } else if (cursorX < 8) {  
  183.       // Toggle the value at current position
  184.       grid[cursorY][cursorX] = 1 - grid[cursorY][cursorX]; // Toggle between 0 and 1
  185.       updateDisplay();
  186.       lcd.setCursor(cursorX, cursorY);
  187.     }
  188.    
  189.     lastButtonTime = millis();
  190.   }
  191. }
  192.  
  193. void handleOperatorSelectMode() {
  194.  
  195.   if (millis() - lastMoveTime > moveDelay) {
  196.     // Move left/right to change operator
  197.     if (xVal < 100 && currentOperator > 0) {
  198.       currentOperator--;
  199.       lastMoveTime = millis();
  200.       updateDisplay();
  201.       lcd.setCursor(10, 0); // Center of operator display
  202.       lcd.blink();
  203.     } else if (xVal > 924 && currentOperator < 5) {
  204.       currentOperator++;
  205.       lastMoveTime = millis();
  206.       updateDisplay();
  207.       lcd.setCursor(10, 0); // Center of operator display
  208.       lcd.blink();
  209.     }
  210.   }
  211.  
  212.   // Return to grid mode when button is pressed
  213.   if (buttonState == LOW && lastButtonState == HIGH &&
  214.       (millis() - lastButtonTime > buttonDelay)) {
  215.  
  216.     currentMode = MODE_GRID;
  217.     cursorX = 10;
  218.     cursorY = 0;
  219.     resetBlink();
  220.     lcd.setCursor(cursorX, cursorY);
  221.     lastButtonTime = millis();
  222.     updateDisplay(); // removes selection arrows
  223.   }
  224. }
  225.  
  226. void executeOperation() {
  227.   // Move between REVERT and RESET buttons
  228.   for (int y = 0; y < 2; y++) {
  229.     for (int x = 0; x < 8; x++) {
  230.       gridBackup[y][x] = grid[y][x];
  231.     }
  232.   }
  233.  
  234.   for (int i = 0; i < 8; i++) {
  235.     switch (currentOperator) {
  236.       case 0: // AND
  237.         grid[1][i] = grid[0][i] & grid[1][i];
  238.         break;
  239.       case 1: // OR
  240.         grid[1][i] = grid[0][i] | grid[1][i];
  241.         break;
  242.       case 2: // XOR
  243.         grid[1][i] = grid[0][i] ^ grid[1][i];
  244.         break;
  245.       case 3: // NAND
  246.         grid[1][i] = !(grid[0][i] & grid[1][i]);
  247.         break;
  248.       case 4: // NOR
  249.         grid[1][i] = !(grid[0][i] | grid[1][i]);
  250.         break;
  251.       case 5: // XNOR
  252.         grid[1][i] = !(grid[0][i] ^ grid[1][i]);
  253.         break;
  254.     }
  255.   }
  256.  
  257.   isCalculated = true;
  258.   currentMode = MODE_RESULT;
  259.   updateDisplay();
  260.   lcd.setCursor(3, 0); // Position on REVERT button
  261.   lcd.blink();
  262. }
  263.  
  264. void handleResultMode() {
  265.  
  266.   // Handle navigation between options if enough time has passed
  267.   if (millis() - lastMoveTime > moveDelay) {
  268.     if (xVal < 100) { // Move left to REVERT
  269.       selectedOption = 0;
  270.       lcd.setCursor(3, 0);
  271.       lastMoveTime = millis();
  272.     } else if (xVal > 924) { // Move right to RESET
  273.       selectedOption = 1;
  274.       lcd.setCursor(12, 0);
  275.       lastMoveTime = millis();
  276.     }
  277.   }
  278.  
  279.   // Handle button press with debounce
  280.   if (buttonState == LOW && lastButtonState == HIGH &&
  281.       (millis() - lastButtonTime > buttonDelay)) {
  282.    
  283.     if (selectedOption == 0) {
  284.       // REVERT - Restore from backup
  285.       for (int y = 0; y < 2; y++) {
  286.         for (int x = 0; x < 8; x++) {
  287.           grid[y][x] = gridBackup[y][x];
  288.         }
  289.       }
  290.     } else {
  291.       // RESET - Set all to zero
  292.       for (int y = 0; y < 2; y++) {
  293.         for (int x = 0; x < 8; x++) {
  294.           grid[y][x] = 0;
  295.         }
  296.       }
  297.     }
  298.    
  299.     isCalculated = false;
  300.     currentMode = MODE_GRID;
  301.     cursorX = 0;
  302.     cursorY = 0;
  303.     updateDisplay();
  304.     lcd.setCursor(cursorX, cursorY);
  305.     resetBlink();
  306.     lastButtonTime = millis();
  307.   }
  308. }
  309.  
  310. void updateDisplay() {
  311.   // Clear display
  312.   lcd.clear();
  313.  
  314.   if (!isCalculated) {
  315.     // Normal mode - show both rows and operator
  316.    
  317.     // Update first row - bits
  318.     lcd.setCursor(0, 0);
  319.     for (int i = 0; i < 8; i++) {
  320.       lcd.print(grid[0][i]);
  321.     }
  322.    
  323.     // Update operator section
  324.     lcd.setCursor(8, 0);
  325.  
  326.     if (currentMode == MODE_OPERATOR) {
  327.       lcd.print("<");
  328.     } else {
  329.       lcd.print(" ");
  330.     }
  331.  
  332.     lcd.print(operators[currentOperator]);
  333.     if (currentOperator >= 0 && currentOperator <= 2) {
  334.       lcd.print("  ");
  335.     } else {
  336.       lcd.write(byte(2));
  337.     };
  338.  
  339.     if (currentOperator == 0 || currentOperator == 3) {
  340.       lcd.print("^");
  341.     } else if (currentOperator == 1 || currentOperator == 4) {
  342.       lcd.write(byte(0));
  343.     } else if (currentOperator == 2 || currentOperator == 5) {
  344.       lcd.write(byte(1));
  345.     };
  346.  
  347.     if (currentMode == MODE_OPERATOR) {
  348.       lcd.print(">");
  349.     }
  350.    
  351.     // Update second row - bits
  352.     lcd.setCursor(0, 1);
  353.     for (int i = 0; i < 8; i++) {
  354.       lcd.print(grid[1][i]);
  355.     }
  356.    
  357.     // Show operation button
  358.     lcd.setCursor(8, 1);
  359.     lcd.print(" OPR8 ");
  360.   }
  361.   else {
  362.     // Result mode - show only result and buttons
  363.  
  364.     lcd.setCursor(0, 0);
  365.     lcd.print("  REVERT  RESET ");
  366.    
  367.     // Show result on bottom row
  368.     lcd.setCursor(0, 1);
  369.     for (int i = 0; i < 8; i++) {
  370.       lcd.print(grid[1][i]);
  371.     }
  372.   }
  373.  
  374.   // Restore cursor position based on mode
  375.   if (currentMode == MODE_GRID) {
  376.     lcd.setCursor(cursorX, cursorY);
  377.   }
  378.   else if (currentMode == MODE_OPERATOR) {
  379.     lcd.setCursor(10, 0);
  380.     resetBlink();
  381.   }
  382.   else if (currentMode == MODE_RESULT) {
  383.     lcd.setCursor(3, 0);
  384.     resetBlink();
  385.   }
  386. }
Advertisement
Add Comment
Please, Sign In to add comment