自动麦提莎分发器LCD故障及系统异常技术求助
Hey there, let's troubleshoot your Malteser dispenser issue! The symptoms you're seeing—stuck LCD blocks, constant LED, unresponsive servo/buttons—strongly point to an initialization failure, so your hunch about the setup() function is spot-on. Let's break down the fixes and possible root causes:
Key Code Issues in setup()
These are the most likely culprits behind your system locking up:
1. Missing DS3231 Initialization
You declared the Clock object but never initialized it with Clock.begin()! When your code tries to call Clock.getSecond() or other time functions later, it gets stuck waiting for I2C communication with an uninitialized module. This blocks the entire program, leading to the frozen behavior you're seeing.
2. Wrong Order for LCD Custom Character
You're calling lcd.createChar() before lcd.begin(). The LCD's memory isn't initialized until begin() runs, so your custom degree symbol never gets saved correctly. This can cause garbled display output like the solid blocks you're seeing.
3. Minor Syntax Bug in Date Reading
In getData(), this line has a misplaced comma:
month = Clock.getMonth(Century), DEC;
It should be:
month = Clock.getMonth(Century, DEC);
The original code ignores the DEC format parameter, which might cause incorrect month values, though this isn't the immediate cause of your freeze.
Fixed setup() Function
Here's the corrected version with proper initialization order and error checking:
void setup() { // Start serial first for debugging Serial.begin(9600); // Initialize LCD BEFORE creating custom characters lcd.begin(16, 2); lcd.createChar(0, degree); // Print initialization message lcd.print("INITIALIZING"); // Initialize I2C and DS3231 clock with error checking Wire.begin(); if (!Clock.begin()) { lcd.clear(); lcd.print("CLOCK ERROR!"); while(1); // Halt if clock isn't detected (prevents lockup) } // Set up button and servo pinMode(button, INPUT); myServo.attach(9); myServo.write(10); // Move servo to initial position after attaching // LED blink sequence pinMode(ledPin, OUTPUT); digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); delay(1000); lcd.clear(); }
Additional Hardware Checks
Since the issue started after leaving the device unused for a while, hardware degradation could also be at play:
- Power Supply Issues: Servo motors draw significant current—if your power supply is weak or has aged, it might cause voltage drops that crash the MCU, make the servo weak, or starve the LCD. Try a higher-current power supply or add a 100µF capacitor across the MCU's power pins to smooth voltage spikes.
- Oxidized Connections: Over time, wire pins or breadboard contacts can oxidize, especially for I2C lines (SDA/SCL). Reseat all wires or clean the pins with a small brush to ensure good connectivity.
- Servo Mechanical Bind: Check if the servo's gear train is stuck—physical resistance can cause it to draw excess current and destabilize the system.
Bonus: Non-Blocking Button Handling
Your current loop() uses delay(5000) when the button is pressed, which makes the system unresponsive during that time. For a smoother experience, replace the delay with millis()-based timing (this won't fix your current freeze but will improve overall functionality):
unsigned long servoActiveTime = 0; bool servoIsActive = false; void loop() { if (digitalRead(button) == LOW && !servoIsActive) { digitalWrite(ledPin, HIGH); myServo.write(170); lcd.clear(); lcd.setCursor(0, 0); lcd.print("---- Have A ----"); lcd.setCursor(0, 1); lcd.print(" Malteser "); servoActiveTime = millis(); servoIsActive = true; mE(); // Increment count immediately } else if (servoIsActive && millis() - servoActiveTime >= 5000) { myServo.write(10); lcd.clear(); check(); digitalWrite(ledPin, LOW); servoIsActive = false; } else { getData(); } }
内容的提问来源于stack exchange,提问作者Electrouino

