Carlo Stramaglia
Published © GPL3+

Biorhythm Clock Using Arduino Nano, RTC, 1602A and 74HC595

It's a biorhythm clock using Arduino Nano showing the Emotional, Physical and Intellectual status of your body!

BeginnerFull instructions provided8 hours330
Biorhythm Clock Using Arduino Nano, RTC, 1602A and 74HC595

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
74HC595
×1
RTC Real Time Clock
×1
1602A LCD Display
×1
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
×1
LED (generic)
LED (generic)
×9
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
4xAA battery holder
4xAA battery holder
×1
Main power switch
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Drill / Driver, Cordless
Drill / Driver, Cordless

Story

Read more

Schematics

Schematics for Biorhythm Clock

Code

Sketch biorhythm with clock

Arduino
// Sketch biorhythm with clock
// Place your default birth date in the sketch


#include <DS3232RTC.h>    
#include <LiquidCrystal.h>
#include <OneButton.h>
#include <RotaryEncoder.h>

// ----- Rotary settings here ----
#define ROTARYSTEPS 1
#define ROTARYMIN 0
#define ROTARYMAX 10
int lastPos = 0;
int exitFlag = 0;
// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(A2, A3);
// Last known rotary position.

DS3232RTC myRTC;
const int rs = 8, en =7, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Setup a new OneButton on pin A1.  
OneButton button1(A1, true);

//Pin connected to ST_CP of 74HC595
int latchPin = 9;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

// Place your default birth date below
int dayBirth = 8;
int monthBirth = 4;
int yearBirth = 1968;
// NOT TO BE CHANGED
int anno = 1950;
int mese = 1;
int giorno = 1;

void setup() {
  Serial.begin(115200);

 encoder.setPosition(0 / ROTARYSTEPS); // start with the value of 0.
 
  // link the button 1 functions.
  button1.attachClick(click1);
  button1.attachDoubleClick(doubleclick1);
  button1.attachLongPressStart(longPressStart1);
  button1.attachLongPressStop(longPressStop1);
  button1.attachDuringLongPress(longPress1);
  delay(200);

  
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(10, OUTPUT);
  
  
  lcd.begin(16, 2);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus() != timeSet)
      Serial.println("Unable to sync with the RTC");
  else
      Serial.println("RTC has set the system time");

  myRTC.begin();


}

void loop() {

  button1.tick();
  int daysPassed;
  
  display();
//  delay(5000);
    char buf[40];
    time_t t = myRTC.get();
    
  daysPassed = dateDiff(yearBirth, monthBirth, dayBirth, year(t), month(t), day(t));
  Serial.print("DAYS PASSED: ");
  Serial.println(daysPassed);
  ledBioritmo(daysPassed);
    
}

// Display Ora a data
void display()
{
    char buf[40];
    time_t t = myRTC.get();

    sprintf(buf, "%.2d:%.2d %.2d/%.2d/%d ",
        hour(t), minute(t), day(t), month(t), year(t));
    Serial.println(buf);
    lcd.setCursor(0, 0);
    lcd.print(buf);
}




void ledBioritmo(int daysPassed)
{
int fisico;
int emotivo;
int intellettuale;


  fisico = bioFisico(daysPassed);
  Serial.print("Physical: ");
  Serial.println(fisico);
  lcd.setCursor(0, 1);
  lcd.print("    PHYSICAL    ");

if (fisico < 0x1ff)
  {
    digitalWrite(10, LOW);
    digitalWrite(6, LOW);
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, fisico);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    delay (3000);
  }
  else
  if (fisico == 0x1FF)
    {
     digitalWrite(10, LOW);
     digitalWrite(6, LOW);
     digitalWrite(latchPin, LOW);
     // shift out the bits:
     shiftOut(dataPin, clockPin, MSBFIRST, 0xFF);  
     //take the latch pin high so the LEDs will light up:
     digitalWrite(latchPin, HIGH);
     digitalWrite(10, HIGH);
     delay (3000);
    }
   else
   if (fisico == 0x2FF)
    {
     digitalWrite(10, LOW);
     digitalWrite(6, LOW);
     digitalWrite(latchPin, LOW);
     // shift out the bits:
     shiftOut(dataPin, clockPin, MSBFIRST, 0xFF);  
     //take the latch pin high so the LEDs will light up:
     digitalWrite(latchPin, HIGH);
     digitalWrite(10, HIGH);
     digitalWrite(6, HIGH);
     delay (3000);
    }   

  emotivo = bioEmotivo(daysPassed);
  Serial.print("Emotional: ");
  Serial.println(emotivo);
  lcd.setCursor(0, 1);
  lcd.print("   EMOTIONAL    ");

if (emotivo < 0x1ff)
  {
    digitalWrite(10, LOW);
    digitalWrite(6, LOW);
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, emotivo);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    delay (3000);
  }
  else
  if (emotivo == 0x1FF)
  {
    digitalWrite(10, LOW);
    digitalWrite(6, LOW);
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFF);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    digitalWrite(10, HIGH);
    delay (3000);
  }
  else
  if (emotivo == 0x2FF)
  {
    digitalWrite(10, LOW);
    digitalWrite(6, LOW);
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFF);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(6, HIGH);
    delay (3000);
  }  
 
  intellettuale = bioIntellettuale(daysPassed);
  Serial.print("Intellectual: ");
  Serial.println(intellettuale);
  lcd.setCursor(0, 1);
  lcd.print("  INTELLECTUAL  ");
  
if (intellettuale < 0x1ff)
  {
    digitalWrite(10, LOW);
    digitalWrite(6, LOW);
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, intellettuale);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    delay (3000);
  }
  else
  if (intellettuale == 0x1FF)
    {
      digitalWrite(10, LOW);
      digitalWrite(6, LOW);
      digitalWrite(latchPin, LOW);
      // shift out the bits:
      shiftOut(dataPin, clockPin, MSBFIRST, 0xFF);  
      //take the latch pin high so the LEDs will light up:
      digitalWrite(latchPin, HIGH);
      digitalWrite(10, HIGH);
      delay (3000);
    }
  else
  if (intellettuale == 0x2FF)
    {
      digitalWrite(10, LOW);
      digitalWrite(6, LOW);
      digitalWrite(latchPin, LOW);
      // shift out the bits:
      shiftOut(dataPin, clockPin, MSBFIRST, 0xFF);  
      //take the latch pin high so the LEDs will light up:
      digitalWrite(latchPin, HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(6, HIGH);
      delay (3000);
    }

}

int bioFisico(int dayPassed)
{
/*   
 *   Positive = 0x1 - (led 1) 
 *   Negative = 0x2 - (led 2) 
 *   Critical Negative = 0x4 - (led 3) 
 *   Critical Positive = 0x8 - (led 4) 
 *   Semicritic = 0x10 - (led 5) 
 *    
 */
  button1.tick();
  int i;
  int fisicoValue;
  fisicoValue = (dayPassed)/23;
  i = fisicoValue * 23;
  fisicoValue = dayPassed - i;

  if (fisicoValue > -1 and fisicoValue < 3)
    fisicoValue = 0x3;
  else
  if (fisicoValue > 2 and fisicoValue < 6)
    fisicoValue = 0x7;
  else
  if (fisicoValue > 5 and fisicoValue < 9)
    fisicoValue = 0xF;
  else   
  if (fisicoValue > 8 and fisicoValue < 12)
    fisicoValue = 0x1F;
  else   
  if (fisicoValue > 11 and fisicoValue < 15)
    fisicoValue = 0x3F;      
  else   
  if (fisicoValue > 14 and fisicoValue < 18)
    fisicoValue = 0x7F;      
  else   
  if (fisicoValue > 17 and fisicoValue < 21)
    fisicoValue = 0xFF;      
  else   
  if (fisicoValue > 20 and fisicoValue < 22)
    fisicoValue = 0x1FF;      
  else
    fisicoValue = 0x2FF;
    
  return (fisicoValue);
 
}

