Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alarms don't work #20

Open
ImaraSpeek opened this issue Oct 18, 2016 · 1 comment
Open

Alarms don't work #20

ImaraSpeek opened this issue Oct 18, 2016 · 1 comment

Comments

@ImaraSpeek
Copy link

Hi! It seems that for some reason my alarms won't set. I changed all the delays to Alarm.delay. Would it be possible that it is due to the scheduled non-busy wait loops?


/******************************************************
   De buitenbloem - prototype vs1
   Imara
*/

// dfplayer
#include <DFPlayer_Mini_Mp3.h>
#include <SoftwareSerial.h>

// adafruit neopixel
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

// esp
#include <ESP8266WiFi.h>

// json streamer
#include <JsonListener.h>
#include <JsonStreamingParser.h>

// weather client librarier
#include "WundergroundClient.h"
#include "TimeClient.h"
#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include "ThingspeakClient.h"

// pin definities
// Serial uses UART0, WHICH IS MAPPED TO GPIO1 (TX) and GPIO3 (RX)
#define KNOP D3    // GPIO0 
#define KNOPLED D7  // GPIO2 IS  alternative TX TODO how to turn of alternative TX??
#define PIR D0      // GPIO
#define NEO D6      // GPIO04
#define BUSY D5     // GPIO05 TODO weghalen?

// GPIO15, GPIO0 en GPIO2 worden gebruikt voor resets

SoftwareSerial mySerial(D1, D2); // RX, TX

// constants
#define NUMPIXELS 39
#define KNOPPIXELS 9
#define LEAFPIXELS 3

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEO, NEO_GRB + NEO_KHZ800);

// wifi variables
#define myPeriodic 15 //in sec | Thingspeak pub is 15sec
const char* server = "api.thingspeak.com";
String apiKey = "bla";
const char* MY_SSID = "XperImara";
const char* MY_PWD = "bla";
const float UTC_OFFSET = 2;
const char WEBSITE[] = "api.pushingbox.com"; //pushingbox API server
const String devid = "bla"; //device ID on Pushingbox for our Scenario

// Wunderground Settings
const boolean IS_METRIC = true;
const String WUNDERGRROUND_API_KEY = "88abd7366bd93123";
const String WUNDERGRROUND_LANGUAGE = "NL";
const String WUNDERGROUND_COUNTRY = "NL";
const String WUNDERGROUND_CITY = "Naarden";

int8_t tempint;
int8_t hourint;

TimeClient timeClient(UTC_OFFSET);

// Set to false, if you prefere imperial/inches, Fahrenheit
WundergroundClient wunderground(IS_METRIC);

ThingspeakClient thingspeak;

String lastUpdate = "--";
String verpleeghuis = "Naarden";
uint8_t landscapeSound, triggerSound;
boolean twice = true;

int sent = 0;

// knoppen variables
uint8_t knopState = HIGH;
uint8_t lastKnopState = HIGH;
uint8_t reading = 0;
uint32_t lastDebounceTime = 0;
uint32_t debounceDelay = 50;

uint8_t playMode = 0;
uint8_t prevPlayMode = 0;
#define offMODE 0
#define introMODE 1
#define playMODE 2
#define outroMODE 3

#define mp3delay 1000

// defining tracks
#define MINTRIGGER 1
#define MAXTRIGGER 11
#define MINLAND 52
#define MAXLAND 64
#define MINCELCIUS 95
#define MAXCELCIUS 130
#define GOEDEMO 151
#define GOEDEMI 152
#define GOEDENA 153
#define LVOL 30
#define TVOL 30

#define INTRO 80
#define OUTRO 81

boolean isOff = true;
boolean playState = HIGH;
boolean landState = HIGH;
boolean trigState = LOW;

// knop tijden
uint32_t knopStart = 0;
uint32_t knopTime = 4000;
#define SHORTINTRO 30000
#define LONGINTRO 30000

uint32_t logDelay = 3600000;
uint32_t lastLogTime = 0;
uint16_t peopleDetected = 0;

// play tijden
uint32_t introStart = 0;
uint32_t introTime = 15000;  // de tijd van de intro
uint32_t playStart = 0;
uint32_t playTime = 100000;
uint32_t outroStart = 0;
uint32_t outroTime = 20000;

