Advertisement
pleasedontcode

"Button Management" rev_01

Apr 18th, 2025
459
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /********* Pleasedontcode.com **********
  2.  
  3.     Pleasedontcode thanks you for automatic code generation! Enjoy your code!
  4.  
  5.     - Terms and Conditions:
  6.     You have a non-exclusive, revocable, worldwide, royalty-free license
  7.     for personal and commercial use. Attribution is optional; modifications
  8.     are allowed, but you're responsible for code maintenance. We're not
  9.     liable for any loss or damage. For full terms,
  10.     please visit pleasedontcode.com/termsandconditions.
  11.  
  12.     - Project: "Button Management"
  13.     - Source Code NOT compiled for: Arduino Uno
  14.     - Source Code created on: 2025-04-18 05:41:53
  15.  
  16. ********* Pleasedontcode.com **********/
  17.  
  18. /****** SYSTEM REQUIREMENTS *****/
  19. /****** SYSTEM REQUIREMENT 1 *****/
  20.     /* Each resource is represented by an RGB LED:  Green */
  21.     /* = free  Red = locked  Yellow = waiting  Tasks try */
  22.     /* to lock resources in opposite order, */
  23.     /* causingdeadlock if both run simultaneously. */
  24.     /* system detects deadlock and recovers by forcing */
  25.     /* one task to release */
  26. /****** END SYSTEM REQUIREMENTS *****/
  27.  
  28. /* START CODE */
  29.  
  30. /****** DEFINITION OF LIBRARIES *****/
  31. #include <EasyButton.h> //https://github.com/evert-arias/EasyButton
  32.  
  33. /****** FUNCTION PROTOTYPES *****/
  34. void setup(void);
  35. void loop(void);
  36.  
  37. /***** DEFINITION OF DIGITAL INPUT PINS *****/
  38. const uint8_t push_button_PushButton_PIN_D2     = 2;
  39. const uint8_t push_button_PushButton_PIN_D3     = 3;
  40.  
  41. // RGB LED pins for Resource A
  42. const int resA_R = 8;
  43. const int resA_G = 9;
  44. const int resA_B = 10;
  45.  
  46. // RGB LED pins for Resource B
  47. const int resB_R = 11;
  48. const int resB_G = 12;
  49. const int resB_B = 13;
  50.  
  51. /***** DEFINITION OF DIGITAL OUTPUT PINS *****/
  52.  
  53. // Task states
  54. enum TaskState {IDLE, LOCK_RES1, WAIT_RES2, LOCK_RES2, WORKING, RELEASE_RES2, RELEASE_RES1};
  55. enum Resource {FREE, LOCKED};
  56.  
  57. struct ResourceMutex {
  58.   volatile Resource state;
  59.   int lockedBy; // -1 if free, else task ID
  60. };
  61.  
  62. ResourceMutex resourceA = {FREE, -1};
  63. ResourceMutex resourceB = {FREE, -1};
  64.  
  65. // Task variables
  66. TaskState task1State = IDLE;
  67. TaskState task2State = IDLE;
  68.  
  69. unsigned long lastMillis = 0;
  70. const unsigned long taskInterval = 100; // ms
  71.  
  72. // Task IDs
  73. const int TASK1 = 1;
  74. const int TASK2 = 2;
  75.  
  76. // Button states
  77. bool button1Pressed = false;
  78. bool button2Pressed = false;
  79.  
  80. // Timing for simulated work
  81. unsigned long task1Timer = 0;
  82. unsigned long task2Timer = 0;
  83. const unsigned long workDuration = 2000; // 2 seconds
  84.  
  85. // Deadlock detection timer
  86. unsigned long deadlockCheckTimer = 0;
  87. const unsigned long deadlockCheckInterval = 1000; // 1 sec
  88.  
  89. // Helper function to set RGB LED color
  90. void setRGB(int rPin, int gPin, int bPin, int rVal, int gVal, int bVal) {
  91.   analogWrite(rPin, rVal);
  92.   analogWrite(gPin, gVal);
  93.   analogWrite(bPin, bVal);
  94. }
  95.  
  96. // Set resource LED based on state
  97. void updateResourceLED(ResourceMutex &res, int rPin, int gPin, int bPin) {
  98.   if (res.state == FREE) {
  99.     // Green
  100.     setRGB(rPin, gPin, bPin, 0, 255, 0);
  101.   } else {
  102.     // Red
  103.     setRGB(rPin, gPin, bPin, 255, 0, 0);
  104.   }
  105. }
  106.  
  107. // Set resource LED to yellow (waiting)
  108. void setResourceWaiting(int rPin, int gPin, int bPin) {
  109.   setRGB(rPin, gPin, bPin, 255, 255, 0);
  110. }
  111.  
  112. // Attempt to lock a resource
  113. bool tryLockResource(ResourceMutex &res, int taskID) {
  114.   if (res.state == FREE) {
  115.     res.state = LOCKED;
  116.     res.lockedBy = taskID;
  117.     return true;
  118.   }
  119.   return false;
  120. }
  121.  
  122. // Release a resource
  123. void releaseResource(ResourceMutex &res, int taskID) {
  124.   if (res.lockedBy == taskID) {
  125.     res.state = FREE;
  126.     res.lockedBy = -1;
  127.   }
  128. }
  129.  
  130. // Deadlock detection: if both tasks are waiting for each other's resource
  131. bool detectDeadlock() {
  132.   if (task1State == WAIT_RES2 && resourceA.lockedBy == TASK1 &&
  133.       task2State == WAIT_RES2 && resourceB.lockedBy == TASK2) {
  134.     return true;
  135.   }
  136.   return false;
  137. }
  138.  
  139. // Deadlock recovery: force Task 2 to release resources and reset
  140. void recoverDeadlock() {
  141.   Serial.println("Deadlock detected! Recovering by resetting Task 2...");
  142.   releaseResource(resourceB, TASK2);
  143.   releaseResource(resourceA, TASK2);
  144.   task2State = IDLE;
  145. }
  146.  
  147. void setup(void)
  148. {
  149.     // put your setup code here, to run once:
  150.  
  151.     pinMode(push_button_PushButton_PIN_D2,  INPUT_PULLUP);
  152.     pinMode(push_button_PushButton_PIN_D3,  INPUT_PULLUP);
  153.  
  154.     // Setup RGB LED pins as outputs
  155.     int rgbPins[] = {resA_R, resA_G, resA_B, resB_R, resB_G, resB_B};
  156.     for (int i = 0; i < 6; i++) {
  157.         pinMode(rgbPins[i], OUTPUT);
  158.     }
  159.  
  160.     // Initialize LEDs to green (free)
  161.     updateResourceLED(resourceA, resA_R, resA_G, resA_B);
  162.     updateResourceLED(resourceB, resB_R, resB_G, resB_B);
  163. }
  164.  
  165. void loop(void)
  166. {
  167.     // put your main code here, to run repeatedly:
  168.     unsigned long currentMillis = millis();
  169.  
  170.     // Read buttons (active HIGH assumed)
  171.     button1Pressed = digitalRead(push_button_PushButton_PIN_D2) == HIGH; // Use defined pin
  172.     button2Pressed = digitalRead(push_button_PushButton_PIN_D3) == HIGH; // Use defined pin
  173.  
  174.     // Run tasks every taskInterval ms (cooperative multitasking)
  175.     if (currentMillis - lastMillis >= taskInterval) {
  176.         lastMillis = currentMillis;
  177.  
  178.         // --- Task 1 ---
  179.         switch (task1State) {
  180.             case IDLE:
  181.                 if (button1Pressed) {
  182.                     Serial.println("Task 1 started");
  183.                     task1State = LOCK_RES1;
  184.                 }
  185.                 break;
  186.  
  187.             case LOCK_RES1:
  188.                 if (tryLockResource(resourceA, TASK1)) {
  189.                     Serial.println("Task 1 locked Resource A");
  190.                     updateResourceLED(resourceA, resA_R, resA_G, resA_B);
  191.                     task1State = WAIT_RES2;
  192.                 } else {
  193.                     Serial.println("Task 1 waiting for Resource A");
  194.                     setResourceWaiting(resA_R, resA_G, resA_B);
  195.                 }
  196.                 break;
  197.  
  198.             case WAIT_RES2:
  199.                 if (tryLockResource(resourceB, TASK1)) {
  200.                     Serial.println("Task 1 locked Resource B");
  201.                     updateResourceLED(resourceB, resB_R, resB_G, resB_B);
  202.                     task1State = WORKING;
  203.                     task1Timer = currentMillis;
  204.                 } else {
  205.                     Serial.println("Task 1 waiting for Resource B");
  206.                     setResourceWaiting(resB_R, resB_G, resB_B);
  207.                 }
  208.                 break;
  209.  
  210.             case WORKING:
  211.                 if (currentMillis - task1Timer >= workDuration) {
  212.                     Serial.println("Task 1 finished work, releasing resources");
  213.                     task1State = RELEASE_RES2;
  214.                 }
  215.                 break;
  216.  
  217.             case RELEASE_RES2:
  218.                 releaseResource(resourceB, TASK1);
  219.                 updateResourceLED(resourceB, resB_R, resB_G, resB_B);
  220.                 task1State = RELEASE_RES1;
  221.                 break;
  222.  
  223.             case RELEASE_RES1:
  224.                 releaseResource(resourceA, TASK1);
  225.                 updateResourceLED(resourceA, resA_R, resA_G, resA_B);
  226.                 task1State = IDLE;
  227.                 break;
  228.         }
  229.  
  230.         // --- Task 2 ---
  231.         switch (task2State) {
  232.             case IDLE:
  233.                 if (button2Pressed) {
  234.                     Serial.println("Task 2 started");
  235.                     task2State = LOCK_RES1;
  236.                 }
  237.                 break;
  238.  
  239.             case LOCK_RES1:
  240.                 if (tryLockResource(resourceB, TASK2)) { // Note reversed order for deadlock
  241.                     Serial.println("Task 2 locked Resource B");
  242.                     updateResourceLED(resourceB, resB_R, resB_G, resB_B);
  243.                     task2State = WAIT_RES2;
  244.                 } else {
  245.                     Serial.println("Task 2 waiting for Resource B");
  246.                     setResourceWaiting(resB_R, resB_G, resB_B);
  247.                 }
  248.                 break;
  249.  
  250.             case WAIT_RES2:
  251.                 if (tryLockResource(resourceA, TASK2)) {
  252.                     Serial.println("Task 2 locked Resource A");
  253.                     updateResourceLED(resourceA, resA_R, resA_G, resA_B);
  254.                     task2State = WORKING;
  255.                     task2Timer = currentMillis;
  256.                 } else {
  257.                     Serial.println("Task 2 waiting for Resource A");
  258.                     setResourceWaiting(resA_R, resA_G, resA_B);
  259.                 }
  260.                 break;
  261.  
  262.             case WORKING:
  263.                 if (currentMillis - task2Timer >= workDuration) {
  264.                     Serial.println("Task 2 finished work, releasing resources");
  265.                     task2State = RELEASE_RES2;
  266.                 }
  267.                 break;
  268.  
  269.             case RELEASE_RES2:
  270.                 releaseResource(resourceA, TASK2);
  271.                 updateResourceLED(resourceA, resA_R, resA_G, resA_B);
  272.                 task2State = RELEASE_RES1;
  273.                 break;
  274.  
  275.             case RELEASE_RES1:
  276.                 releaseResource(resourceB, TASK2);
  277.                 updateResourceLED(resourceB, resB_R, resB_G, resB_B);
  278.                 task2State = IDLE;
  279.                 break;
  280.         }
  281.  
  282.         // Deadlock detection every deadlockCheckInterval
  283.         if (currentMillis - deadlockCheckTimer >= deadlockCheckInterval) {
  284.             deadlockCheckTimer = currentMillis;
  285.             if (detectDeadlock()) {
  286.                 recoverDeadlock();
  287.             }
  288.         }
  289.     }
  290. }
  291.  
  292. /* END CODE */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement