#include <MD_MAX72xx.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"
// WiFi credentials
const char* ssid = "yourSSID";
const char* password = "yourPASSWORD";
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Define MAX7219 parameters
#define MAX_DEVICES 4
#define CLK_PIN 19
#define DATA_PIN 23
#define CS_PIN 18
// Specify the correct module type for your MAX7219 module
#define MODULE_TYPE MD_MAX72XX::PAROLA_HW
// Create a new instance of the MD_MAX72XX class
MD_MAX72XX mx = MD_MAX72XX(MODULE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// RTC object
RTC_DS1307 RTC;
char days[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Sensor pins
const int photoelectricPin = 32;
const int laserInterruptPin = 33;
const int resetCountPin= 2;
//Output pins
const int mechCounterPin =13;
const int buzzerPin=12;
// Object counter
int objectCount = 0;
DateTime now;
void setup() {
Serial.begin(115200);
Serial.println("Hello");
/* // Start WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print("hello.");
}
Serial.println("\nWiFi connected.");
*/
// Initialize RTC
if (!RTC.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
//Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
delay(1000);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(30, 20);
// Display static text;
display.println("RTC");
display.display();
//delay(3000);
display.clearDisplay();
// Initialize LED Matrix
mx.begin();
mx.control(MD_MAX72XX::TEST, true);
delay(200);
mx.control(MD_MAX72XX::TEST, false);
mx.control(MD_MAX72XX::INTENSITY, 5);
// Initialize pins
pinMode(photoelectricPin, INPUT_PULLUP);
pinMode(laserInterruptPin, INPUT_PULLUP);
pinMode(mechCounterPin, OUTPUT);
pinMode(resetCountPin, INPUT_PULLUP);
pinMode(buzzerPin, OUTPUT);
}
int pflag=0;// is the flag to say photoelectric sensor is armed
int stuckflag=0; //this is the stuck flag when both sensors are on
int laserflag=0; // this is the laser trigger flag
void loop() {
//checkstuck();
if (digitalRead(resetCountPin)== LOW) {
objectCount=0; // reset count
updateLEDMatrix(); // Update LED matrix display
sendToOled(); //update OLED
}
if ((digitalRead(photoelectricPin) == LOW) && pflag==0 && stuckflag==0) {
delay(50); // Debounce delay
pflag=1; // is the flag to say photoelectric sensor is triggered
}
// if (digitalRead(photoelectricPin) == LOW) {
if ((digitalRead(laserInterruptPin) == LOW) && pflag==1 && stuckflag==0 && laserflag==0) {
laserflag=1;
}
if (pflag ==1 && laserflag ==1 && stuckflag==0){
objectCount++;
now = RTC.now(); // Get current time
updateLEDMatrix(); // Update LED matrix display
sendToOled(); //update OLED
sendToCounter(); // pulse the mechanical counter
// sendDataToServer();
delay(100); // Adjust for object passing time
pflag=0; //reset the photoelectric sensor flag is armed
laserflag=0; //reset the laser sensor flag
}
checkstuck();
sendToOled();
}
void checkstuck() {
if ((digitalRead(laserInterruptPin) == LOW) && (digitalRead(photoelectricPin) == LOW) ) {
stuckflag=1; //both sensors are stuck then arm the stuck flag bit
soundBuzzer();
}
if ((digitalRead(laserInterruptPin) == HIGH) || (digitalRead(photoelectricPin) == HIGH) ) {
stuckflag=0; //reset the stuck flag bit
}
}
void updateLEDMatrix() {
mx.clear();
mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF); // Turn off automatic updates
char buf[10];
snprintf(buf, sizeof(buf), "%4d", objectCount);
int bufLen = strlen(buf);
// Calculate starting position for right-aligned text and shift left by 4 pixels
int startPos = MAX_DEVICES * 8 - bufLen * 8 + 4;
for (int i = 0; i < bufLen; i++) {
// Place each character starting from the rightmost position
mx.setChar(startPos + i * 8, buf[bufLen - 1 - i]);
}
//Serial.print(objectCount);
Serial.println(objectCount);
// Serial.print(pflag);
mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::ON); // Turn on automatic updates
mx.update();
}
void sendDataToServer() {
// Send data to server every 10 seconds
static unsigned long lastTime = 0;
if ((WiFi.status() == WL_CONNECTED) && (millis() - lastTime > 10000)) {
lastTime = millis();
WiFiClient client;
HTTPClient http;
http.begin(client, "http://example.com/update"); // Replace with your server URL
http.addHeader("Content-Type", "application/json");
char timeStr[20];
snprintf(timeStr, 20, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
String httpRequestData = "{\"count\":" + String(objectCount) + ",\"time\":\"" + timeStr + "\"}";
int httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
} else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end();
}
}
void sendToOled(){
DateTime now = RTC.now();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print(now.day());
display.print('/');
display.print(now.month());
display.print('/');
display.print(now.year());
display.print('-');
display.println(days[now.dayOfTheWeek()]);
display.println(' ');
display.setCursor(15, 14);
display.setTextSize(2);
if (now.hour() < 10)
display.print('0');
display.print(now.hour());
display.print(':');
if (now.minute() < 10)
display.print('0');
display.print(now.minute());
display.print(':');
if (now.second() < 10)
display.print('0');
display.println(now.second());
display.setCursor(5, 34);
display.setTextSize(4);
display.print(objectCount);
display.drawLine(1,33,127,33, SSD1306_WHITE);
display.drawLine(1,33,1,63, SSD1306_WHITE);
display.drawLine(127,33,127,63, SSD1306_WHITE);
display.drawLine(1,63,127,63, SSD1306_WHITE);
display.display();
}
void sendToCounter() {
digitalWrite(mechCounterPin, HIGH);
delay(100);
digitalWrite(mechCounterPin, LOW);
}
void soundBuzzer() {
digitalWrite(buzzerPin, HIGH); //Keep buzzer off
delay(200);
digitalWrite(buzzerPin, LOW); //Keep buzzer on
delay(50);
}