Advertisement
Ramis84

Ramis & Linda Arduinoklocka 2020-01-03 Source

Jan 27th, 2020
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.40 KB | None | 0 0
  1. // NEOPIXEL BEST PRACTICES for most reliable operation:
  2. // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
  3. // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
  4. // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
  5. // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
  6. //   connect GROUND (-) first, then +, then data.
  7. // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
  8. //   a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
  9. // (Skipping these may work OK on your workbench but can fail in the field)
  10.  
  11. #include <Adafruit_NeoPixel.h>
  12.  
  13. // Date and time functions using a DS3231 RTC connected via I2C and Wire lib
  14. #include "RTClib.h"
  15.  
  16. // Which pin on the Arduino is connected to the NeoPixels?
  17. // On a Trinket or Gemma we suggest changing this to 1:
  18.  
  19. // Pro Micro, 10
  20. #define LED_PIN    10
  21.  
  22. // Pro Micro, A3
  23. #define TIME_SET_PIN    21
  24.  
  25. // LED indices for each digit
  26. #define DIGIT_1_INDEX    0
  27. #define DIGIT_2_INDEX    35
  28. #define DIGIT_3_INDEX    72
  29. #define DIGIT_4_INDEX    107
  30.  
  31. // LED index of colon
  32. #define COLON_INDEX    70
  33.  
  34. // LED index offsets for each segment (within each digit)
  35. #define SEGMENT_1_OFFSET    0
  36. #define SEGMENT_2_OFFSET    5
  37. #define SEGMENT_3_OFFSET    10
  38. #define SEGMENT_4_OFFSET    15
  39. #define SEGMENT_5_OFFSET    20
  40. #define SEGMENT_6_OFFSET    25
  41. #define SEGMENT_7_OFFSET    30
  42.  
  43. #define BLACK strip.Color(0, 0, 0)
  44.  
  45. // How many NeoPixels are attached to the Arduino?
  46. #define LED_COUNT 142
  47.  
  48. // Declare our NeoPixel strip object:
  49. Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
  50. // Argument 1 = Number of pixels in NeoPixel strip
  51. // Argument 2 = Arduino pin number (most are valid)
  52. // Argument 3 = Pixel type flags, add together as needed:
  53. //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
  54. //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
  55. //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
  56. //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
  57. //   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
  58.  
  59. RTC_DS3231 rtc;
  60.  
  61. int firstDigit;
  62. int secondDigit;
  63. int thirdDigit;
  64. int fourthDigit;
  65.  
  66. unsigned long lastTimeCheckMillis = 0;
  67.  
  68. int timeSetButtonState = HIGH;
  69. int timeSetButtonLastReading = HIGH;
  70. unsigned long timeSetButtonLastDebounceTime = 0;
  71. unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
  72. unsigned long timeSetButtonTimePressed = 0;
  73. unsigned long timeSetButtonTimeLastIncremented = 0;
  74. int timeSetButtonMinutesIncremented = 0;
  75. int timeSetButtonIncrementFastDelay = 1000;    // Time you have to press the button until in increments fast
  76. int timeSetButtonTimeBetweenFastIncrements = 7;    // Time between fast increments
  77.  
  78. int tempHours = 0;
  79. int tempMinutes = 0;
  80. int tempSeconds = 0;
  81.  
  82. // setup() function -- runs once at startup --------------------------------
  83.  
  84. void setup() {
  85.   // initialize serial communication at 9600 bits per second:
  86.   Serial.begin(9600);
  87.  
  88.   delay(3000); // wait for console opening
  89.  
  90.   if (! rtc.begin()) {
  91.     Serial.println("Couldn't find RTC");
  92.     while (1);
  93.   }
  94.  
  95.   if (rtc.lostPower()) {
  96.     Serial.println("RTC lost power, lets set the time!");
  97.     rtc.adjust(DateTime(2020, 1, 1, 0, 0, 0));
  98.   }
  99.  
  100.   strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  101.   strip.show();            // Turn OFF all pixels ASAP
  102.   strip.setBrightness(255);
  103.  
  104.   pinMode(TIME_SET_PIN, INPUT_PULLUP);
  105. }
  106.  
  107.  
  108. // loop() function -- runs repeatedly as long as board is on ---------------
  109.  
  110. void loop() {
  111.   unsigned long currentMillis = millis();
  112.  
  113.   // Handle button
  114.   if (debounceTimeSetButton()) {
  115.     // Debouncing, skip other code
  116.     return;
  117.   }
  118.  
  119.   if (timeSetButtonState == LOW) {
  120.     // Skip normal clock cycle when button is pressed, no delay
  121.     if (timeSetButtonMinutesIncremented > 0) {
  122.       // We have already incremented, after a specified time. Start counting up fast
  123.       if ((currentMillis - timeSetButtonTimePressed) > timeSetButtonIncrementFastDelay) {
  124.         if ((currentMillis - timeSetButtonTimeLastIncremented) > timeSetButtonTimeBetweenFastIncrements) {
  125.           addMinuteToTime();
  126.           printTime(tempHours, tempMinutes, 0, false);
  127.           timeSetButtonTimeLastIncremented = currentMillis;
  128.         }
  129.       }
  130.     } else {
  131.       // Increment one
  132.       addMinuteToTime();
  133.       printTime(tempHours, tempMinutes, 0, false);
  134.     }
  135.     return;
  136.   } else {
  137.     timeSetButtonMinutesIncremented = 0;
  138.   }
  139.  
  140.   // Only check time every tenth of a second
  141.   if (currentMillis - lastTimeCheckMillis > 100) {
  142.     lastTimeCheckMillis = currentMillis;
  143.    
  144.     // Copy time to variables, to be able to increment later if changing with button
  145.     DateTime now = rtc.now();
  146.     int newHours = now.hour();
  147.     int newMinutes = now.minute();
  148.     int newSeconds = now.second();
  149.  
  150.     if (newHours != tempHours || newMinutes != tempMinutes || newSeconds != tempSeconds) {
  151.       // Time has changed, update variables and leds
  152.       tempHours = newHours;
  153.       tempMinutes = newMinutes;
  154.       tempSeconds = newSeconds;
  155.      
  156.       printTime(tempHours, tempMinutes, tempSeconds, true);
  157.     }
  158.   }
  159.  
  160.   delay(30);
  161. }
  162.  
  163. void addMinuteToTime() {
  164.   tempMinutes++;
  165.   if (tempMinutes >= 60) {
  166.     tempMinutes = 0;
  167.     tempHours++;
  168.   }
  169.   if (tempHours >= 24) {
  170.     tempHours = 0;
  171.   }
  172.   timeSetButtonMinutesIncremented++;
  173. }
  174.  
  175. void printTime(int hours, int minutes, int seconds, bool doFade) {
  176.   long currentColorHue = (minutes * 60 + seconds) * 65536 / 3600; // Cycles each hour
  177.   uint32_t currentColor = strip.gamma32(strip.ColorHSV(currentColorHue));
  178.  
  179.   Serial.print("Time ");
  180.   Serial.print(hours);
  181.   Serial.print(':');
  182.   Serial.print(minutes);
  183.   Serial.print(':');
  184.   Serial.print(seconds);
  185.   Serial.print(" Hue: ");
  186.   Serial.print(currentColorHue);
  187.   Serial.println();
  188.  
  189.   int newFirstDigit = hours / 10;
  190.   int newSecondDigit = hours % 10;
  191.   int newThirdDigit = minutes / 10;
  192.   int newFourthDigit = minutes % 10;
  193.  
  194.   // Set digits
  195.   colonSet(COLON_INDEX, currentColor);
  196.  
  197.   bool firstDigitChanged = newFirstDigit != firstDigit;
  198.   bool secondDigitChanged = newSecondDigit != secondDigit;
  199.   bool thirdDigitChanged = newThirdDigit != thirdDigit;
  200.   bool fourthDigitChanged = newFourthDigit != fourthDigit;
  201.  
  202.   // Print without transition if requested, or if digit is not changed
  203.   if (!doFade || !firstDigitChanged) {
  204.     digitSet(DIGIT_1_INDEX, newFirstDigit, currentColor);
  205.   }
  206.   if (!doFade || !secondDigitChanged) {
  207.     digitSet(DIGIT_2_INDEX, newSecondDigit, currentColor);
  208.   }
  209.   if (!doFade || !thirdDigitChanged) {
  210.     digitSet(DIGIT_3_INDEX, newThirdDigit, currentColor);
  211.   }
  212.   if (!doFade || !fourthDigitChanged) {
  213.     digitSet(DIGIT_4_INDEX, newFourthDigit, currentColor);
  214.   }
  215.  
  216.   // Print transition on all digits that have changed
  217.   if (doFade && (firstDigitChanged || secondDigitChanged || thirdDigitChanged || fourthDigitChanged)) {
  218.     // Animate transition from 0-100
  219.     for (int i = 0; i <= 100; i++) {
  220.       if (firstDigitChanged) {
  221.         digitSetTransition(DIGIT_1_INDEX, newFirstDigit, firstDigit, currentColorHue, i);
  222.       }
  223.       if (secondDigitChanged) {
  224.         digitSetTransition(DIGIT_2_INDEX, newSecondDigit, secondDigit, currentColorHue, i);
  225.       }
  226.       if (thirdDigitChanged) {
  227.         digitSetTransition(DIGIT_3_INDEX, newThirdDigit, thirdDigit, currentColorHue, i);
  228.       }
  229.       if (fourthDigitChanged) {
  230.         digitSetTransition(DIGIT_4_INDEX, newFourthDigit, fourthDigit, currentColorHue, i);
  231.       }
  232.       strip.show();
  233.     }
  234.   } else {
  235.     strip.show();
  236.   }
  237.  
  238.   firstDigit = newFirstDigit;
  239.   secondDigit = newSecondDigit;
  240.   thirdDigit = newThirdDigit;
  241.   fourthDigit = newFourthDigit;
  242. }
  243.  
  244. bool debounceTimeSetButton() {
  245.   int timeSetButtonReading = digitalRead(TIME_SET_PIN);
  246.   if (timeSetButtonReading != timeSetButtonLastReading) {
  247.     // Start debounce timer
  248.     timeSetButtonLastDebounceTime = millis();
  249.   }
  250.  
  251.   if (timeSetButtonLastDebounceTime > 0 && (millis() - timeSetButtonLastDebounceTime) > debounceDelay) {
  252.     timeSetButtonLastDebounceTime = 0;
  253.     if (timeSetButtonReading != timeSetButtonState) {
  254.       timeSetButtonState = timeSetButtonReading;
  255.      
  256.       Serial.print("Button changed state to: ");
  257.       Serial.print(timeSetButtonState);
  258.       Serial.println();
  259.  
  260.       if (timeSetButtonState == LOW) {
  261.         // Button was pressed
  262.         timeSetButtonTimePressed = millis();
  263.       } else {
  264.         // Button was released, set time to clock module
  265.         timeSetButtonTimePressed = 0;
  266.         rtc.adjust(DateTime(2020, 1, 1, tempHours, tempMinutes, 0));
  267.         Serial.print("RTC set to 2020-01-01 ");
  268.         Serial.print(tempHours);
  269.         Serial.print(":");
  270.         Serial.print(tempMinutes);
  271.         Serial.print(":00");
  272.         Serial.println();
  273.       }
  274.     }
  275.   }
  276.  
  277.   timeSetButtonLastReading = timeSetButtonReading;
  278.  
  279.   if (timeSetButtonLastDebounceTime > 0) {
  280.     // Skip normal clock cycle while debouncing
  281.     return true;
  282.   }
  283.  
  284.   return false; // Not debouncing
  285. }
  286.  
  287. void digitSet(int index, int digit, uint32_t color) {
  288.   bool newSegment1Enabled = isSegment1Enabled(digit);
  289.   bool newSegment2Enabled = isSegment2Enabled(digit);
  290.   bool newSegment3Enabled = isSegment3Enabled(digit);
  291.   bool newSegment4Enabled = isSegment4Enabled(digit);
  292.   bool newSegment5Enabled = isSegment5Enabled(digit);
  293.   bool newSegment6Enabled = isSegment6Enabled(digit);
  294.   bool newSegment7Enabled = isSegment7Enabled(digit);
  295.  
  296.   uint32_t newSegment1Color, newSegment2Color, newSegment3Color, newSegment4Color, newSegment5Color, newSegment6Color, newSegment7Color;
  297.  
  298.   if (newSegment1Enabled) {
  299.     newSegment1Color = color;
  300.   } else {
  301.     newSegment1Color = BLACK;
  302.   }
  303.  
  304.   if (newSegment2Enabled) {
  305.     newSegment2Color = color;
  306.   } else {
  307.     newSegment2Color = BLACK;
  308.   }
  309.  
  310.   if (newSegment3Enabled) {
  311.     newSegment3Color = color;
  312.   } else {
  313.     newSegment3Color = BLACK;
  314.   }
  315.  
  316.   if (newSegment4Enabled) {
  317.     newSegment4Color = color;
  318.   } else {
  319.     newSegment4Color = BLACK;
  320.   }
  321.  
  322.   if (newSegment5Enabled) {
  323.     newSegment5Color = color;
  324.   } else {
  325.     newSegment5Color = BLACK;
  326.   }
  327.  
  328.   if (newSegment6Enabled) {
  329.     newSegment6Color = color;
  330.   } else {
  331.     newSegment6Color = BLACK;
  332.   }
  333.  
  334.   if (newSegment7Enabled) {
  335.     newSegment7Color = color;
  336.   } else {
  337.     newSegment7Color = BLACK;
  338.   }
  339.  
  340.   segmentSet(index+SEGMENT_1_OFFSET, newSegment1Color);
  341.   segmentSet(index+SEGMENT_2_OFFSET, newSegment2Color);
  342.   segmentSet(index+SEGMENT_3_OFFSET, newSegment3Color);
  343.   segmentSet(index+SEGMENT_4_OFFSET, newSegment4Color);
  344.   segmentSet(index+SEGMENT_5_OFFSET, newSegment5Color);
  345.   segmentSet(index+SEGMENT_6_OFFSET, newSegment6Color);
  346.   segmentSet(index+SEGMENT_7_OFFSET, newSegment7Color);
  347. }
  348.  
  349. void digitSetTransition(int index, int digit, int oldDigit, long colorHue, int transitionStep){
  350.   bool oldSegment1Enabled = isSegment1Enabled(oldDigit);
  351.   bool oldSegment2Enabled = isSegment2Enabled(oldDigit);
  352.   bool oldSegment3Enabled = isSegment3Enabled(oldDigit);
  353.   bool oldSegment4Enabled = isSegment4Enabled(oldDigit);
  354.   bool oldSegment5Enabled = isSegment5Enabled(oldDigit);
  355.   bool oldSegment6Enabled = isSegment6Enabled(oldDigit);
  356.   bool oldSegment7Enabled = isSegment7Enabled(oldDigit);
  357.  
  358.   bool newSegment1Enabled = isSegment1Enabled(digit);
  359.   bool newSegment2Enabled = isSegment2Enabled(digit);
  360.   bool newSegment3Enabled = isSegment3Enabled(digit);
  361.   bool newSegment4Enabled = isSegment4Enabled(digit);
  362.   bool newSegment5Enabled = isSegment5Enabled(digit);
  363.   bool newSegment6Enabled = isSegment6Enabled(digit);
  364.   bool newSegment7Enabled = isSegment7Enabled(digit);
  365.  
  366.   uint32_t colorEnabled = strip.gamma32(strip.ColorHSV(colorHue));
  367.   uint32_t colorTransitioningUp = strip.gamma32(strip.ColorHSV(colorHue, 255, transitionStep*255/100));
  368.   uint32_t colorTransitioningDown = strip.gamma32(strip.ColorHSV(colorHue, 255, (100-transitionStep)*255/100));
  369.   uint32_t newSegment1Color, newSegment2Color, newSegment3Color, newSegment4Color, newSegment5Color, newSegment6Color, newSegment7Color;
  370.  
  371.   if (newSegment1Enabled && oldSegment1Enabled) {
  372.     // No need to transition, keep enabled
  373.     newSegment1Color = colorEnabled;
  374.   } else if (newSegment1Enabled) {
  375.     // Transition from off to on
  376.     newSegment1Color = colorTransitioningUp;
  377.   } else if (oldSegment1Enabled) {
  378.     // Transition from on to off
  379.     newSegment1Color = colorTransitioningDown;
  380.   } else {
  381.     // No need to transition, keep off
  382.     newSegment1Color = BLACK;
  383.   }
  384.  
  385.   if (newSegment2Enabled && oldSegment2Enabled) {
  386.     // No need to transition, keep enabled
  387.     newSegment2Color = colorEnabled;
  388.   } else if (newSegment2Enabled) {
  389.     // Transition from off to on
  390.     newSegment2Color = colorTransitioningUp;
  391.   } else if (oldSegment2Enabled) {
  392.     // Transition from on to off
  393.     newSegment2Color = colorTransitioningDown;
  394.   } else {
  395.     // No need to transition, keep off
  396.     newSegment2Color = BLACK;
  397.   }
  398.  
  399.   if (newSegment3Enabled && oldSegment3Enabled) {
  400.     // No need to transition, keep enabled
  401.     newSegment3Color = colorEnabled;
  402.   } else if (newSegment3Enabled) {
  403.     // Transition from off to on
  404.     newSegment3Color = colorTransitioningUp;
  405.   } else if (oldSegment3Enabled) {
  406.     // Transition from on to off
  407.     newSegment3Color = colorTransitioningDown;
  408.   } else {
  409.     // No need to transition, keep off
  410.     newSegment3Color = BLACK;
  411.   }
  412.  
  413.   if (newSegment4Enabled && oldSegment4Enabled) {
  414.     // No need to transition, keep enabled
  415.     newSegment4Color = colorEnabled;
  416.   } else if (newSegment4Enabled) {
  417.     // Transition from off to on
  418.     newSegment4Color = colorTransitioningUp;
  419.   } else if (oldSegment4Enabled) {
  420.     // Transition from on to off
  421.     newSegment4Color = colorTransitioningDown;
  422.   } else {
  423.     // No need to transition, keep off
  424.     newSegment4Color = BLACK;
  425.   }
  426.  
  427.   if (newSegment5Enabled && oldSegment5Enabled) {
  428.     // No need to transition, keep enabled
  429.     newSegment5Color = colorEnabled;
  430.   } else if (newSegment5Enabled) {
  431.     // Transition from off to on
  432.     newSegment5Color = colorTransitioningUp;
  433.   } else if (oldSegment5Enabled) {
  434.     // Transition from on to off
  435.     newSegment5Color = colorTransitioningDown;
  436.   } else {
  437.     // No need to transition, keep off
  438.     newSegment5Color = BLACK;
  439.   }
  440.  
  441.   if (newSegment6Enabled && oldSegment6Enabled) {
  442.     // No need to transition, keep enabled
  443.     newSegment6Color = colorEnabled;
  444.   } else if (newSegment6Enabled) {
  445.     // Transition from off to on
  446.     newSegment6Color = colorTransitioningUp;
  447.   } else if (oldSegment6Enabled) {
  448.     // Transition from on to off
  449.     newSegment6Color = colorTransitioningDown;
  450.   } else {
  451.     // No need to transition, keep off
  452.     newSegment6Color = BLACK;
  453.   }
  454.  
  455.   if (newSegment7Enabled && oldSegment7Enabled) {
  456.     // No need to transition, keep enabled
  457.     newSegment7Color = colorEnabled;
  458.   } else if (newSegment7Enabled) {
  459.     // Transition from off to on
  460.     newSegment7Color = colorTransitioningUp;
  461.   } else if (oldSegment7Enabled) {
  462.     // Transition from on to off
  463.     newSegment7Color = colorTransitioningDown;
  464.   } else {
  465.     // No need to transition, keep off
  466.     newSegment7Color = BLACK;
  467.   }
  468.  
  469.   segmentSet(index+SEGMENT_1_OFFSET, newSegment1Color);
  470.   segmentSet(index+SEGMENT_2_OFFSET, newSegment2Color);
  471.   segmentSet(index+SEGMENT_3_OFFSET, newSegment3Color);
  472.   segmentSet(index+SEGMENT_4_OFFSET, newSegment4Color);
  473.   segmentSet(index+SEGMENT_5_OFFSET, newSegment5Color);
  474.   segmentSet(index+SEGMENT_6_OFFSET, newSegment6Color);
  475.   segmentSet(index+SEGMENT_7_OFFSET, newSegment7Color);
  476. }
  477.  
  478. bool isSegment1Enabled(int digit) {
  479.   switch (digit) {
  480.     case 2:
  481.     case 3:
  482.     case 4:
  483.     case 5:
  484.     case 6:
  485.     case 8:
  486.     case 9:
  487.       return true;
  488.     default:
  489.       return false;
  490.   }
  491. }
  492.  
  493. bool isSegment2Enabled(int digit) {
  494.   switch (digit) {
  495.     case 0:
  496.     case 1:
  497.     case 2:
  498.     case 3:
  499.     case 4:
  500.     case 7:
  501.     case 8:
  502.     case 9:
  503.       return true;
  504.     default:
  505.       return false;
  506.   }
  507. }
  508.  
  509. bool isSegment3Enabled(int digit) {
  510.   switch (digit) {
  511.     case 0:
  512.     case 2:
  513.     case 3:
  514.     case 5:
  515.     case 6:
  516.     case 7:
  517.     case 8:
  518.     case 9:
  519.       return true;
  520.     default:
  521.       return false;
  522.   }
  523. }
  524.  
  525. bool isSegment4Enabled(int digit) {
  526.   switch (digit) {
  527.     case 0:
  528.     case 4:
  529.     case 5:
  530.     case 6:
  531.     case 8:
  532.     case 9:
  533.       return true;
  534.     default:
  535.       return false;
  536.   }
  537. }
  538.  
  539. bool isSegment5Enabled(int digit) {
  540.   switch (digit) {
  541.     case 0:
  542.     case 2:
  543.     case 6:
  544.     case 8:
  545.       return true;
  546.     default:
  547.       return false;
  548.   }
  549. }
  550.  
  551. bool isSegment6Enabled(int digit) {
  552.   switch (digit) {
  553.     case 0:
  554.     case 2:
  555.     case 3:
  556.     case 5:
  557.     case 6:
  558.     case 8:
  559.     case 9:
  560.       return true;
  561.     default:
  562.       return false;
  563.   }
  564. }
  565.  
  566. bool isSegment7Enabled(int digit) {
  567.   switch (digit) {
  568.     case 0:
  569.     case 1:
  570.     case 3:
  571.     case 4:
  572.     case 5:
  573.     case 6:
  574.     case 7:
  575.     case 8:
  576.     case 9:
  577.       return true;
  578.     default:
  579.       return false;
  580.   }
  581. }
  582.  
  583. void segmentSet(int ledIndex, uint32_t color){
  584.   for(int i=ledIndex; i<ledIndex+5; i++){
  585.     strip.setPixelColor(i, color);
  586.   }  
  587. }
  588.  
  589. void colonSet(int ledIndex, uint32_t color){
  590.   for(int i=ledIndex; i<ledIndex+2; i++){
  591.     strip.setPixelColor(i, color);
  592.   }  
  593. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement