#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// Set the LCD address for each display
LiquidCrystal_I2C lcdA(0x20, 16, 2); // Address 0x20 for Material A
LiquidCrystal_I2C lcdB(0x27, 16, 2); // Address 0x27 for Material B
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Server IP Address
const char* server_ip = "localhost:5000"; // Update with your actual server IP
// Server URLs (use HTTPS)
const String SERVER_ADD_STOCK_URL = "http://" + String(server_ip) + "/api/add_stock";
const String SERVER_REMOVE_STOCK_URL = "http://" + String(server_ip) + "/api/remove_stock";
const String SERVER_GET_CITY_URL = "http://" + String(server_ip) + "/api/get_latest_city";
// Sensor pins
const int trigPinA = 5;
const int echoPinA = 17;
const int trigPinB = 16;
const int echoPinB = 4;
// LED pins
const int ledRedPinA = 15;
const int ledGreenPinA = 2;
const int ledYellowPinA = 13;
const int ledRedPinB = 23;
const int ledGreenPinB = 25;
const int ledYellowPinB = 26;
// Distance threshold
const int thresholdDistanceA = 200; // 200 cm
const int thresholdDistanceB = 150; // 150 cm (example threshold for Material B)
// Material details
const char* kodeA = "SF421015";
const char* materialNameA = "Material A";
String materialDateA = "2024-07-14"; // Example date
const char* kodeB = "SF421018";
const char* materialNameB = "Material B";
String materialDateB = "2024-07-14"; // Example date for Material B
// Variable to store the last processed distance
int lastProcessedDistanceA = -1;
int lastProcessedDistanceB = -1;
// Time intervals
unsigned long lastMeasurementTimeA = 0;
unsigned long lastMeasurementTimeB = 0;
const unsigned long measurementInterval = 5000; // 5 seconds
unsigned long lastDisplayUpdateTimeA = 0;
unsigned long lastDisplayUpdateTimeB = 0;
const unsigned long displayInterval = 2000; // 2 seconds
bool displayMaterialNameA = true;
bool displayMaterialNameB = true;
// Variables for blinking the yellow LED
unsigned long lastBlinkTimeA = 0;
unsigned long lastBlinkTimeB = 0;
const unsigned long blinkInterval = 200; // 200 ms
bool yellowLEDAState = false;
bool yellowLEDBState = false;
String latestCity = ""; // Variable to store the latest city
void setup() {
Serial.begin(115200);
Serial.println("Initializing LCDs...");
// Initialize the LCDs
lcdA.init();
lcdA.backlight();
lcdB.init();
lcdB.backlight();
// Print a message to the LCDs
lcdA.setCursor(0, 0);
lcdA.print("Smart Monitoring");
lcdA.setCursor(0, 1);
lcdA.print("Warehouse Stock");
lcdB.setCursor(0, 0);
lcdB.print("Smart Monitoring");
lcdB.setCursor(0, 1);
lcdB.print("Warehouse Stock");
delay(2000); // Display initial message for 2 seconds
// Display material names
lcdA.clear();
lcdA.setCursor(0, 0);
lcdA.print(materialNameA);
lcdB.clear();
lcdB.setCursor(0, 0);
lcdB.print(materialNameB);
// Set up sensor pins
pinMode(trigPinA, OUTPUT);
pinMode(echoPinA, INPUT);
pinMode(trigPinB, OUTPUT);
pinMode(echoPinB, INPUT);
// Set up LED pins
pinMode(ledRedPinA, OUTPUT);
pinMode(ledGreenPinA, OUTPUT);
pinMode(ledYellowPinA, OUTPUT);
pinMode(ledRedPinB, OUTPUT);
pinMode(ledGreenPinB, OUTPUT);
pinMode(ledYellowPinB, OUTPUT);
// Connect to Wi-Fi
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Update LCDs
lcdA.setCursor(0, 1);
lcdA.print("WiFi Connected");
lcdB.setCursor(0, 1);
lcdB.print("WiFi Connected");
delay(2000); // Display WiFi Connected for 2 seconds
// Display material names
lcdA.clear();
lcdA.setCursor(0, 0);
lcdA.print(materialNameA);
lcdB.clear();
lcdB.setCursor(0, 0);
lcdB.print(materialNameB);
// Get the latest city from the server
getLatestCity();
Serial.println("Setup completed.");
}
void loop() {
// Get the current time
unsigned long currentTime = millis();
// Update LCD display for Material A
if (currentTime - lastDisplayUpdateTimeA >= displayInterval) {
lastDisplayUpdateTimeA = currentTime;
lcdA.clear();
lcdA.setCursor(0, 0);
if (displayMaterialNameA) {
lcdA.print(materialNameA);
} else {
lcdA.print(materialDateA);
}
displayMaterialNameA = !displayMaterialNameA;
}
// Update LCD display for Material B
if (currentTime - lastDisplayUpdateTimeB >= displayInterval) {
lastDisplayUpdateTimeB = currentTime;
lcdB.clear();
lcdB.setCursor(0, 0);
if (displayMaterialNameB) {
lcdB.print(materialNameB);
} else {
lcdB.print(materialDateB);
}
displayMaterialNameB = !displayMaterialNameB;
}
// Check if it's time to take a new measurement for Material A
if (currentTime - lastMeasurementTimeA >= measurementInterval) {
lastMeasurementTimeA = currentTime;
processMaterial(trigPinA, echoPinA, lastProcessedDistanceA, materialNameA, materialDateA, ledRedPinA, ledGreenPinA, ledYellowPinA, kodeA, thresholdDistanceA, lcdA, lastBlinkTimeA, yellowLEDAState);
}
// Check if it's time to take a new measurement for Material B
if (currentTime - lastMeasurementTimeB >= measurementInterval) {
lastMeasurementTimeB = currentTime;
processMaterial(trigPinB, echoPinB, lastProcessedDistanceB, materialNameB, materialDateB, ledRedPinB, ledGreenPinB, ledYellowPinB, kodeB, thresholdDistanceB, lcdB, lastBlinkTimeB, yellowLEDBState);
}
// Handle blinking yellow LED for Material A
if (yellowLEDAState && (currentTime - lastBlinkTimeA >= blinkInterval)) {
lastBlinkTimeA = currentTime;
digitalWrite(ledYellowPinA, !digitalRead(ledYellowPinA));
}
// Handle blinking yellow LED for Material B
if (yellowLEDBState && (currentTime - lastBlinkTimeB >= blinkInterval)) {
lastBlinkTimeB = currentTime;
digitalWrite(ledYellowPinB, !digitalRead(ledYellowPinB));
}
delay(100); // Short delay to allow other tasks to run
}
void processMaterial(int trigPin, int echoPin, int &lastProcessedDistance, const char* materialName, String materialDate, int ledRedPin, int ledGreenPin, int ledYellowPin, const char* kode, int thresholdDistance, LiquidCrystal_I2C &lcd, unsigned long &lastBlinkTime, bool &yellowLEDState) {
Serial.println("Measuring distance...");
int currentDistance = getDistance(trigPin, echoPin);
// Only process if the distance has changed
if (currentDistance != lastProcessedDistance) {
Serial.println("Processing distance...");
lcd.setCursor(0, 1);
lcd.print(" "); // Clear the second line
if (lastProcessedDistance >= 0) { // Ensure lastProcessedDistance is valid
int quantityChange = abs(currentDistance - lastProcessedDistance) / 50 * 50;
if (quantityChange > 0) { // Ensure quantityChange is not zero
if (currentDistance > lastProcessedDistance) {
// Distance increased, remove stock
handleLED(ledRedPin);
lcd.setCursor(0, 1);
lcd.print("Removing Stock ");
Serial.println("Sending to server...");
sendToServer(SERVER_REMOVE_STOCK_URL.c_str(), quantityChange, "out", kode, latestCity.c_str()); // Send the city name
} else {
// Distance decreased, add stock
handleLED(ledGreenPin);
lcd.setCursor(0, 1);
lcd.print("Adding Stock ");
Serial.println("Sending to server...");
sendToServer(SERVER_ADD_STOCK_URL.c_str(), quantityChange, "in", kode, latestCity.c_str()); // Send the city name
}
} else {
lcd.setCursor(0, 1);
lcd.print("------- ");
}
} else {
handleLED(ledYellowPin);
lcd.setCursor(0, 1);
lcd.print("No Transaction ");
}
lastProcessedDistance = currentDistance;
Serial.println("Distance processed.");
}
// Display stock condition
if (currentDistance <= thresholdDistance) {
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledRedPin, LOW);
yellowLEDState = false;
digitalWrite(ledYellowPin, LOW);
lcd.setCursor(0, 1);
lcd.print("Stock Safe ");
} else {
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, LOW);
yellowLEDState = false;
digitalWrite(ledYellowPin, LOW);
lcd.setCursor(0, 1);
lcd.print("Stock Limit ");
}
// Blink yellow LED if expired
if (materialDate == "2024-07-14") { // Example condition for expiration
yellowLEDState = true;
lastBlinkTime = millis();
}
}
int getDistance(int trigPin, int echoPin) {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
long duration = pulseIn(echoPin, HIGH);
// Calculating the distance
int distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.println(distance);
return distance;
}
void sendToServer(const char* serverUrl, int quantity, String type, const char* kode, const char* kota) {
Serial.print("Sending to server: ");
Serial.println(serverUrl);
if (WiFi.status() == WL_CONNECTED) {
WiFiClientSecure client;
client.setInsecure(); // Disable SSL certificate verification
HTTPClient http;
http.begin(client, serverUrl);
http.addHeader("Content-Type", "application/json");
String payload;
payload = "{\"type\": \"" + type + "\", \"kode\": \"" + String(kode) + "\", \"quantity\": " + String(quantity) + ", \"kota\": \"" + String(kota) + "\"}";
Serial.print("Payload: ");
Serial.println(payload);
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("HTTP Response code: " + String(httpResponseCode));
Serial.println("Response: " + response);
} else {
Serial.println("Error on sending POST: " + String(httpResponseCode));
Serial.println(http.errorToString(httpResponseCode));
}
http.end();
} else {
Serial.println("WiFi Disconnected");
}
}
void handleLED(int ledPin) {
// Turn off all LEDs
digitalWrite(ledRedPinA, LOW);
digitalWrite(ledGreenPinA, LOW);
digitalWrite(ledYellowPinA, LOW);
digitalWrite(ledRedPinB, LOW);
digitalWrite(ledGreenPinB, LOW);
digitalWrite(ledYellowPinB, LOW);
// Turn on the specified LED
digitalWrite(ledPin, HIGH);
}
void getLatestCity() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(SERVER_GET_CITY_URL);
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("City fetched: " + response);
StaticJsonDocument<200> doc;
deserializeJson(doc, response);
if (doc.containsKey("latest_city")) {
latestCity = doc["latest_city"].as<String>();
Serial.println("Latest city: " + latestCity);
}
} else {
Serial.println("Error on HTTP request");
}
http.end();
} else {
Serial.println("WiFi Disconnected");
}
}