c++ 在报警时间触发功能

hsvhsicv  于 2023-01-03  发布在  其他
关注(0)|答案(1)|浏览(210)

我正在尝试用esp8266和ws2812b发光二极管做一个闹钟。在闹钟时间它必须调用日出()函数。当我直接把它放在循环函数中时,日出()函数工作正常。但它在闹钟触发器中不工作。

if (AlarmData.AlarmOn[Current.Day])
  {
    if (!AlarmActive)//do not enter this routine if alarm already active
    {
      if (Current.Hour == AlarmData.Hour[Current.Day])
      {
        if (Current.Minute == AlarmData.Minute[Current.Day])
        {
          if (Current.Second > 0 && Current.Second < 3)
          {
            AlarmActive = true;
            sunrise();
            alarmTriggerTime = micros();
            Serial.println("Its time for your alarm!");

          }
        }
      }
    }
  }

我的代码如下.提前感谢您的帮助

#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include "EEPROMAnything.h"
#include "get_time.h"
#include "OTA.h"
#include <stdio.h>
#include <stdint.h>
#include "web_portal.h"
#include "ESP8266TimerInterrupt.h"
#include "restore_factory_settings.h"
#include "FastLED.h"

#define NUM_LEDS 60
#define DATA_PIN 5


// Define the array of leds
CRGB leds[NUM_LEDS];
#define timeZone 3

#define TenSecs 10000000
#define OneMin 60000000
#define TenMins 600000000

#define TIMER_INTERVAL_MS   1000

ESP8266Timer ITimer;

int timer;
int alarmTriggerTime;
struct CurrentTime Current;
bool AlarmActive;
struct AlarmDataStruct AlarmData;
int WiFiTimer;
char factory_settings_stored [3];
bool OneSecoundPassed;

void ICACHE_RAM_ATTR TimerHandler(void)
{
  OneSecoundPassed = true;
}


void setup() {

  Serial.begin(115200);
  Serial.println("Booting");
  EEPROM.begin(512);
  EEPROM_readAnything(150, factory_settings_stored);
  if (memcmp(&factory_settings_stored, "YES", 3) != 0)
  {
    restore_factory_settings();
  }
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(0);
  WiFi.mode(WIFI_STA);
  WiFiManager wm;

  bool response;
  response = wm.autoConnect("AutoConnectAP"); // anonymous ap
  if (!response) {
    Serial.println("Failed to connect");
    // ESP.restart();
  }
  else {
    //if you get here you have connected to the WiFi
    Serial.println("Lets Go");
  }

  start_server();
  SetupOTA();
  setup_time(timeZone);
  Current = Current_Time();

  EEPROM_readAnything(100, AlarmData);
  Serial.print("Alarm set for ");
  Serial.print(AlarmData.Hour[Current.Day]);
  Serial.print(":");
  Serial.println(AlarmData.Minute[Current.Day]);
  timer = micros();
  WiFiTimer = timer;

  // Interval in microsecs
  if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler))
  {
    Serial.println("Starting  ITimer OK, millis() = " + String(millis()));
  }
  else
  {
    Serial.println("Can't set ITimer correctly. Select another freq. or interval");
  }
}

void loop() {
  if (!AlarmActive)
  {
    ArduinoOTA.handle();
    handle_client();

    if ((micros() - WiFiTimer) > TenMins) // check if wifi connection lost and if so try to reconnect
    {
      if (WiFi.status() != WL_CONNECTED)
      {
        ESP.restart(); //try to reconnect rather than resetting
      }
      WiFiTimer = micros();
    }

    if (OneSecoundPassed)
    {
      updateLocalTime();
      OneSecoundPassed = false;
    }

    //update current hour from NTP server
    if ((micros() - timer) > TenMins)
    {
      Current = Current_Time();
      timer = micros();
    }

  }
  if (AlarmActive)
  {
    if ((micros() - alarmTriggerTime) > TenMins)
    {
      AlarmActive = false; //if alarm active for 10mins and no one switches it off then do it auto
    }
  }

  if (AlarmData.AlarmOn[Current.Day])
  {
    if (!AlarmActive)//do not enter this routine if alarm already active
    {
      if (Current.Hour == AlarmData.Hour[Current.Day])
      {
        if (Current.Minute == AlarmData.Minute[Current.Day])
        {
          if (Current.Second > 0 && Current.Second < 3)
          {
            AlarmActive = true;
            sunrise();
            alarmTriggerTime = micros();
            Serial.println("Its time for your alarm!");

          }
        }
      }
    }
  }


  else
  {
    if (!AlarmActive)
    {

    }
  }
}



void updateLocalTime () {
  Current.Second++;
  if (Current.Second >= 60)
  {
    Current.Second = 0;
    Current.Minute++;
    if (Current.Minute >= 60)
    {
      Current.Minute = 0;
      Current.Hour++;
      if (Current.Hour >= 24)
      {
        Current.Hour = 0;
        Current.Day++;
        if (Current.Day >= 7)
        {
          Current.Day = 0;
        }
      }
    }
  }
  char tempTime[6];
  if (Current.Minute < 10 && Current.Second < 10)
  {
    sprintf(tempTime, "0%d:0%d", Current.Minute, Current.Second);
  }
  else if (Current.Minute < 10)
  {
    sprintf(tempTime, "0%d:%d", Current.Minute, Current.Second);
  }
  else if (Current.Second < 10)
  {
    sprintf(tempTime, "%d:0%d", Current.Minute, Current.Second);
  }
  else
  {
    sprintf(tempTime, "%d:%d", Current.Minute, Current.Second);
  }

}

void sunrise() {
  static const uint8_t sunriseLength = 30; //(min)
  static const uint8_t interval = (sunriseLength * 60) / 256;
  static const uint8_t binterval = (sunriseLength * 60) / 256;

  // current gradient palette color index
  static uint8_t heatIndex = 0; // start out at 0
  static uint8_t brIndex = 0;

  // HeatColors_p is a gradient palette built in to FastLED
  // that fades from black to red, orange, yellow, white
  // feel free to use another palette or define your own custom one
  CRGB color = ColorFromPalette(HeatColors_p, heatIndex);
  fill_solid(leds, NUM_LEDS, color); // fill the entire strip with the current color
  EVERY_N_SECONDS(binterval) {
    if (brIndex < 255) {
      FastLED.setBrightness(brIndex);
      brIndex++;
    }
  }
  EVERY_N_SECONDS(interval) {
    if (heatIndex < 255) {
      heatIndex++;
    }
  }
  FastLED.show();
}
yyyllmsg

yyyllmsg1#

你的sunrise函数应该被一遍又一遍地调用,每一次调用都会稍微改变LED的颜色。这就是为什么它能工作,然后你把它放进loop函数。
但是,您已经保护了它,以便它只被专门调用一次-所以现在它被调用,将LED设置为可能的最暗设置,并且不再被调用。
你需要做的是把它分成两部分:一个用于检测何时激活sunrise,另一个用于在时间到时连续调用。例如:

void loop()
{
    /* stuff */

    if (AlarmData.AlarmOn[Current.Day])
    {
        if (!AlarmActive) // do not enter this routine if alarm already active
        {
            if (Current.Hour == AlarmData.Hour[Current.Day])
            {
                if (Current.Minute == AlarmData.Minute[Current.Day])
                {
                    if (Current.Second > 0 && Current.Second < 3)
                    {
                        AlarmActive = true;
                        alarmTriggerTime = micros();
                        Serial.println("Its time for your alarm!");
                    }
                }
            }
        }
    }

    if (AlarmActive)
        sunrise();
}

相关问题