Guest User

Smart Clock - PM

a guest
Jun 1st, 2021
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.92 KB | None | 0 0
  1. //Gherman Sebastian-Costin
  2. //https://ocw.cs.pub.ro/courses/pm/prj2021/dbrigalda/502
  3. //Smart Clock
  4.  
  5. #include <dht11.h>
  6. // Include Wire Library for I2C
  7. #include <Wire.h>
  8. #include <SPI.h>
  9. // Include NewLiquidCrystal Library for I2C
  10. #include <LiquidCrystal_I2C.h>
  11. #include <MD_Parola.h>
  12. #include <MD_MAX72xx.h>
  13. #include <ds3231.h>
  14.  
  15. #define DHT11PIN A0
  16. #define echoPin 4
  17. #define trigPin 5
  18. #define whiteLedPin A2
  19. #define blueLedPin A3
  20. #define upPin 6
  21. #define downPin 7
  22. #define menuPin 8
  23. #define buzzerPin A1
  24. #define maxOptions 6
  25. #define interrupt_pin 2
  26.  
  27. #define HARDWARE_TYPE MD_MAX72XX::FC16_HW
  28. #define MAX_DEVICES 4
  29. #define CS_PIN 3
  30.  
  31. // We always wait a bit between updates of the display
  32. #define  DELAYTIME  40  // in milliseconds
  33. #define SPEED_TIME  50
  34. #define PAUSE_TIME  1000
  35.  
  36.  
  37. // Create a new instance of the MD_MAX72XX class:
  38. MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
  39. MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
  40.  
  41. // Define LCD pinout
  42. const short  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
  43.  
  44. // Define I2C Address - change if reqiuired
  45. const int i2c_addr = 0x27;
  46.  
  47. LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);
  48.  
  49. dht11 DHT11;
  50. bool state = 0;
  51.  
  52. unsigned char option = 0;
  53. bool upButton; //for forward
  54. bool downButton; //for backward
  55. bool optionButton; //for option
  56.  
  57. bool nightLights = 0;
  58. bool noSensors = 0;
  59. struct ts t;
  60.  
  61.  
  62. void setup()
  63. {
  64.   Wire.begin();
  65.   pinMode(DHT11PIN,INPUT);
  66.   pinMode(upPin, INPUT_PULLUP);
  67.   pinMode(downPin, INPUT_PULLUP);
  68.   pinMode(menuPin, INPUT_PULLUP);
  69.   pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  70.   pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
  71.   pinMode(whiteLedPin,OUTPUT);
  72.   pinMode(blueLedPin,OUTPUT);
  73.   pinMode(buzzerPin, OUTPUT);
  74.   digitalWrite(blueLedPin, HIGH);
  75.  
  76.   pinMode(interrupt_pin,INPUT);
  77.   attachInterrupt(digitalPinToInterrupt(interrupt_pin),interrupt_routine,RISING);
  78.  
  79.   DS3231_init(DS3231_CONTROL_INTCN);
  80.  
  81.  
  82.  
  83.   mx.begin();
  84.  
  85.   myDisplay.begin();
  86.   // Set the intensity (brightness) of the display (0-15):
  87.   myDisplay.setIntensity(5);
  88.   // Clear the display:
  89.   LedFunctionTemperatureON();
  90.   lcd.begin(16,2);
  91.   lcd.setCursor(0,0);
  92.   lcd.print("Pornire Ceas");
  93.   lcd.setCursor(0,1);
  94.   lcd.print("Inteligent!");
  95.  
  96.   tone(buzzerPin, 659, 500);
  97.   delay(100);
  98.   tone(buzzerPin, 523, 500);
  99.   delay(400);
  100.   tone(buzzerPin, 659, 500);
  101.   delay(100);
  102.   tone(buzzerPin, 523, 500);
  103.   delay(400);
  104.   tone(buzzerPin, 784, 500);
  105.  
  106.   scrollText("Salut !");
  107.   delay(2000);
  108.   mx.control(MD_MAX72XX::INTENSITY, 0);
  109.   spiral();
  110.   delay(3000);
  111.   mx.control(MD_MAX72XX::INTENSITY, 15);
  112.  
  113.   lcd.clear();
  114.  
  115.   myDisplay.displayClear();
  116.  
  117.   myDisplay.setTextAlignment(PA_CENTER);
  118.   digitalWrite(blueLedPin, LOW);
  119. }
  120.  
  121.  
  122. void scrollText(const char *p)
  123. {
  124.   uint8_t charWidth;
  125.   uint8_t cBuf[8];  // this should be ok for all built-in fonts
  126.  
  127.   mx.clear();
  128.  
  129.   while (*p != '\0')
  130.   {
  131.     charWidth = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
  132.  
  133.     for (uint8_t i=0; i<=charWidth; i++)  // allow space between characters
  134.     {
  135.       mx.transform(MD_MAX72XX::TSL);
  136.       if (i < charWidth)
  137.         mx.setColumn(0, cBuf[i]);
  138.       delay(DELAYTIME);
  139.     }
  140.   }
  141. }
  142. void bounce()
  143. // Animation of a bouncing ball
  144. {
  145.   const int minC = 0;
  146.   const int maxC = mx.getColumnCount()-1;
  147.   const int minR = 0;
  148.   const int maxR = ROW_SIZE-1;
  149.  
  150.   int  nCounter = 0;
  151.  
  152.   int  r = 0, c = 2;
  153.   int8_t dR = 1, dC = 1;  // delta row and column
  154.  
  155.   mx.clear();
  156.  
  157.   while (nCounter++ < 200)
  158.   {
  159.     mx.setPoint(r, c, false);
  160.     r += dR;
  161.     c += dC;
  162.     mx.setPoint(r, c, true);
  163.     delay(DELAYTIME/4);
  164.     if ((r == minR) || (r == maxR))
  165.       dR = -dR;
  166.     if ((c == minC) || (c == maxC))
  167.       dC = -dC;
  168.   }
  169. }
  170.  
  171. void newHour(){
  172.   //can be changed for hours
  173.   if(t.sec == 0 || t.sec == 1) bounce();
  174. }
  175. void spiral()
  176. // setPoint() used to draw a spiral across the whole display
  177. {
  178.   int  rmin = 0, rmax = ROW_SIZE-1;
  179.   int  cmin = 0, cmax = (COL_SIZE*MAX_DEVICES)-1;
  180.  
  181.   mx.clear();
  182.   while ((rmax > rmin) && (cmax > cmin))
  183.   {
  184.     // do row
  185.     for (int i=cmin; i<=cmax; i++)
  186.     {
  187.       mx.setPoint(rmin, i, true);
  188.       delay(DELAYTIME/MAX_DEVICES);
  189.     }
  190.     rmin++;
  191.  
  192.     // do column
  193.     for (uint8_t i=rmin; i<=rmax; i++)
  194.     {
  195.       mx.setPoint(i, cmax, true);
  196.       delay(DELAYTIME/MAX_DEVICES);
  197.     }
  198.     cmax--;
  199.  
  200.     // do row
  201.     for (int i=cmax; i>=cmin; i--)
  202.     {
  203.       mx.setPoint(rmax, i, true);
  204.       delay(DELAYTIME/MAX_DEVICES);
  205.     }
  206.     rmax--;
  207.  
  208.     // do column
  209.     for (uint8_t i=rmax; i>=rmin; i--)
  210.     {
  211.       mx.setPoint(i, cmin, true);
  212.       delay(DELAYTIME/MAX_DEVICES);
  213.     }
  214.     cmin++;
  215.   }
  216. }
  217.  
  218. void getCurrentTemperature(){
  219.   DHT11.read(DHT11PIN);
  220.   tone(buzzerPin, 523, 500);
  221.   delay(300);
  222.   tone(buzzerPin, 659, 500);
  223.   delay(300);
  224.   tone(buzzerPin, 784, 500);
  225.   lcd.setCursor(0,0);
  226.   lcd.print("Umiditate: ");
  227.   lcd.print((float)DHT11.humidity, 2);
  228.  
  229.   lcd.setCursor(0,1);
  230.   lcd.print("Temp (C): ");
  231.   lcd.print((float)DHT11.temperature, 2);
  232.  
  233.   delay(5000);
  234.  
  235.   lcd.clear();
  236.  
  237. }
  238. void getUltrasonicDistance(){
  239.   unsigned int duration;
  240.   unsigned short distance;
  241.   // Clears the trigPin condition
  242.   digitalWrite(trigPin, LOW);
  243.   delayMicroseconds(2);
  244.   // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  245.   digitalWrite(trigPin, HIGH);
  246.   delayMicroseconds(10);
  247.   digitalWrite(trigPin, LOW);
  248.   // Reads the echoPin, returns the sound wave travel time in microseconds
  249.   duration = pulseIn(echoPin, HIGH);
  250.   // Calculating the distance
  251.   distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  252.    
  253.   if (distance < 6 && distance > 0){
  254.  
  255.     lcd.clear();
  256.     LedFunctionTemperatureON();
  257.     for(unsigned char i = 0; i < 10; i++){  
  258.       lcd.print(".");
  259.       delay(100);
  260.     }
  261.    
  262.     getCurrentTemperature();    
  263.     digitalWrite(blueLedPin, HIGH);
  264.     digitalWrite(whiteLedPin, LOW);
  265.    
  266.  
  267.   }
  268.   delay(10);
  269.  
  270. }
  271.  
  272. void displayClock(){
  273.   DS3231_get(&t);
  274.   newHour();
  275.   char timeToPrint[10] = {};
  276.   char hoursPrint, minutesPrint;
  277.   if(t.hour < 10) hoursPrint ='0';
  278.   else hoursPrint = ' ';
  279.   if(t.min < 10) minutesPrint = '0';
  280.   else minutesPrint = ' ';
  281.   sprintf(timeToPrint,"%c%d:%c%d",hoursPrint, t.hour, minutesPrint, t.min);
  282.  
  283.   myDisplay.print(timeToPrint);
  284. }
  285. void displayDate(){
  286.  
  287.   DS3231_get(&t);
  288.   lcd.clear();
  289.   lcd.setCursor(0,0);
  290.   lcd.print(t.mday);
  291.   lcd.print("/");
  292.   lcd.print(t.mon);
  293.   lcd.print("/");
  294.   lcd.print(t.year);  
  295.  
  296. }
  297. void LedFunctionClock(){
  298.   digitalWrite(whiteLedPin, !digitalRead(whiteLedPin));
  299.   digitalWrite(blueLedPin, !digitalRead(blueLedPin));
  300. }
  301. void LedFunctionTemperatureON(){
  302.   digitalWrite(whiteLedPin, HIGH);
  303.   digitalWrite(blueLedPin, HIGH);
  304. }
  305. void displaySetHours(){
  306.   lcd.clear();
  307.   lcd.setCursor(0,0);
  308.   lcd.print("Seteaza Ora: ");
  309.   if(upButton){
  310.     if(t.hour == 23)
  311.       t.hour = 0;
  312.     else t.hour++;
  313.   }
  314.   if(downButton){
  315.     if(t.hour == 0)
  316.       t.hour = 23;
  317.     else t.hour--;
  318.   }
  319.   t.sec = 0;
  320.   lcd.setCursor(0,1);
  321.   lcd.print(t.hour);
  322.   DS3231_set(t);
  323. }
  324. void displaySetMinutes(){
  325.   lcd.clear();
  326.   lcd.setCursor(0,0);
  327.   lcd.print("Seteaza Minut: ");
  328.   if(upButton){
  329.     if(t.min == 59)
  330.       t.min = 0;
  331.     else t.min++;
  332.   }
  333.   if(downButton){
  334.     if(t.min == 0)
  335.       t.min = 59;
  336.     else t.min--;
  337.   }
  338.   t.sec = 0;
  339.   lcd.setCursor(0,1);
  340.   lcd.print(t.min);
  341.   DS3231_set(t);
  342. }
  343. void displaySetDays(){
  344.   lcd.clear();
  345.   lcd.setCursor(0,0);
  346.   lcd.print("Seteaza Ziua: ");
  347.   if(upButton){
  348.     if(t.mon % 2 == 0){
  349.       //max days 30
  350.       if(t.mday == 31)
  351.         t.mday = 1;
  352.       else t.mday ++;    
  353.     }
  354.     else {
  355.       if(t.mday == 32)
  356.         t.mday = 1;
  357.       else t.mday ++;      
  358.     }
  359.   }
  360.  
  361.   if(downButton){
  362.     if(t.mon % 2 == 0){
  363.       //max days 30
  364.       if(t.mday == 1)
  365.         t.mday = 30;
  366.       else t.mday--;
  367.     }
  368.     else {
  369.       if(t.mday == 1)
  370.         t.mday = 31;
  371.       else t.mday--;
  372.     }
  373.   }
  374.   lcd.setCursor(0,1);
  375.   lcd.print(t.mday);
  376.   DS3231_set(t);
  377. }
  378. void displaySetMonths(){
  379.   lcd.clear();
  380.   lcd.setCursor(0,0);
  381.   lcd.print("Seteaza Luna: ");
  382.   if(upButton){
  383.     if(t.mon == 13)
  384.       t.mon = 1;
  385.     else t.mon++;
  386.   }
  387.  
  388.  
  389.   if(downButton){
  390.      if(t.mon == 13)
  391.       t.mon = 1;
  392.      else t.mon--;
  393.   }
  394.   lcd.setCursor(0,1);
  395.   lcd.print(t.mon);
  396.   DS3231_set(t);
  397. }
  398. void displaySetYears(){
  399.   lcd.clear();
  400.   lcd.setCursor(0,0);
  401.   lcd.print("Seteaza Anul: ");
  402.   if(upButton)
  403.     t.year++;
  404.  
  405.   if(downButton)
  406.      t.year--;
  407.   lcd.setCursor(0,1);
  408.   lcd.print(t.year);
  409.   DS3231_set(t);
  410. }
  411.  
  412. void buttonFunction(){  
  413.   delay(500);
  414.   upButton = !digitalRead(upPin);
  415.   downButton = !digitalRead(downPin);
  416.   optionButton = !digitalRead(menuPin);
  417.   if(optionButton)
  418.     option++;
  419.  
  420.   if(upButton && option == 0){
  421.     nightLights = !nightLights;
  422.    
  423.     if(nightLights){
  424.       lcd.clear();
  425.       lcd.print("Night Lights ON");
  426.       delay(1000);
  427.       lcd.clear();
  428.   }
  429.     else{
  430.       lcd.clear();
  431.       lcd.print("Night Lights OFF");
  432.       delay(1000);
  433.       lcd.clear();
  434.     }
  435.   }
  436.  
  437.  
  438.   if(downButton && option == 0){
  439.     noSensors = !noSensors;
  440.     if(!noSensors){
  441.       lcd.clear();
  442.       lcd.print("Sensors ON");
  443.       delay(1000);
  444.       lcd.clear();
  445.     }
  446.     else{
  447.       lcd.clear();
  448.       lcd.print("Sensors OFF");
  449.       delay(1000);
  450.       lcd.clear();
  451.     }
  452.   }
  453.  
  454.   if(option == maxOptions){
  455.     lcd.clear();
  456.     lcd.print("Ceasul s-a setat");
  457.     delay(1000);
  458.     lcd.clear();
  459.     option = 0;
  460.   }
  461.    
  462. }
  463. void menuFunction(){
  464.    switch(option){
  465.     case 1:
  466.       displaySetHours();
  467.       break;
  468.     case 2:
  469.       displaySetMinutes();
  470.       break;
  471.     case 3:
  472.       displaySetDays();
  473.       break;
  474.     case 4:
  475.       displaySetMonths();
  476.       break;
  477.     case 5:
  478.       displaySetYears();
  479.       break;
  480.     default:
  481.       displayClock();
  482.       break;
  483.   }
  484. }
  485. void motionDetected(){
  486.   if(state == 1 && option == 0){
  487.     lcd.clear();
  488.     lcd.setCursor(0,0);
  489.    
  490.     lcd.print("Hai noroc");
  491.     delay(3000);
  492.     lcd.clear();
  493.     lcd.print("Apropie mana ");
  494.     lcd.setCursor(0,1);
  495.     lcd.print("de senzor ");
  496.     delay(5000);
  497.     lcd.clear();
  498.     state = 0;
  499.   }
  500. }
  501. void loop()
  502. {
  503.   if(nightLights){
  504.     mx.control(MD_MAX72XX::INTENSITY, 1);  
  505.     digitalWrite(blueLedPin, 0);
  506.     digitalWrite(whiteLedPin, 0);
  507.   }
  508.   else{
  509.     //if night lights was on previously turn one led
  510.     if(digitalRead(blueLedPin) == 0 && digitalRead(whiteLedPin) == 0 )
  511.       digitalWrite(blueLedPin, 1);
  512.     LedFunctionClock();
  513.     delay(500);
  514.     mx.control(MD_MAX72XX::INTENSITY, 10);
  515.    
  516.    
  517.   }
  518.    
  519.  
  520.   if(!noSensors){
  521.     motionDetected();
  522.     getUltrasonicDistance();
  523.   }
  524.  
  525.   buttonFunction();  
  526.   displayDate();
  527.   menuFunction();
  528. }
  529.  
  530. void interrupt_routine(){
  531.   state = 1;
  532. }
Advertisement
Add Comment
Please, Sign In to add comment