//---------------------------------------------
//ATtiny85 - DS3231 RTC Read Time, Date & Temp
//---------------------------------------------
#include <TinyWireM.h>
//--------------------------------------------------------------------
byte read_DS3231[8];
unsigned long millisCapture = millis(), myDelay = 60000;
//====================================================================
void setup()
{
TinyWireM.begin();
MAX7219_init();
//------------------------------------------------------------------
MAX7219_clear_disp();
}
//====================================================================
void loop()
{
//write to set pointer register to seconds
//-----------------------------------------
TinyWireM.beginTransmission(0x68);
TinyWireM.send(0x00); //point to Seconds register
TinyWireM.endTransmission();
//----------
//read time
//----------
TinyWireM.requestFrom(0x68, 3);
if(TinyWireM.available())
{
read_DS3231[0] = TinyWireM.receive(); //read seconds
read_DS3231[1] = TinyWireM.receive(); //read minutes
read_DS3231[2] = TinyWireM.receive(); //read hours
}
delayMicroseconds(48);
//--------------------------------------
//write to set pointer register to date
//--------------------------------------
TinyWireM.beginTransmission(0x68);
TinyWireM.send(0x04); //point to Date register
TinyWireM.endTransmission();
//----------
//read date
//----------
TinyWireM.requestFrom(0x68, 3);
if(TinyWireM.available())
{
read_DS3231[3] = TinyWireM.receive(); //read day
read_DS3231[4] = TinyWireM.receive(); //read month
read_DS3231[5] = TinyWireM.receive(); //read year
}
delayMicroseconds(48);
//--------------------------------------
//write to set pointer register to temp
//--------------------------------------
TinyWireM.beginTransmission(0x68);
TinyWireM.send(0x11); //point to Temp register
TinyWireM.endTransmission();
//----------
//read temp
//----------
TinyWireM.requestFrom(0x68, 2);
if(TinyWireM.available())
{
read_DS3231[6] = TinyWireM.receive(); //read integer part of temp
read_DS3231[7] = TinyWireM.receive(); //read fraction part of temp
}
delayMicroseconds(48);
//------------------------------------------------------------------
if(millis() - millisCapture > myDelay) disp_date_temp();
//------------------------------------------------------------------
MAX7219_write(3, (read_DS3231[0] & 0x0F));
MAX7219_write(4, (read_DS3231[0] & 0xF0) >> 4); //display seconds
//------------------------------------------------------------------
MAX7219_write(5, ((read_DS3231[1] & 0x0F))|0x80);
MAX7219_write(6, (read_DS3231[1] & 0xF0) >> 4); //display minutes
//------------------------------------------------------------------
MAX7219_write(7, ((read_DS3231[2] & 0x0F))|0x80);//display hours
if((read_DS3231[2] & 0x10) >> 4 == 0)
{
MAX7219_write(0x09, 0b01111100);
MAX7219_write(8, 0);
}
else
{
MAX7219_write(0x09, 0b11111100);
MAX7219_write(8, (read_DS3231[2] & 0x10) >> 4);
}
//------------------------------------------------------------------
byte AM_PM = read_DS3231[2] & 0x20; //display A (AM) or P (PM)
if(AM_PM == 0x20) {MAX7219_write(2, 0); MAX7219_write(1, 0x67);}
else {MAX7219_write(2, 0); MAX7219_write(1, 0x77);}
}
//====================================================================
void disp_date_temp()
{
MAX7219_write(0x09, 0); //decode mode OFF
MAX7219_clear_disp();
delay(1000);
//------------------------------------------------------------------
MAX7219_write(0x09, 0b11011011); //change decode byte
MAX7219_write(3, 1); MAX7219_write(6, 1);
MAX7219_write(1, (read_DS3231[5] & 0x0F));
MAX7219_write(2, (read_DS3231[5] & 0xF0) >> 4); //display year
//------------------------------------------------------------------
MAX7219_write(4, (read_DS3231[4] & 0x0F));
MAX7219_write(5, (read_DS3231[4] & 0xF0) >> 4); //display month
//------------------------------------------------------------------
MAX7219_write(7, (read_DS3231[3] & 0x0F));
MAX7219_write(8, (read_DS3231[3] & 0xF0) >> 4); //display day
//------------------------------------------------------------------
delay(3000);
MAX7219_write(0x09, 0); //decode mode OFF
MAX7219_clear_disp();
delay(500);
//------------------------------------------------------------------
display_temp();
//------------------------------------------------------------------
MAX7219_write(0x09, 0); //decode mode OFF
MAX7219_clear_disp();
delay(1000);
//------------------------------------------------------------------
MAX7219_write(0x09, 0b11111100); //change decode byte
millisCapture = millis();
}
//====================================================================
void display_temp()
{
MAX7219_write(0x09, 0b01111000); //change decode byte
MAX7219_write(1, 0); MAX7219_write(8, 0);
MAX7219_write(3, 0x63); MAX7219_write(2, 0x4E); //disp text °C
MAX7219_write(6, ((read_DS3231[6]%10))|0x80); //display integer
MAX7219_write(7, (read_DS3231[6]/10)); //part of temp
//------------------------------------------------------------------
read_DS3231[7] = read_DS3231[7] >> 6; //extract 2-bit fraction part
//------------------------------------------------------------------
switch(read_DS3231[7])
{
case 0: //if 2-bit value is 0, fraction value = 0.00
MAX7219_write(5, 0); MAX7219_write(4, 0); break;
case 1: //if 2-bit value is 1, fraction value = 0.25
MAX7219_write(5, 2); MAX7219_write(4, 5); break;
case 2: //if 2-bit value is 2, fraction value = 0.50
MAX7219_write(5, 5); MAX7219_write(4, 0); break;
case 3: //if 2-bit value is 0, fraction value = 0.75
MAX7219_write(5, 7); MAX7219_write(4, 5);
}
delay(3000);
}
//====================================================================
void MAX7219_init()
{
//PB1 ==> DIN, PB3 ==> CS, PB4 ==> CLK
DDRB |= (1<<PB1)|(1<<PB3)|(1<<PB4); //set pins for o/p
//------------------------------------------------------------------
MAX7219_write(0x09, 0b11111100); //decoding byte
MAX7219_write(0x0A, 2); //light intensity: 2 (0-15)
MAX7219_write(0x0B, 7); //scan limit: all digits ON
MAX7219_write(0x0C, 1); //turn ON MAX7219
}
//====================================================================
void MAX7219_write(uint8_t cmd_byte, uint8_t data_byte)
{
PORTB &= ~(1<<PB3); //CS low pulse to enable MAX7219
//------------------------------------------------------------------
SPI_send(cmd_byte); //send command byte to MAX7219
SPI_send(data_byte); //send data byte to MAX7219
//------------------------------------------------------------------
PORTB |= (1<<PB3); //CS high pulse to disable MAX7219
}
//====================================================================
void SPI_send(uint8_t data)
{
uint8_t i;
for(i=0; i<8; i++)
{
PORTB &= ~(1<<PB4); //CLK low pulse
//----------------------------------------------------------------
if(data & 0x80) PORTB |= (1<<PB1); //o/p high if MSB = 1
else PORTB &= ~(1<<PB1); //o/p low if MSB = 0
//----------------------------------------------------------------
PORTB |= (1<<PB4); //CLK high pulse
data = data << 1; //shift data left one bit
}
}
//====================================================================
void display_byte(uint8_t im[8])
{
uint8_t i;
for(i=0; i<8; i++) MAX7219_write(i+1, im[i]);
}
//====================================================================
void MAX7219_clear_disp()
{
for(byte i=1; i<=8; i++) MAX7219_write(i, 0);
}