DS3231 analoge klok

Beste forumleden,

Ik heb een klein projectje, dacht ik. Ik heb een grote wandklok en aan de achterkant heb ik 60 ledjes (WS2812, 5v) gemaakt en tijdens het maken kwam ik erachter dat als de klok zou lopen dat hij tegen de klok in zou lopen. Ik dacht dat het geen probleem zou zijn omdat ik er vanuit ging dat het een simpele aanpassing in de RTClib zou zijn maar helaas was dat te makkelijk gedacht van mij. Ik gebruik een Arduino nano voor de aansturing. Kan iemand mij vertellen of uitleggen hoe ik de klok tegengesteld kan laten lopen? Alvast bedankt.

Groeten Michel

verander in regel 21 de weerstand van de triac :smiley:

Met andere woorden.....
Op basis van de door je aangeleverde info is het niet waarschijnlijk dat er een duidelijk antwoord zal komen. Als je software matige adviezen wil, is het handig het gebruikte programma hier te vermelden opdat ernaar gekeken en over nagedacht kan worden.

Suc7

Hoi Frits,

Bedankt voor je reactie. Ik gebruik Arduino IDE 2.2.1 om de code te uploaden naar mijn Aduino nano. Dit is de code die ik gebruik:


```cpp
// Add options for background settings
// TO DO: Clean up and comment code...
// BUG: demo state should start as mode 0 after intro
// NICE TO HAVE: When alarm is cancelled, the alarm still remains set for next day.

//Add the following libraries to the respective folder for you operating system. See http://arduino.cc/en/Guide/Environment
#include <FastLED.h> // FastSPI Library from http://code.google.com/p/fastspi/
#include <Wire.h> //This is to communicate via I2C. On arduino Uno & Nano use pins A4 for SDA (yellow/orange) and A5 for SCL (green). For other boards ee http://arduino.cc/en/Reference/Wire
#include <RTClib.h>           // Include the RTClib library to enable communication with the real time clock.
#include <EEPROM.h>           // Include the EEPROM library to enable the storing and retrevel of settings.
#include <Bounce.h>           // Include the Bounce library for de-bouncing issues with push buttons.
#include <Encoder.h>          // Include the Encoder library to read the out puts of the rotary encoders

RTC_DS1307 RTC; // Establishes the chipset of the Real Time Clock

#define LEDStripPin A0 // Pin used for the data to the LED strip
#define menuPin A3 // Pin used for the menu button (green stripe)
#define numLEDs 60 // Number of LEDs in strip

// Setting up the LED strip
struct CRGB leds[numLEDs];
Encoder rotary1(2, 3); // Setting up the Rotary Encoder

DateTime old; // Variable to compare new and old time, to see if it has moved on.
int rotary1Pos  = 0;
int subSeconds; // 60th's of a second
int secondBrightness;
int secondBrightness2;
int breathBrightness;
long newSecTime; // Variable to record when a new second starts, allowing to create milli seconds
long oldSecTime;
long flashTime; //
long breathCycleTime;
#define holdTime 1500
int cyclesPerSec;
float cyclesPerSecFloat; // So can be used as a float in calcs
float fracOfSec;
float breathFracOfSec;
boolean demo;
#define demoTime 12 // seconds
long previousDemoTime;
long currentDemoTime;
boolean swingBack = false;

int timeHour;
int timeMin;
int timeSec;
int alarmMin; // The minute of the alarm  
int alarmHour; // The hour of the alarm 0-23
int alarmDay = 0; // The day of the alarm
boolean alarmSet; // Whether the alarm is set or not
int modeAddress = 0; // Address of where mode is stored in the EEPROM
int alarmMinAddress = 1; // Address of where alarm minute is stored in the EEPROM
int alarmHourAddress = 2; // Address of where alarm hour is stored in the EEPROM
int alarmSetAddress = 3; // Address of where alarm state is stored in the EEPROM
int alarmModeAddress = 4; // Address of where the alarm mode is stored in the EEPROM
boolean alarmTrig = false; // Whether the alarm has been triggered or not
long alarmTrigTime; // Milli seconds since the alarm was triggered
boolean countDown = false;
long countDownTime = 0;
long currentCountDown = 0;
long startCountDown;
int countDownMin;
int countDownSec;
int countDownFlash;
int demoIntro = 0;
int j = 0;
long timeInterval = 5;
long currentMillis;
long previousMillis = 0;
float LEDBrightness = 0;
float fadeTime;
float brightFadeRad;

int state = 0; // Variable of the state of the clock, with the following defined states 
#define clockState 0
#define alarmState 1
#define setAlarmHourState 2
#define setAlarmMinState 3
#define setClockHourState 4
#define setClockMinState 5
#define setClockSecState 6
#define countDownState 7
#define demoState 8
int mode; // Variable of the display mode of the clock
int modeMax = 6; // Change this when new modes are added. This is so selecting modes can go back beyond.
int alarmMode; // Variable of the alarm display mode
int alarmModeMax = 3;

Bounce menuBouncer = Bounce(menuPin,20); // Instantiate a Bounce object with a 50 millisecond debounce time for the menu button
boolean menuButton = false; 
boolean menuPressed = false;
boolean menuReleased = false;
int advanceMove = 0;
boolean countTime = false;
long menuTimePressed;
long lastRotary;
int rotaryTime = 1000;

int LEDPosition;
int reverseLEDPosition;
int pendulumPos;
int fiveMins;
int odd;
int LEDOffset = 30;

void setup()
{
  // Set up all pins
  pinMode(menuPin, INPUT_PULLUP);     // Uses the internal 20k pull up resistor. Pre Arduino_v.1.0.1 need to be "digitalWrite(menuPin,HIGH);pinMode(menuPin,INPUT);"
    
  // Start LEDs
  LEDS.addLeds<WS2811, LEDStripPin, GRB>(leds, numLEDs); // Structure of the LED data. I have changed to from rgb to grb, as using an alternative LED strip. Test & change these if you're getting different colours. 
  
  // Start RTC
  Wire.begin(); // Starts the Wire library allows I2C communication to the Real Time Clock
  RTC.begin(); // Starts communications to the RTC
  
  Serial.begin(9600); // Starts the serial communications

  // Uncomment to reset all the EEPROM addresses. You will have to comment again and reload, otherwise it will not save anything each time power is cycled
  // write a 0 to all 512 bytes of the EEPROM
//  for (int i = 0; i < 512; i++)
//  {EEPROM.write(i, 0);}

  // Load any saved setting since power off, such as mode & alarm time  
  mode = EEPROM.read(modeAddress); // The mode will be stored in the address "0" of the EEPROM
  alarmMin = EEPROM.read(alarmMinAddress); // The mode will be stored in the address "1" of the EEPROM
  alarmHour = EEPROM.read(alarmHourAddress); // The mode will be stored in the address "2" of the EEPROM
  alarmSet = EEPROM.read(alarmSetAddress); // The mode will be stored in the address "2" of the EEPROM
  alarmMode = EEPROM.read(alarmModeAddress);
  // Prints all the saved EEPROM data to Serial
  Serial.print("Mode is ");Serial.println(mode);
  Serial.print("Alarm Hour is ");Serial.println(alarmHour);
  Serial.print("Alarm Min is ");Serial.println(alarmMin);
  Serial.print("Alarm is set ");Serial.println(alarmSet);
  Serial.print("Alarm Mode is ");Serial.println(alarmMode);

  // create a loop that calcuated the number of counted milliseconds between each second.
  DateTime now = RTC.now();
  //  startTime = millis();  
  //  while (RTC.old() = RTC.new())
  
  //  if (now.month() == 1 && now.day() == 1 && now.hour() == 0 && now.minute() == 0 && now.minute() == 0)
  //    {}
      
  Serial.print("Hour time is... ");
  Serial.println(now.hour());
  Serial.print("Min time is... ");
  Serial.println(now.minute());
  Serial.print("Sec time is... ");
  Serial.println(now.second());

  Serial.print("Year is... ");
  Serial.println(now.year());
  Serial.print("Month is... ");
  Serial.println(now.month());
  Serial.print("Day is... ");
  Serial.println(now.day());
}


void loop()
{
  DateTime now = RTC.now(); // Fetches the time from RTC
  
  // Check for any button presses and action accordingley
  menuButton = menuBouncer.update();  // Update the debouncer for the menu button and saves state to menuButton
  rotary1Pos = rotary1.read(); // Checks the rotary position
  if (rotary1Pos <= -2 && lastRotary - millis() >= rotaryTime)
    {
      advanceMove = -1;
      rotary1.write(0);
      lastRotary = millis();
    } 
  if (rotary1Pos >= 2 && lastRotary - millis() >= rotaryTime)
    {
      advanceMove = 1;
      rotary1.write(0);
      lastRotary = millis();
    }
  if (menuButton == true || advanceMove != 0 || countTime == true) {buttonCheck(menuBouncer,now);}
  
  // clear LED array
  memset(leds, 0, numLEDs * 3);
  
  // Check alarm and trigger if the time matches
  if (alarmSet == true && alarmDay != now.day()) // The alarmDay statement ensures it is a newly set alarm or repeat from previous day, not within the minute of an alarm cancel.
    {
      if (alarmTrig == false) {alarm(now);}
      else {alarmDisplay();}
    }
 // Check the Countdown Timer
  if (countDown == true)
    {
      currentCountDown = countDownTime + startCountDown - now.unixtime();
      if ( currentCountDown <= 0)
        {
          state =countDownState;
        }
    } 
  // Set the time LED's
  if (state == setClockHourState || state == setClockMinState || state == setClockSecState) {setClockDisplay(now);}
  else if (state == alarmState || state == setAlarmHourState || state == setAlarmMinState) {setAlarmDisplay();}
  else if (state == countDownState) {countDownDisplay(now);}
  else if (state == demoState) {runDemo(now);}
  else {timeDisplay(now);}

  // Update LEDs
  LEDS.show();
}

void buttonCheck(Bounce menuBouncer, DateTime now)
{
  if (menuBouncer.fallingEdge()) // Checks if a button is pressed, if so sets countTime to true
    {
      countTime = true;
      Serial.println("rising edge");
    }
  if (menuBouncer.risingEdge()) // Checks if a button is released,
    {
      countTime = false;
      Serial.println("rising edge");
    } // if so sets countTime to false. Now the ...TimePressed will not be updated when enters the buttonCheck,
  if (countTime) // otherwise will menuBouncer.duration will 
    {
      menuTimePressed = menuBouncer.duration();
      if (menuTimePressed >= (holdTime - 100) && menuTimePressed <= holdTime)
        {
          clearLEDs();
          LEDS.show();
          delay(100);
        }
    }
  menuReleased = menuBouncer.risingEdge();
  if (menuPressed == true) {Serial.println("Menu Button Pressed");}
  if (menuReleased == true) {Serial.println("Menu Button Released");}
  Serial.print("Menu Bounce Duration ");
  Serial.println(menuTimePressed);
  if (alarmTrig == true)
    {
      alarmTrig = false;
      alarmDay = now.day(); // When the alarm is cancelled it will not display until next day. As without it, it would start again if within a minute, or completely turn off the alarm.
      delay(300); // I added this 300ms delay, so there is time for the button to be released
      return; // This return exits the buttonCheck function, so no actions are performs
    }  
  switch (state)
    {
      case clockState: // State 0
        if (advanceMove == -1 && mode == 0)
          {
            mode = modeMax;
            advanceMove = 0;
          }
        else if(advanceMove != 0) //if displaying the clock, advance button is pressed & released, then mode will change
          {
            mode = mode + advanceMove;
            EEPROM.write(modeAddress,mode);
            advanceMove = 0;
          }
        else if(menuReleased == true) 
          {
            if (menuTimePressed <= holdTime) {state = alarmState; newSecTime = millis();}// if displaying the clock, menu button is pressed & released, then Alarm is displayed 
            else {state = setClockHourState;} // if displaying the clock, menu button is held & released, then clock hour can be set
          }
        break;
      case alarmState: // State 1
        if (advanceMove == -1 && alarmMode <= 0)
          {
            alarmMode = alarmModeMax;
            alarmSet = 1;
          }
        else if (advanceMove == 1 && alarmMode >= alarmModeMax)
          {
            alarmMode = 0;
            alarmSet = 0;
          }
        else if (advanceMove != 0)
          {
            alarmMode = alarmMode + advanceMove;
            if (alarmMode == 0) {alarmSet = 0;}
            else {alarmSet = 1;}
          }          
        Serial.print("alarmState is ");
        Serial.println(alarmState);            
        Serial.print("alarmMode is ");
        Serial.println(alarmMode);
        EEPROM.write(alarmSetAddress,alarmSet);
        EEPROM.write(alarmModeAddress,alarmMode);
        advanceMove = 0;
        alarmTrig = false;
        if (menuReleased == true) 
          {
            if (menuTimePressed <= holdTime) {state = countDownState; j = 0;}// if displaying the alarm time, menu button is pressed & released, then clock is displayed
            else {state = setAlarmHourState;} // if displaying the alarm time, menu button is held & released, then alarm hour can be set
          }
        break;
      case setAlarmHourState: // State 2
        if (menuReleased == true) {state = setAlarmMinState;}
        else if (advanceMove == 1 && alarmHour >= 23) {alarmHour = 0;}
        else if (advanceMove == -1 && alarmHour <= 0) {alarmHour = 23;}
        else if (advanceMove != 0) {alarmHour = alarmHour + advanceMove;}
        EEPROM.write(alarmHourAddress,alarmHour);
        advanceMove = 0;
        break;
      case setAlarmMinState: // State 3
        if (menuReleased == true)
          {
            state = alarmState;
            alarmDay = 0;
            newSecTime = millis();
          }
        else if (advanceMove == 1 && alarmMin >= 59) {alarmMin = 0;}
        else if (advanceMove == -1 && alarmMin <= 0) {alarmMin = 59;}
        else if (advanceMove != 0) {alarmMin = alarmMin + advanceMove;}
        EEPROM.write(alarmMinAddress,alarmMin);
        advanceMove = 0;
        break;
      case setClockHourState: // State 4
        if (menuReleased == true) {state = setClockMinState;}
        else if (advanceMove == 1 && now.hour() == 23)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), 0, now.minute(), now.second()));
            advanceMove = 0;
          }
        else if (advanceMove == -1 && now.hour() == 0)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), 23, now.minute(), now.second()));
            advanceMove = 0;
          }
        else if (advanceMove != 0)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + advanceMove), now.minute(), now.second()));
            advanceMove = 0;
          }
        break;
      case setClockMinState: // State 5
        if (menuReleased == true) {state = setClockSecState;}
        else if (advanceMove == 1 && now.minute() == 59)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 0, now.second()));
            advanceMove = 0;
          }
        else if (advanceMove == -1 && now.minute() == 0)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 59, now.second()));
            advanceMove = 0;
          }
        else if (advanceMove != 0)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), (now.minute() + advanceMove), now.second()));
            advanceMove = 0;
          }
        break;
      case setClockSecState: // State 6
        if (menuReleased == true) {state = clockState;}
        else if (advanceMove == 1 && now.second() == 59)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 0));
            advanceMove = 0;
          }
        else if (advanceMove == -1 && now.second() == 0)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 59));
            advanceMove = 0;
          }
        else if (advanceMove != 0)
          {
            RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), (now.second() + advanceMove)));
            advanceMove = 0;
          }
        break;
      case countDownState: // State 7
        if(menuReleased == true) 
          {
            if (menuTimePressed <= holdTime)
              {
                if (countDown == true && countDownTime <= 0) {countDown = false; countDownTime = 0; currentCountDown = 0;}
                else if (countDown == false && countDownTime > 0) {countDown = true; startCountDown = now.unixtime();}
                else {state = demoState; demoIntro = 1; j = 0;}// if displaying the count down, menu button is pressed & released, then demo State is displayed 
              } 
            else {countDown = false; countDownTime = 0; currentCountDown = 0; j = 0;} // if displaying the clock, menu button is held & released, then the count down is reset
          }
        else if (advanceMove == -1 && currentCountDown <= 0)
          {
            countDown = false;
            countDownTime = 0;
            currentCountDown = 0;
            demoIntro = 0;          
          }
        else if (advanceMove == 1 && currentCountDown >= 3600)
          {
            countDown = false;
            countDownTime = 3600;           
          }
        else if (advanceMove != 0) //if displaying the count down, rotary encoder is turned then will change accordingley
          {
            countDown = false;
            countDownTime = currentCountDown - currentCountDown%60 + advanceMove*60; // This rounds the count down minute up to the next minute
          }
        advanceMove = 0;
        break;
      case demoState: // State 8
        if(menuReleased == true) {state = clockState; mode = EEPROM.read(modeAddress);} // if displaying the demo, menu button pressed then the clock will display and restore to the mode before demo started
        break;
    }
  if (menuReleased || advanceMove !=0) {countTime = false;}
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("State is ");
  Serial.println(state);
}

void setAlarmDisplay()
{

  for (int i = 0; i < numLEDs; i++)
    {
      fiveMins = i%5;
      if (fiveMins == 0)
        {
          leds[i].r = 100;
          leds[i].g = 100;
          leds[i].b = 100;
        }
    }

  if (alarmSet == 0)
    {
      for (int i = 0; i < numLEDs; i++) // Sets background to red, to state that alarm IS NOT set
        {
          fiveMins = i%5;
          if (fiveMins == 0)
            {
              leds[i].r = 20;
              leds[i].g = 0;
              leds[i].b = 0;
            }  
        }     
    }
  else
    {
      for (int i = 0; i < numLEDs; i++) // Sets background to green, to state that alarm IS set
        {
          fiveMins = i%5;
          if (fiveMins == 0)
            {
              leds[i].r = 0;
              leds[i].g = 20;
              leds[i].b = 0;
            }  
        }     
    }
  if (alarmHour <= 11)
    {
      leds[(alarmHour*5+LEDOffset)%60].r = 255;
    }
  else
    {
      leds[((alarmHour - 12)*5+LEDOffset+59)%60].r = 25;    
      leds[((alarmHour - 12)*5+LEDOffset)%60].r = 255;
      leds[((alarmHour - 12)*5+LEDOffset+1)%60].r = 25;
    }
  leds[(alarmMin+LEDOffset)%60].g = 100;
  flashTime = millis();
  if (state == setAlarmHourState && flashTime%300 >= 150)
    {
      leds[(((alarmHour%12)*5)+LEDOffset+59)%60].r = 0;   
      leds[(((alarmHour%12)*5)+LEDOffset)%60].r = 0;
      leds[(((alarmHour%12)*5)+LEDOffset+1)%60].r = 0; 
    }
  if (state == setAlarmMinState && flashTime%300 >= 150)
    {
      leds[(alarmMin+LEDOffset)%60].g = 0;
    }
  leds[(alarmMode+LEDOffset)%60].b = 255;
}

void setClockDisplay(DateTime now)
{
  for (int i = 0; i < numLEDs; i++)
    {
      fiveMins = i%5;
      if (fiveMins == 0)
        {
          leds[i].r = 10;
          leds[i].g = 10;
          leds[i].b = 10;
        }
    } 
  if (now.hour() <= 11) {leds[(now.hour()*5+LEDOffset)%60].r = 255;}
  else
    {
      leds[((now.hour() - 12)*5+LEDOffset+59)%60].r = 255;
      leds[((now.hour() - 12)*5+LEDOffset)%60].r = 255;   
      leds[((now.hour() - 12)*5+LEDOffset+1)%60].r = 255;
    }
  flashTime = millis();
  if (state == setClockHourState && flashTime%300 >= 150)
    {
      leds[(((now.hour()%12)*5)+LEDOffset+59)%60].r = 0;   
      leds[((now.hour()%12)*5+LEDOffset)%60].r = 0;
      leds[(((now.hour()%12)*5)+LEDOffset+1)%60].r = 0; 
    }
  if (state == setClockMinState && flashTime%300 >= 150) {leds[(now.minute()+LEDOffset)%60].g = 0;}
  else {leds[(now.minute()+LEDOffset)%60].g = 255;}
  if (state == setClockSecState && flashTime%300 >= 150) {leds[(now.second()+LEDOffset)%60].b = 0;}
  else {leds[(now.second()+LEDOffset)%60].b = 255;}
}

// Check if alarm is active and if is it time for the alarm to trigger
void alarm(DateTime now)
{
  if ((alarmMin == now.minute()%60) && (alarmHour == now.hour()%24)) //check if the time is the same to trigger alarm
    {
      alarmTrig = true;
      alarmTrigTime = millis();
    }
}

void alarmDisplay() // Displays the alarm
{
  switch (alarmMode)
    {
      case 1:
        // set all LEDs to a dim white
        for (int i = 0; i < numLEDs; i++)
          {
            leds[i].r = 100;
            leds[i].g = 100;
            leds[i].b = 100;
          }
        break;
      case 2:
        LEDPosition = ((millis() - alarmTrigTime)/300);
        reverseLEDPosition = 60 - LEDPosition;
        if (LEDPosition >= 0 && LEDPosition <= 29)
          {
            for (int i = 0; i < LEDPosition; i++)
              {
                leds[(i+LEDOffset)%60].r = 5;
                leds[(i+LEDOffset)%60].g = 5;
                leds[(i+LEDOffset)%60].b = 5;
              }
          }
        if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31)
          {
            for (int i = 59; i > reverseLEDPosition; i--)
              {
                leds[(i+LEDOffset)%60].r = 5;
                leds[(i+LEDOffset)%60].g = 5;
                leds[(i+LEDOffset)%60].b = 5;
              }              
          }
        if (LEDPosition >= 30)
          {
            for (int i = 0; i < numLEDs; i++)
              {
                leds[(i+LEDOffset)%60].r = 5;
                leds[(i+LEDOffset)%60].g = 5;
                leds[(i+LEDOffset)%60].b = 5;
              }           
          }            
        break;
      case 3:
        fadeTime = 60000;
        brightFadeRad = (millis() - alarmTrigTime)/fadeTime; // Divided by the time period of the fade up.
        if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255;
        else LEDBrightness = 255.0*(1.0+sin((1.57*brightFadeRad)-1.57));
        Serial.println(brightFadeRad);
        Serial.println(LEDBrightness);
        for (int i = 0; i < numLEDs; i++)
          {
            leds[i].r = LEDBrightness;
            leds[i].g = LEDBrightness;
            leds[i].b = LEDBrightness;
          }
        break;

// Currently not working        
//      case 4:
//        fadeTime = 60000;
//        brightFadeRad = (millis() - alarmTrigTime)/fadeTime; // Divided by the time period of the fade up.
//        LEDPosition = ((millis() - alarmTrigTime)/(fadeTime/30));
////        if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255; // If the fade time is complete, then the LED brightness will be set to full.
//        if (brightFadeRad <= 0) LEDBrightness = 0;
//        else if (brightFadeRad >= 0) LEDBrightness = 1;
//        else LEDBrightness = 255.0*(1.0+sin((1.57*brightFadeRad)-1.57));
//        
////        Serial.println(brightFadeRad);
////        Serial.println(LEDBrightness);
//        reverseLEDPosition = 60 - LEDPosition;
//        if (LEDPosition >= 0 && LEDPosition <= 29)
//          {
//            for (int i = 0; i < LEDPosition; i++)
//              {
//                leds[i].r = LEDBrightness;
//                leds[i].g = LEDBrightness;
//                leds[i].b = LEDBrightness;
//              }
//          }
//        if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31)
//          {
//            for (int i = 59; i > reverseLEDPosition; i--)
//              {
//                leds[i].r = LEDBrightness;
//                leds[i].g = LEDBrightness;
//                leds[i].b = LEDBrightness;
//              }              
//          }
//        if (LEDPosition >= 30)
//          {
//            for (int i = 0; i < numLEDs; i++)
//              {
//                leds[i].r = LEDBrightness;
//                leds[i].g = LEDBrightness;
//                leds[i].b = LEDBrightness;
//              }           
//          }  
//        break;
    }
}

//  
void countDownDisplay(DateTime now)
{
  flashTime = millis();
  if (countDown == true)
    {
      currentCountDown = countDownTime + startCountDown - now.unixtime();
      if (currentCountDown > 0)
        {
          countDownMin = currentCountDown / 60;
          countDownSec = currentCountDown%60 * 4; // have multiplied by 4 to create brightness
          for (int i = 0; i < countDownMin; i++) {leds[(i+LEDOffset+1)%60].b = 240;} // Set a blue LED for each complete minute that is remaining 
          leds[(countDownMin+LEDOffset+1)%60].b = countDownSec; // Display the remaining secconds of the current minute as its brightness      
        }
      else
        {
          countDownFlash = now.unixtime()%2;
          if (countDownFlash == 0)
            {
              for (int i = 0; i < numLEDs; i++) // Set the background as all off
                {
                  leds[i].r = 0;
                  leds[i].g = 0;
                  leds[i].b = 0;
                }
            }
          else
            {
              for (int i = 0; i < numLEDs; i++) // Set the background as all blue
                {
                  leds[i].r = 0;
                  leds[i].g = 0;
                  leds[i].b = 255;
                }
            }
        }
    }
  else
    {
      currentCountDown = countDownTime;
      if (countDownTime == 0)
        {
          currentMillis = millis();
          clearLEDs();
          switch (demoIntro)
            {
              case 0:
                for (int i = 0; i < j; i++) {leds[(i+LEDOffset+1)%60].b = 20;}
                if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
                if (j == numLEDs) {demoIntro = 1;}
                break;
              case 1:
                for (int i = 0; i < j; i++) {leds[(i+LEDOffset+1)%60].b = 20;}
                if (currentMillis - previousMillis > timeInterval) {j--; previousMillis = currentMillis;}
                if (j < 0) {demoIntro = 0;}
                break;
            }
        }
      else if (countDownTime > 0 && flashTime%300 >= 150)
        {
          countDownMin = currentCountDown / 60; //
          for (int i = 0; i < countDownMin; i++) {leds[(i+LEDOffset+1)%60].b = 255;} // Set a blue LED for each complete minute that is remaining
        }
    }
}

void runDemo(DateTime now)
{
  currentDemoTime = now.unixtime();
  currentMillis = millis();
  clearLEDs();
  switch (demoIntro)
    {
      case 0:
        timeDisplay(now);
        if (currentDemoTime - previousDemoTime > demoTime) {previousDemoTime = currentDemoTime; mode++;}
        break;
      case 1:
        for (int i = 0; i < j; i++) {leds[i].r = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 2:
        for (int i = j; i < numLEDs; i++) {leds[i].r = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 3:
        for (int i = 0; i < j; i++) {leds[i].g = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 4:
        for (int i = j; i < numLEDs; i++) {leds[i].g = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 5:
        for (int i = 0; i < j; i++) {leds[i].b = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 6:
        for (int i = j; i < numLEDs; i++) {leds[i].b = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 7:
        for (int i = 0; i < j; i++) {leds[i].r = 255; leds[i].g = 255; leds[i].b = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs) {j = 0; demoIntro++;}
        break;
      case 8:
        for (int i = j; i < numLEDs; i++) {leds[i].r = 255; leds[i].g = 255; leds[i].b = 255;}
        if (currentMillis - previousMillis > timeInterval) {j++; previousMillis = currentMillis;}
        if (j == numLEDs)
          {
            demoIntro = 0;
            mode = 0;
            Serial.print("Mode is ");
            Serial.println(mode);
            Serial.print("State is ");
            Serial.println(state);
          }
        break;
    }
}

void clearLEDs()
{      
  for (int i = 0; i < numLEDs; i++) // Set all the LEDs to off
    {
      leds[i].r = 0;
      leds[i].g = 0;
      leds[i].b = 0;
    }
}

void timeDisplay(DateTime now)
{ 
  switch (mode)
    {
      case 0:
        minimalClock(now);
        break;
      case 1:
        basicClock(now);
        break;
      case 2:
        smoothSecond(now);
        break;
      case 3:
        outlineClock(now);
        break;
      case 4:
        minimalMilliSec(now);
        break;
      case 5:
        simplePendulum(now);
        break;
      case 6:
        breathingClock(now);
        break;
      default: // Keep this here and add more timeDisplay modes as defined cases.
        {
          mode = 0;
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////
//   CLOCK DISPLAY MODES
// Add any new display mode functions here. Then add to the "void timeDisplay(DateTime now)" function.
// Add each of the new display mode functions as a new "case", leaving default last.
////////////////////////////////////////////////////////////////////////////////////////////

//
void minimalClock(DateTime now)
{
  unsigned char hourPos = (now.hour()%12)*5;
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.second()+LEDOffset)%60].b = 255;
}

//
void basicClock(DateTime now)
{
  unsigned char hourPos = ((now.hour()%12)*5 + (now.minute()+6)/12);
  leds[(hourPos+LEDOffset+59)%60].r = 255;
  leds[(hourPos+LEDOffset+59)%60].g = 0;
  leds[(hourPos+LEDOffset+59)%60].b = 0;  
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(hourPos+LEDOffset)%60].g = 0;
  leds[(hourPos+LEDOffset)%60].b = 0;
  leds[(hourPos+LEDOffset+1)%60].r = 255;
  leds[(hourPos+LEDOffset+1)%60].g = 0;
  leds[(hourPos+LEDOffset+1)%60].b = 0;
  leds[(now.minute()+LEDOffset)%60].r = 0;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.minute()+LEDOffset)%60].b = 0;  
  leds[(now.second()+LEDOffset)%60].r = 0;
  leds[(now.second()+LEDOffset)%60].g = 0;
  leds[(now.second()+LEDOffset)%60].b = 255;
  
}

// 
void smoothSecond(DateTime now)
{
  if (now.second()!=old.second())
    {
      old = now;
      cyclesPerSec = millis() - newSecTime;
      cyclesPerSecFloat = (float) cyclesPerSec;
      newSecTime = millis();      
    } 
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime)/cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec) {secondBrightness = 50.0*(1.0+sin((3.14*fracOfSec)-1.57));}
  if (subSeconds < cyclesPerSec) {secondBrightness2 = 50.0*(1.0+sin((3.14*fracOfSec)+1.57));}
  unsigned char hourPos = ((now.hour()%12)*5 + (now.minute()+6)/12);
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos+LEDOffset+59)%60].r = 255;   
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(hourPos+LEDOffset+1)%60].r = 255;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.second()+LEDOffset)%60].b = secondBrightness;
  leds[(now.second()+LEDOffset+59)%60].b = secondBrightness2;
}

//
void outlineClock(DateTime now)
{
  for (int i = 0; i < numLEDs; i++)
    {
      fiveMins = i%5;
      if (fiveMins == 0)
        {
          leds[i].r = 100;
          leds[i].g = 100;
          leds[i].b = 100;
        }
    }
  unsigned char hourPos = ((now.hour()%12)*5 + (now.minute()+6)/12);
  leds[(hourPos+LEDOffset+59)%60].r = 255;   
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(hourPos+LEDOffset+1)%60].r = 255;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.second()+LEDOffset)%60].b = 255;
}
//
void minimalMilliSec(DateTime now)
{
  if (now.second()!=old.second())
    {
      old = now;
      cyclesPerSec = (millis() - newSecTime);
      newSecTime = millis();
    } 
  // set hour, min & sec LEDs
  unsigned char hourPos = ((now.hour()%12)*5 + (now.minute()+6)/12);
  subSeconds = (((millis() - newSecTime)*60)/cyclesPerSec)%60;  // This divides by 733, but should be 1000 and not sure why???
  // Millisec lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(subSeconds+LEDOffset)%60].r = 50;
  leds[(subSeconds+LEDOffset)%60].g = 50;
  leds[(subSeconds+LEDOffset)%60].b = 50;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos+LEDOffset+59)%60].r = 255;   
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(hourPos+LEDOffset+1)%60].r = 255;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.second()+LEDOffset)%60].b = 255;
}

// Pendulum will be at the bottom and left for one second and right for one second
void simplePendulum(DateTime now)
{
  if (now.second()!=old.second())
    {
      old = now;
      cyclesPerSec = millis() - newSecTime;
      cyclesPerSecFloat = (float) cyclesPerSec;
      newSecTime = millis();
      if (swingBack == true) {swingBack = false;}
      else {swingBack = true;}
    } 
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime)/cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec && swingBack == true) {pendulumPos = 27.0 + 3.4*(1.0+sin((3.14*fracOfSec)-1.57));}
  if (subSeconds < cyclesPerSec && swingBack == false) {pendulumPos = 27.0 + 3.4*(1.0+sin((3.14*fracOfSec)+1.57));}
  unsigned char hourPos = ((now.hour()%12)*5 + (now.minute()+6)/12);
  // Pendulum lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(pendulumPos + LEDOffset)%60].r = 100;
  leds[(pendulumPos + LEDOffset)%60].g = 100;
  leds[(pendulumPos + LEDOffset)%60].b = 100;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos+LEDOffset+59)%60].r = 255;   
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(hourPos+LEDOffset+1)%60].r = 255;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.second()+LEDOffset)%60].b = 255;
}

void breathingClock(DateTime now)
{
  if (alarmTrig == false)
    {
      breathBrightness = 15.0*(1.0+sin((3.14*millis()/2000.0)-1.57));
      for (int i = 0; i < numLEDs; i++)
        {
          fiveMins = i%5;
          if (fiveMins == 0)
            {
              leds[i].r = breathBrightness + 5;
              leds[i].g = breathBrightness + 5;
              leds[i].b = breathBrightness + 5;
            }
          else
            {
              leds[i].r = 0;
              leds[i].g = 0;
              leds[i].b = 0;
            }
        }
    }
  unsigned char hourPos = ((now.hour()%12)*5 + (now.minute()+6)/12);
  leds[(hourPos+LEDOffset+59)%60].r = 255;   
  leds[(hourPos+LEDOffset)%60].r = 255;
  leds[(hourPos+LEDOffset+1)%60].r = 255;
  leds[(now.minute()+LEDOffset)%60].g = 255;
  leds[(now.second()+LEDOffset)%60].b = 255;
}


/*
// Cycle through the color wheel, equally spaced around the belt
void rainbowCycle(uint8_t wait)
{
  uint16_t i, j;
  for (j=0; j < 384 * 5; j++)
    {     // 5 cycles of all 384 colors in the wheel
      for (i=0; i < numLEDs; i++)
        {
          // tricky math! we use each pixel as a fraction of the full 384-color
          // wheel (thats the i / strip.numPixels() part)
          // Then add in j which makes the colors go around per pixel
          // the % 384 is to make the wheel cycle around
          strip.setPixelColor(i, Wheel(((i * 384 / numLEDs) + j) % 384));
        }
      delay(wait);
    }
}

//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g - b - back to r

uint32_t Wheel(uint16_t WheelPos)
{
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128; // red down
      g = WheelPos % 128;       // green up
      b = 0;                    // blue off
      break;
    case 1:
      g = 127 - WheelPos % 128; // green down
      b = WheelPos % 128;       // blue up
      r = 0;                    // red off
      break;
    case 2:
      b = 127 - WheelPos % 128; // blue down
      r = WheelPos % 128;       // red up
      g = 0;                    // green off
      break;
  }
  return(strip.Color(r,g,b));
}
*/

Hopelijk is het zo iets duidelijker.

Groeten Michel

Houdt dat in dat bv 5 minuten aangeduidt wordt met een led op 55 minuten? Indien ja, dan kun je je for-loops aanpassen

for (int i = 0; i < numLEDs; i++)
// fixed i++ to i--
for (int i = NUMLEDS - 1; i >= 0; i--)

Er zal waarschijnlijk wat meer nodig zijn maar dit zou je op weg moeten helpen.

Hoi Sterretje,

Bedankt voor je reactie. Helaas is dat niet het geval. Als ik de klok omdraai, dus met de ledjes van de muur af dan loopt hij gewoon goed. Hij moet echt tegen de klok in draaien.

Groeten Michel

Ik denk dat we hetzelfde bedoelen. Hieronder twee test versies voor de loop() functie.

Als ik je goed begrijp draait de onderstaande tegen de klok in (wat je niet wilt; linksom).

void loop()
{
  for (int i = 0; i < NUMLEDS; i++)
  {
    leds[i] = CRGB::Red;
    FastLED.show();
    delay(1000);
  }
}

En deze zou dan met de klok mee moeten draaien (rechtsom).

void loop()
{
  for (int i = NUMLEDS -1 ; i >= 0; i--)
  {
    leds[i] = CRGB::Red;
    FastLED.show();
    delay(1000);
  }
}

Als ik je probleem verkeerd begrepen heb zul je een betere beschrijving moeten geven.

PS
Er zat een foutje in mijn vorige antwoord; gecorrigeerd.

Ik had al het vermoeden het iets was met i ++ en i -- . In de code die ik gebruik staan niet die gegevens bij de void loop() waardoor ik de waardes ook niet kan aanpassen. Ik heb de regels die je gestuurd hebt ingevoegd bij de void loop() maar nu krijg ik andere foutmeldingen.

C:\Users\marij\Documents\Arduino\clock\clock.ino:176:3: error: 'menuButton' does not name a type
   menuButton = menuBouncer.update();  // Update the debouncer for the menu button and saves state to menuButton
   ^~~~~~~~~~
C:\Users\marij\Documents\Arduino\clock\clock.ino:177:3: error: 'rotary1Pos' does not name a type
   rotary1Pos = rotary1.read(); // Checks the rotary position
   ^~~~~~~~~~
C:\Users\marij\Documents\Arduino\clock\clock.ino:178:3: error: expected unqualified-id before 'if'
   if (rotary1Pos <= -2 && lastRotary - millis() >= rotaryTime)
   ^~
C:\Users\marij\Documents\Arduino\clock\clock.ino:184:3: error: expected unqualified-id before 'if'
   if (rotary1Pos >= 2 && lastRotary - millis() >= rotaryTime)
   ^~
C:\Users\marij\Documents\Arduino\clock\clock.ino:190:3: error: expected unqualified-id before 'if'
   if (menuButton == true || advanceMove != 0 || countTime == true) {buttonCheck(menuBouncer,now);}
   ^~
C:\Users\marij\Documents\Arduino\clock\clock.ino:193:9: error: expected constructor, destructor, or type conversion before '(' token
   memset(leds, 0, numLEDs * 3);
         ^
C:\Users\marij\Documents\Arduino\clock\clock.ino:196:3: error: expected unqualified-id before 'if'
   if (alarmSet == true && alarmDay != now.day()) // The alarmDay statement ensures it is a newly set alarm or repeat from previous day, not within the minute of an alarm cancel.
   ^~
C:\Users\marij\Documents\Arduino\clock\clock.ino:202:3: error: expected unqualified-id before 'if'
   if (countDown == true)
   ^~
C:\Users\marij\Documents\Arduino\clock\clock.ino:211:3: error: expected unqualified-id before 'if'
   if (state == setClockHourState || state == setClockMinState || state == setClockSecState) {setClockDisplay(now);}
   ^~
C:\Users\marij\Documents\Arduino\clock\clock.ino:212:3: error: expected unqualified-id before 'else'
   else if (state == alarmState || state == setAlarmHourState || state == setAlarmMinState) {setAlarmDisplay();}
   ^~~~
C:\Users\marij\Documents\Arduino\clock\clock.ino:213:3: error: expected unqualified-id before 'else'
   else if (state == countDownState) {countDownDisplay(now);}
   ^~~~
C:\Users\marij\Documents\Arduino\clock\clock.ino:214:3: error: expected unqualified-id before 'else'
   else if (state == demoState) {runDemo(now);}
   ^~~~
C:\Users\marij\Documents\Arduino\clock\clock.ino:215:3: error: expected unqualified-id before 'else'
   else {timeDisplay(now);}
   ^~~~
In file included from C:\Users\marij\Documents\Arduino\clock\clock.ino:7:0:
C:\Users\marij\AppData\Local\Arduino15\libraries\FastLED\src/FastLED.h:655:14: error: 'FastLED' does not name a type
 #define LEDS FastLED
              ^
C:\Users\marij\Documents\Arduino\clock\clock.ino:218:3: note: in expansion of macro 'LEDS'
   LEDS.show();
   ^~~~
C:\Users\marij\Documents\Arduino\clock\clock.ino:219:1: error: expected declaration before '}' token
 }
 ^
Multiple libraries were found for "Bounce.h"
  Used: C:\Users\marij\Documents\Arduino\libraries\Bounce
  Not used: C:\Users\marij\Documents\Arduino\libraries\Bounce2
exit status 1

Compilation error: 'menuButton' does not name a type

Ik heb het nu onderaan de loop gezet en ik krijg geen foutmelding meer maar de klok doet het ook niet meer, ook niet na een reset.

Het was een test programma om de draairichting te demonstreren en uit te vogelen wat je probleem is. Het is niet bedoeld om direct te integreren in je programma.

Als het tweede test programma in de juiste richting draait (en het eerste niet) zul je alle for-loops moeten aanpassen. Plus mogelijk wat logica in de for-loops, ik heb daar verdet niet naar gekeken.

Dit is geen simpel projectje......
Vermoedelijk van internet gehaald.

Ik kan het niet compileren omdat ik de diverse library's niet heb en zou ik ze wel hebben, dan kan ik nog niet testen.
Wat ik in de code tegenkwam is LEDPosition en reverseLEDPosition. Deze krijgen een waarde afhankelijk van een for next loop waarin opgeteld of verlaagd wordt. Daar zou ik zoeken.

Daarnaast kwam ik
if (state == countDownState) {countDownDisplay(now);}
tegen. er is dus ergens een countdowndisplay procedure. Welllicht dat die je meer duidelijkheid kan bezorgen.

suc7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.