pleasedontcode

Salt Dispenser rev_01

Sep 27th, 2025
143
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: Salt Dispenser
  13.     - Source Code NOT compiled for: ESP32 DevKit V1
  14.     - Source Code created on: 2025-09-27 15:32:02
  15.  
  16. ********* Pleasedontcode.com **********/
  17.  
  18. /****** SYSTEM REQUIREMENTS *****/
  19. /****** SYSTEM REQUIREMENT 1 *****/
  20.     /* The user requirement must describe the Salt */
  21.     /* dispenser project (Project_3455) releasing a */
  22.     /* precise salt amount when a trigger occurs, with a */
  23.     /* safe, finite dispense cycle and a clear */
  24.     /* idle/dispensing state. */
  25. /****** END SYSTEM REQUIREMENTS *****/
  26.  
  27.  
  28. /* START CODE */
  29.  
  30. /****** DEFINITION OF LIBRARIES *****/
  31.  
  32. #include <Arduino.h>
  33.  
  34. /****** FUNCTION PROTOTYPES *****/
  35. void setup(void);
  36. void loop(void);
  37. // New helper routines for the salt dispenser
  38. void startDispense(float grams);
  39. void updateDispense(void);
  40.  
  41. // --------- Dispenser Configuration (adjust for your hardware) ---------
  42. // Target amount of salt per dispense (grams)
  43. const float SALT_PER_DISPENSE_G = 5.0f; // adjustable per calibration
  44. // Estimated salt flow rate for the dispenser (grams per second)
  45. const float SALT_FLOW_RATE_G_PER_S = 2.0f; // customize to your pump/solenoid
  46.  
  47. // GPIO assignments (adjust to your ESP32 board wiring)
  48. // Trigger input (use a pull-up and press to ground
  49. const uint8_t TRIGGER_PIN = 35;     // GPIO for trigger button (input)
  50. const uint8_t DISPENSE_PIN = 25;     // GPIO controlling the dispenser (output)
  51. const uint8_t STATUS_LED_PIN = 26;  // GPIO for a status LED (output)
  52.  
  53. // Debounce and timing
  54. const unsigned long DEBOUNCE_MS = 50;     // button debounce
  55. const unsigned long COOLDOWN_MS = 2000;    // cooldown after a dispense (finalize cycle)
  56.  
  57. // State machine for dispense operation
  58. enum DispenseState {IDLE, DISPENSING};
  59. DispenseState g_state = IDLE;
  60. unsigned long g_dispenseEndTime = 0; // when to stop dispensing
  61. float g_targetGrams = 0.0f;           // grams to dispense for this cycle
  62. unsigned long g_lastButtonTime = 0;    // last debounce time
  63. int g_lastButtonReading = HIGH;          // last read state of trigger pin
  64.  
  65. // LED handling
  66. unsigned long g_lastLedToggle = 0;     // for blinking during dispensing
  67. bool g_ledState = false;                 // LED state during dispensing
  68.  
  69. // cooldown handling
  70. unsigned long g_cooldownEnd = 0;       // end time for cooldown
  71.  
  72. /*********** SETUP ***********/
  73. void setup(void)
  74. {
  75.     // Initialize serial for debugging (optional)
  76.     Serial.begin(115200);
  77.     while (!Serial) { /* wait for serial to be ready */ }
  78.  
  79.     // Configure pins
  80.     pinMode(TRIGGER_PIN, INPUT_PULLUP);
  81.     pinMode(DISPENSE_PIN, OUTPUT);
  82.     pinMode(STATUS_LED_PIN, OUTPUT);
  83.  
  84.     // Initial states
  85.     digitalWrite(DISPENSE_PIN, LOW);       // dispenser off
  86.     digitalWrite(STATUS_LED_PIN, HIGH);    // idle state indicated by LED on
  87.  
  88.     // Print a startup message
  89.     Serial.println("Project_3455 Salt Dispenser: idle");
  90. }
  91.  
  92. /*********** LOOP ***********/
  93. void loop(void)
  94. {
  95.     // Read trigger with debouncing
  96.     int reading = digitalRead(TRIGGER_PIN);
  97.     if (reading != g_lastButtonReading) {
  98.         g_lastButtonTime = millis();
  99.         g_lastButtonReading = reading;
  100.     }
  101.  
  102.     if ((millis() - g_lastButtonTime) > DEBOUNCE_MS) {
  103.         // Detect press: active LOW (button pulls trigger to GND when pressed)
  104.         if (reading == LOW && g_lastButtonReading == HIGH) {
  105.             // Only allow new dispense if currently idle and not cooling down
  106.             if (g_state == IDLE && millis() >= g_cooldownEnd) {
  107.                 startDispense(SALT_PER_DISPENSE_G);
  108.             } else {
  109.                 // Optionally report that a dispense cannot start yet
  110.                 Serial.println("Dispense request ignored: busy or cooling down");
  111.             }
  112.         }
  113.         // Update last reading after debounce interval
  114.         g_lastButtonReading = reading;
  115.     }
  116.  
  117.     // Update the current dispense state (non-blocking)
  118.     updateDispense();
  119.  
  120.     // Optional small idle task: keep a stable idle LED
  121.     if (g_state == IDLE) {
  122.         // Idle LED on
  123.         digitalWrite(STATUS_LED_PIN, HIGH);
  124.     }
  125. }
  126.  
  127. /*********** DISPENSE HANDLERS ***********/
  128. // Start a dispense cycle for a given target amount (grams)
  129. void startDispense(float grams)
  130. {
  131.     g_targetGrams = grams;
  132.     // Compute duration based on flow rate. Ensure a minimum duration.
  133.     float durationSec = grams / SALT_FLOW_RATE_G_PER_S;
  134.     unsigned long durationMs = (unsigned long)(durationSec * 1000.0f);
  135.     if (durationMs < 10) durationMs = 10; // safeguard
  136.  
  137.     g_dispenseEndTime = millis() + durationMs;
  138.     g_state = DISPENSING;
  139.  
  140.     // Activate the dispenser
  141.     digitalWrite(DISPENSE_PIN, HIGH);
  142.  
  143.     // LED should blink during dispensing
  144.     g_lastLedToggle = millis();
  145.     g_ledState = true; // start in ON state for clarity
  146.     digitalWrite(STATUS_LED_PIN, LOW); // indicate dispensing by LED off
  147.  
  148.     Serial.print("Dispensing "); Serial.print(grams); Serial.println(" g");
  149.     Serial.print("Will operate for ~"); Serial.print(durationMs); Serial.println(" ms");
  150. }
  151.  
  152. // Non-blocking update for the current dispense state
  153. void updateDispense(void)
  154. {
  155.     if (g_state == DISPENSING) {
  156.         unsigned long now = millis();
  157.         if (now >= g_dispenseEndTime) {
  158.             // End of dispense cycle
  159.             digitalWrite(DISPENSE_PIN, LOW);
  160.             g_state = IDLE;
  161.             // Start cooldown
  162.             g_cooldownEnd = now + COOLDOWN_MS;
  163.             // Restore idle LED quickly
  164.             digitalWrite(STATUS_LED_PIN, HIGH);
  165.             Serial.println("Dispense cycle complete");
  166.         } else {
  167.             // Blink LED to indicate dispensing is active
  168.             if ((now - g_lastLedToggle) >= 250) {
  169.                 g_lastLedToggle = now;
  170.                 g_ledState = !g_ledState;
  171.                 digitalWrite(STATUS_LED_PIN, g_ledState ? HIGH : LOW);
  172.             }
  173.         }
  174.     }
  175. }
  176.  
  177. /* END CODE */
  178.  
Advertisement
Add Comment
Please, Sign In to add comment