Advertisement
ldirko

sand clock 16x16

Jan 12th, 2021
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Sand clock
  2. //ldirko. Yaroslaw Turbin, 12-01-2021
  3. //16x16 FastLed matrix demo
  4. //https://vk.com/ldirko
  5. //https://www.reddit.com/user/ldirko/
  6. //not for commercial use )
  7.  
  8. //how it look in emulator https://wokwi.com/arduino/projects/287419421301932557
  9.  
  10. #include <FastLED.h>
  11. #include <LiquidCrystal_I2C.h>
  12. #include <Wire.h>
  13.  
  14. // RTC module at address 0x68
  15. #define DS1307_ADDRESS 0x68
  16.  
  17. // LCD module at address 0x27
  18. LiquidCrystal_I2C lcd(0x27, 20, 4);
  19.  
  20. uint8_t clear = 0x00;
  21.  
  22. #define WIDTH 16
  23. #define HEIGHT 16
  24. #define NUM_ROWS HEIGHT
  25. #define NUM_COLS WIDTH
  26. #define NUM_LEDS ((WIDTH) * (HEIGHT))
  27.  
  28. CRGB leds[NUM_LEDS + 1];
  29. CRGB ledsbuff[NUM_LEDS + 1];
  30.  
  31.  
  32. uint16_t XY(uint8_t x, uint8_t y) {
  33.   if (x >= WIDTH) return NUM_LEDS;
  34.   if (y >= HEIGHT) return NUM_LEDS;
  35.   // if (y & 1)
  36.   //   return (y + 1) * WIDTH - 1 - x;
  37.   // else
  38.     return y * WIDTH + x;
  39. }
  40.  
  41. void setup()
  42. {
  43.   FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS);
  44.   LEDS.clear();
  45.   Wire.begin();
  46.   Serial.begin(9600);
  47.   lcd.begin (16,2);
  48.   lcd.backlight();
  49.   // Use a line below to customize a date and time
  50.   // sec, min, hour, month, day, day of week, year % 100
  51.   // setDateTime(40, 59, 23, 1, 4, 1, 21);
  52. }
  53.  
  54. void loop()
  55. {
  56.  
  57. timeLCD();
  58.   SandMachine();
  59.   PrintTime();
  60.   FastLED.show();
  61. }
  62.  
  63. void SandMachine(){
  64.   EVERY_N_MILLISECONDS(80) {updatesand(); randomdot();}    
  65.   EVERY_N_MILLISECONDS(10000) {randomdel(); falldown(); falldown(); falldown();}
  66.   memcpy8(leds, ledsbuff, NUM_LEDS*3);
  67. }
  68.  
  69. void PrintTime(){
  70.   static byte numbers;
  71.   static byte colorNumber;
  72.   Wire.beginTransmission(DS1307_ADDRESS);
  73.   Wire.write(clear);
  74.   Wire.endTransmission();
  75.   Wire.requestFrom(DS1307_ADDRESS, 0x07);
  76.   uint8_t seconds = bcdToDec(Wire.read());
  77.   uint8_t minutes = bcdToDec(Wire.read());
  78.   uint8_t hours = bcdToDec(Wire.read() & 0xff);
  79.   uint8_t wday = bcdToDec(Wire.read());
  80.   uint8_t mday = bcdToDec(Wire.read());
  81.   uint8_t month = bcdToDec(Wire.read());
  82.   uint8_t year = bcdToDec(Wire.read());
  83.  
  84.       colorNumber = 170;
  85.       prnCHR(0,2,hours/10,colorNumber);
  86.       prnCHR(4,2,hours%10,colorNumber);
  87.       prnCHR(9,2,minutes/10,colorNumber);
  88.       prnCHR(13,2,minutes%10,colorNumber);
  89.  
  90.  
  91. }
  92.  
  93. void prnCHR(byte x, byte y, byte number, byte numberhue){
  94. const static boolean Numbers [150] = {
  95. 1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,   //0
  96. 0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,   //1
  97. 0,1,1,0,0,1,1,1,1,1,0,0,1,1,1,   //2
  98. 1,1,1,0,0,1,0,1,1,0,0,1,0,1,1,   //3
  99. 1,0,0,1,0,1,1,1,1,0,0,1,0,0,1,   //4
  100. 1,1,0,1,0,0,1,1,1,0,0,1,1,1,1,   //5
  101. 1,1,0,1,0,0,1,1,1,1,0,1,1,1,1,   //6
  102. 1,1,1,1,0,1,0,0,1,0,0,1,0,0,1,   //7
  103. 1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,   //8
  104. 1,1,1,1,0,1,1,1,1,0,0,1,0,1,1};  //9
  105.  
  106. byte numbind = number*15;
  107. for (byte j=y; j<(y+5);j++){
  108. for (byte i=x; i<(x+3);i++){
  109. if (Numbers[numbind++]) leds[XY(i,j)]=CHSV(numberhue+j*8+beatsin8(20,0,20),255,255);
  110. }}
  111. }
  112.  
  113. void randomdot(){
  114. #define randomdothue 30
  115. byte a= NUM_COLS/2; //random8(NUM_COLS/4)+NUM_COLS*3/8; //
  116. if (!random8(4)) ledsbuff[XY(a,0)].setHue(random8(randomdothue,randomdothue+45));      
  117. }
  118.  
  119. void updatesand (){
  120. int index, indexXadd1Y, indexXsub1Y, indexXYadd1;  
  121. for (int y=NUM_ROWS-1; y>0; y--) {
  122. for (int x=1; x<NUM_COLS-1; x++) {
  123. index = XY(x,y); indexXadd1Y = XY(x+1,y); indexXsub1Y = XY(x-1,y); indexXYadd1 = XY(x,y-1);
  124.   if (!ledsbuff[index] && !ledsbuff[indexXYadd1]) continue;
  125.   if (!ledsbuff[index] && ledsbuff[indexXYadd1]) {ledsbuff[index]=ledsbuff[indexXYadd1]; ledsbuff[indexXYadd1]=0;}
  126.   if (ledsbuff[index] && ledsbuff[indexXYadd1] && !ledsbuff[indexXsub1Y] && !ledsbuff[indexXadd1Y])
  127.       if (random8(2)) {ledsbuff[indexXsub1Y]=ledsbuff[indexXYadd1]; ledsbuff[indexXYadd1]=0;}
  128.         else {ledsbuff[indexXadd1Y]=ledsbuff[indexXYadd1]; ledsbuff[indexXYadd1]=0;}
  129.   if (ledsbuff[index] && ledsbuff[indexXYadd1] && !ledsbuff[indexXsub1Y] && ledsbuff[indexXadd1Y]) {ledsbuff[indexXsub1Y]=ledsbuff[indexXYadd1]; ledsbuff[indexXYadd1]=0;}
  130.   if (ledsbuff[index] && ledsbuff[indexXYadd1] && ledsbuff[indexXsub1Y] && !ledsbuff[indexXadd1Y]) {ledsbuff[indexXadd1Y]=ledsbuff[indexXYadd1]; ledsbuff[indexXYadd1]=0;}
  131. }}
  132. }
  133.  
  134. void randomdel(){
  135.  for (int i=0; i<NUM_LEDS; i++) {
  136.    if (!random8(3)) ledsbuff[i]=0;
  137. }
  138. }
  139.  
  140. void falldown(){
  141. int indexXYsub1, index;
  142. for (int y=NUM_ROWS-1; y>0; y--) {
  143. for (int x=0; x<NUM_COLS; x++) {
  144.  indexXYsub1 =XY(x,y-1); index= XY(x,y);
  145.   if (!ledsbuff[index] && ledsbuff[indexXYsub1]) {ledsbuff[index]=ledsbuff[indexXYsub1]; ledsbuff[indexXYsub1]=0;}
  146. }}
  147. }
  148.  
  149. //____  procedures for  work with display and DS1307 by arcostasi  _______________
  150.  
  151. // Set the date and time of the DS1307
  152. void setDateTime(uint8_t seconds, uint8_t minutes, uint8_t hours,
  153.   uint8_t wday, uint8_t mday, uint8_t month, uint8_t year)
  154. {
  155.   Wire.beginTransmission(DS1307_ADDRESS);
  156.   Wire.write(clear); // Write clear, so that it can receive data
  157.  
  158.   // The lines below write in the CI the date and time values ​​
  159.   // that were placed in the variables above
  160.   Wire.write(decToBcd(seconds));
  161.   Wire.write(decToBcd(minutes));
  162.   Wire.write(decToBcd(hours));
  163.   Wire.write(decToBcd(wday));
  164.   Wire.write(decToBcd(mday));
  165.   Wire.write(decToBcd(month));
  166.   Wire.write(decToBcd(year));
  167.   Wire.write(clear);
  168.   Wire.endTransmission();
  169. }
  170.  
  171. uint8_t decToBcd(uint8_t value)
  172. {
  173.   // Converts the decimal number to BCD
  174.   return ((value / 10 * 16) + (value % 10));
  175. }
  176.  
  177. uint8_t bcdToDec(uint8_t value)
  178. {
  179.   // Converts from BCD to decimal
  180.   return ((value / 16 * 10) + (value % 16));
  181. }
  182.  
  183.  
  184. void timeLCD(){
  185. // Read the values ​​(date and time) of the DS1307 module
  186.   Wire.beginTransmission(DS1307_ADDRESS);
  187.   Wire.write(clear);
  188.   Wire.endTransmission();
  189.   Wire.requestFrom(DS1307_ADDRESS, 0x07);
  190.  
  191.   uint8_t seconds = bcdToDec(Wire.read());
  192.   uint8_t minutes = bcdToDec(Wire.read());
  193.   uint8_t hours = bcdToDec(Wire.read() & 0xff);
  194.   uint8_t wday = bcdToDec(Wire.read());
  195.   uint8_t mday = bcdToDec(Wire.read());
  196.   uint8_t month = bcdToDec(Wire.read());
  197.   uint8_t year = bcdToDec(Wire.read());
  198.  
  199.   // Shows the data on the display
  200.   lcd.setCursor(0,0);
  201.   lcd.print("    ");
  202.  
  203.   // Adds 0 (clear) if the time is less than 10
  204.   if (hours < 10)
  205.     lcd.print("0");
  206.  
  207.   lcd.print(hours);
  208.   if (seconds & 1)
  209.     lcd.print(":");
  210.   else
  211.     lcd.print(" ");
  212.  
  213.   // Adds 0 (clear) if minutes are less than 10
  214.   if (minutes < 10)
  215.      lcd.print("0");
  216.  
  217.   lcd.print(minutes);
  218.  
  219.   if (seconds & 1)
  220.     lcd.print(":");
  221.   else
  222.     lcd.print(" ");
  223.  
  224.   if (seconds < 10)
  225.      lcd.print("0");
  226.  
  227.   lcd.print(seconds);
  228.  
  229.   lcd.setCursor(2,1);
  230.  
  231.   // Show the day of the week
  232.   switch(wday-1)  // fixed
  233.     {
  234.       case 0:lcd.print("Sun");
  235.       break;
  236.       case 1:lcd.print("Mon");
  237.       break;
  238.       case 2:lcd.print("Tue");
  239.       break;
  240.       case 3:lcd.print("Wed");
  241.       break;
  242.       case 4:lcd.print("Thu");
  243.       break;
  244.       case 5:lcd.print("Fri");
  245.       break;
  246.       case 6:lcd.print("Sat");
  247.     }
  248.  
  249.     lcd.setCursor(6,1);
  250.  
  251.     // Adds 0 (clear) if day of the month is less than 10
  252.     if (mday < 10)
  253.       lcd.print("0");
  254.  
  255.     lcd.print(mday);
  256.     lcd.print("/");
  257.  
  258.     // Add 0 (clear) if month is less than 10
  259.     if (month < 10)
  260.       lcd.print("0");
  261.  
  262.     lcd.print(month);
  263.     lcd.print("/");
  264.     lcd.print(year);
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement