Pedro Martin
Published © GPL3+

Smart Night Light & Alarm Clock

Playback messages & white noise (amp & speaker), control Philips WiZ smart lights (via IFTTT), play tunes (via piezo), PIR movement sensor.

AdvancedFull instructions provided1,789
Smart Night Light & Alarm Clock

Things used in this project

Hardware components

Arduino Oplà IoT Kit
Arduino Oplà IoT Kit
×1
Adafruit Mono 2.5W Class D Audio Amplifier - PAM8302
×1
Adafruit Mini Oval Speaker with Short Wires - 8 Ohm 1 Watt
×1
Adafruit On-Off Power Button / Pushbutton Toggle Switch
×1
18650 Rechargable Battery
×1
Micro SDXC Samsung 64GB
×1

Software apps and online services

Arduino IDE
Arduino IDE
Maker service
IFTTT Maker service
Philips Wiz Connected Lighting App
Blynk
Blynk
Audacity

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

MKR WiFi 1010 w/ PAM8302 Class D Amplifier & Speaker

The Fritzing file of MKR 1010 is not annotated and has blank pins (i.e. 5V), so I used its full pinout image to draw this BMP image

Code

SmartNightLight_V2.ino

Arduino
#include "credentials.h"  //Blynk & WiFi credentials
//#define BLYNK_PRINT Serial  //only for debug, comment out in production
#include <WiFiNINA.h>
#include <BlynkSimpleWifi.h>
#include <Arduino_MKRIoTCarrier.h>
MKRIoTCarrier nightBox;
#include <SPI.h>;
#include <SD.h>
#include "globalVars.h"

void setup() {
  Serial.begin(115200); delay(1000);
  Serial.println("setup begin");
  CARRIER_CASE = true;  //------change to TRUE once in production
  nightBox.begin();
  nightBox.display.fillScreen(noColor);
  nightBox.display.drawBitmap(60,5,wifi_image,50,30,Gray);
  pinMode(BUZZER, OUTPUT);
  pinMode(GROVE_AN2, INPUT);
  pinMode(A0, OUTPUT);
  digitalWrite(14, LOW);
  rtc.begin();
  Blynk.begin(auth, ssid, pass);  
  WiFi_ON = true;
  while (!Blynk.connected()) { // to avoid time out and not connect
    Serial.print("."); delay(10);}
  Blynk.syncAll();
  unsigned long startSync = millis();
  Serial.print("Wait 3 sec for sync of Blynk Vars.");  //ocurring async from syncAll cmd
  while (millis() - startSync < 3000) {
    Serial.print("."); delay(100);} 
  Serial.println("\nsetup end");
}
//--------------END OF SETUP---------------------------

void loop() {
  Blynk.run();
  chkShake();
  updateBatt();
  updateClock();
  chkAlarm(); 
  if (!wakeSeqStarted) {
    stateVar = 0;
    chkMove(); 
    chkLums();
    chkTimeSlot();
    chkCalm();
    if (itIsCalm) stateVar += 8; 
    if (stateVar!= lastStateVar) {
      //Serial.print("stateVar="+String(stateVar)+" BIN:");Serial.println(stateVar,BIN);
      lastStateVar = stateVar;
      if (stateVar == 2 || stateVar == 3 || stateVar == 10) 
        dispClock(Blue); else dispClock(Red);
      if (stateVar == 0 || stateVar == 1 || stateVar == 4 || stateVar == 5 ||
          stateVar == 8 || stateVar == 12)
        setLeds("Night",nightBrightness); else setLeds("Off",0);
      if (stateVar == 5) whiteNoise(1);
      if (stateVar == 7) whiteNoise(2);
      if (stateVar == 6 || stateVar == 7) setWiZ("stateVar_67");
      if (stateVar == 14) setWiZ("WiZ_Off");
    }
  }else {
    if (millis() - wakeMillis < 600000) { //wake sequence takes 10 minutes (60sec * 1000millis * 10 minutes)
      if (millis() - lastWakeStep > 9500) { //increase LED brightness every 9.5 seconds to ensure total brightness < 255
        lastWakeStep = millis();
        wakeInc += 4; 
        setLeds("Alarm",wakeInc);
        if (wakeInc == 100) singUnderworld();
        if (wakeInc == 180) singMario();
      } 
    }else {
      wakeSeqStarted = false;  //wake sequence ended because 10 mins have passed
      setLeds("Off",0); 
    }
  }
}
//--------------END OF LOOP------------------------------

