Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********* Pleasedontcode.com **********
- Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- - Terms and Conditions:
- You have a non-exclusive, revocable, worldwide, royalty-free license
- for personal and commercial use. Attribution is optional; modifications
- are allowed, but you're responsible for code maintenance. We're not
- liable for any loss or damage. For full terms,
- please visit pleasedontcode.com/termsandconditions.
- - Project: Salt Dispenser
- - Source Code NOT compiled for: ESP32 DevKit V1
- - Source Code created on: 2025-09-27 15:32:02
- ********* Pleasedontcode.com **********/
- /****** SYSTEM REQUIREMENTS *****/
- /****** SYSTEM REQUIREMENT 1 *****/
- /* The user requirement must describe the Salt */
- /* dispenser project (Project_3455) releasing a */
- /* precise salt amount when a trigger occurs, with a */
- /* safe, finite dispense cycle and a clear */
- /* idle/dispensing state. */
- /****** END SYSTEM REQUIREMENTS *****/
- /* START CODE */
- /****** DEFINITION OF LIBRARIES *****/
- #include <Arduino.h>
- /****** FUNCTION PROTOTYPES *****/
- void setup(void);
- void loop(void);
- // New helper routines for the salt dispenser
- void startDispense(float grams);
- void updateDispense(void);
- // --------- Dispenser Configuration (adjust for your hardware) ---------
- // Target amount of salt per dispense (grams)
- const float SALT_PER_DISPENSE_G = 5.0f; // adjustable per calibration
- // Estimated salt flow rate for the dispenser (grams per second)
- const float SALT_FLOW_RATE_G_PER_S = 2.0f; // customize to your pump/solenoid
- // GPIO assignments (adjust to your ESP32 board wiring)
- // Trigger input (use a pull-up and press to ground
- const uint8_t TRIGGER_PIN = 35; // GPIO for trigger button (input)
- const uint8_t DISPENSE_PIN = 25; // GPIO controlling the dispenser (output)
- const uint8_t STATUS_LED_PIN = 26; // GPIO for a status LED (output)
- // Debounce and timing
- const unsigned long DEBOUNCE_MS = 50; // button debounce
- const unsigned long COOLDOWN_MS = 2000; // cooldown after a dispense (finalize cycle)
- // State machine for dispense operation
- enum DispenseState {IDLE, DISPENSING};
- DispenseState g_state = IDLE;
- unsigned long g_dispenseEndTime = 0; // when to stop dispensing
- float g_targetGrams = 0.0f; // grams to dispense for this cycle
- unsigned long g_lastButtonTime = 0; // last debounce time
- int g_lastButtonReading = HIGH; // last read state of trigger pin
- // LED handling
- unsigned long g_lastLedToggle = 0; // for blinking during dispensing
- bool g_ledState = false; // LED state during dispensing
- // cooldown handling
- unsigned long g_cooldownEnd = 0; // end time for cooldown
- /*********** SETUP ***********/
- void setup(void)
- {
- // Initialize serial for debugging (optional)
- Serial.begin(115200);
- while (!Serial) { /* wait for serial to be ready */ }
- // Configure pins
- pinMode(TRIGGER_PIN, INPUT_PULLUP);
- pinMode(DISPENSE_PIN, OUTPUT);
- pinMode(STATUS_LED_PIN, OUTPUT);
- // Initial states
- digitalWrite(DISPENSE_PIN, LOW); // dispenser off
- digitalWrite(STATUS_LED_PIN, HIGH); // idle state indicated by LED on
- // Print a startup message
- Serial.println("Project_3455 Salt Dispenser: idle");
- }
- /*********** LOOP ***********/
- void loop(void)
- {
- // Read trigger with debouncing
- int reading = digitalRead(TRIGGER_PIN);
- if (reading != g_lastButtonReading) {
- g_lastButtonTime = millis();
- g_lastButtonReading = reading;
- }
- if ((millis() - g_lastButtonTime) > DEBOUNCE_MS) {
- // Detect press: active LOW (button pulls trigger to GND when pressed)
- if (reading == LOW && g_lastButtonReading == HIGH) {
- // Only allow new dispense if currently idle and not cooling down
- if (g_state == IDLE && millis() >= g_cooldownEnd) {
- startDispense(SALT_PER_DISPENSE_G);
- } else {
- // Optionally report that a dispense cannot start yet
- Serial.println("Dispense request ignored: busy or cooling down");
- }
- }
- // Update last reading after debounce interval
- g_lastButtonReading = reading;
- }
- // Update the current dispense state (non-blocking)
- updateDispense();
- // Optional small idle task: keep a stable idle LED
- if (g_state == IDLE) {
- // Idle LED on
- digitalWrite(STATUS_LED_PIN, HIGH);
- }
- }
- /*********** DISPENSE HANDLERS ***********/
- // Start a dispense cycle for a given target amount (grams)
- void startDispense(float grams)
- {
- g_targetGrams = grams;
- // Compute duration based on flow rate. Ensure a minimum duration.
- float durationSec = grams / SALT_FLOW_RATE_G_PER_S;
- unsigned long durationMs = (unsigned long)(durationSec * 1000.0f);
- if (durationMs < 10) durationMs = 10; // safeguard
- g_dispenseEndTime = millis() + durationMs;
- g_state = DISPENSING;
- // Activate the dispenser
- digitalWrite(DISPENSE_PIN, HIGH);
- // LED should blink during dispensing
- g_lastLedToggle = millis();
- g_ledState = true; // start in ON state for clarity
- digitalWrite(STATUS_LED_PIN, LOW); // indicate dispensing by LED off
- Serial.print("Dispensing "); Serial.print(grams); Serial.println(" g");
- Serial.print("Will operate for ~"); Serial.print(durationMs); Serial.println(" ms");
- }
- // Non-blocking update for the current dispense state
- void updateDispense(void)
- {
- if (g_state == DISPENSING) {
- unsigned long now = millis();
- if (now >= g_dispenseEndTime) {
- // End of dispense cycle
- digitalWrite(DISPENSE_PIN, LOW);
- g_state = IDLE;
- // Start cooldown
- g_cooldownEnd = now + COOLDOWN_MS;
- // Restore idle LED quickly
- digitalWrite(STATUS_LED_PIN, HIGH);
- Serial.println("Dispense cycle complete");
- } else {
- // Blink LED to indicate dispensing is active
- if ((now - g_lastLedToggle) >= 250) {
- g_lastLedToggle = now;
- g_ledState = !g_ledState;
- digitalWrite(STATUS_LED_PIN, g_ledState ? HIGH : LOW);
- }
- }
- }
- }
- /* END CODE */
Advertisement
Add Comment
Please, Sign In to add comment