/*
Note
wokwi
1) permit to supply external devices using +5V PIN
it is not possible in real cases
2) don't permit the use resistor partitores
3) see https://docs.wokwi.com/parts/board-ssd1306
4) ...... see all wokwi advices and instructions .....
Max Korrad Team
https://www.facebook.com/groups/883620498953478
*/
#include <stdio.h>
#include <Wire.h> // protocollo i2c per settare ad esempio la velocità
#include <Adafruit_GFX.h> // font
#include <Adafruit_SSD1306.h>
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#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)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define reset_interrup -2
#define wait_interrupt -1
#define button_st 4
#define button_up 3
#define button_dw 2
volatile int new_state=-1;
volatile int state=0;
volatile bool up=false, dw=false;
int old_state=0;
void call_up() {
// call interrupt
detachInterrupt(digitalPinToInterrupt(button_up));
up=true;
new_state=state+1;
}
void call_dw() {
// call interrupt
detachInterrupt(digitalPinToInterrupt(button_dw));
dw=true;
new_state=state-1;
}
//long int blink_duration = 300;
int start_h=00, start_m=00, clk=53;
char outstr[30];
void reset_watch (void) {
// RTC setup simulation
start_h=00;
start_m=00;
clk=53;
}
void clock(void) {
// clear
display.setTextSize(2); // 2:1 pixel scale
display.setCursor(25, 0);
display.setTextColor(SSD1306_BLACK);
sprintf(outstr,"%02d:%02d:%02d",start_h,start_m,clk);
display.print(outstr);
// tic RTC simulation
if(clk==59) {
if(start_m==59) {
if(start_h==23) start_h=0;
else start_h++;
start_m=-1;
}
start_m++;
clk=-1;
}
clk++;
// print
display.setCursor(25, 0);
display.setTextColor(SSD1306_WHITE);
sprintf(outstr,"%02d:%02d:%02d",start_h,start_m,clk);
display.print(outstr);
display.display();
}
ISR(TIMER1_COMPB_vect) {
digitalWrite(8,HIGH);
digitalWrite(9,HIGH);
}
ISR(TIMER1_COMPA_vect) {
state =3;
digitalWrite(8,LOW);
digitalWrite(9,LOW);
}
ISR(TIMER1_OVF_vect) {
digitalWrite(8,HIGH);
digitalWrite(9,LOW);
/* with TCNT1 > 0 timer1 will start from this value e not zero*/
//TCNT1=15000;
}
void setup() {
Serial.begin(9600); // initialize the serial port:
//cli(); // Nointerrupt
/*
{
"type": "wokwi-ssd1306",
"id": "ssd1306",
"top": -112.62,
"left": 1.39,
"attrs": { "i2c-address": "0x3D" }
},
[ "uno:5V", "ssd1306:VIN", "red", [ "v19.24", "h-165.59", "v-423.92", "h287.17" ] ],
[ "ssd1306:DATA", "uno:A4.2", "violet", [ "v-21.61", "h-362.75", "v188.24", "h86.53" ] ],
[ "ssd1306:CLK", "uno:A5.2", "blue", [ "v-28.64", "h-379.26", "v198.94", "h84.04" ] ],
[ "ssd1306:GND", "btn1:1.r", "black", [ "v-34.74", "h59.57", "v163.2", "h-0.08", "v15.48" ] ],
{ "type": "board-ssd1306", "id": "oled1", "top": -16.91, "left": -128.06, "attrs": {} },
[ "oled1:VCC", "uno:5V", "red", [ "v-32.43", "h77.3", "v289.31", "h-276.71" ] ],
[ "oled1:SCL", "uno:A5", "blue", [ "v-23.09", "h61.81", "v267.45", "h-175.17" ] ],
[ "oled1:SDA", "uno:A4", "purple", [ "v-13.09", "h46", "v226.46", "h-178.69" ] ],
[ "oled1:GND", "btn1:2.l", "black", [ "v-18.78", "h-48.49", "v-76.54" ] ],
*/
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 << CS11); //(1 << CS11)|(1 << CS10);(1 << CS12)|
TCCR1B |= (1 << WGM10);
//TCCR1B |= (1 << WGM12); //CTC : with CTC led1 don't work
OCR1A = 37000;
OCR1B = 26000;
TIMSK1 |= (1 << OCIE1B);
TIMSK1 |= (1 << OCIE1A);
TCNT1=0;
TIMSK1 |= (1 << TOIE1);
/* */
// Display setup
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.clearDisplay(); // no logo
pinMode(button_st,INPUT_PULLUP);
pinMode(button_up,INPUT_PULLUP);
pinMode(button_dw,INPUT_PULLUP);
pinMode( 8,OUTPUT);
pinMode( 9,OUTPUT);
pinMode(13,OUTPUT);
//PORTB|=B00100000;
//PORTB&=B11100000;
display.setTextSize(2); // 2:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(36, 22); // top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
display.write("START");
display.display();
// Abilita interrupt
attachInterrupt(digitalPinToInterrupt(button_up),call_up,FALLING);
attachInterrupt(digitalPinToInterrupt(button_dw),call_dw,FALLING);
int new_state=-1; // numero trasmesso
int state=0;
bool up=false, dw=false;
int old_state=0;
//Serial.println(state);
display.setTextColor(SSD1306_BLACK); // Draw white text
display.setCursor(36, 22); // top-left corner
display.write("START");
delay(800);
digitalWrite(13, LOW);
display.setTextSize(4); // 4:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(56, 20); // top-left corner
display.write("0");
display.display();
sei(); // ok interrupt
}
void loop() {
bool start_flag=false;
static unsigned long now,last=0L; // clock
static int i,k=0; // tic clock x funzione reset_watch di debug
// CTR simulation (each one can choice if introduce the CTR or not)
now=millis();
if( (now-last) > 1000)
{
clock();
last=now;
// only for debug
k++;
if(k==600)
{ // reset abaut each 30 minutes
k=1;
reset_watch();
} }
if(!start_flag)
{
// start_flag=true;
}
switch(new_state)
{ case reset_interrup:
if(state!=old_state)
{ digitalWrite(13, HIGH);
// during LED13 .....
display.setTextSize(4); // 2:1 pixel scale
display.setTextColor(SSD1306_BLACK); // Draw white text
display.setCursor(56, 20); // top-left corner
display.write(old_state+48);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(56, 20); // top-left corner
display.write(state+48);
display.display();
old_state=state;
}
//debouncing
if( (PIND&B00001000) && (PIND&B00000100)) delay(200);
//reset
if( (PIND&B00001000) && (PIND&B00000100))
{
if (up && state<5)
{ attachInterrupt(digitalPinToInterrupt(button_up),call_up,FALLING);
up=false;
}
{ attachInterrupt(digitalPinToInterrupt(button_dw),call_dw,FALLING);
if (dw && state>0)
dw=false;
}
new_state=wait_interrupt;
digitalWrite(13, LOW);
}
break;
case wait_interrupt:
// wait state
// aspetto un click
break;
case 0:
new_state=reset_interrup;
old_state=state;
state=0;
break;
case 1:
new_state=reset_interrup;
old_state=state;state=1;
break;
case 2:
new_state=reset_interrup;
old_state=state;state=2;
break;
case 3:
new_state=reset_interrup;
old_state=state;state=3;
break;
case 4:
new_state=reset_interrup;
old_state=state;state=4;
break;
case 5:
new_state=reset_interrup;
old_state=state;state=5;
break;
case 6:
new_state=reset_interrup;
old_state=state;
break;
default:
new_state=reset_interrup;
break;
}
}
// Max KORRAD Team
// FB: Elettronica Hobby Arduino https://www.facebook.com/groups/883620498953478