//--------------FUNCTIONS TO TRIGGER RESPONSES-----------
void chkShake() {
  float Gx, Gy, Gz;
  nightBox.IMUmodule.readGyroscope(Gx, Gy, Gz);
  if ((Gy < -100 || Gx < -100 || Gz < -100) && WiFi_ON) {
      Blynk.disconnect();
      WiFi.disconnect();
      WiFi.end();
      nightBox.display.fillRect(60,5,50,30,noColor);
      WiFi_ON = false;
  }
}
void setWiZ(String action) {
  //Serial.println("setWiZ: "+action);
  if (!WiFi_ON) {
    int status = WL_IDLE_STATUS;
    while (status != WL_CONNECTED) {
      //Serial.println("reconnecting WiFi for WiZ");
      status = WiFi.begin(ssid, pass);
      delay(3000);
    }
    nightBox.display.drawBitmap(60,5,wifi_image,50,30,Red);
  }
  if (client.connect(server, 443)) {
    Serial.println("connected to server");
    String httpGET = "GET https://maker.ifttt.com/trigger/" + action + "/with/key/" + IFTTT_Key;
    client.println(httpGET);
    client.println("Connection: close");
    client.println();
    Serial.println("Connection closed");
    if (!client.connected()) {        // if the server is disconnected, stop the client:
     Serial.println("disconnecting from server");
     client.stop();
    }
    delay(1000); //time for IFTTT to settle in case another one is called immediately after
  }
  if (!WiFi_ON) {
    WiFi.disconnect();
    WiFi.end();
    nightBox.display.fillRect(60,5,50,30,noColor);
  }
}
void whiteNoise(uint8_t fileNum) {
  //for white or brown noise see https://www.audiocheck.net/testtones_brownnoise.php
  digitalWrite(14, HIGH); //turn on the amplifier
  AudioPlayer.begin(44100, 1, 512);  //sample rate, number of simultaneous audio channels, audio buffer size
  if (fileNum == 1) AudioPlayer.play("bNoise10.wav"); //filenames must have 8 chars max
  if (fileNum == 2) AudioPlayer.play("bNoise20.wav");
  while (AudioPlayer.isPlaying(1)) { } //block execution to avoid conflicts with CLKs and other stuff
  AudioPlayer.end();
  digitalWrite(14, LOW); 
}
void setLeds(String newState, byte newBright) {
  static String ledsState = "";
  static byte brightState = 0;
  if (ledsState != newState || brightState != newBright) {
    ledsState = newState; 
    brightState = newBright;
    if (newState == "Night") nightBox.leds.fill(Orange,0,5); 
    if (newState == "Alarm") nightBox.leds.fill(BlueLED,0,5);
    if (newState == "Off") nightBox.leds.fill(noColor,0,5);
    nightBox.leds.setBrightness(newBright);
    nightBox.leds.show();
  }
}
void dispClock(uint16_t setColor) {
  static uint16_t clockState = 0;
  byte t = clockTextSize; //clock number text size 
  byte w = localTime.length()*(5+1)*t; //clock number width
  byte h = 7 * t; //clock number height
  if (clockState != setColor) {
    if (setColor != keepColor) clockState = setColor;
    nightBox.display.fillRect(0,(240-h)/2-1,240,h+2,noColor); 
    nightBox.display.setTextColor(clockState);
    nightBox.display.setTextSize(t);
    nightBox.display.setCursor((240-w)/2+1,(240-h)/2);
    nightBox.display.print(localTime);
  }
}
//--------------FUNCTIONS TO CHECK STATES----------------
void chkAlarm() {
  if (alarmStatus == 1) {
    if (wakeHour == hour && wakeMinute == minute && !wakeSeqStarted) {
      wakeMillis = millis();
      wakeSeqStarted = true;
      lastWakeStep = 0;  
      wakeInc = 0;    
      setWiZ("wakeSeqStarted");  
    }
  }else {
    if (wakeSeqStarted) { //alamrmStatus changed to OFF during a wakeSequenceStarted
      wakeSeqStarted = false; //wake sequence ended because change in alarmStatus
      setLeds("Off",0);  
    }
  }
}
void chkCalm() {
  if (millis() - firstMove > calmPeriod && !moved) {
    itIsCalm = true; //stateVar += 8; will set fourth bit of state variable byte in main loop
    firstMove = millis();
  }
}
void chkTimeSlot() { //designed (i.e. works) only for timeSlotBegin < 24 and timeSlotEnd > 0
  if (hour >= timeSlotBegin || hour < timeSlotEnd) { //hour is in 24hr format, localtime is 12hr format
      stateVar += 4; //set third bit of state variable byte
    }
}
void chkLums() {
  while (!nightBox.Light.colorAvailable()) delay(5);
  int r,g,b,lums,acumLums;
  int lumsLevel;
  float depaso;
  acumLums = 0;
  for (int i=0; i<20; i++) {
    nightBox.Light.readColor(r,g,b,lums); 
    depaso = r * 100 / b;
    //Serial.print(depaso);Serial.print(",");Serial.println(lums);
    acumLums += lums; }
  lums = acumLums / 20;  // average 20 samples to assist hysteresis
  lumsLevel = getHystLevel(lums);  //see Hysteresis function at bottom
  if (lumsLevel > lumsLimit && depaso < redToBlue) {
    stateVar += 2;  //set second bit of state variable byte
  }
}
void chkMove() {
  static int moveCounter;
  static unsigned long nextPIRread;
  int PIR_val = digitalRead(GROVE_AN2); 
  if (PIR_val == HIGH && !moved) {  //it's the first movement detected since startup or flag reset
      moved = true;
      firstMove = millis();
      moveCounter = 0;
      //Serial.println("first move");
  }
  if (moved) {
    if (millis() - firstMove > mutePeriod) {  //mute period is over
      if (millis() - firstMove < movePeriod + mutePeriod) {  //still inside Move Eval Period 
        if (millis() - nextPIRread > 1000) {  //limit subsecuent PIR sensor reads to once per second
          PIR_val = digitalRead(GROVE_AN2);  
          nextPIRread = millis();
          if (PIR_val == HIGH) {moveCounter += 1;}//Serial.println("next move");} 
        }   
      }else { //Move Eval Period has expired
        moved = false;
        if (moveCounter > moveCounterLimit) 
          {stateVar += 1;  //set first bit of state variable byte
          itIsCalm = false;}
      }
    } //if mute period is not over, then do nothing
  } //if no movement detetcted, then do nothing
}
//--------------FUNCTIONS TO DISPLAY DATA----------------
void updateBatt() {
  static unsigned long lastBattRead = 0;
  static byte lastBattPercent = 0;
  if (millis() - lastBattRead > 5000) {  //read Batt every 10 seconds to mitigate Hysteresis
    lastBattRead = millis();  
    int battSensor = analogRead(ADC_BATTERY);
    int battPercent = map(battSensor,0,1023,0,100); 
    if (battPercent != lastBattPercent){   
      lastBattPercent = battPercent;                     
      int length = map(battPercent,73,100,1,25); //map battPercent to 25 pixels @ 73% = 3.1v (brownout cutoff)
      nightBox.display.fillRect(108,5,36,39,noColor);  //clear the battery display
      uint16_t setColor = Gray;
      if (battPercent < 78) setColor = Red; //75% = 3.15v
      nightBox.display.drawRect(108,5,27,13,setColor);
      nightBox.display.fillRect(135,9,3,5,setColor);
      nightBox.display.fillRect(110,7,length,9,setColor);    
      nightBox.display.setCursor(112,25);     
      nightBox.display.setTextSize(1);
      nightBox.display.setTextColor(Gray); 
      nightBox.display.print(String(battPercent) + "%");       
    }
  }
}
void updateClock() {
  if (rtc.getMinutes() != minute) {   
    hour = rtc.getHours();
    minute = rtc.getMinutes();
    if (hour>12) localTime = String(hour - 12);
    else localTime = String(hour);
    localTime.trim();
    if (minute<10) localTime = localTime + ":0" + String(minute);
    else localTime = localTime + ":" + String(minute);
    dispClock(keepColor);  
  }
}
void dispAlarm() {
  String alarmTime = String(alarmHour) + ":"; 
  if (alarmMinute > 9) alarmTime = alarmTime + String(alarmMinute);
  else alarmTime = alarmTime + "0" + String(alarmMinute);
  nightBox.display.fillRect(0, 200, 239, 239, noColor);
  nightBox.display.setTextColor(Gray);
  nightBox.display.setTextSize(2);
  nightBox.display.setCursor(100,210);
  nightBox.display.print(alarmTime);
  if (alarmStatus == 1) nightBox.display.fillCircle(83,217,5,Gray);
  else nightBox.display.fillCircle(83,217,5,noColor);
}
//--------------BLYNK FUNCTIONS--------------------------
BLYNK_WRITE(V0) {
  alarmHour = param.asInt();
  dispAlarm();
}
BLYNK_WRITE(V1) {
  alarmMinute = param.asInt();
  dispAlarm();
}
BLYNK_WRITE(V2) {
  alarmStatus = param.asInt();
  dispAlarm();
  wakeMinute = alarmMinute - 10;
  wakeHour = alarmHour;
  if (wakeMinute < 0) {
    wakeMinute += 60;
    wakeHour -= 1;
  }
}
BLYNK_WRITE(V3) {
  lumsLimit = param.asInt();
}
BLYNK_WRITE(V4) {
  nightBrightness = param.asInt();
}
BLYNK_WRITE(V5) {
  timeSlotBegin = param.asInt();
}
BLYNK_WRITE(V6) {
  timeSlotEnd = param.asInt();
}
BLYNK_WRITE(V7) {
  moveCounterLimit = param.asInt();
}
BLYNK_WRITE(V8) {
  clockTextSize = param.asInt();
}
BLYNK_WRITE(V9) {
  redToBlue = param.asInt();
}
BLYNK_CONNECTED() {
  // Serial.println("\nStarting blynk connected");
  // this is executed before end of setup, asynchronus from Blynk.begin?
  Blynk.sendInternal("utc", "iso"); // ISO-8601 formatted time: requests for different internal data
  // for full time zone data https://docs.blynk.io/en/blynk.edgent/api/timezone-location
}
BLYNK_WRITE(InternalPinUTC) {
  //asynchronus: arrives after setup, even after first loop iteration. chk Blynk.run()
  String iso_time;
  String cmd = param[0].asStr();
  if (cmd == "iso") iso_time = param[1].asStr(); 
  Serial.print("ISO-8601 time:   "); Serial.println(iso_time);  //to chk in case format moves
  int isoIndex = iso_time.indexOf('T');
  String isoHour   = iso_time.substring(isoIndex + 1, isoIndex + 3);
  String isoMinute = iso_time.substring(isoIndex + 4, isoIndex + 6);
  String isoSecond = iso_time.substring(isoIndex + 7, isoIndex + 9);
  rtc.setHours(isoHour.toInt());
  rtc.setMinutes(isoMinute.toInt());
  rtc.setSeconds(isoSecond.toInt());
}
//--------------AUXILIARY FUNCTIONS----------------------
int getHystLevel(int inputLevel) {
  // Note for SmartNightLight: table is nonlinear since only interest is dark/not dark room. 
  // Other or later functions may use varying levels of room lums
    
  // From:  Hysteresis  https://forum.arduino.cc/t/hysteresis/506190
  //  convert an input value into an output value with hysteresis
  // ========================================
  // margin sets the 'stickyness' of the hysteresis or the relucatance to leave the current state.
  // It is measured in units of the the input level. As a guide it is a few percent of the
  // difference between two end points. Don't make the margin too wide or ranges may overlap.
  int margin = 0;  //modified for non-linear margin
  // set the number of output levels. These are numbered starting from 0.
  const byte numberOfLevelsOutput = 7;  
  // define input to output conversion table/formula by specifying endpoints of the levels.
  // the number of end points is equal to the number of output levels plus one.
  const int endPointInput[numberOfLevelsOutput + 1] = {0,10,30,90,270,540,1620,4097} ;
  // initial output level (usually zero)
  const int initialOutputLevel = 0;
  // ========================================
  // the current output level is retained for the next calculation.
  // Note: initial value of a static variable is set at compile time.
  static int currentOutputLevel = initialOutputLevel ;
  
  //-----My Mod for SmartNightLight: non linear margin:
  if (currentOutputLevel < numberOfLevelsOutput)
    margin = (endPointInput[currentOutputLevel+1] - endPointInput[currentOutputLevel]) * 0.1;
  else
    margin = endPointInput[currentOutputLevel] * 0.1;
    
  // get lower and upper bounds for currentOutputLevel
  int lb = endPointInput[currentOutputLevel];
  if (currentOutputLevel > 0) lb -= margin ;   // subtract margin
  int ub = endPointInput[currentOutputLevel + 1];
  if (currentOutputLevel < numberOfLevelsOutput) ub +=  margin ;  // add margin
  // now test if input is between the outer margins for current output value
  byte i;
  if (inputLevel < lb || inputLevel > ub) {
    for (i=0; i<numberOfLevelsOutput; i++)  // determine new output level by scanning endPointInput array
      if (inputLevel >= endPointInput[i] && inputLevel <= endPointInput[i+1]) break;
    currentOutputLevel = i ;
  }
  return currentOutputLevel ;
}

