fish_feeder_temperature/fish_feeder.ino

126 lines
3.5 KiB
C++

// fish_feeder_final_fixed.ino
#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// --- 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();
}
}