int bioEmotivo(int dayPassed)
{
/*   
 *   Positive = 0x1 - (led 1) 
 *   Negative = 0x2 - (led 2) 
 *   Critical Negative = 0x4 - (led 3) 
 *   Critical Positive = 0x8 - (led 4) 
 *   Semicritic = 0x10 - (led 5) 
 *    
 */
  button1.tick();
  int i;
  int fisicoValue;
  fisicoValue = (dayPassed)/28;
  i = fisicoValue * 28;
  fisicoValue = dayPassed - i;

  if (fisicoValue > -1 and fisicoValue < 3)
    fisicoValue = 0x3;
  else
  if (fisicoValue > 2 and fisicoValue < 7)
    fisicoValue = 0x7;
  else
  if (fisicoValue > 6 and fisicoValue < 10)
    fisicoValue = 0xF;
  else   
  if (fisicoValue > 9 and fisicoValue < 14)
    fisicoValue = 0x1F;
  else   
  if (fisicoValue > 13 and fisicoValue < 18)
    fisicoValue = 0x3F;      
  else   
  if (fisicoValue > 17 and fisicoValue < 21)
    fisicoValue = 0x7F;      
  else   
  if (fisicoValue > 20 and fisicoValue < 25)
    fisicoValue = 0xFF;      
  else   
  if (fisicoValue > 24 and fisicoValue < 27)
    fisicoValue = 0x1FF;      
  else
    fisicoValue = 0x2FF;
  
  return (fisicoValue);
 
}

int bioIntellettuale(int dayPassed)
{
/*   
 *   Positive = 0x1 - (led 1) 
 *   Negative = 0x2 - (led 2) 
 *   Critical Negative = 0x4 - (led 3) 
 *   Critical Positive = 0x8 - (led 4) 
 *   Semicritic = 0x10 - (led 5) 
 *    
 */
  button1.tick();
  int i;
  int fisicoValue;
  fisicoValue = (dayPassed)/33;
  i = fisicoValue * 33;
  fisicoValue = dayPassed - i;
  
  if (fisicoValue > -1 and fisicoValue < 4)
    fisicoValue = 0x3;
  else
  if (fisicoValue > 3 and fisicoValue < 8)
    fisicoValue = 0x7;
  else
  if (fisicoValue > 7 and fisicoValue < 12)
    fisicoValue = 0xF;
  else   
  if (fisicoValue > 11 and fisicoValue < 16)
    fisicoValue = 0x1F;
  else   
  if (fisicoValue > 15 and fisicoValue < 20)
    fisicoValue = 0x3F;      
  else   
  if (fisicoValue > 19 and fisicoValue < 24)
    fisicoValue = 0x7F;      
  else   
  if (fisicoValue > 23 and fisicoValue < 28)
    fisicoValue = 0xFF;      
  else   
  if (fisicoValue > 27 and fisicoValue < 32)
    fisicoValue = 0x1FF;      
  else
    fisicoValue = 0x2FF;
  
  return (fisicoValue);
 
}

int dateDiff(int year1, int mon1, int day1, int year2, int mon2, int day2)
{
    int ref,dd1,dd2,i;
    ref = year1;
    if(year2<year1)
    ref = year2;
    dd1=0;
    dd1=dater(mon1);
    for(i=ref;i<year1;i++)
    {
        if(i%4==0)
        dd1+=1;
    }
    dd1=dd1+day1+(year1-ref)*365;
    dd2=0;
    for(i=ref;i<year2;i++)
    {
        if(i%4==0)
        dd2+=1;
    }
    dd2=dater(mon2)+dd2+day2+((year2-ref)*365);
    return dd2-dd1;
}

int dater(int x)
{ const int dr[]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  return dr[x-1];
}

void illuminaLed(int val)
{
  Serial.print("VAL: ");
  Serial.println(val);
  int i=0;
  int led=0;
  if (val == 2)
    led = 9;
  else if (val == 4)
    led = 10;
  else if (val == 8)
    led = 11;
  else if (val == 1)
    led = 6;
  else if (val == 16)
    led = 11; 


  Serial.print("LED: ");
  Serial.println(led);

  for (i=0;i<20;i++)
  {
    analogWrite(led,i);
    delay (50);
  }

  for (i=20;i>-1;i--)
  {
    analogWrite(led,i);
    delay (50);
  }
  
}


void click1() {
  Serial.println("Button 1 click.");
 
} 
// This function will be called when the button1 was pressed 2 times in a short timeframe.