uint8_t readPIR = 0;
uint8_t lastPIRState = LOW;
uint8_t calibrationTime = 30;

uint8_t ledState = LOW;
uint8_t lokState = LOW;

// led counters
uint8_t leafCounter = 0;
uint8_t brightness = 0;    // how bright the LED is
uint8_t fadeAmount = 5;    // how many points to fade the LED by
uint32_t lastFadeTime = 0;
uint32_t fadeDelay = 30;
uint32_t rainbowDelay = 10;
uint8_t UP = LOW;
uint32_t liveDelay = 50;
#define FADEMIN 30
#define FADEMAX 150

// Color definitions
uint32_t pixelsOff = pixels.Color(0, 0, 0);
#define NUMCOLORS 7
uint32_t leafColor[NUMCOLORS] = { pixels.Color(217, 14, 14),
                                  pixels.Color(24, 250, 35),
                                  pixels.Color(0, 0, 255),
                                  pixels.Color(242, 250, 10),
                                  pixels.Color(240, 0, 230),
                                  pixels.Color(0, 250, 170),
                                  pixels.Color(250, 100, 0)
                                };

// individual components to fade colors with
uint8_t leafR;
uint8_t leafG;
uint8_t leafB;


tmElements_t tmi;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.setDebugOutput(true);
  Serial.println("");
  Serial.println(F("Welkom bij de buitenbloem"));

  // set up input
  pinMode(KNOP, INPUT);
  pinMode(PIR, INPUT);
  pinMode(BUSY, INPUT);

  /*
    // calibrate the pir
    digitalWrite(PIR, LOW);
    //give the sensor some time to calibrate
    Serial.print("calibrating sensor ");
    for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    Alarm.delay(1000);
    }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    Alarm.delay(50);
  */

  // set up output
  pinMode(KNOPLED, OUTPUT);
  //analogWrite(KNOPLED, 0);
  digitalWrite(KNOPLED, HIGH);
  pixels.begin(); // This initializes the NeoPixel library.
  setPixels(pixelsOff);

  // set up mp3 player
  mySerial.begin(9600);
  mp3_set_serial (mySerial);  //set Serial for DFPlayer-mini mp3 module
  mp3_set_volume (LVOL);
  Alarm.delay(mp3delay);
  mp3_stop();
  Alarm.delay(mp3delay);  //wait 1ms for mp3 module to set volume

  // connect to the wifi
  //WiFi.disconnect();
  //Alarm.delay(2000);
  //connectWifi();

  timeClient.updateTime();
  Serial.println(timeClient.getFormattedTime());
  Serial.println(timeClient.getHours());
  updateData();

  setTime(timeClient.getHours().toInt(),timeClient.getMinutes().toInt(),timeClient.getSeconds().toInt(),1,1,11);
  Alarm.timerRepeat(30, Repeats);            // timer for every 15 seconds   
  Alarm.alarmRepeat(11,48,0, MorningAlarm);

  // blink flower green to show its connected
  setPixels(pixels.Color(0, 255 , 0));
  Alarm.delay(500);
  setPixels(pixelsOff);
  Alarm.delay(500);
}

void Repeats(){
  Serial.println("15 second timer");         
}

void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}



void loop() {
  reading = digitalRead(KNOP);
  readPIR = digitalRead(PIR);
  isOff = digitalRead(BUSY);

  if (reading != lastKnopState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != knopState) {
      knopState = reading;

      // button has an internal pull-up
      if (knopState == LOW) {
        // als hij ingedrukt wordt wanneer hij uit staat
        Serial.println("Knop");

        // start counting whether the button is a long or short press
        knopStart = millis();

        if (playMode == playMODE) {
          Serial.print(F("speel een trigger geluid: "));
          mp3_stop();
          Alarm.delay(100);
          mp3_set_volume(TVOL);
          Alarm.delay(100);
          // make sure every trigger is player twice
          if (twice == true) {
            triggerSound = random(MINTRIGGER, MAXTRIGGER);
          }
          Serial.println(triggerSound);
          mp3_play(triggerSound);
          twice = !twice;
          Alarm.delay(mp3delay);
          // Alarm.delay niet nodig vanwege het versturen van de data
          mp3_set_volume(LVOL);
          sendValue(HIGH, landscapeSound, triggerSound);
        }
      }

      // if the button is released
      else {
        if (playMode == offMODE) {
          // seed the randomness
          randomSeed ( (unsigned int)( millis() + analogRead(A0) ) );
          analogWrite(KNOPLED, 255);
          setKnopPixels(pixelsOff);
          introStart = millis();
          // if the button is pressed long enough, do a long intro, else a short one
          if (millis() - knopStart > knopTime) {
            introTime = LONGINTRO;
            playMode = introMODE;
            // zet de intro aan
            Serial.println(F("intro"));
            mp3_play(INTRO);
            Alarm.delay(mp3delay);
            sendValue(HIGH, 0, 0);
            peopleDetected = 0;
            // update alle data
            updateData();
          }
          // if it is not supposed to turn on, turn on trigger
          else {
            // blink flower green to show its connected
            setPixels(leafColor[random(0, 7)]);
            Serial.print(F("speel een trigger geluid: "));
            mp3_stop();
            Alarm.delay(100);
            if (twice == true) {
              triggerSound = random(MINTRIGGER, MAXTRIGGER);
            }
            Serial.println(triggerSound);
            mp3_play(triggerSound);
            twice = !twice;
            Alarm.delay(mp3delay);
            sendValue(HIGH, 0, triggerSound);
            setPixels(pixelsOff);
          }
        }
      }
    }
  }

  // log the number of people detected
  if (millis() - lastLogTime > logDelay) {
    sendValue(LOW, 0, 0);
  }

  // dynamische acties - faden etc
  switch (playMode) {
    case offMODE:
      // if someone has been detected or has not been detected anymore
      if (lastPIRState != readPIR) {
        lokState = !lokState;
        // er is net iemand gedetecteerd
        if (lokState == HIGH) {
          peopleDetected++;
          Serial.print(F("people detected: "));
          Serial.println(peopleDetected);
        }
        // als er niemand meer gedetecteerd word, zet dan het hart licht uit
        if (lokState == LOW) {
          Serial.println(F("nobody detected"));
          setKnopPixels(pixelsOff);
          analogWrite(KNOPLED, 0);
        }
      }
      if (lokState == HIGH) {
        lokMensen();
      }
      break;
    case introMODE:
      // fade de kleuren lichtjes zoals de intro
      intro();

      // if intro is done, go to play
      if (millis() - introStart > introTime) {
        // play a random landscape
        landscapeSound = random(MINLAND, MAXLAND);
        mp3_play(landscapeSound);
        Alarm.delay(mp3delay);
        // pick the trigger colors
        playMode = playMODE;
        uint8_t player = random(NUMCOLORS);
        setPixels(leafColor[player]);
        Serial.println(leafColor[player], HEX);

        // get the chosen color individual elements;
        uint32_t color = pixels.getPixelColor(NUMPIXELS - 1);
        leafR = (color & 0xFF0000) >> 16;
        leafG = (color & 0x00FF00) >> 8;
        leafB = (color & 0x0000FF);

        leafCounter = 255;
        brightness = 255;
        playStart = millis();
        Serial.printf("playmode: ");
        Serial.println(player);

        // wacht even en groet dan
        Alarm.delay(2000);

        if (hourint < 12) {
          mp3_play(GOEDEMO);
          Alarm.delay(3000);
        }
        else if (hourint < 18) {
          mp3_play(GOEDEMI);
          Alarm.delay(3000);
        }
        else {
          mp3_play(GOEDENA);
          Alarm.delay(3000);
        }
        // laat weten hoe warm het is
        Serial.println(F("goeden iets"));
        mp3_play(100 + tempint);
        Alarm.delay(5000);
        Serial.println(F("Het is vandaag "));
        Serial.print(tempint);
        Serial.print(F(" graden"));
      }
      break;
    case playMODE:
      // slowly fade the colors in and out
      play(leafR, leafG, leafB);

      // if song has stopped, play another - check the busy line on DSP
      if (isOff) {
        // turn on background song
        Serial.println("play random");
        landscapeSound = random(MINLAND, MAXLAND);
        mp3_play(landscapeSound);
        Alarm.delay(mp3delay);
      }
      // if play is done, go to outro
      if (millis() - playStart > playTime) {
        mp3_play(OUTRO);
        Alarm.delay(mp3delay);
        analogWrite(KNOPLED, 0);
        playMode = outroMODE;
        outroStart = millis();
        Serial.println(F("outro"));
      }
      break;
    case outroMODE:
      // animate outro
      outro();

      // if outro is done, got back to off
      if (millis() - outroStart > outroTime) {
        mp3_pause();
        brightness = 0;
        setPixels(pixelsOff);
        playMode = offMODE;
        Serial.println("off");
        sendValue(LOW, 0, 0);
        lokState = LOW;
      }
      break;
  }

  lastPIRState = readPIR;
  lastKnopState = reading;
  prevPlayMode = playMode;
}

void setKnopPixels(uint32_t c) {
  for (uint8_t i = 0; i < KNOPPIXELS; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
}

void setPixels(uint32_t c) {
  for (uint8_t i = KNOPPIXELS; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
}

void lokMensen() {
  if (millis() - lastFadeTime > fadeDelay) {
    // change the brightness for next time through the loop:
    brightness = brightness + fadeAmount;

    // reverse the direction of the fading at the ends of the fade:
    if (brightness <= 0 || brightness >= 255) {
      fadeAmount = -fadeAmount;
    }

    // animeer alleen de pixels in de knop
    for (uint8_t i = 0; i < KNOPPIXELS; i++) {
      pixels.setPixelColor(i, pixels.Color(brightness, 0, 0));
    }
    pixels.show();

    analogWrite(KNOPLED, brightness);
    lastFadeTime = millis();
  }
}

void lokAnimatie() {
  uint8_t i;
  for (i = 2; i < NUMPIXELS; i += 3) {
    pixels.setPixelColor(i, pixels.Color(50, 0, 0));
  }
  pixels.show();
  Alarm.delay(100);
  for (i = 2; i < NUMPIXELS; i += 3) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
  }
  for (i = 1; i < NUMPIXELS; i += 3) {
    pixels.setPixelColor(i, pixels.Color(100, 0, 0));
  }
  pixels.show();
  Alarm.delay(200);
  for (i = 1; i < NUMPIXELS; i += 3) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
  }
  for (i = 0; i < NUMPIXELS; i += 3) {
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));
  }
  pixels.show();
  Alarm.delay(300);
  setPixels(pixelsOff);
  Alarm.delay(400);
}

void intro() {
  if (millis() - lastFadeTime > rainbowDelay) {
    // animeer alleen de pixels in de knop
    uint8_t i;

    brightness = 255 * (millis() - introStart) / introTime;

    for (i = KNOPPIXELS; i < pixels.numPixels(); i += LEAFPIXELS) {
      pixels.setPixelColor(i, WheelValue(((i * 256 / pixels.numPixels()) + leafCounter) & 255, brightness));
      pixels.setPixelColor(i + 1, WheelValue(((i * 256 / pixels.numPixels()) + leafCounter) & 255, brightness));
      pixels.setPixelColor(i + 2, WheelValue(((i * 256 / pixels.numPixels()) + leafCounter) & 255, brightness));
    }
    leafCounter++;
    if (leafCounter > 255) leafCounter = 0;

    pixels.show();
    lastFadeTime = millis();
  }
}

void play(uint8_t c1, uint8_t c2, uint8_t c3) {
  if (millis() - lastFadeTime > liveDelay) {
    // animeer alleen de pixels in de knop
    uint8_t i;

    for (i = KNOPPIXELS; i < pixels.numPixels(); i++) {
      pixels.setPixelColor(i, pixels.Color(c1 * leafCounter / 255, c2 * leafCounter / 255, c3 * leafCounter / 255));
      pixels.show();
    }

    if (!UP) {
      leafCounter--;
    }
    else {
      leafCounter++;
    }

    if (leafCounter < FADEMIN) {
      UP = HIGH;
    }
    else if (leafCounter > FADEMAX) {
      UP = LOW;
    }

    pixels.show();
    lastFadeTime = millis();
  }
}

void outro() {
  if (millis() - lastFadeTime > rainbowDelay) {
    uint8_t i;

    // start a little less bright
    brightness = 180 * (outroTime - (millis() - outroStart)) / outroTime;

    for (i = KNOPPIXELS; i < pixels.numPixels(); i += LEAFPIXELS) {
      pixels.setPixelColor(i, WheelValue(((i * 256 / pixels.numPixels()) + leafCounter) & 255, brightness));
      pixels.setPixelColor(i + 1, WheelValue(((i * 256 / pixels.numPixels()) + leafCounter) & 255, brightness));
      pixels.setPixelColor(i + 2, WheelValue(((i * 256 / pixels.numPixels()) + leafCounter) & 255, brightness));
    }
    leafCounter++;
    if (leafCounter > 255) leafCounter = 0;

    pixels.show();
    lastFadeTime = millis();
  }
}

void connectWifi()
{
  Serial.print("Connecting to " + *MY_SSID);
  WiFi.begin(MY_SSID, MY_PWD);
  while (WiFi.status() != WL_CONNECTED) {
    Alarm.delay(1000);
    Serial.print(".");
  }

  // blink flower green to show its connected
  setPixels(pixels.Color(0, 0 , 255));
  Alarm.delay(500);
  setPixels(pixelsOff);
  Alarm.delay(500);

  Serial.println("");
  Serial.println("Connected");
  Serial.println("");
}

void sendValue(int pressed, int landscape, int trigger)
{
  long timetosend = millis();
  Serial.println("\nSending Data to Server...");
  // if you get a connection, report back via serial:
  WiFiClient client;  //Instantiate WiFi object, can scope from here or Globally

  //API service using WiFi Client through PushingBox then relayed to Google
  if (client.connect(WEBSITE, 80))
  {
    if (pressed == HIGH) {
      client.print("GET /pushingbox?devid=" + devid
                   + "&humidityData=" + verpleeghuis
                   + "&celData="      + (String) pressed
                   + "&fehrData="     + landscape
                   + "&hicData="      + trigger
                   + "&hifData="      + peopleDetected
                  );
    }
    else {
      client.print("GET /pushingbox?devid=" + devid
                   + "&humidityData=" + verpleeghuis
                   + "&celData="      + (String) pressed
                   + "&fehrData="     + "--"
                   + "&hicData="      + "--"
                   + "&hifData="      + peopleDetected
                  );
      peopleDetected = 0;
      lastLogTime = millis();
    }

    // HTTP 1.1 provides a persistent connection, allowing batched requests
    // or pipelined to an output buffer
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(WEBSITE);
    client.println("User-Agent: ESP8266/1.0");
    client.println("Connection: close");
    client.println();
  }
  timetosend = millis() - timetosend;
  Serial.println(timetosend);
}

void updateData() {
  Serial.println("Updating conditions");
  wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);

  // update the time in the setup
  String hours = timeClient.getHours();
  hourint = hours.toInt();
  //Serial.println("time is: ");
  //Serial.print(hourint);
  //Serial.println("");

  String temp = wunderground.getCurrentTemp() + "°C";
  tempint = temp.toInt();
  //Serial.println("temperature is: ");
  //Serial.println(tempint);
  //Serial.println("");

  //Serial.println("done");
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

uint32_t WheelValue(byte WheelPos, byte Value) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return pixels.Color((255 - WheelPos * 3) * Value / 255, 0, (WheelPos * 3) * Value / 255);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return pixels.Color(0, (WheelPos * 3) * Value / 255, (255 - WheelPos * 3) * Value / 255);
  }
  WheelPos -= 170;
  return pixels.Color((WheelPos * 3) * Value / 255, (255 - WheelPos * 3) * Value / 255, 0);
}

@luckyhacky
Copy link

The Alarm.delay function is not for waiting. It is for active waiting and servicing the Alarm jobs. If a Alarm is served, it may overrun and your waiting time is not exact.
Actually you should use the Alarm.delay() for garanteing time for Alarms to be served.
What you want to do is using delay function
replace Alarm.delay() with delay()
waiting greater than 500ms will also trigger the soft watchdog and reset the board. A possible fix is avaible under pull request #29
But this fix does not fix the jitter due to serving Alarm functions!
To serve your alarm functions you should put it at the and of loop functions or where appropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants