Page : | [ 1 ] | [ 2 ] | [ 3 ] | [ 4 ] | [ 5 ] |
Here's some simple code to dispay the time. This is pretty barebones and illustrates how to get this thing to display the time! Overall it's pretty straight forward :)
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <TimeLib.h>
#define PIN_LE 16 //Shift Register Latch Enable
#define PIN_CLK 17 //Shift Register Clock
#define PIN_DATA 19 //Shift Register Data
#define PIN_BL 18 //Shift Register Blank (0=display off 1=display on)
WiFiMulti wifiMulti;
const int timeZone = 16;
const int dst = 0;
// lookup tables for the high and low value of mins/sec to determine
// which number needs to be displayed on each of the minutes and seconds tubes
// e.g. if the clock is to diplay 26 minutes then it
// will look up the values at the 26th position and display a 2 on the high mins tube and a 6 on the low mins tube
const byte minsec_high[]= {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,11};
const byte minsec_low[] = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,11};
// lookup tables for the high and low value of hours to determine
// which number needs to be displayed on each of the tubes for the hour display
// it can handle if its 24hr display or not and also if a leading zeo is displayed
// the "10" values are to indicate if the leading zero is blanked or not since its outside the range of a normal digit of 0-9
const byte hour_high[2][2][24] = {{{1,10,10,10,10,10,10,10,10,10,1,1,1,10,10,10,10,10,10,10,10,10,1,1},{1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1}},{{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2},{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2}}};
const byte hour_low[2][2][24] = {{{2, 1, 2, 3, 4, 5, 6, 7, 8, 9,0,1,2, 1, 2, 3, 4, 5, 6, 7, 8, 9,0,1},{2,1,2,3,4,5,6,7,8,9,0,1,2,1,2,3,4,5,6,7,8,9,0,1}},{{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3},{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3}}};
volatile int show24hr = false;
volatile int leadingZero = false; // whether or not to show the
// leading zero when in 12 hour mode
// e.g. 7am would either show as 7 or 07
// shift register positions for each digit in each tube
// Digit 0 1 2 3 4 5 6 7 8 9
int tube1[] = {29, 28, 27, 26, 25, 24, 23, 32, 31, 30};
int tube2[] = {18, 17, 16, 15, 14, 13, 12, 22, 20, 19};
int tube3[] = { 7, 6, 5, 4, 3, 2, 1, 11, 9, 8};
int tube4[] = {60, 59, 58, 57, 56, 55, 54, 64, 62, 61};
int tube5[] = {49, 48, 47, 46, 45, 44, 43, 53, 51, 50};
int tube6[] = {39, 38, 37, 36, 35, 34, 33, 42, 41, 40};
// for future reference. the decimal point pins wired up are
// Tube 2 Left Side : shift register pos 21
// Tube 3 Left Side : shift register pos 10
// Tube 4 Left Side : shift register pos 63
// Tube 5 Left Side : shift register pos 52
// how many milliseconds the display will be on and off for
// this is for dimming.
// can control these values via some sort of analog input or through software.
volatile int onDuration = 4;
volatile int offDuration = 8;
// setting up the timer interrupt for blanking (dimming) the display
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile int interruptState = 0; // whether the display is in on state or off state
volatile int interruptCounter = 0; // for counting interrupts fired (milliseconds) between state changes
// the function called by the timer interrupt that handles the
// actual blanking. it keeps track of the state of the display (on or off)
// and handles the duration for that state accordingly
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
interruptCounter++;
if (interruptState == 0){
if (interruptCounter >= offDuration){
interruptState = !interruptState;
interruptCounter = 0;
digitalWrite(PIN_BL, HIGH);
}
} else {
if (interruptCounter >= onDuration){
interruptState = !interruptState;
interruptCounter = 0;
digitalWrite(PIN_BL, LOW);
}
}
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
pinMode(PIN_LE, OUTPUT);
pinMode(PIN_BL, OUTPUT);
pinMode(PIN_DATA,OUTPUT);
pinMode(PIN_CLK, OUTPUT);
digitalWrite(PIN_BL, LOW);
Serial.begin(115200);
wifiMulti.addAP("YOUR_ACCESS_POINT_SSID", "YOUR_WIFI_PASSWORD");
if(wifiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
}
// stuff for the timer interrupt (found this online somewhere!)
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 1000, true);
timerAlarmEnable(timer);
configTime(timeZone * 3600, dst * 0, "pool.ntp.org", "time.nist.gov");
Serial.println("\nWaiting for time");
while (!time(nullptr)) {
Serial.print(".");
delay(1000);
}
Serial.println("");
}
unsigned long previousSRMillis = 0; // keeping track last time shift register values were clocked in
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousSRMillis >= 250) { // clocking in 4 times a second
previousSRMillis = currentMillis;
boolean srBuffer[64] = {0};
time_t now;
struct tm * timeinfo;
time(&now);
timeinfo = localtime(&now);
int hours = timeinfo->tm_hour;
int seconds = timeinfo->tm_sec;
int minutes = timeinfo->tm_min;
// doing the lookups for what number to display then
// looking up which shift register position
// for each tube
// "10" from the lookup table indicates to blank the tube since it is out of range.
srBuffer[tube1[hour_high[show24hr][leadingZero][hours]] - 1] = (hour_high[show24hr][leadingZero][hours] == 10) ? 0 : 1;
srBuffer[tube2[hour_low[show24hr][leadingZero][hours]] - 1] = 1;
srBuffer[tube3[minsec_high[minutes]] - 1] = 1;
srBuffer[tube4[minsec_low[minutes]] - 1] = 1;
srBuffer[tube5[minsec_high[seconds]] - 1] = 1;
srBuffer[tube6[minsec_low[seconds]] - 1] = 1;
srBuffer[10 - 1] = 1; // tube 2 decimal point
srBuffer[52 - 1] = 1; // tube 5 decimal point
digitalWrite(PIN_LE, LOW);
for(int i = 63;i >= 0;i--){
digitalWrite(PIN_DATA,srBuffer[i]);
digitalWrite(PIN_CLK,HIGH);
delayMicroseconds(5);
digitalWrite(PIN_CLK,LOW);
delayMicroseconds(5);
}
digitalWrite(PIN_LE, HIGH);
}
}
(Page 5 of 5) | ||