/*
*/
#include <stdio.h>
#include <stdint.h>
#include <ShiftRegister74HC595.h>
#include <Wire.h>
#include <RTClib.h>
#include <Timezone.h>
#include <WiFi.h>
#include <Arduino_MultiWiFi.h>
// define GPIO pins
#define sr595_dataPin 13 // Data pin of 74HC595 is connected to Digital pin 13 (DS/SER, chip pin 14)
#define sr595_latchPin 14 // Latch pin of 74HC595 is connected to Digital pin 14 (ST_CP/RCLK, chip pin 12)
#define sr595_clockPin 27 // Clock pin of 74HC595 is connected to Digital pin 27 (SH_CP/SRCLK, chip pin 11)
#define oePin 4 // Output enable pin
#define sr165_dataPin 5
#define sr165_latchPin 16
#define sr165_clockPin 17
#define sda 21
#define scl 22
//define pushbutton GPIOs
#define KEY1 18
#define KEY2 19
#define KEY3 21
#define KEY4 23
// global vars
uint8_t keyvalue=0;
uint8_t pb_value,old_pb_value,inputs_value,old_inputs_value;
char daysOfWeek[7][12] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
// time / clock object initialize
RTC_DS3231 rtc;
// define shift registers for output
// "ShiftRegister<number of registers> object(datapin,clockpin,latchpin)"
ShiftRegister74HC595<3> sr_595(13, 27, 14);
//===================== WiFi ===========================================================================
MultiWiFi multi;
void wifi_connect() {
// Configure the known networks (first one gets higher priority)
multi.add("Wokwi-GUEST","");
multi.add("ssid1", "password1");
multi.add("ssid2", "password2");
// Connect to the first available network
Serial.println("Connecting to wifi...");
multi.run();
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
}
Serial.println("Wifi connected");
}
//===================== NTP ===========================================================================
//===================== Sleep Timer ===========================================================================
//===================== Battery Monitor =========================================================================
//===================== display ===========================================================================
// Define the segment-patterns for 7-segment displays
byte digitOne[44] =
{
// GFEDCBA Segments 7-segment map:
0b00111111, // 0 "0" AAA
0b00000110, // 1 "1" F B
0b01011011, // 2 "2" F B
0b01001111, // 3 "3" GGG
0b01100110, // 4 "4" E C
0b01101101, // 5 "5" E C
0b01111101, // 6 "6" DDD
0b00000111, // 7 "7"
0b01111111, // 8 "8"
0b01101111, // 9 "9"
0b01110111, // 10 'A'
0b01111100, // 11 'b'
0b00111001, // 12 'C'
0b01011110, // 13 'd'
0b01111001, // 14 'E'
0b01110001, // 15 'F'
0b00111101, // 16 'G'
0b01110110, // 17 'H'
0b00110000, // 18 'I'
0b00001110, // 19 'J'
0b01110101, // 20 'K' Same as 'H'
0b00111000, // 21 'L'
0b00010101, // 22 'M' NO DISPLAY
0b01010100, // 23 'n'
0b00111111, // 24 'O'
0b01110011, // 25 'P'
0b01100111, // 26 'q'
0b01010000, // 27 'r'
0b01101101, // 28 'S'
0b01111000, // 29 't'
0b00111110, // 30 'U'
0b00111110, // 31 'V' Same as 'U'
0b00101010, // 32 'W' NO DISPLAY
0b01110110, // 33 'X' Same as 'H'
0b01101110, // 34 'y'
0b01011011, // 35 'Z' Same as '2'
0b00000000, // 36 ' ' BLANK
0b01000000, // 37 '-' DASH
0b10000000, // 38 '.' PERIOD
0b01100011, // 39 '*' DEGREE ..
0b00001000, // 40 '_' UNDERSCORE
};
void showCharacter(uint8_t digit, char character, bool dot) {
byte pattern=0;
byte pattern1;
// match functions for character to binary pattern table
if(character >= '0' && character <= '9') {
pattern = digitOne[character - '0'];
} else if (character >= 'A' && character <= 'Z') {
pattern = digitOne[character - 'A' + 10];
} else if (character >= 'a' && character <= 'z') {
pattern = digitOne[character - 'a' + 10];
} else if (character == ' ') {
pattern = digitOne[36];
} else if (character == '-') {
pattern = digitOne[37];
} else if (character == '.') {
pattern = digitOne[38];
} else if (character == '*') {
pattern = digitOne[39];
} else if (character == '_') {
pattern = digitOne[40];
}
if (dot==true) { //is decimal parameter set
pattern1=pattern|0x80; //change first bit to 1 for DP
} else {
pattern1=pattern; //character bits pattern
}
for (int i=8; i<=11; i++) { //turn off all digits
sr_595.set(i, HIGH);
}
for (int i=0; i<=7; i++) { //turn off all segments
sr_595.set(i,LOW);
}
sr_595.set(digit+8, LOW); //set digit register LOW to turn on
for(int i=7; i>=0; i--) { //loop through each bit
if(pattern1 & 0x80) { //does this digit have the decimal?
sr_595.set(i,HIGH); //yes, turn on DP
} else {
sr_595.set(i,LOW); //no, turn off DP
};
pattern1<<=1; //next bit
}
//usleep(10);
sr_595.set(digit+8, HIGH);
}
void setDisplay(const char text[]) {
int i=0;
int cnt;
for(cnt=0; cnt<=strlen(text)-1; cnt++) {
if(text[i+1]=='.'){ //peek ahead to see if next character is a dot
showCharacter(cnt,text[i],true); //set dot parameter to true
i++; //skip ahead to next character
} else {
showCharacter(cnt,text[i],false);
}
i++;
}
}
//===================== pushbuttons =============================================================================
uint8_t get_pushbuttons() {
uint8_t Value=0;
if(digitalRead(KEY1)==0){Value = 0x01;return Value;} //setDisplay("KEY1");return Value;}
if(digitalRead(KEY2)==0){Value = 0x02;return Value;} //setDisplay("KEY2");return Value;}
if(digitalRead(KEY3)==0){Value = 0x04;return Value;} //setDisplay("KEY3");return Value;}
if(digitalRead(KEY4)==0){Value = 0x08;return Value;} //setDisplay("KEY4");return Value;} else {return 0;}
}
//===================== input triggers ===========================================================================
uint8_t get_inputs(void) {
byte Temp={ B11111111 };
char name;
digitalWrite(sr165_latchPin, LOW);
delayMicroseconds(20);
digitalWrite(sr165_latchPin, HIGH);
Temp = shiftIn(sr165_dataPin, sr165_clockPin, MSBFIRST);
switch(Temp) {
case 0xfe: setDisplay("INP1");delay(1000); break;
//case 0xfd: setDisplay("INP2");break;
//case 0xfb: setDisplay("INP3");break;
//case 0xf7: setDisplay("INP4");break;
//case 0xef: setDisplay("INP5");break;
//case 0xdf: setDisplay("INP6");break;
//case 0xbf: setDisplay("INP7");break;
//case 0x7f: setDisplay("INP8");break;
default: break;
}
return Temp;
}
//===================== utility ===========================================================================
void printBin(byte aByte) {
for (int8_t aBit = 7; aBit >= 0; aBit--)
Serial.write(bitRead(aByte, aBit) ? '1' : '0');
}
//===================== clock ===========================================================================
unsigned long lastontime=millis();
char clockDisplay[5];
void displayClock() {
//unsigned long currentMillis=millis();
DateTime now = rtc.now();
if(now.second() %2 == 0) {
sprintf(clockDisplay,"%02u.%02u",now.hour(),now.minute()); // 13.00
} else {
sprintf(clockDisplay,"%02u%02u",now.hour(),now.minute()); // 1300
}
// send to display
Serial.println(clockDisplay);
setDisplay(clockDisplay);
}
//==============================================================================================================
void setup() {
Serial.begin(115200);
Serial.println("Booting; setup");
// setup pins ====
pinMode(oePin, OUTPUT);
pinMode(sr595_clockPin, OUTPUT);
pinMode(sr595_dataPin, OUTPUT);
pinMode(sr595_latchPin, OUTPUT);
pinMode(sr165_clockPin, OUTPUT);
pinMode(sr165_dataPin, INPUT);
pinMode(sr165_latchPin, OUTPUT);
pinMode(KEY1, INPUT_PULLUP);
pinMode(KEY2, INPUT_PULLUP);
pinMode(KEY3, INPUT_PULLUP);
pinMode(KEY4, INPUT_PULLUP);
digitalWrite(oePin, HIGH);
// turn off all shift register pins.
sr_595.setAllLow();
digitalWrite(oePin, LOW);
//rtc - ds3231 board ====
if (! rtc.begin()) {
Serial.println("RTC module is NOT found");
Serial.flush();
while (1);
}
// connect to known wifi AP(s)
Serial.println("Calling WiFi connect...");
wifi_connect();
}
void loop() {
/*
// output pin testing
// setting all pins at the same time to either HIGH or LOW
sr_595.setAllHigh(); // set all pins HIGH
Serial.println("All high");
delay(50);
//set digit pins low
for(int i=8; i<=11; i++) {
sr_595.set(i,LOW);
delay(100);
}
sr_595.setAllLow(); // set all pins LOW
Serial.println("all low");
delay(10);
// spin digits
//turn off digits
uint8_t digit,segs;
for(digit=8; digit<=11; digit++){
sr_595.set(digit, HIGH);
}
for(digit=8; digit<=8; digit++){
for(segs=0; segs<=5; segs++){
Serial.print(digit);
Serial.print(":");
Serial.println(segs);
sr_595.set(digit, LOW);
sr_595.set(segs, HIGH);
delay(5);
//sr_595.setAll(B00000000);
}
for(segs=0; segs<=5; segs++){
sr_595.set(segs,LOW);
}
sr_595.set(digit,HIGH);
}
/*
// setting single pins
for (int i = 0; i < 8; i++) {
Serial.print("set pin high; pin ");
Serial.println(i);
sr_595.set(i, HIGH); // set single pin HIGH
delay(100);
}
//
// set all pins at once SEGMENTS DIGITS RELAYS
uint8_t relays=B01010101;
uint8_t digits=B11110000;
uint8_t segments=B11111111;
uint8_t pinValues[] = { segments, digits, relays };
printf("Set all at once : SEGMENTS:%d\tDIGITS:%d\tRELAYS:%d\n",segments,digits,relays) ;
sr_595.setAll(pinValues);
delay(100);
// set pins without immediate update
sr_595.setNoUpdate(0, HIGH);
sr_595.setNoUpdate(3, HIGH);
sr_595.setNoUpdate(10, HIGH);
sr_595.setNoUpdate(23, LOW);
Serial.println("pin 0 high, pin 1 low, pin 10. pin 12 LOW");
// at this point of time, pin 0 and 1 did not change yet
sr_595.updateRegisters(); // update the pins to the set values
delay(100);
*/
// input pin testing
// get pushbuttons
// uint8_t pb_value;
// pb_value=get_pushbuttons();
// get input from 74HC165
pb_value=get_pushbuttons();
inputs_value=get_inputs();
//Serial.print("keys: ");
//printBin(pb_value);
//Serial.print(" inputs: ");
//printBin(inputs_value);
//Serial.println();
// time functions
displayClock();
}