#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
//---------------- Wifi configuration -----------------------------
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Defining the WiFi channel speeds up the connection:
#define WIFI_CHANNEL 6
int status = WL_IDLE_STATUS; // the Wifi radio's status
//------ Stepper Motor Pins with A4988 and ESP32 Driver -----------
#define DIR_PIN 12
#define STEP_PIN 13
#define DELAY 2000
//----------- LDR configuration ---------------------------------
#define LDR_PIN 35 // sets the photoresistor read pin LDR
// Constants that correspond to the "gamma" and "rl10" attributes of the photoresistor.
const float GAMMA = 0.7;
const float RL10 = 33;
float lux = 0;
//----------------- Leds configuration --------------------------
const int ledCount = 10; // Set number of LEDs in the bar graph
// Array of pins for LEDs in the bar graph (in ordem)
int ledPins[] = {
15, 2, 4, 5, 18, 19, 21, 22, 23, 34
};
// Map the result to a range from lux to the number of LEDs
int ledLevel = map(lux, 0, 10000, 0, ledCount);
//----------- MQTT configuration --------------------------------
const char* mqtt_server = "test.mosquitto.org";// MQTT broker
char* my_topic_SUB = "analogLux";// the chosen topic
char* my_topic_PUB = "analogLux";// the chosen topic
//---------- Wifi and MQTT configuration ------------------------
WiFiClient espClient;
PubSubClient client(espClient);
//------------------ Reading time setting -----------------------
int contador = 1;
char msg[30];
unsigned long lastMillis = 0;
//---------------- Stepper Motor angles ------------------------
const int theta0 = 34.0; // ~61.2º // Each step = 1.8 degrees.
const int theta1 = 17.0; // ~30.6º // Adds clockwise angle.
//---------------------------------------------------------------
void setup() {
// Setup code, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
conectawifi();
client.setServer(mqtt_server, 1883); // Set the MQTT broker server and port
client.setCallback(callback); // Set the callback function for incoming MQTT messages
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
delay(DELAY);
// Loop over the LEDs pins and set all to output
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
pinMode(ledPins[thisLed], OUTPUT);
}
} // end setup()
void loop() {
float sunlight = photoresistor();
leds(); // Update lights leds
// Check MQTT connection and process incoming messages
if (!client.connected()) {
reconnect();
}
client.loop();
delay(DELAY); // Add a delay to avoid flooding the MQTT broker with messages
// Wait 15 seconds to send a new message
if (millis() - lastMillis > 15000) {
lastMillis = millis();
sprintf(msg, "%.2f", sunlight);
Serial.print("Message sent: ");
Serial.println(msg);
// Send the message to the broker
client.publish(my_topic_PUB, msg);
Serial.print(contador);
Serial.println(" - Message sent successfully...");
contador++; // Increment the counter
leds(); // Update lights leds
}
leds(); // Update lights leds
//-------------------- Stepper Motor Rotation ------------------------
// Defines rotation direction (clockwise)
digitalWrite(DIR_PIN, HIGH);
// Turns angle theta0 (clockwise)
for (int i = 0; i < theta0; i++) {
// Take a step
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(DELAY);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(DELAY);
} // end for i
Serial.println("At 6 am - 8 am");
leds(); // Update lights leds
delay(DELAY);
// Changes the direction of rotation of angle theta_1 (counterclockwise)
digitalWrite(DIR_PIN, LOW);
for (int j = 0; j < 4; j++) { // j: 0-3 Nº de ângulos no sentido anti-horário
for (int i = 0; i < theta1; i++) {
// Take a step
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(DELAY);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(DELAY);
} // end for i
if (j==0) Serial.println("At 8 am - 10 am");
if (j==1) Serial.println("At 10 am - 1 pm");
if (j==2) Serial.println("At 1 pm - 3 pm");
if (j==3) Serial.println("At 3 pm - 5 pm");
leds(); // Update lights leds
delay(DELAY);
} // end for j
//------------------- Return the panel to Azimuth ------------------------------------
// Defines direction of rotation (clockwise).
digitalWrite(DIR_PIN, HIGH);
// Performs the rotation of 2 theta1 angles (clockwise).
for (int j = 0; j < 2; j++) { // j: 0-1 Nº de ângulos no sentido horário
for (int i = 0; i < theta1; i++) {
// Take a step
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(DELAY);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(DELAY);
} // end for i
if (j==0 or j==1) Serial.println("Returning the panel to the east...");
leds(); // Update lights leds
delay(DELAY);
} // end for j
} // end loop()
void conectawifi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
Serial.print("Conectando ao WiFi ");
Serial.print(WIFI_SSID);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
//WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
}
Serial.println(" Connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} // end conectawifi()
void leds() {
// Map the result to a range from lux to the number of LEDs
ledLevel = map(lux, 0, 10000, 0, ledCount);
// Loop over the LEDs pins and set element
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
// If the array element's index is less than ledLevel
if (thisLed < ledLevel) {
// Turn the pin for this element on
digitalWrite(ledPins[thisLed], HIGH);
} else {
// Turn off all pins higher than the ledLevel
digitalWrite(ledPins[thisLed], LOW);
}
}
} // end leds
float photoresistor() {
int analogLux = analogRead(LDR_PIN);
Serial.print("analogLux value: ");
Serial.println(analogLux);
// Only reads if there is a change in value
// if (analogLux != valorAnterior) {
// Code provided by WOKWI to convert the return value from analogRead()
// into an illuminance level value (in lux).
// Read more: [https://docs.wokwi.com/parts/wokwi-photoresistor-sensor]
float voltage = analogLux / 4096. * 3.3;
float resistance = 2000 * voltage / (1 - voltage / 3.3);
lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
// Prints message about sunlight intensity
if (analogLux <= 39)
Serial.println("Excelent! ");
else if (analogLux <= 54 and analogLux > 39)
Serial.println("Good ");
else if (analogLux <= 86 and analogLux > 54)
Serial.println("Moderate ");
else if (analogLux <= 169 and analogLux > 86)
Serial.println("Weak ");
else
Serial.println("Inappropriate ");
Serial.print("Luminosidade: ");
Serial.println(lux);
return lux;
}
// Process incoming MQTT message and control the servo motor
void callback(char* topic, byte* payload, unsigned int length) {
String string;
Serial.print("The message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
string += ((char)payload[i]);
} // for
Serial.print(string);
} // end callback()
// Attempt to reconnect to the MQTT broker if the connection is lost
void reconnect() {
while (!client.connected()) {
Serial.print("Tentando conectar ao MQTT ...");
if (client.connect("ESPClient")) {
Serial.println("Conectado");
client.subscribe(my_topic_SUB);
} else {
Serial.print("falhou, rc=");
Serial.print(client.state());
Serial.println(" Tente novamente em 5 segundos");
} // else
} // while
} // end reconnect()