//Kode for ESP32-sensornodemodul.
//------------------ Libraries --------------------------
#include <WiFi.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
Servo servo;
//------------------- Structs -------------------
struct Timer
{
unsigned long startTime;
void reset()
{
startTime = millis();
}
unsigned long getElapsedTime()
{
return millis() - startTime;
}
bool isFinished(unsigned long duration)
{
return getElapsedTime() >= duration;
}
};
Timer timer1;
//------------------ Global variables -----------------------------
const char* ssid = "Gruppe C31";
const char* password = "gruppec31";
const char* mqtt_server = "192.168.137.81";
WiFiClient sensornode;
PubSubClient client(sensornode);
char msg[50];
int lightsensor1pin = 34; //Pins
int lightsensor2pin = 35;
int tempsensorpin = 32;
int servopin = 13;
int enablepin = 27;
int input2pin = 26;
int inputpin = 25;
int lightsensor1value;
int lightsensor2value;
int tempsensorvalue = 10000; //10000 to prevent dc motor from starting when
booting up.
bool lightsensor1status;
bool lightsensor2status;
bool tempsensorstatus;
bool dcmotorstatus;
bool servomanualstatus;
int servoposition = 90;
int lightthreshold = 200;
int tempthreshold = 700; //750 resembles approximately 22 degrees Celsius.
//--------------------- Functions ---------------------------------
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
if (String(topic) == "maintopic")
//Responses to messages on maintopic.
{
if (messageTemp == "lightsensor1_on")
{
lightsensor1status = true;
Serial.println("Enabling lightsensor1");
}
else if (messageTemp == "lightsensor1_off")
{
lightsensor1status = false;
Serial.println("Disabling lightsensor1");
}
if (messageTemp == "lightsensor2_on")
{
lightsensor2status = true;
Serial.println("Enabling lightsensor2");
}
else if (messageTemp == "lightsensor2_off")
{
lightsensor2status = false;
Serial.println("Disabling lightsensor2");
}
if (messageTemp == "tempsensor_on")
{
tempsensorstatus = true;
Serial.println("Enabling tempsensor");
}
else if (messageTemp == "tempsensor_off")
{
tempsensorstatus = false;
Serial.println("Disabling tempsensor");
}
if (messageTemp == "servomanual_on")
{
servomanualstatus = true;
Serial.println("Enabling manual control of servo");
}
else if (messageTemp == "servomanual_off")
{
servomanualstatus = false;
Serial.println("Disabling manual control of servo");
}
}
if (String(topic) == "tempthresholdtopic")
//Responses to messages on tempthresholdtopic.
{
tempthreshold = messageTemp.toInt();
Serial.print("Setting tempthreshold to ");
Serial.println(tempthreshold);
}
if (String(topic) == "servotopic" && servomanualstatus)
//Responses to messages on servotopic.
{
servo.write(messageTemp.toInt());
Serial.print("Setting servo to ");
Serial.println(messageTemp);
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("sensornode")) {
Serial.println("connected");
// Subscribe
client.subscribe("maintopic");
client.subscribe("tempthresholdtopic");
client.subscribe("servotopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void read_serial_monitor_input()
//Checks for user input in serial monitor
//and performs different operations based on the input.
//(Symbolizes maintopic and tempthresholdtopic)
{
if (Serial.available() > 0)
{
String input = Serial.readStringUntil('\n');
Serial.println(input);
if (input == "lightsensor1_on")
{
lightsensor1status = true;
Serial.println("Enabling lightsensor1");
}
else if (input == "lightsensor1_off")
{
lightsensor1status = false;
Serial.println("Disabling lightsensor1");
}
if (input == "lightsensor2_on")
{
lightsensor2status = true;
Serial.println("Enabling lightsensor2");
}
else if (input == "lightsensor2_off")
{
lightsensor2status = false;
Serial.println("Disabling lightsensor2");
}
if (input == "tempsensor_on")
{
tempsensorstatus = true;
Serial.println("Enabling tempsensor");
}
else if (input == "tempsensor_off")
{
tempsensorstatus = false;
Serial.println("Disabling tempsensor");
}
if (input == "servomanual_on")
{
servomanualstatus = true;
Serial.println("Enabling manual control of servo");
}
else if (input == "servomanual_off")
{
servomanualstatus = false;
Serial.println("Disabling manual control of servo");
}
if (isDigit(input[0]))
{
tempthreshold = input.toInt();
Serial.print("Setting tempthreshold to ");
Serial.println(input);
}
}
}
void read_enabled_sensors()
//Reads enabled sensors and publishes value to a topic.
{
if (lightsensor1status)
{
lightsensor1value = analogRead(lightsensor1pin);
Serial.print("lightsensor1: ");
Serial.println(lightsensor1value);
char tempString[8];
dtostrf(lightsensor1value, 1, 2, tempString);
client.publish("lightsensor1topic", tempString);
}
if (lightsensor2status)
{
lightsensor2value = analogRead(lightsensor2pin);
Serial.print("lightsensor2: ");
Serial.println(lightsensor2value);
char tempString[8];
dtostrf(lightsensor2value, 1, 2, tempString);
client.publish("lightsensor2topic", tempString);
}
if (tempsensorstatus)
{
tempsensorvalue = analogRead(tempsensorpin);
Serial.print("tempsensor: ");
Serial.println(tempsensorvalue);
char tempString[8];
dtostrf(tempsensorvalue, 1, 2, tempString);
client.publish("tempsensortopic", tempString);
}
}
void set_servo_motor_position()
//Sets servo motor position based on light sensor values
//if servo manual control is disabled.
{
if (!servomanualstatus)
{
if (lightsensor1value > lightthreshold && lightsensor2value >
lightthreshold
&& servoposition != 90)
{
servo.write(90);
servoposition = 90;
Serial.println("Setting servo to 90 degrees");
}
else if (lightsensor1value > lightthreshold && lightsensor2value <
lightthreshold
&& servoposition != 0)
{
servo.write(0);
servoposition = 0;
Serial.println("Setting servo to 0 degrees");
}
else if (lightsensor1value < lightthreshold && lightsensor2value >
lightthreshold
&& servoposition != 180)
{
servo.write(180);
servoposition = 180;
Serial.println("Setting servo to 180 degrees");
}
}
}
void set_dc_motor_state()
//Enables or disables dc motor based on temperature sensor values.
{
if (tempsensorvalue < tempthreshold && !dcmotorstatus)
{
analogWrite(enablepin, 10);
dcmotorstatus = true;
Serial.println("Temperature under threshold. Starting dc motor");
}
else if (tempsensorvalue > tempthreshold && dcmotorstatus)
{
analogWrite(enablepin, 0);
dcmotorstatus = false;
Serial.println("Temperature over threshold. Stopping dc motor");
}
}
void send_currency_to_node_red()
//Reads light sensors and sends currency to node-red if there is enough light.
{
int value1 = analogRead(lightsensor1pin);
int value2 = analogRead(lightsensor2pin);
if (value1 > lightthreshold && value2 > lightthreshold)
{
Serial.println("Gaining high income from solar panels");
Serial.println("Sending 2 kr to maintopic");
char tempString[8];
dtostrf(2, 1, 2, tempString);
client.publish("maintopic", tempString);
}
else if (value1 > lightthreshold ^ value2 > lightthreshold)
{
Serial.println("Gaining low income from solarpanels");
Serial.println("Sending 1 kr to maintopic");
char tempString[8];
dtostrf(1, 1, 2, tempString);
client.publish("maintopic", tempString);
}
}
//------------------- setup and loop -----------------------
void setup()
{
Serial.begin(115200);
pinMode(lightsensor1pin, INPUT);
pinMode(lightsensor2pin, INPUT);
pinMode(tempsensorpin, INPUT);
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
servo.setPeriodHertz(50); // standard 50 hz servo
servo.attach(servopin, 500, 2400);
servo.write(90); //Setting starting position
pinMode(enablepin, OUTPUT);
pinMode(inputpin, OUTPUT);
pinMode(input2pin, OUTPUT);
digitalWrite(inputpin, HIGH); //Setting direciton for DC motor
digitalWrite(input2pin, LOW);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop()
{
if (timer1.isFinished(5000))
{
timer1.reset();
Serial.println("Loop is running");
if (!client.connected()) {
reconnect();
Serial.print("reconnect");
}
client.loop();
read_serial_monitor_input();
read_enabled_sensors();
set_servo_motor_position();
set_dc_motor_state();
send_currency_to_node_red();
}
}