void doubleclick1() {
  Serial.println("Button 1 doubleclick.");
  lcd.noBlink();
  if (exitFlag == 0)
  {
    yearBirth = anno+lastPos;
    exitFlag = 1;
    exit;
  }
  else
    if (exitFlag == 1)
    {
      monthBirth = mese+lastPos;
      exitFlag = 2;
      exit;
    }
  else
    if (exitFlag == 2)
    {
      dayBirth = giorno+lastPos;
      exitFlag = 3;
      exit;
    }
    
    
} // doubleclick1


// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  Serial.println("Button 1 longPress start");

  
  lcd.setCursor(0, 0);
  lcd.print(" SET BIRTH DATE ");
  lcd.setCursor(0,1);
  lcd.print("Year:           ");
  lcd.setCursor(6,1);
  lcd.blink();
  lcd.print(anno+lastPos);
  lcd.setCursor(6,1);


  exitFlag = 0; 
while(exitFlag < 1)
  {
    encoder.tick();
    button1.tick();
    // Insert year
    #define ROTARYMAX 70
    int newPos = encoder.getPosition() * ROTARYSTEPS;
  
    if (newPos < ROTARYMIN) {
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
      newPos = ROTARYMIN;

    } else if (newPos > ROTARYMAX) {
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
      newPos = ROTARYMAX;
    } 

    if (lastPos != newPos) {
      Serial.print(newPos+anno);
      Serial.println();
      lcd.print(newPos+anno);
      lcd.setCursor(6,1);
      lastPos = newPos;
    } // if
  }

  lastPos = 0;
  lcd.setCursor(0, 0);
  lcd.print(" SET BIRTH DATE ");
  lcd.setCursor(0,1);
  lcd.print("Month:          ");
  lcd.setCursor(7,1);
  lcd.blink();
  lcd.print(mese+lastPos, DEC);
  lcd.setCursor(7,1);
  encoder.setPosition(0 / ROTARYSTEPS); // start with the value of 1.

while(exitFlag < 2)
  {
    encoder.tick();
    button1.tick();
    // Insert month
    #define ROTARYMAX 11
    int newPos = encoder.getPosition() * ROTARYSTEPS;
  
    if (newPos < ROTARYMIN) {
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
      newPos = ROTARYMIN;

    } else if (newPos > ROTARYMAX) {
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
      newPos = ROTARYMAX;
    } 

    if (lastPos != newPos) {
      Serial.print(newPos+mese);
      Serial.println();
      lcd.setCursor(0,1);
      lcd.print("Month:          ");
      lcd.setCursor(7,1);
      lcd.print(newPos+mese,DEC);
      lcd.setCursor(7,1);
      lastPos = newPos;
    } 
  }

  lastPos = 0;
  lcd.setCursor(0, 0);
  lcd.print(" SET BIRTH DATE ");
  lcd.setCursor(0,1);
  lcd.print("Day:            ");
  lcd.setCursor(5,1);
  lcd.blink();
  lcd.print(mese+lastPos);
  lcd.setCursor(5,1);
  encoder.setPosition(0 / ROTARYSTEPS); // start with the value of 1.

while(exitFlag < 3)
  {
    encoder.tick();
    button1.tick();
    // Insert day
    #define ROTARYMAX 30
    int newPos = encoder.getPosition() * ROTARYSTEPS;
  
    if (newPos < ROTARYMIN) {
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
      newPos = ROTARYMIN;

    } else if (newPos > ROTARYMAX) {
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
      newPos = ROTARYMAX;
    } // if

    if (lastPos != newPos) {
      Serial.print(newPos+giorno);
      Serial.println();
      lcd.setCursor(0,1);
      lcd.print("Day:            ");
      lcd.setCursor(5,1);
      lcd.print(newPos+giorno);
      lcd.setCursor(5,1);
      lastPos = newPos;
    } 
  }



} // longPressStart1


// This function will be called often, while the button1 is pressed for a long time.
void longPress1() {
  Serial.println("Button 1 longPress...");

} // longPress1


// This function will be called once, when the button1 is released after beeing pressed for a long time.
void longPressStop1() {
  Serial.println("Button 1 longPress stop");

} // longPressStop1

Credits

Carlo Stramaglia
1 project • 1 follower
Contact

Comments

Please log in or sign up to comment.