globalVars.h

Arduino
#include "icons.h"
#include "tunes.h"

//---IFTTT
char server[] = "maker.ifttt.com";
WiFiSSLClient client;
bool WiFi_ON = false;

//---AUDIO
#include <SamdAudioSD.h>
SamdAudioSD AudioPlayer;

//---NIGHTLIGHT STATES
byte lastStateVar = 99;
byte stateVar = 0; //init state = outside of TimeSlot & Lights On
//       - Variables with States   -    Actions based on States
//                In
// Num of- it's  Time  Lums   Just -  Clock   LEDS    WiZ   WhiteNoise
// State   Calm  Slot   On   Moved
//   0   -   0     0     0     0   -   R      on
//   1   -   0     0     0     1   -   R      on
//   2   -   0     0     1     0   -   B      off
//   3   -   0     0     1     1   -   B      off
//   4   -   0     1     0     0   -   R      on
//   5   -   0     1     0     1   -   R      on              SHORT
//   6   -   0     1     1     0   -   R      off     RLX 
//   7   -   0     1     1     1   -   R      off     RLX     LONG
//   8   -   1     0     0     0   -   R      on
//  10   -   1     0     1     0   -   B      off
//  12   -   1     1     0     0   -   R      on
//  14   -   1     1     1     0   -   R      off     off 
// States 9,11,13 & 15 are not possible (Calm=1, Just Moved =1)

//---MOVEMENT
unsigned long firstMove = 0;
bool moved = false;
int moveCounterLimit;
bool itIsCalm = false;
const long mutePeriod = 10 * 1000; //seconds * (millis) interval before considering more detections consider that PIR Sensor
                                  //  has aprox 2.5 sec block time with both POTs full counterclockwise
const long movePeriod = 30 * 1000; //seconds * (millis) interval to chk for more movement either after first movement or
                                  // to considier it still again 
const long calmPeriod = 12*60*1000; //minutes * 60 seconds * (millis) interval to chk for no movemente after firstmove
                                    // to consider all is quiet & still

//---LEDS & LUMS
byte lumsLimit, nightBrightness;
//Colors for LED Strip are 32-bit. https://learn.adafruit.com/adafruit-dotstar-leds/arduino-library-use
//to pick 32-bit colors see https://www.w3schools.com/colors/colors_picker.asp?
uint32_t Orange = nightBox.leds.Color(100,255,0);  //NOTE: LED strip is GRB not RGB
uint32_t BlueLED = nightBox.leds.Color(0,0,255);
//Colors for TFT are 16-bit. https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/Adafruit_ST77xx.h
//to pick 16-bit colors see  https://chrishewett.com/blog/true-rgb565-colour-picker/
uint16_t noColor = 0x0000;
uint16_t keepColor = 0xffff;  //using code for full white as code for no color change
uint16_t Blue = 0x001f;
uint16_t Red = 0xf800;
uint16_t Gray = 0x3186;
int redToBlue;

