#include <WiFi.h>
#include "time.h"
#include "esp_sntp.h"
const char* ssid = "username";
const char* password = "password";
unsigned long reconnect_count = 0;
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 0;
unsigned long epochTime;
// Please tune the following value if the clock gains or loses.
// Theoretically, standard of this value is 60000.
#define MILLIS_PER_MIN 60000 // milliseconds per a minute
// Motor and clock parameters
// 4096 * 90 / 12 = 30720
#define STEPS_PER_ROTATION 30720 // steps for a full turn of minute rotor
// wait for a single step of stepper
int delaytime = 2;
// ports used to control the stepper motor
// if your motor rotate to the opposite direction,
// change the order as {2, 3, 4, 5};
//int port[4] = {5, 4, 3, 2};
//int port[4] = {19, 18, 5, 17};
int port[4] = {17, 5, 18, 19};
// sequence of stepper motor control
int seq[8][4] = {
{ LOW, HIGH, HIGH, LOW},
{ LOW, LOW, HIGH, LOW},
{ LOW, LOW, HIGH, HIGH},
{ LOW, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, LOW},
{ HIGH, HIGH, LOW, LOW},
{ LOW, HIGH, LOW, LOW}
};
void rotate(int step) {
static int phase = 0;
int i, j;
int delta = (step > 0) ? 1 : 7;
int dt = 20;
step = (step > 0) ? step : -step;
for(j = 0; j < step; j++) {
phase = (phase + delta) % 8;
for(i = 0; i < 4; i++) {
digitalWrite(port[i], seq[phase][i]);
}
delay(dt);
if(dt > delaytime) dt--;
}
// power cut
for(i = 0; i < 4; i++) {
digitalWrite(port[i], LOW);
}
}
void Wifi_connected (WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.println("ESP32 WIFI Connected to Access Point");
}
void Get_IPAddress(WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.println("WIFI Connected!");
Serial.println("IP address of Connected WIFI: ");
Serial.println(WiFi.localIP());
}
void Wifi_disconnected (WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.println("Disconnected from WIFI");
Serial.print("Connection Lost Reason:");
Serial.println(info.disconnected.reason);
Serial.println("Reconnecting...");
reconnect_count ++;
if (reconnect_count % 50 == 0) {
ESP.restart();
}
WiFi.begin(ssid, password);
WiFi.setSleep(true);
setCpuFrequencyMhz(240);
}
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup() {
Serial.begin(115200);
WiFi.disconnect(true);
delay(1000);
WiFi.onEvent(Wifi_connected, SYSTEM_EVENT_STA_CONNECTED);
WiFi.onEvent(Get_IPAddress, SYSTEM_EVENT_STA_GOT_IP) ;
WiFi.onEvent(Wifi_disconnected, SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.begin(ssid, password);
Serial.println("Waiting for WIFI network...");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
pinMode(port[0], OUTPUT);
pinMode(port[1], OUTPUT);
pinMode(port[2], OUTPUT);
pinMode(port[3], OUTPUT);
rotate(-20); // for approach run
rotate(20); // approach run without heavy load
rotate(STEPS_PER_ROTATION / 60);
}
// Function that gets current epoch time
unsigned long getTime() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
//Serial.println("Failed to obtain time");
return(0);
}
time(&now);
return now;
}
boolean init_loop = false;
long epochMinutes = 0;
void loop() {
// https://randomnerdtutorials.com/epoch-unix-time-esp32-arduino/
while (!init_loop) {
epochMinutes = getTime() / 60;
if (epochMinutes > 0) {
Serial.print("Epoch Time: ");
Serial.println(epochTime);
init_loop = true;
}
delay(1000);
}
//static long prev_min = 0, prev_pos = 0;
static long prev_min = epochMinutes, prev_pos = (STEPS_PER_ROTATION * prev_min) / 60;;
long min;
static long pos;
//min = millis() / MILLIS_PER_MIN;
min = getTime() / 60;
//Serial.print("Min: ");
//Serial.println(min);
if(prev_min == min) {
return;
}
prev_min = min;
pos = (STEPS_PER_ROTATION * min) / 60;
rotate(-20); // for approach run
rotate(20); // approach run without heavy load
if(pos - prev_pos > 0) {
rotate(pos - prev_pos);
}
prev_pos = pos;
}