Created
November 6, 2019 11:08
-
-
Save somebox/53982aa0b38e804da79193437b9df2dc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include "ESP8266WiFi.h" | |
#include "SPI.h" | |
#include <NTPClient.h> | |
#include <WiFiUdp.h> | |
/* | |
A large four digit 7-segment LED clock, controlled by an ESP8266. | |
The LED modules are quite large, 5" tall, and require high voltage to drive the many | |
leds in series for each segment (12-14v). To do this, four shift registers are used in | |
series (TPIC6C596). These chips were purchased on breakout boards, based on a board | |
design by Sparkfun (https://learn.sparkfun.com/tutorials/large-digit-driver-hookup-guide/all). | |
It allows each digit of the large seven segments to be controlled with higer voltages. | |
As the ESP8266 is 3.3v logic, and the TPIC chip requires 5v logic, a level conversion was | |
required. A four channel 75HTC125N chip does the job here. | |
There are four connections to the ESP8266. Three for the shift register chips, and one | |
for the blinky dots (animated with PWM). | |
*/ | |
char ssid[] = "SSID"; | |
char pass[] = "mypassword"; | |
#define PIN_CLK D6 // Clock on the TPIC6C596 | |
#define PIN_LATCH D5 // Latch | |
#define PIN_DATA D7 // Serial data | |
#define PIN_DOTS D2 // Clock dots (colon) | |
#define PIN_BRIGHTNESS D4 // PWM Enable on TPIC6C596 | |
#define DISPLAY_SIZE 4 // Number of digits | |
WiFiClient wifi; | |
WiFiUDP ntpUDP; | |
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 7200, 600000); // proto, host, timeOffset, updateInterval | |
int number = 0; | |
int t = 0; | |
int hour = 0; | |
int minute = 0; | |
void log_status_info() | |
{ | |
Serial.print("ESP version: "); | |
Serial.println(ESP.getFullVersion()); | |
Serial.print(" flash size: "); | |
Serial.println(ESP.getFlashChipRealSize()); | |
Serial.print(" CPU MHz: "); | |
Serial.println(ESP.getCpuFreqMHz()); | |
Serial.print(" chip ID: "); | |
Serial.println(ESP.getChipId()); | |
Serial.print(" sketch size: "); | |
Serial.println(ESP.getSketchSize()); | |
} | |
void connect_to_wifi() | |
{ | |
Serial.print("Connecting to "); | |
Serial.println(ssid); | |
WiFi.mode(WiFiMode::WIFI_STA); | |
WiFi.begin(ssid, pass); | |
while (WiFi.status() != WL_CONNECTED) { | |
Serial.print("."); | |
//showNumber(t); | |
t++; | |
delay(20); | |
} | |
t=0; | |
Serial.println(); | |
Serial.println("WiFi connected"); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
Serial.print("MAC address: "); | |
Serial.println(WiFi.macAddress()); | |
Serial.print("RSSI: "); | |
Serial.print(WiFi.RSSI()); | |
Serial.println("db"); | |
delay(1000); | |
Serial.println("getting current time..."); | |
timeClient.begin(); | |
timeClient.update(); | |
Serial.println(timeClient.getFormattedTime()); | |
WiFi.mode(WiFiMode::WIFI_OFF); | |
} | |
//Given a number, or '-', shifts it out to the display | |
void postNumber(byte number, boolean decimal) | |
{ | |
// --- A | |
// / / F, B | |
// --- G | |
// / / E, C | |
// --- . D, DP | |
#define a 1<<0 | |
#define b 1<<6 | |
#define c 1<<5 | |
#define d 1<<4 | |
#define e 1<<3 | |
#define f 1<<1 | |
#define g 1<<2 | |
#define dp 1<<7 | |
byte segments = 0; | |
switch (number) | |
{ | |
case 1: segments = b | c; break; | |
case 2: segments = a | b | d | e | g; break; | |
case 3: segments = a | b | c | d | g; break; | |
case 4: segments = f | g | b | c; break; | |
case 5: segments = a | f | g | c | d; break; | |
case 6: segments = a | f | g | e | c | d; break; | |
case 7: segments = a | b | c; break; | |
case 8: segments = a | b | c | d | e | f | g; break; | |
case 9: segments = a | b | c | d | f | g; break; | |
case 0: segments = a | b | c | d | e | f; break; | |
case ' ': segments = 0; break; | |
case 'c': segments = g | e | d; break; | |
case '-': segments = g; break; | |
} | |
if (decimal) segments |= dp; | |
shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, segments); | |
//Clock these bits out to the drivers | |
// for (byte x = 0 ; x < 8 ; x++) | |
// { | |
// digitalWrite(PIN_CLK, LOW); | |
// digitalWrite(PIN_DATA, segments & 1 << (7 - x)); | |
// digitalWrite(PIN_CLK, HIGH); //Data transfers to the register on the rising edge of SRCK | |
// } | |
} | |
//Takes a number and displays 2 numbers. Displays absolute value (no negatives) | |
void showNumber(float value) | |
{ | |
int number = abs(value); | |
digitalWrite(PIN_LATCH, LOW); | |
// update all digits of the display | |
for (byte x = 0 ; x < DISPLAY_SIZE ; x++) | |
{ | |
int remainder = number % 10; | |
postNumber(remainder, false); | |
number /= 10; | |
} | |
//Latch the current segment data | |
digitalWrite(PIN_LATCH, HIGH); //Register moves storage register on the rising edge of RCK | |
} | |
void setup() | |
{ | |
Serial.begin(115200); | |
Serial.println("Large Digit Driver Example"); | |
pinMode(PIN_CLK, OUTPUT); | |
pinMode(PIN_DATA, OUTPUT); | |
pinMode(PIN_LATCH, OUTPUT); | |
pinMode(PIN_DOTS, OUTPUT); | |
pinMode(PIN_BRIGHTNESS, OUTPUT); | |
digitalWrite(PIN_CLK, LOW); | |
digitalWrite(PIN_DATA, LOW); | |
digitalWrite(PIN_LATCH, LOW); | |
log_status_info(); | |
connect_to_wifi(); | |
} | |
void blankDisplay(){ | |
digitalWrite(PIN_LATCH, LOW); | |
for (int i=0; i<4; i++){ | |
shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, 0); | |
} | |
digitalWrite(PIN_LATCH, HIGH); //Register moves storage register on the rising edge of RCK | |
} | |
int pmax = 100000; | |
int p = pmax; | |
int brightness = 0; | |
int bright_levels = 10; | |
bool debug = true; | |
int level = 0; | |
int last_level = 0; | |
int dot_level = 0; | |
void loop() | |
{ | |
if (p++ > pmax){ | |
hour = timeClient.getHours(); | |
minute = timeClient.getMinutes(); | |
p=0; | |
} | |
if (p % 3000 == 0){ | |
last_level = level; | |
brightness = analogRead(A0); | |
level = map(brightness, 50, 1024, 1024, 0); | |
level = last_level + (level - last_level)/30; // slew changes, avoid jumps | |
level = max(50, level); | |
level = min(1005, level); | |
analogWrite(PIN_BRIGHTNESS, level); | |
} | |
dot_level = abs(map(millis() % 2000, 0, 1999, -1023, 1023)); | |
analogWrite(PIN_DOTS, map(dot_level, 0, 1024, 0, 1024 - level * 0.9)); | |
if (p % 1000) { | |
showNumber(hour*100+minute); | |
} | |
if (debug && p % 1000 == 0) { | |
Serial.print(" sensor: "); | |
Serial.print(analogRead(A0)); | |
Serial.print(" level: "); | |
Serial.println(level); | |
} | |
//delayMicroseconds(100); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment