// fish_feeder_final_fixed.ino #include #include #include #include // --- PIN DEFINITIONS --- #define TEMP_PIN 14 // Signal wire from DS18B20 #define MOTOR_PIN 2 // Gate of MOSFET (Also the Blue LED) // --- NETWORK SETTINGS --- const char* ssid = "Aussie Broadband 8729"; const char* pass = "Ffdfmunfca"; const char* mqtt_server = "192.168.20.30"; WiFiClient net; PubSubClient mqtt(net); OneWire oneWire(TEMP_PIN); DallasTemperature sensors(&oneWire); void setup() { Serial.begin(115200); // 1. Setup Motor (Safety First) pinMode(MOTOR_PIN, OUTPUT); digitalWrite(MOTOR_PIN, LOW); // Ensure motor is OFF // 2. Setup Sensor sensors.begin(); sensors.setWaitForConversion(false); Serial.println("--------------------------------"); Serial.println("šŸ”Œ System Start"); // 3. Connect WiFi Serial.print("šŸ“¶ Connecting to WiFi..."); WiFi.begin(ssid, pass); int attempts = 0; while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); attempts++; if(attempts > 20) { Serial.println("\nāŒ WiFi Failed! Check credentials."); break; } } if (WiFi.status() == WL_CONNECTED) { Serial.printf("\nāœ… WiFi Connected! IP: %s\n", WiFi.localIP().toString().c_str()); } // 4. Setup MQTT mqtt.setServer(mqtt_server, 1883); mqtt.setCallback([](char* topic, byte* payload, unsigned int len) { Serial.println("⚔ MQTT Message Received!"); triggerFeed(); // Run the feed function }); Serial.println("āœ… System Ready. Type 'pulse' in Serial Monitor to test."); } // Separate function to handle the motor logic void triggerFeed() { Serial.println("⚔ Feeding Fish..."); digitalWrite(MOTOR_PIN, HIGH); delay(500); // Run motor for 0.5 seconds digitalWrite(MOTOR_PIN, LOW); Serial.println("āœ… Feed Cycle Complete"); } void loop() { // 1. Maintain MQTT if (WiFi.status() == WL_CONNECTED && !mqtt.connected()) { if (mqtt.connect("fish-feeder", "mqtt-user", "sam4jo")) { Serial.println("šŸ”Œ MQTT Reconnected"); mqtt.subscribe("tank/feed"); const char* discovery_topic = "homeassistant/sensor/fishtank_temp/config"; const char* payload = "{" "\"name\": \"Fish Tank Temp\"," "\"state_topic\": \"tank/temperature\"," "\"unit_of_measurement\": \"°C\"," "\"device_class\": \"temperature\"," "\"unique_id\": \"fishtank_temp_auto\"" "}"; // Publish with 'true' for Retain (so HA sees it even after restart) mqtt.publish(discovery_topic, payload, true); // ---------------------------------------------------- } else { Serial.print("failed, rc="); Serial.print(mqtt.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } mqtt.loop(); // 2. LISTEN FOR SERIAL COMMANDS (This was missing) if (Serial.available()) { String cmd = Serial.readStringUntil('\n'); cmd.trim(); // Remove spaces/enter keys if (cmd == "pulse") { triggerFeed(); } } // 3. Temperature Logic static unsigned long lastTemp = 0; if (millis() - lastTemp > 60000) { // Every 10 seconds sensors.requestTemperatures(); float t = sensors.getTempCByIndex(0); Serial.printf("šŸŒ”ļø Temp: %.2f°C\n", t); if (mqtt.connected() && t > -100) { char buf[10]; snprintf(buf, sizeof(buf), "%.2f", t); mqtt.publish("tank/temperature", buf); } lastTemp = millis(); } }