/**************************************************************************
https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts
FreeMono12pt7b.h FreeSansBoldOblique12pt7b.h FreeMono18pt7b.h FreeSansBoldOblique18pt7b.h
FreeMono24pt7b.h FreeSansBoldOblique24pt7b.h FreeMono9pt7b.h FreeSansBoldOblique9pt7b.h
FreeMonoBold12pt7b.h FreeSansOblique12pt7b.h FreeMonoBold18pt7b.h FreeSansOblique18pt7b.h
FreeMonoBold24pt7b.h FreeSansOblique24pt7b.h FreeMonoBold9pt7b.h FreeSansOblique9pt7b.h
FreeMonoBoldOblique12pt7b.h FreeSerif12pt7b.h FreeMonoBoldOblique18pt7b.h FreeSerif18pt7b.h
FreeMonoBoldOblique24pt7b.h FreeSerif24pt7b.h FreeMonoBoldOblique9pt7b.h FreeSerif9pt7b.h
FreeMonoOblique12pt7b.h FreeSerifBold12pt7b.h FreeMonoOblique18pt7b.h FreeSerifBold18pt7b.h
FreeMonoOblique24pt7b.h FreeSerifBold24pt7b.h FreeMonoOblique9pt7b.h FreeSerifBold9pt7b.h
FreeSans12pt7b.h FreeSerifBoldItalic12pt7b.h FreeSans18pt7b.h FreeSerifBoldItalic18pt7b.h
FreeSans24pt7b.h FreeSerifBoldItalic24pt7b.h FreeSans9pt7b.h FreeSerifBoldItalic9pt7b.h
FreeSansBold12pt7b.h FreeSerifItalic12pt7b.h FreeSansBold18pt7b.h FreeSerifItalic18pt7b.h
FreeSansBold24pt7b.h FreeSerifItalic24pt7b.h FreeSansBold9pt7b.h FreeSerifItalic9pt7b.h
**************************************************************************/
//#include <SPI.h> // protocollo SPI alternativo al i2c
#include <Wire.h> // protocollo i2c per settare ad esempio la velocità
#include <Adafruit_GFX.h> // font
#include <Adafruit_SSD1306.h>
#include <stdio.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int start_h=15, start_m=04, clk=53;
char outstr[30];
#define led1 11 // led 1 sulla porta 13
#define led2 8 // led 2 sulla porta 4
#define led3 4
#define button 3 // pulsante sulla porta 3
volatile bool buttonState;
volatile bool state=false;
volatile long counter=0L,start=0L,stop=0L;
void rising_count() {
// interrupt
stop=millis();
attachInterrupt(digitalPinToInterrupt(button),count,FALLING);
}
void count() {
// interrupt
start=millis();
attachInterrupt(digitalPinToInterrupt(button),rising_count,RISING);
counter++;
}
void setup() {
Serial.begin(9600);
//Wire.begin();
//Wire.setClock(400000L); // velocità dell' i2c
// 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(); // cancella il logo iniziale di Adafruit
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(led3,OUTPUT);
pinMode(button,INPUT_PULLUP);
cli(); // Nointerrupt
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 << CS12)|(1 << CS10); //(1 << CS11)|(1 << CS10);
TCCR1B |= (1 << WGM10);
//TCCR1B |= (1 << WGM12); //CTC con CTC non si accende il led1
OCR1A = 37000;
OCR1B = 26000;
TIMSK1 |= (1 << OCIE1B);
TIMSK1 |= (1 << OCIE1A);
//TCNT1=0;
TIMSK1 |= (1 << TOIE1);
sei(); // ok interrupt
attachInterrupt(digitalPinToInterrupt(button),count,FALLING);
// START
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
delay(300);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
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();
delay(300);
display.clearDisplay();
// READY
display.setTextSize(1); // Normal 1:1 pixel scale
display.setCursor(6,0);
display.print("COUNTER");
display.setCursor(80, 24);
display.setTextColor(SSD1306_WHITE);
display.print("00000");
reset_watch();
digitalWrite(led1,HIGH);
}
ISR(TIMER1_COMPB_vect) {
state =2;
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
digitalWrite(led3,LOW);
}
ISR(TIMER1_COMPA_vect) {
state =3;
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
}
ISR(TIMER1_OVF_vect) {
state =1;
digitalWrite(led1,HIGH);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
/* assegnando a TCNT1 un valore maggiore di zero
DOPO IL RESET di overflow NON RIPARTE DA ZERO
ma dal valore assegnato a TCNT1 */
//TCNT1=15000;
}
void reset_watch (void){
// simula inizializzazione del RTC
start_h=17;
start_m=59;
clk=53;
}
void clock(void)
{
// cancella vecchio orario
display.setCursor(80, 0);
display.setTextColor(SSD1306_BLACK);
sprintf(outstr,"%02d:%02d:%02d",start_h,start_m,clk);
display.print(outstr);
// simula RTC
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++;
// stampa orario aggiornato
display.setCursor(80, 0);
display.setTextColor(SSD1306_WHITE);
sprintf(outstr,"%02d:%02d:%02d",start_h,start_m,clk);
display.print(outstr);
display.display();
}
void loop() {
static long now,last,old_counter=0;
static int k=0;
if((stop-start)>1200)
{ stop=0L;
start=0L;
counter=0L;
}
if(counter!=old_counter)
{
display.setCursor(80, 24);
display.setTextColor(SSD1306_BLACK);
sprintf(outstr,"%05d",old_counter);
display.print(outstr);
display.setCursor(80, 24);
display.setTextColor(SSD1306_WHITE);
sprintf(outstr,"%05d",counter);
display.print(outstr);
old_counter=counter;
display.display();
}
// aggiorna orario sul display ogni 1000ms
// meglio farlo con un timer
now=millis();
if( (now-last) > 1000L)
{ clock();
last=now;
k++;
// funzione di debug
if(k==900)
{ // ogni 15 minuti resetta l'orologio
k=0;
reset_watch();
} }
}