/**************************************************************************
LogicHINO
**************************************************************************/
#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 -1 // Reset pin # (or -1 if sharing Arduino reset pin)
volatile Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// 6 pulsanti sulla porta B
#define UP 13
#define LF 12
#define RG 11
#define DW 10
#define MS 9
#define HO 8
// parola di stato dei 6 LSB bit della porta B
volatile byte portB_state=B00000000;
volatile byte portB_flag=false;
volatile byte least_one=false;
volatile byte portB_oldstate=B00000000;
//long start_mm, dtime;
int start_h=17, start_m=59, clk=53;
char *outstr;
char ch,outstr1[30];
void setup() {
outstr=&(outstr1[0]); // esercizio sui puntatori
PCICR = B00000000; // No Change pin interrupt
Serial.begin(9600);
//Wire.begin();
//Wire.setClock(400000L); // velocità dell' i2c
// 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.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
// Clear the buffer
display.clearDisplay();
pinMode(UP, INPUT_PULLUP);
pinMode(LF, INPUT_PULLUP);
pinMode(RG, INPUT_PULLUP);
pinMode(DW, INPUT_PULLUP);
pinMode(MS, INPUT_PULLUP);
pinMode(HO, INPUT_PULLUP);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
display.write("START");
display.display();
delay(300);
display.clearDisplay();
display.setCursor(6,0);
PORTD = B11111100;
delay(300);
PORTD &= B10000100;
delay(300);
PORTD &= B00000000;
start_h=17;
start_m=59;
clk=53;
write_list();
display.setTextSize(1);
portB_state=B00000000;
PCICR |= B00000001; //Bit0 = 1 -> "PCIE0" enabeled (PCINT8 to PCINT13)
PCMSK0 |= B00111111;
}
void write_list (void)
{ /* questa funzione scrive le "8" righe che terminano con OUTmode */
display.setTextColor(SSD1306_WHITE);
for (int i=0;i<6;i++)
{ display.setCursor(0,(i+1)*8);
sprintf(outstr,"%2d ",i+1);
display.print(outstr);
}
for (int i=0;i<68;i+=6)
{ display.setCursor(i+36,48);
sprintf(outstr,"%1d",(i/6)%10);
display.print(outstr);
}
sprintf(outstr,"chanel");
display.setTextColor(SSD1306_WHITE);
display.setCursor(48,40);
display.print(outstr);
sprintf(outstr,"%c",219);
display.setTextColor(SSD1306_WHITE);
display.setCursor(36,56);
display.print(outstr);
display.display();
}
void clock(void)
{ /* questa funzione simula la stampa dell'orario corrente nella prima riga */
// cancella orario precedete
display.setCursor(76, 0);
display.setTextColor(SSD1306_BLACK);
sprintf(outstr,"%02d:%02d:%02d",start_h,start_m,clk);
display.print(outstr);
// cambio del minuto
if(clk==59) {
// cambio dell'ora
if(start_m==59){
if(start_h==23) start_h=0;
else start_h++;
start_m=-1;
}
start_m++;
clk=-1;
}
// incremento dei secondi
clk++;
// stampa nuovo orario
display.setCursor(76, 0);
display.setTextColor(SSD1306_WHITE);
sprintf(outstr,"%02d:%02d:%02d",start_h,start_m,clk);
display.print(outstr);
display.display();
}
ISR (PCINT0_vect)
//PCIFR = B00000001; non serve
{ /* N = valore dec dei 6 LSB della porta B
li shifto di 2 bit a sinistra (moltiplico Nx4)
calcolo PORTD=252-Nx4
in modo tale che se pin13(12,11,10,9,8) è messo a massa
allora il led pin7(6,5,4,3,2,1) si accenda
Se PORTD !=0 ho premuto uno dei 6 tasti
si è acceso il relativo led e
memorizzo il valore dec nella parola di stato:
portB_state
*********************************************************/
PORTD = 252 - ( (PINB & B00111111) << 2);
/* PINB è normalmente alto e si attiva quando uno dei suoi pin
viene messo a massa
PORTB invece funziona in logica negata e quindi occorre fare
il complemento ad 1 dei 6 MSB
*/
portB_state=PORTD;
if (PORTD!=portB_oldstate)
{ /* la porta B ha cambiato stato
//portando almeno un bit ad 1
*/
portB_flag=true;
least_one=true;
}
else
{ /* la porta B ha cambiato stato
portando tutti i suoi bit a zero
*/
portB_flag=false;
}
}
int chanel_flag=1;
void loop()
{
static long now,last;
static int k=3;
int i,num;
byte tmpbyte=B10000000;
char tmpch[2]={219,0};
static int chanel=0, old_chanel;
// K va inizializzato con l'unità in secondi dello start
//PORTD |=0b00111111;
//se è cambiata la parola di stato;
if(portB_flag || least_one)
{ // num=6-int(log10(portB_state>>2)/log10(2)+0.01);
least_one=false;
// stampa il codice numerico della parola di stato
display.setTextColor(SSD1306_BLACK);
display.setCursor(104,10);
sprintf(outstr,"%c%c%c",219,219,219);
display.print(outstr);
display.setCursor(74,20);
sprintf(outstr,"%c%c%c%c%c%c%c%c",219,219,219,219,219,219,219,219);
display.print(outstr);
for(i=0;i<8;i++,outstr++)
{
if(portB_state&tmpbyte)
{ *outstr=49;
display.setTextColor(SSD1306_WHITE);
}
else
{ *outstr=48;
display.setTextColor(SSD1306_BLACK);
}
display.setCursor(20,(i+1)*8);
display.print(tmpch);
tmpbyte=tmpbyte>>1;
}
display.setTextColor(SSD1306_WHITE);
outstr=&(outstr1[0]);
display.setCursor(74,20);
display.print(outstr);
display.setCursor(104,10);
sprintf(outstr,"%3d",portB_state);
display.print(outstr);
/*
// stampa un quadratino sull'ultima colonna
// per memorizzare l'ultimo tasto premuto
// +0.01 serve a compensare un errore di log10()
sprintf(outstr,"%c",219);
display.setTextColor(SSD1306_BLACK);
display.setCursor(20,(6-int(log10(portB_oldstate>>2)/log10(2)+0.01))*8);
display.print(outstr);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20,num*8);
display.print(outstr);
portB_oldstate=portB_state;
if(chanel_flag)
{
switch(num)
{
case 5:
chanel_flag=0;
sprintf(outstr,"%c",219);
display.setTextColor(SSD1306_BLACK);
display.setCursor(chanel*6+36,56);
display.print(outstr);
chanel--;
if(chanel<0)chanel=0;
display.setTextColor(SSD1306_WHITE);
display.setCursor(chanel*6+36,56);
display.print(outstr);
break;
case 6:
chanel_flag=0;
sprintf(outstr,"%c",219);
display.setTextColor(SSD1306_BLACK);
display.setCursor(chanel*6+36,56);
display.print(outstr);
chanel++;
if(chanel>11)chanel=11;
display.setTextColor(SSD1306_WHITE);
display.setCursor(chanel*6+36,56);
display.print(outstr);
break;
default:
break;
}
}
*/
}
else
{ chanel_flag=1;
/*
// stampa il codice numerico della parola di stato
display.setTextColor(SSD1306_BLACK);
display.setCursor(104,0);
sprintf(outstr,"%3d",num);
display.print(outstr);
*/
// stampa un quadratino sull'ultima colonna
// per memorizzare l'ultimo tasto premuto
// +0.01 serve a compensare un errore di log10()
sprintf(outstr,"%c",219);
display.setTextColor(SSD1306_BLACK);
display.setCursor(20,num*8);
display.print(outstr);
}
display.display();
portB_oldstate=portB_state;
// simulatore RTC
now=millis(); // sostituire con timer di 1 sec
if( (now-last) > 500L) {
clock();
//chanel_flag=1; // timer ogni 333ms
last=now;
k++;
}
}