#include <Adafruit_MLX90614.h>
#include <DS3231.h>
#include <WiFi.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
/*
This applicatioon is an accessory to the 3018 PRO CNC (DIY Version)
Using an esp32 WROOM-32 38 pin dev module in a side car configuration
it provides real time spindle RPM information as well as control for
the work table illumination and safety lighting. Also a running timer
keeps track of job times by monitoring spindle status.(to follow).
*/
//***********************************************************************
// DEFINES
//***********************************************************************
#define OFF 0
#define ON 1
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1// Reset pin # (or -1 if sharing Arduino reset pin)
#define OLED_ADDR 0x3C
#define IR_ADDR 0x5B // Normally this would be 0x5A, this MLX has been fixed to 0x5B.
const char *ssid = "******"; // add your network SSID here
const char *password = "***********"; // add your network password here
const long utcOffsetInSeconds = -14400;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char months[12][4] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
bool Century = false, h12, pm;
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
// GPIO Pin definitions
const int Touch8 = 33;
const int Touch9 = 32;
const int TACH_IN = 1;
const int WORK_LED = 12;
const int SPINDLE_ACTIVE_LED = 14;
const int FAN_MOTOR = 13;
const int DEMO_LED1 = 15;
const int DEMO_LED2 = 3;
const int I2C_FAST = 400000;
const int I2C_SLOW = 100000;
const int analogInPin = A0; // ESP32 Analog Pin ADC0 = A0
bool LAMP = false;
volatile byte REV; // VOLATILE DATA TYPE TO STORE REVOLUTIONS
int TouchValue8, TouchValue9, RPM, UP_TIME;
int TouchThreshold = 30;
double MOTOR_VOLTAGE;
double MOTOR_TEMP;
DS3231 Clock;
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_MLX90614 mlx = Adafruit_MLX90614(IR_ADDR);
byte Year;
byte Month;
byte Date;
byte DoW;
byte Hour;
byte Minute;
byte Second;
//***********************************************************************
// FUNCTIONS
//***********************************************************************
void InitPins() {
pinMode(TACH_IN, INPUT);
pinMode(WORK_LED, OUTPUT);
pinMode(DEMO_LED1, OUTPUT);
pinMode(DEMO_LED2, OUTPUT);
pinMode(SPINDLE_ACTIVE_LED, OUTPUT);
digitalWrite(WORK_LED, OFF);
digitalWrite(DEMO_LED1, OFF);
digitalWrite(DEMO_LED2, OFF);
}
void InitDisplay() {
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display1.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display1.clearDisplay();
display1.display();
Serial.println();
Serial.println("SSD1306 display OK and ready");
}
void InitIRSensor() {
Wire.setClock(I2C_SLOW);
mlx.begin();
delay(100);
Serial.println("IR Sensor ready");
Wire.setClock(I2C_FAST);
}
void ReadIRSensor() {
Wire.setClock(I2C_SLOW);
MOTOR_TEMP = mlx.readObjectTempC();
delay(50);
Wire.setClock(I2C_FAST);
}
void ReadTachometer() {
// init quarter sec timer loop - non blocking
int CM = millis();
int FM = millis() + 250;
REV = 0;
while (millis() < FM) {}
// .5 second is up
int COUNT = REV;
//count ticks
// RPM = ticks/2*240;
RPM = (COUNT / 2) * 240;
}
void ReadVoltage() {
double av = analogRead(analogInPin);
MOTOR_VOLTAGE = av * .0322256;
}
void JoinNetwork() {
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
display1.clearDisplay();
display1.setCursor(4, 4);
display1.print("ETMS");
display1.setCursor(64, 30);
display1.print("Connecting......");
display1.display();
}
timeClient.begin();
delay(50);
timeClient.update();
String current_time = timeClient.getFormattedTime();
display1.clearDisplay();
display1.display();
ShowWifi();
}
void InitTime() {
Clock.setClockMode(false); // set to 24h
Clock.setYear(Year);
Clock.setMonth(Month);
Clock.setDate(Date);
Clock.setDoW(DoW);
Clock.setHour(Hour);
Clock.setMinute(Minute);
Clock.setSecond(Second);
// Test of alarm functions
// set A1 to one minute past the time we just set the clock
// on current day of week.
//Clock.setA1Time(DoW, Hour, Minute+1, Second, 0x0, true, false, false);
// set A2 to two minutes past, on current day of month.
//Clock.setA2Time(Date, Hour, Minute+2, 0x0, false, false, false);
// Turn on both alarms, with external interrupt
//Clock.turnOnAlarm(1);
//Clock.turnOnAlarm(2);
}
void ShowTime() {
display1.fillRect(74, 0, display1.width(), 16, WHITE);
display1.setCursor(78, 4);
display1.setTextColor(BLACK); // Draw black text
display1.print(Clock.getHour(h12, pm));
display1.print(":");
if (Clock.getMinute() < 10) {
display1.print("0");
}
display1.print(Clock.getMinute());
display1.print(":");
if (Clock.getSecond() < 10) {
display1.print("0");
}
display1.print(Clock.getSecond());
display1.display();
}
void ShowRibbon() {
display1.setTextSize(1); // Large 1:1 pixel scale
display1.fillRect(0, 0, 74, 16, WHITE);
display1.setTextColor(BLACK); // Draw black text
display1.setCursor(4, 4);
display1.print("Spindle775");
display1.display();
}
void ShowWifi() {
String ip = WiFi.localIP().toString();
display1.setCursor(32, 16);
display1.print("Wifi connected...");
display1.setCursor(32, 32);
display1.print("IP Address:");
display1.setCursor(32, 48);
display1.print(ip);
display1.display();
delay(2000);
display1.clearDisplay();
display1.display();
}
void ShowPage1() {
Serial.print("show rpm -->");
Serial.println(RPM);
//send RPM to display
display1.setTextSize(1); // Large 1:1 pixel scale
display1.setTextColor(WHITE); // Draw white text
display1.setCursor(15, 20);
display1.print("RPM:");
display1.setCursor(60, 20);
display1.setTextSize(2); // Large 2:1 pixel scale for RPM value
display1.print(RPM);
display1.setCursor(20, 45);
display1.setTextSize(1); // Normal 1:1 pixel scale
Serial.println("show motor voltage->");
display1.print("Voltage:");
display1.fillRect(80, 45, 127, 60, BLACK);
display1.setCursor(80, 45);
display1.print(MOTOR_VOLTAGE);
display1.print(" V");
Serial.println("show motor temperature->");
display1.setCursor(20, 55);
display1.print("Temp:");
display1.fillRect(80, 55, 127, 60, BLACK);
display1.setCursor(80, 55);
display1.print(MOTOR_TEMP);
display1.display();
}
void FlashLED() {
digitalWrite(WORK_LED, ON);
delay(750);
digitalWrite(WORK_LED, OFF);
}
void SetWorkLight(int val) {
if (val = 0) digitalWrite(WORK_LED, OFF);
else digitalWrite(WORK_LED, ON);
}
void RPMCount() // EVERYTIME WHEN THE SENSOR GOES FROM LOW TO HIGH , THIS FUNCTION WILL BE INVOKED
{
REV++; // INCREASE REVOLUTIONS
}
void ToggleWorkLamp() {
Serial.print("set lamp->");
int touch_sensor_value = touchRead(T8);
Serial.print("Touch8 value is = ");
Serial.println( touch_sensor_value);
LAMP = !LAMP;
digitalWrite(WORK_LED, LAMP);
delay(100);
}
void setup() {
Serial.begin(19200);
InitPins();
InitDisplay();
FlashLED();
InitIRSensor();
JoinNetwork(); // goes online and gets Time from ntp
//attachInterrupt(digitalPinToInterrupt(TACH_IN), RPMCount, RISING); // ADD A HIGH PRIORITY ACTION ( AN INTERRUPT) WHEN THE SENSOR GOES FROM LOW TO HIGH
touchAttachInterrupt(T8, ToggleWorkLamp, TouchThreshold);
}
void loop() {
// put your main code here, to run repeatedly:
ShowTime();
ShowRibbon();
ReadVoltage();
//ReadTachometer();
ReadIRSensor();
ShowPage1();
if (RPM > 0) FlashLED();
delay(1000);
}
Comments