//---CLOCK
#include <RTCZero.h>
RTCZero rtc;
String localTime;
int clockTextSize;
byte hour, minute, timeSlotBegin, timeSlotEnd;
byte alarmStatus;
int alarmHour, alarmMinute, wakeHour, wakeMinute;
bool wakeSeqStarted = false;
unsigned long lastWakeStep, wakeMillis = 0;  
byte wakeInc = 0;  

tunes.h

Arduino
//details in https://create.arduino.cc/projecthub/jrance/super-mario-theme-song-w-piezo-buzzer-and-arduino-1cc2e4
// mores songs in https://github.com/robsoncouto/arduino-songs
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

//Mario main theme melody
int melody[] = {
  NOTE_E7, NOTE_E7, 0, NOTE_E7,
  0, NOTE_C7, NOTE_E7, 0,
  NOTE_G7, 0, 0,  0,
  NOTE_G6, 0, 0, 0,

  NOTE_C7, 0, 0, NOTE_G6,
  0, 0, NOTE_E6, 0,
  0, NOTE_A6, 0, NOTE_B6,
  0, NOTE_AS6, NOTE_A6, 0,

  NOTE_G6, NOTE_E7, NOTE_G7,
  NOTE_A7, 0, NOTE_F7, NOTE_G7,
  0, NOTE_E7, 0, NOTE_C7,
  NOTE_D7, NOTE_B6, 0, 0,

  NOTE_C7, 0, 0, NOTE_G6,
  0, 0, NOTE_E6, 0,
  0, NOTE_A6, 0, NOTE_B6,
  0, NOTE_AS6, NOTE_A6, 0,

  NOTE_G6, NOTE_E7, NOTE_G7,
  NOTE_A7, 0, NOTE_F7, NOTE_G7,
  0, NOTE_E7, 0, NOTE_C7,
  NOTE_D7, NOTE_B6, 0, 0
};
//Mario main them tempo
int tempo[] = {
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  9, 9, 9,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  9, 9, 9,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
};


//Underworld melody
int underworld_melody[] = {
  NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
  NOTE_AS3, NOTE_AS4, 0,
  0,
  NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
  NOTE_AS3, NOTE_AS4, 0,
  0,
  NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
  NOTE_DS3, NOTE_DS4, 0,
  0,
  NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
  NOTE_DS3, NOTE_DS4, 0,
  0, NOTE_DS4, NOTE_CS4, NOTE_D4,
  NOTE_CS4, NOTE_DS4,
  NOTE_DS4, NOTE_GS3,
  NOTE_G3, NOTE_CS4,
  NOTE_C4, NOTE_FS4, NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4,
  NOTE_GS4, NOTE_DS4, NOTE_B3,
  NOTE_AS3, NOTE_A3, NOTE_GS3,
  0, 0, 0
};
//Underwolrd tempo
int underworld_tempo[] = {
  12, 12, 12, 12,
  12, 12, 6,
  3,
  12, 12, 12, 12,
  12, 12, 6,
  3,
  12, 12, 12, 12,
  12, 12, 6,
  3,
  12, 12, 12, 12,
  12, 12, 6,
  6, 18, 18, 18,
  6, 6,
  6, 6,
  6, 6,
  18, 18, 18, 18, 18, 18,
  10, 10, 10,
  10, 10, 10,
  3, 3, 3
};
void buzz(long frequency, long length) {
  long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions
  //// 1 second's worth of microseconds, divided by the frequency, then split in half since there are two phases to each cycle
  long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing
  //// multiply frequency, which is really cycles per second, by the number of seconds to get the total number of cycles to produce
  for (long i = 0; i < numCycles; i++) { // for the calculated length of time...
    digitalWrite(BUZZER, HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(BUZZER, LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait again for the calculated delay value
  }
}
void singUnderworld() {
    int size = sizeof(underworld_melody) / sizeof(int);
    for (int thisNote = 0; thisNote < size; thisNote++) {
      //to calculate note duration, take one second divided by the note type. e.g. quarter note = 1000/4, eighth note = 1000/8, etc.
      int noteDuration = 1000 / underworld_tempo[thisNote];
      buzz(underworld_melody[thisNote], noteDuration);
      // to distinguish the notes, set a minimum time between them. the note's duration + 30% seems to work well:
      int pauseBetweenNotes = noteDuration * 1.20;
      delay(pauseBetweenNotes);
      buzz(0, noteDuration);      // stop the tone playing:
    }
}
void singMario() {
    int size = sizeof(melody) / sizeof(int);
    for (int thisNote = 0; thisNote < size; thisNote++) {
      // to calculate the note duration, take one second divided by the note type. e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
      int noteDuration = 1000 / tempo[thisNote];
      buzz(melody[thisNote], noteDuration);
      // to distinguish the notes, set a minimum time between them. the note's duration + 30% seems to work well:
      int pauseBetweenNotes = noteDuration * 1.3;
      delay(pauseBetweenNotes);
      buzz(0, noteDuration);      // stop the tone playing:
    }
}

icons.h

Arduino
const unsigned char wifi_image [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 
  0x00, 0x00, 0x03, 0xfe, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x01, 0xf8, 0x00, 0x00, 0x00, 
  0x0f, 0xc3, 0xf8, 0x7c, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xfe, 0x1e, 0x00, 0x00, 0x00, 0x0e, 0x3f, 
  0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xe0, 
  0x00, 0x00, 0x00, 0x01, 0xf0, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xf8, 0xe0, 0x00, 0x00, 
  0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x1e, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00
};

credentials.h

Arduino
#define BLYNK_TEMPLATE_ID ""
#define BLYNK_DEVICE_NAME ""
#define BLYNK_AUTH_TOKEN ""
#define IFTTT_Key ""
char ssid[] = "";
char pass[] = "";
char auth[] = BLYNK_AUTH_TOKEN;

Credits

Pedro Martin

Pedro Martin

8 projects • 16 followers

Comments