adding in the full source with bargraph.

error: pathspec 'Arduino/Neutrino_Wand_With_Graph/Neutrino_Wand_With_Graph.ino' did not match any file(s) known to git

--- Arduino/Neutrino_Wand_With_Graph/Neutrino_Wand_With_Graph.ino
+++ Arduino/Neutrino_Wand_With_Graph/Neutrino_Wand_With_Graph.ino
@@ -0,0 +1,1163 @@
+#include <QueueArray.h>
+
+#include <Wire.h> // Include the I2C library (required)
+#include <SparkFunSX1509.h> // Include SX1509 library
+
+// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
+const byte SX1509_ADDRESS = 0x3E;  // SX1509 I2C address
+SX1509 io; // Create an SX1509 object to be used throughout
+
+// bargraph helper variables
+int seq_1_current = 0;  // current led in sequence 1
+const int num_led = 15; // total number of leds in bar graph
+
+// SX1509 pin definitions for the leds on the graph:
+const byte SX1509_BAR_01 = 0;
+const byte SX1509_BAR_02 = 1;
+const byte SX1509_BAR_03 = 2;
+const byte SX1509_BAR_04 = 3;
+const byte SX1509_BAR_05 = 4;
+const byte SX1509_BAR_06 = 5;
+const byte SX1509_BAR_07 = 6;
+const byte SX1509_BAR_08 = 7;
+const byte SX1509_BAR_09 = 8;
+const byte SX1509_BAR_10 = 9;
+const byte SX1509_BAR_11 = 10;
+const byte SX1509_BAR_12 = 11;
+const byte SX1509_BAR_13 = 12;
+const byte SX1509_BAR_14 = 13;
+const byte SX1509_BAR_15 = 14;
+
+// for the sound board
+#include <SoftwareSerial.h>
+#include "Adafruit_Soundboard.h"
+
+#include <Adafruit_NeoPixel.h>
+
+// for led triggers
+#define HIGH 0x1
+#define LOW  0x0
+
+// neopixel pins / setup
+#define NEO_POWER 2 // for cyclotron and powercell
+Adafruit_NeoPixel powerStick = Adafruit_NeoPixel(48, NEO_POWER, NEO_GRB + NEO_KHZ800);
+
+#define NEO_NOSE 3 // for nose of wand
+Adafruit_NeoPixel noseJewel = Adafruit_NeoPixel(7, NEO_NOSE, NEO_GRB + NEO_KHZ800);
+
+#define NEO_WAND 4 // for nose of wand
+Adafruit_NeoPixel wandLights = Adafruit_NeoPixel(4, NEO_WAND, NEO_GRB + NEO_KHZ800);
+
+// LED indexes into the neopixel powerstick chain for the cyclotron
+const int powercellLedCount = 14;                                         // total number of led's in the animation
+const int powercellIndexOffset = 1;                                       // first led offset into the led chain for the animation
+
+int c1Start = 16;
+int c1End = 22;
+int c2Start = 23;
+int c2End = 29;
+int c3Start = 30;
+int c3End = 36;
+int c4Start = 37;
+int c4End = 43;
+int ventStart = 44;
+int ventEnd = 47;
+
+// inputs for switches and buttons
+const int THEME_SWITCH = 5;
+const int STARTUP_SWITCH = 6;
+const int SAFETY_SWITCH = 7;
+const int FIRE_BUTTON = 8;
+
+// soundboard pins and setup
+#define SFX_RST 9
+#define SFX_RX 10
+#define SFX_TX 11
+const int ACT = 12;    // this allows us to know if the audio is playing
+
+SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
+Adafruit_Soundboard sfx = Adafruit_Soundboard( &ss, NULL, SFX_RST);
+
+// ##############################
+// available options
+// ##############################
+const bool useGameCyclotronEffect = true;   // set this to true to get the fading previous cyclotron light in the idle sequence
+const bool useCyclotronFadeInEffect = false; // Instead of the yellow alternate flashing on boot/vent this fades the cyclotron in from off to red
+const bool useDialogTracks = true;          // set to true if you want the dialog tracks to play after firing for 5 seconds
+
+// Possible Pack states
+bool powerBooted = false;   // has the pack booted up
+bool isFiring = false;      // keeps track of the firing state
+bool shouldWarn = false;    // track the warning state for alert audio
+bool shuttingDown = false;  // is the pack in the process of shutting down
+bool poweredDown = true;    // is the pack powered down
+bool venting = false;       // is the pack venting
+
+// physical switch states
+bool startup = false;
+bool theme = false;
+bool safety = false;
+bool fire = false;
+bool warning = false;
+
+// audio track names on soundboard
+char startupTrack[] =   "T00     WAV";
+char blastTrack[] =     "T01     WAV";
+char endTrack[] =       "T02     WAV";
+char idleTrack[] =      "T03     WAV";
+char shutdownTrack[] =  "T04     WAV";
+char clickTrack[] =     "T05     WAV";
+char chargeTrack[] =    "T06     WAV";
+char warnTrack[] =      "T07     WAV";
+char ventTrack[] =      "T08     WAV";
+char texTrack[] =       "T09     WAV";
+char choreTrack[] =     "T10     WAV";
+char toolsTrack[] =     "T11     WAV";
+char listenTrack[] =    "T12     WAV";
+char thatTrack[] =      "T13     WAV";
+char neutronizedTrack[]="T14     WAV";
+char boxTrack[] =       "T15     WAV";
+char themeTrack[] =     "T16     OGG";
+
+// this queue holds a shuffled list of dialog tracks we can pull from so we don't
+// play the same ones twice
+QueueArray <int> dialogQueue;
+int numDialog = 7;
+
+// timer trigger times/states
+unsigned long firingStateMillis;
+const int firingWarmWaitTime = 5000;  // how long to hold down fire for lights to speed up
+const int firingWarnWaitTime = 10000;  // how long to hold down fire before warning sounds
+
+// Arduino setup function
+void setup() {
+  // softwareserial at 9600 baud for the audio board
+  ss.begin(9600);
+
+  // see if we have the soundboard
+  // If we fail to communicate, loop forever for now but it would be nice to warn the user somehow
+  if (!sfx.reset()) {
+    while (1);
+  }
+
+  // set act modes for the fx board
+  pinMode(ACT, INPUT);
+
+  // configure nose jewel
+  noseJewel.begin();
+  noseJewel.setBrightness(100);
+  noseJewel.show(); // Initialize all pixels to 'off'
+
+  // configure powercell/cyclotron
+  powerStick.begin();
+  powerStick.setBrightness(75);
+  powerStick.show(); // Initialize all pixels to 'off'
+
+  // configure wand lights
+  wandLights.begin();
+  wandLights.setBrightness(75);
+  wandLights.show();
+
+  // set the modes for the switches/buttons
+  pinMode(THEME_SWITCH, INPUT);
+  digitalWrite(THEME_SWITCH, HIGH);
+  pinMode(STARTUP_SWITCH, INPUT);
+  digitalWrite(STARTUP_SWITCH, HIGH);
+  pinMode(SAFETY_SWITCH, INPUT);
+  digitalWrite(SAFETY_SWITCH, HIGH);
+  pinMode(FIRE_BUTTON, INPUT);
+  digitalWrite(FIRE_BUTTON, HIGH);
+
+  // Call io.begin(<address>) to initialize the SX1509. If it
+  // successfully communicates, it'll return 1.
+  if (!io.begin(SX1509_ADDRESS)) {
+    while (1) ; // If we fail to communicate, loop forever for now but it would be nice to warn the user somehow
+  }
+
+  // configuration for the bargraph LED's
+  io.pinMode(SX1509_BAR_01, OUTPUT);
+  io.pinMode(SX1509_BAR_02, OUTPUT);
+  io.pinMode(SX1509_BAR_03, OUTPUT);
+  io.pinMode(SX1509_BAR_04, OUTPUT);
+  io.pinMode(SX1509_BAR_05, OUTPUT);
+  io.pinMode(SX1509_BAR_06, OUTPUT);
+  io.pinMode(SX1509_BAR_07, OUTPUT);
+  io.pinMode(SX1509_BAR_08, OUTPUT);
+  io.pinMode(SX1509_BAR_09, OUTPUT);
+  io.pinMode(SX1509_BAR_10, OUTPUT);
+  io.pinMode(SX1509_BAR_11, OUTPUT);
+  io.pinMode(SX1509_BAR_12, OUTPUT);
+  io.pinMode(SX1509_BAR_13, OUTPUT);
+  io.pinMode(SX1509_BAR_14, OUTPUT);
+  io.pinMode(SX1509_BAR_15, OUTPUT);
+
+  // set everything off initially
+  shutdown_leds();
+}
+
+/* ************* Audio Board Helper Functions ************* */
+// helper function to play a track by name on the audio board
+void playAudio( char* trackname, int playing ) {
+  // stop track if one is going
+  if (playing == 0) {
+    sfx.stop();
+  }
+
+  // now go play
+  if (sfx.playTrack(trackname)) {
+    sfx.unpause();
+  }
+}
+
+void playDialogTrack( int playing ){
+  // if the queue is empty reseed it
+  if ( dialogQueue.isEmpty() ){
+    for (int i=1; i<=numDialog; i++){
+      dialogQueue.enqueue(i);
+    }
+  }
+
+  switch (dialogQueue.dequeue()){
+    case (1):
+      playAudio(texTrack, playing);
+      break;
+    case (2):
+      playAudio(listenTrack, playing);
+      break;
+    case (3):
+      playAudio(choreTrack, playing);
+      break;
+    case (4):
+      playAudio(boxTrack, playing);
+      break;
+    case (5):
+      playAudio(thatTrack, playing);
+      break;
+    case (6):
+      playAudio(neutronizedTrack, playing);
+      break;
+    case (7):
+      playAudio(toolsTrack, playing);
+      break;
+    default:
+      playAudio(endTrack, playing);
+      break;
+  }
+}
+
+/* ************* Main Loop ************* */
+int cyclotronRunningFadeOut = 255;  // we reset this variable every time we change the cyclotron index so the fade effect works
+int cyclotronRunningFadeIn = 0;     // we reset this to 0 to fade the cyclotron in from nothing
+
+// intervals that can be adjusted in real time to speed up animations
+int pwr_interval = 60;        // interval at which to cycle lights for the powercell. We update this in the loop to speed up the animation so must be declared here (milliseconds)
+int cyc_interval = 1000;      // interval at which to cycle lights for the cyclotron.
+int cyc_fade_interval = 15;   // fade the inactive cyclotron to light to nothing
+int firing_interval = 40;     // interval at which to cycle firing lights on the bargraph. We update this in the loop to speed up the animation so must be declared here (milliseconds).
+
+void loop() {
+  // get the current time
+  int currentMillis = millis();
+
+  // find out of the audio board is playing audio
+  int playing = digitalRead(ACT);
+
+  // get the current switch states
+  int theme_switch = digitalRead(THEME_SWITCH);
+
+  // if the theme switch has recently changed from off to on we
+  // should play the full ghostbusters theme song
+  if (theme_switch == 1) {
+    if (theme == false) {
+      playAudio(themeTrack, playing);
+      theme = true;
+    }
+  } else {
+    theme = false;
+  }
+
+  int startup_switch = digitalRead(STARTUP_SWITCH);
+  int safety_switch = digitalRead(SAFETY_SWITCH);
+  int fire_button = digitalRead(FIRE_BUTTON);
+
+  // while the startup switch is set on
+  if (startup_switch == 1) {
+    // in general we always try to play the idle sound if started
+    if (playing == 1 && startup == true) {
+      playAudio(idleTrack, playing);
+    }
+
+    // choose the right powercell animation sequence for booted/on
+    if ( powerBooted == true ) {
+      // standard idle power sequence for the pack
+      poweredDown = false;
+      shuttingDown = false;
+      venting = false;
+      setWandLightState(3, 0, 0); //set sloblow red
+      setVentLightState(ventStart, ventEnd, 2);
+      powerSequenceOne(currentMillis, pwr_interval, cyc_interval, cyc_fade_interval);
+    } else {
+      // boot up the pack. powerSequenceBoot will set powerBooted when complete
+      powerSequenceBoot(currentMillis);
+      setWandLightState(3, 7, currentMillis);   //set sloblow red blinking
+    }
+
+    // if we are not started up we should play the startup sound and begin the boot sequence
+    if (startup == false) {
+      startup = true;
+      playAudio(startupTrack, playing);
+
+      // get the current safety switch state
+      if (safety_switch == 1 && safety == false) {
+        safety = true;
+      }
+    }
+
+    if( startup == true && safety_switch == 1 ){
+      if( venting == false && powerBooted == true ){
+        setWandLightState(1, 2, 0);    //  set back light orange
+        setWandLightState(2, 1, 0);    //  set body led white
+      }else{
+        setWandLightState(1, 4, 0);    //  set back light off
+        setWandLightState(2, 4, 0);    //  set body led off
+      }
+
+      // if the safety switch is set off then we can fire when the button is pressed
+      if ( fire_button == 0) {
+        // if the button is just pressed we clear all led's to start the firing animations
+        if ( isFiring == false ) {
+          shutdown_leds();
+          isFiring = true;
+        }
+
+        // show the firing bargraph sequence
+        barGraphSequenceTwo(currentMillis);
+
+        // strobe the nose pixels
+        fireStrobe(currentMillis);
+
+        // now powercell/cyclotron/wand lights
+        // if this is the first time reset some variables and play the blast track
+        if (fire == false) {
+          shouldWarn = false;
+          fire = true;
+          firingStateMillis = millis();
+          playAudio(blastTrack, playing);
+        } else {
+          // find out what our timing is
+          long diff = millis() - firingStateMillis;
+
+          if ( diff > firingWarnWaitTime) { // if we are in the fire warn interval
+            pwr_interval = 10;      // speed up the powercell animation
+            firing_interval = 20;   // speed up the bar graph animation
+            cyc_interval = 50;      // really speed up cyclotron
+            cyc_fade_interval = 5;  // speed up the fade of the cyclotron
+            if (playing == 1 || shouldWarn == false ) {
+              shouldWarn = true;
+              playAudio(warnTrack, playing); // play the firing track with the warning
+            }
+            setWandLightState(0, 8, currentMillis);    // set top light red flashing fast
+          } else if ( diff > firingWarmWaitTime) { // if we are in the dialog playing interval
+            pwr_interval = 30;      // speed up the powercell animation
+            firing_interval = 30;   // speed up the bar graph animation
+            cyc_interval = 200;     // speed up cyclotron
+            cyc_fade_interval = 10; // speed up the fade of the cyclotron
+            if (playing == 1) {
+              playAudio(blastTrack, playing); // play the normal blast track
+            }
+            setWandLightState(0, 6, currentMillis);    // set top light orange flashing
+          }
+        }
+      } else { // if we were firing and are no longer reset the leds
+        if ( isFiring == true ) {
+          shutdown_leds();
+          isFiring = false;
+        }
+
+        // and do the standard bargraph sequence
+        barGraphSequenceOne(currentMillis);
+
+        if (fire == true) { // if we were firing let's reset the animations and play the correct final firing track
+          clearFireStrobe();
+          setWandLightState(0, 4, currentMillis);    // set top light off
+
+          pwr_interval = 60;
+          firing_interval = 40;
+          cyc_interval = 1000;
+          cyc_fade_interval = 15;
+          fire = false;
+
+          // see if we've been firing long enough to get the dialog or vent sounds
+          long diff = millis() - firingStateMillis;
+
+          if ( diff > firingWarnWaitTime) { // if we are past the warning let's vent the pack
+            playAudio(ventTrack, playing);
+            venting = true;
+            clearPowerStrip(); // play the boot animation on the powercell
+          } else if ( diff > firingWarmWaitTime) { // if in the dialog time play the dialog in sequence
+            if( useDialogTracks == true ){
+              playDialogTrack(playing);
+            }else{
+              playAudio(endTrack, playing);
+            }
+          } else {
+            playAudio(endTrack, playing);
+          }
+        }
+      }
+
+      // if the safety was just changed play the click track
+      if (safety == false) {
+        safety = true;
+        playAudio(chargeTrack, playing);
+      }
+    } else {
+      // if the safety is switched off play the click track
+      if (safety == true) {
+        setWandLightState(1, 4, 0);    // set back light off
+        setWandLightState(2, 4, 0);    // set body off
+        safety = false;
+        playAudio(clickTrack, playing);
+      }
+    }
+  } else { // if we are powering down
+    if( poweredDown == false ){
+      if( shuttingDown == false ){
+        playAudio(shutdownTrack, playing); // play the pack shutdown track
+        shuttingDown = true;
+      }
+      cyclotronRunningFadeOut = 255;
+      powerSequenceShutdown(currentMillis);
+    }else{
+      if (startup == true) { // if started reset the variables
+        clearPowerStrip(); // clear all led's
+        shutdown_leds();
+        startup = false;
+        safety = false;
+        fire = false;
+      }
+    }
+  }
+  delay(1);
+}
+
+/*************** Wand Light Helpers *********************/
+unsigned long prevFlashMillis = 0; // last time we changed a powercell light in the idle sequence
+bool flashState = false;
+const int wandFastFlashInterval = 100; // interval at which we flash the top led on the wand
+const int wandMediumFlashInterval = 500; // interval at which we flash the top led on the wand
+
+void setWandLightState(int lednum, int state, int currentMillis){
+  switch ( state ) {
+    case 0: // set led red
+      wandLights.setPixelColor(lednum, wandLights.Color(255, 0, 0));
+      break;
+    case 1: // set led white
+      wandLights.setPixelColor(lednum, wandLights.Color(255, 255, 255));
+      break;
+    case 2: // set led orange
+      wandLights.setPixelColor(lednum, wandLights.Color(255, 127, 0));
+      break;
+    case 3: // set led blue
+      wandLights.setPixelColor(lednum, wandLights.Color(0, 0, 255));
+      break;
+    case 4: // set led off
+      wandLights.setPixelColor(lednum, 0);
+      break;
+    case 5: // fast white flashing
+      if (currentMillis - prevFlashMillis > wandFastFlashInterval) {
+        prevFlashMillis = currentMillis;
+        if( flashState == false ){
+          wandLights.setPixelColor(lednum, wandLights.Color(255, 255, 255));
+          flashState = true;
+        }else{
+          wandLights.setPixelColor(lednum, 0);
+          flashState = false;
+        }
+      }
+      break;
+    case 6: // slower orange flashing
+      if (currentMillis - prevFlashMillis > wandMediumFlashInterval) {
+        prevFlashMillis = currentMillis;
+        if( flashState == false ){
+          wandLights.setPixelColor(lednum, wandLights.Color(255, 127, 0));
+          flashState = true;
+        }else{
+          wandLights.setPixelColor(lednum, 0);
+          flashState = false;
+        }
+      }
+      break;
+    case 7: // medium red flashing
+      if (currentMillis - prevFlashMillis > wandMediumFlashInterval) {
+        prevFlashMillis = currentMillis;
+        if( flashState == false ){
+          wandLights.setPixelColor(lednum, wandLights.Color(255, 0, 0));
+          flashState = true;
+        }else{
+          wandLights.setPixelColor(lednum, 0);
+          flashState = false;
+        }
+      }
+      break;
+    case 8: // fast red flashing
+      if (currentMillis - prevFlashMillis > wandFastFlashInterval) {
+        prevFlashMillis = currentMillis;
+        if( flashState == false ){
+          wandLights.setPixelColor(lednum, wandLights.Color(255, 0, 0));
+          flashState = true;
+        }else{
+          wandLights.setPixelColor(lednum, 0);
+          flashState = false;
+        }
+      }
+      break;
+  }
+
+  wandLights.show();
+}
+
+/*************** Vent Light *************************/
+void setVentLightState(int startLed, int endLed, int state ){
+  switch ( state ) {
+    case 0: // set all leds to white
+      for(int i=startLed; i <= endLed; i++) {
+        powerStick.setPixelColor(i, powerStick.Color(255, 255, 255));
+      }
+      break;
+    case 1: // set all leds to blue
+      for(int i=startLed; i <= endLed; i++) {
+        powerStick.setPixelColor(i, powerStick.Color(0, 0, 255));
+      }
+      break;
+    case 2: // set all leds off
+      for(int i=startLed; i <= endLed; i++) {
+        powerStick.setPixelColor(i, 0);
+      }
+      break;
+  }
+}
+
+/*************** Powercell/Cyclotron Animations *********************/
+// timer helpers and intervals for the animations
+unsigned long prevPwrBootMillis = 0;    // the last time we changed a powercell light in the boot sequence
+const int pwr_boot_interval = 60;       // interval at which to cycle lights (milliseconds). Adjust this if
+
+unsigned long prevCycBootMillis = 0;    // the last time we changed a cyclotron light in the boot sequence
+const int cyc_boot_interval = 500;      // interval at which to cycle lights (milliseconds).
+const int cyc_boot_alt_interval = 600;      // interval at which to cycle lights (milliseconds).
+
+unsigned long prevShtdMillis = 0;       // last time we changed a light in the idle sequence
+const int pwr_shutdown_interval = 200;  // interval at which to cycle lights (milliseconds).
+
+unsigned long prevPwrMillis = 0;        // last time we changed a powercell light in the idle sequence
+unsigned long prevCycMillis = 0;        // last time we changed a cyclotron light in the idle sequence
+unsigned long prevFadeCycMillis = 0;    // last time we changed a cyclotron light in the idle sequence
+
+// LED tracking variables
+const int powerSeqTotal = powercellLedCount;                              // total number of led's for powercell 0 based
+int powerSeqNum = powercellIndexOffset;                                   // current running powercell sequence led
+int powerShutdownSeqNum = powercellLedCount - powercellIndexOffset;       // shutdown sequence counts down
+
+// animation level trackers for the boot and shutdown
+int currentBootLevel = powercellIndexOffset;                              // current powercell boot level sequence led
+int currentLightLevel = powercellLedCount - powercellIndexOffset;         // current powercell boot light sequence led
+
+void setCyclotronLightState(int startLed, int endLed, int state ){
+  switch ( state ) {
+    case 0: // set all leds to red
+      for(int i=startLed; i <= endLed; i++) {
+        powerStick.setPixelColor(i, powerStick.Color(255, 0, 0));
+      }
+      break;
+    case 1: // set all leds to orange
+      for(int i=startLed; i <= endLed; i++) {
+        powerStick.setPixelColor(i, powerStick.Color(255, 106, 0));
+      }
+      break;
+    case 2: // set all leds off
+      for(int i=startLed; i <= endLed; i++) {
+        powerStick.setPixelColor(i, 0);
+      }
+      break;
+    case 3: // fade all leds from red
+      for(int i=startLed; i <= endLed; i++) {
+        if( cyclotronRunningFadeOut >= 0 ){
+          powerStick.setPixelColor(i, 255 * cyclotronRunningFadeOut/255, 0, 0);
+          cyclotronRunningFadeOut--;
+        }else{
+          powerStick.setPixelColor(i, 0);
+        }
+      }
+      break;
+    case 4: // fade all leds to red
+      for(int i=startLed; i <= endLed; i++) {
+        if( cyclotronRunningFadeIn < 255 ){
+          powerStick.setPixelColor(i, 255 * cyclotronRunningFadeIn/255, 0, 0);
+          cyclotronRunningFadeIn++;
+        }else{
+          powerStick.setPixelColor(i, powerStick.Color(255, 0, 0));
+        }
+      }
+      break;
+  }
+}
+
+// shuts off and resets the powercell/cyclotron leds
+void clearPowerStrip() {
+  // reset vars
+  powerBooted = false;
+  poweredDown = true;
+  powerSeqNum = powercellIndexOffset;
+  powerShutdownSeqNum = powercellLedCount - powercellIndexOffset;
+  currentLightLevel = powercellLedCount;
+  currentBootLevel = powercellIndexOffset;
+  cyclotronRunningFadeIn = 0;
+
+  // shutoff the leds
+  for ( int i = 0; i <= c4End; i++) {
+    powerStick.setPixelColor(i, 0);
+  }
+  powerStick.show();
+
+  for ( int j=0; j<=3; j++ ){
+    wandLights.setPixelColor(j, 0);
+  }
+  wandLights.show();
+
+  if( venting == true ){
+    setVentLightState(ventStart, ventEnd, 0);
+  }
+}
+
+// boot animation on the powercell/cyclotron
+bool reverseBootCyclotron = false;
+void powerSequenceBoot(int currentMillis) {
+  bool doUpdate = false;
+
+  // START CYCLOTRON
+  if( useCyclotronFadeInEffect == false ){
+    if (currentMillis - prevCycBootMillis > cyc_boot_interval) {
+      prevCycBootMillis = currentMillis;
+
+      if( reverseBootCyclotron == false ){
+        setCyclotronLightState(c1Start, c1End, 1);
+        setCyclotronLightState(c2Start, c2End, 2);
+        setCyclotronLightState(c3Start, c3End, 1);
+        setCyclotronLightState(c4Start, c4End, 2);
+
+        doUpdate = true;
+        reverseBootCyclotron = true;
+      }else{
+        setCyclotronLightState(c1Start, c1End, 2);
+        setCyclotronLightState(c2Start, c2End, 1);
+        setCyclotronLightState(c3Start, c3End, 2);
+        setCyclotronLightState(c4Start, c4End, 1);
+
+        doUpdate = true;
+        reverseBootCyclotron = false;
+      }
+    }
+  }else{
+    if (currentMillis - prevCycBootMillis > cyc_boot_alt_interval) {
+      prevCycBootMillis = currentMillis;
+      setCyclotronLightState(c1Start, c4End, 4);
+      doUpdate = true;
+    }
+  }
+  // END CYCLOTRON
+
+  if (currentMillis - prevPwrBootMillis > pwr_boot_interval) {
+    // save the last time you blinked the LED
+    prevPwrBootMillis = currentMillis;
+
+    // START POWERCELL
+    if( currentBootLevel != powerSeqTotal ){
+      if( currentBootLevel == currentLightLevel){
+        if(currentLightLevel+1 <= powerSeqTotal){
+          powerStick.setPixelColor(currentLightLevel+1, 0);
+        }
+        powerStick.setPixelColor(currentBootLevel, powerStick.Color(0, 0, 255));
+        currentLightLevel = powerSeqTotal;
+        currentBootLevel++;
+      }else{
+        if(currentLightLevel+1 <= powerSeqTotal){
+          powerStick.setPixelColor(currentLightLevel+1, 0);
+        }
+        powerStick.setPixelColor(currentLightLevel, powerStick.Color(0, 0, 255));
+        currentLightLevel--;
+      }
+      doUpdate = true;
+    }else{
+      powerBooted = true;
+      currentBootLevel = powercellIndexOffset;
+      currentLightLevel = powercellLedCount - powercellIndexOffset;
+    }
+    // END POWERCELL
+  }
+
+  // if we have changed an led
+  if( doUpdate == true ){
+    powerStick.show(); // commit all of the changes
+  }
+}
+
+// idle/firing animation for the powercell/cyclotron
+int cycOrder = 0;     // which cyclotron led will be lit next
+int cycFading = -1;   // which cyclotron led is fading out for game style
+void powerSequenceOne(int currentMillis, int anispeed, int cycspeed, int cycfadespeed) {
+  bool doUpdate = false;  // keep track of if we changed something so we only update on changes
+
+  // START CYCLOTRON
+  if( useGameCyclotronEffect == true ){ // if we are doing the video game style cyclotron
+    if (currentMillis - prevCycMillis > cycspeed) {
+      prevCycMillis = currentMillis;
+
+      switch ( cycOrder ) {
+        case 0:
+          setCyclotronLightState(c1Start, c1End, 0);
+          setCyclotronLightState(c2Start, c2End, 2);
+          setCyclotronLightState(c3Start, c3End, 2);
+          cycFading = 0;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 1;
+          break;
+        case 1:
+          setCyclotronLightState(c2Start, c2End, 0);
+          setCyclotronLightState(c3Start, c3End, 2);
+          setCyclotronLightState(c4Start, c4End, 2);
+          cycFading = 1;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 2;
+          break;
+        case 2:
+          setCyclotronLightState(c1Start, c1End, 2);
+          setCyclotronLightState(c3Start, c3End, 0);
+          setCyclotronLightState(c4Start, c4End, 2);
+          cycFading = 2;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 3;
+          break;
+        case 3:
+          setCyclotronLightState(c1Start, c1End, 2);
+          setCyclotronLightState(c2Start, c2End, 2);
+          setCyclotronLightState(c4Start, c4End, 0);
+          cycFading = 3;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 0;
+          break;
+      }
+
+      doUpdate = true;
+    }
+
+    // now figure out the fading light
+    if( currentMillis - prevFadeCycMillis > cycfadespeed ){
+      prevFadeCycMillis = currentMillis;
+      if( cycFading != -1 ){
+        switch ( cycFading ) {
+          case 0:
+            setCyclotronLightState(c4Start, c4End, 3);
+            break;
+          case 1:
+            setCyclotronLightState(c1Start, c1End, 3);
+            break;
+          case 2:
+            setCyclotronLightState(c2Start, c2End, 3);
+            break;
+          case 3:
+            setCyclotronLightState(c3Start, c3End, 3);
+            break;
+        }
+        doUpdate = true;
+      }
+    }
+  }else{ // otherwise this is the standard version
+    if (currentMillis - prevCycMillis > cycspeed) {
+      prevCycMillis = currentMillis;
+
+      switch ( cycOrder ) {
+        case 0:
+          setCyclotronLightState(c4Start, c4End, 2);
+          setCyclotronLightState(c1Start, c1End, 0);
+          setCyclotronLightState(c2Start, c2End, 2);
+          setCyclotronLightState(c3Start, c3End, 2);
+          cycFading = 0;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 1;
+          break;
+        case 1:
+          setCyclotronLightState(c1Start, c1End, 2);
+          setCyclotronLightState(c2Start, c2End, 0);
+          setCyclotronLightState(c3Start, c3End, 2);
+          setCyclotronLightState(c4Start, c4End, 2);
+          cycFading = 1;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 2;
+          break;
+        case 2:
+          setCyclotronLightState(c1Start, c1End, 2);
+          setCyclotronLightState(c2Start, c2End, 2);
+          setCyclotronLightState(c3Start, c3End, 0);
+          setCyclotronLightState(c4Start, c4End, 2);
+          cycFading = 2;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 3;
+          break;
+        case 3:
+          setCyclotronLightState(c1Start, c1End, 2);
+          setCyclotronLightState(c2Start, c2End, 2);
+          setCyclotronLightState(c3Start, c3End, 2);
+          setCyclotronLightState(c4Start, c4End, 0);
+          cycFading = 3;
+          cyclotronRunningFadeOut = 255;
+          cycOrder = 0;
+          break;
+      }
+
+      doUpdate = true;
+    }
+  }
+  // END CYCLOTRON
+
+  // START POWERCELL
+  if (currentMillis - prevPwrMillis > anispeed) {
+    // save the last time you blinked the LED
+    prevPwrMillis = currentMillis;
+
+    for ( int i = powercellIndexOffset; i <= powerSeqTotal; i++) {
+      if ( i <= powerSeqNum ) {
+        powerStick.setPixelColor(i, powerStick.Color(0, 0, 150));
+      } else {
+        powerStick.setPixelColor(i, 0);
+      }
+    }
+
+    if ( powerSeqNum <= powerSeqTotal) {
+      powerSeqNum++;
+    } else {
+      powerSeqNum = powercellIndexOffset;
+    }
+
+    doUpdate = true;
+  }
+  // END POWERCELL
+
+  // if we changed anything update
+  if( doUpdate == true ){
+    powerStick.show();
+  }
+}
+
+// shutdown animation for the powercell/cyclotron
+int cyclotronFadeOut = 255;
+void powerSequenceShutdown(int currentMillis) {
+  if (currentMillis - prevShtdMillis > pwr_shutdown_interval) {
+    prevShtdMillis = currentMillis;
+
+    // START CYCLOTRON
+    for(int i=c1Start; i <= c4End; i++) {
+      if( cyclotronFadeOut >= 0 ){
+        powerStick.setPixelColor(i, 255 * cyclotronFadeOut/255, 0, 0);
+        cyclotronFadeOut--;
+      }else{
+        powerStick.setPixelColor(i, 0);
+      }
+    }
+    // END CYCLOTRON
+
+    // START POWERCELL
+    for ( int i = powerSeqTotal; i >= powercellIndexOffset; i--) {
+      if ( i <= powerShutdownSeqNum ) {
+        powerStick.setPixelColor(i, powerStick.Color(0, 0, 150));
+      } else {
+        powerStick.setPixelColor(i, 0);
+      }
+    }
+
+    powerStick.show();
+
+    if ( powerShutdownSeqNum >= powercellIndexOffset) {
+      powerShutdownSeqNum--;
+    } else {
+      poweredDown = true;
+      powerShutdownSeqNum = powercellLedCount - powercellIndexOffset;
+      cyclotronFadeOut = 255;
+    }
+    // END POWERCELL
+  }
+}
+
+/*************** Nose Jewel Firing Animations *********************/
+unsigned long prevFireMillis = 0;
+const int fire_interval = 50;     // interval at which to cycle lights (milliseconds).
+int fireSeqNum = 0;
+int fireSeqTotal = 5;
+
+void clearFireStrobe() {
+  for ( int i = 0; i < 7; i++) {
+    noseJewel.setPixelColor(i, 0);
+  }
+  noseJewel.show();
+  fireSeqNum = 0;
+}
+
+void fireStrobe(int currentMillis) {
+  if (currentMillis - prevFireMillis > fire_interval) {
+    prevFireMillis = currentMillis;
+
+    switch ( fireSeqNum ) {
+      case 0:
+        noseJewel.setPixelColor(0, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(1, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(2, 0);
+        noseJewel.setPixelColor(3, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(4, 0);
+        noseJewel.setPixelColor(5, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(6, 0);
+        break;
+      case 1:
+        noseJewel.setPixelColor(0, noseJewel.Color(0, 0, 255));
+        noseJewel.setPixelColor(1, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(3, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(4, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(5, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
+        break;
+      case 2:
+        noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(1, 0);
+        noseJewel.setPixelColor(2, noseJewel.Color(0, 0, 255));
+        noseJewel.setPixelColor(3, 0);
+        noseJewel.setPixelColor(4, noseJewel.Color(0, 0, 255));
+        noseJewel.setPixelColor(5, 0);
+        noseJewel.setPixelColor(6, noseJewel.Color(255, 0, 0));
+        break;
+      case 3:
+        noseJewel.setPixelColor(0, noseJewel.Color(0, 0, 255));
+        noseJewel.setPixelColor(1, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(3, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(4, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(5, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
+        break;
+      case 4:
+        noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(1, 0);
+        noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(3, 0);
+        noseJewel.setPixelColor(4, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(5, 0);
+        noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
+        break;
+      case 5:
+        noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 255));
+        noseJewel.setPixelColor(1, noseJewel.Color(0, 255, 0));
+        noseJewel.setPixelColor(2, noseJewel.Color(255, 0, 0));
+        noseJewel.setPixelColor(3, noseJewel.Color(0, 0, 255));
+        noseJewel.setPixelColor(4, noseJewel.Color(255, 0, 255));
+        noseJewel.setPixelColor(5, noseJewel.Color(255, 255, 255));
+        noseJewel.setPixelColor(6, noseJewel.Color(0, 0, 255));
+        break;
+    }
+
+    noseJewel.show();
+
+    fireSeqNum++;
+    if ( fireSeqNum > fireSeqTotal ) {
+      fireSeqNum = 0;
+    }
+  }
+}
+
+/*************** Bar Graph Animations *********************/
+// This is the idle sequence
+unsigned long prevBarMillis_on = 0;   // bargraph on tracker
+const int pwrcl_interval = 60;     // interval at which to cycle lights (milliseconds).
+bool reverseSequenceOne = false;
+
+void barGraphSequenceOne(int currentMillis) {
+  // normal sync animation on the bar graph
+  if (currentMillis - prevBarMillis_on > pwrcl_interval) {
+    // save the last time you blinked the LED
+    prevBarMillis_on = currentMillis;
+
+    if ( reverseSequenceOne == false ) {
+      switch_graph_led(seq_1_current, HIGH);
+      seq_1_current++;
+      if ( seq_1_current > num_led ) {
+        reverseSequenceOne = true;
+      }
+    } else {
+      switch_graph_led(seq_1_current, LOW);
+      seq_1_current--;
+      if ( seq_1_current < 0  ) {
+        reverseSequenceOne = false;
+      }
+    }
+  }
+}
+
+// This is the firing sequence
+unsigned long prevBarMillis_fire = 0; // bargraph firing tracker
+int fireSequenceNum = 1;
+
+void barGraphSequenceTwo(int currentMillis) {
+  if (currentMillis - prevBarMillis_fire > firing_interval) {
+    // save the last time you blinked the LED
+    prevBarMillis_fire = currentMillis;
+
+    switch (fireSequenceNum) {
+      case 1:
+        switch_graph_led(2, LOW);
+        switch_graph_led(14, LOW);
+        switch_graph_led(1, HIGH);
+        switch_graph_led(15, HIGH);
+        fireSequenceNum++;
+        break;
+      case 2:
+        switch_graph_led(1, LOW);
+        switch_graph_led(15, LOW);
+        switch_graph_led(2, HIGH);
+        switch_graph_led(14, HIGH);
+        fireSequenceNum++;
+        break;
+      case 3:
+        switch_graph_led(2, LOW);
+        switch_graph_led(14, LOW);
+        switch_graph_led(3, HIGH);
+        switch_graph_led(13, HIGH);
+        fireSequenceNum++;
+        break;
+      case 4:
+        switch_graph_led(3, LOW);
+        switch_graph_led(13, LOW);
+        switch_graph_led(4, HIGH);
+        switch_graph_led(12, HIGH);
+        fireSequenceNum++;
+        break;
+      case 5:
+        switch_graph_led(4, LOW);
+        switch_graph_led(12, LOW);
+        switch_graph_led(5, HIGH);
+        switch_graph_led(11, HIGH);
+        fireSequenceNum++;
+        break;
+      case 6:
+        switch_graph_led(5, LOW);
+        switch_graph_led(11, LOW);
+        switch_graph_led(6, HIGH);
+        switch_graph_led(10, HIGH);
+        fireSequenceNum++;
+        break;
+      case 7:
+        switch_graph_led(6, LOW);
+        switch_graph_led(10, LOW);
+        switch_graph_led(7, HIGH);
+        switch_graph_led(9, HIGH);
+        fireSequenceNum++;
+        break;
+      case 8:
+        switch_graph_led(7, LOW);
+        switch_graph_led(9, LOW);
+        switch_graph_led(6, HIGH);
+        switch_graph_led(10, HIGH);
+        fireSequenceNum++;
+        break;
+      case 9:
+        switch_graph_led(6, LOW);
+        switch_graph_led(10, LOW);
+        switch_graph_led(5, HIGH);
+        switch_graph_led(11, HIGH);
+        fireSequenceNum++;
+        break;
+      case 10:
+        switch_graph_led(5, LOW);
+        switch_graph_led(11, LOW);
+        switch_graph_led(4, HIGH);
+        switch_graph_led(12, HIGH);
+        fireSequenceNum++;
+        break;
+      case 11:
+        switch_graph_led(4, LOW);
+        switch_graph_led(12, LOW);
+        switch_graph_led(3, HIGH);
+        switch_graph_led(13, HIGH);
+        fireSequenceNum++;
+        break;
+      case 12:
+        switch_graph_led(3, LOW);
+        switch_graph_led(13, LOW);
+        switch_graph_led(2, HIGH);
+        switch_graph_led(14, HIGH);
+        fireSequenceNum = 1;
+        break;
+    }
+  }
+}
+
+/************************* Shutdown and helper functions ****************************/
+void shutdown_leds() {
+  // reset the sequence
+  seq_1_current = 1;
+  fireSequenceNum = 1;
+
+  // shut all led's off
+  for (int i = 1; i <= 15; i++) {
+    switch_graph_led(i, LOW);
+  }
+}
+
+void switch_graph_led(int num, int state) {
+  switch (num) {
+    case 1:
+      io.digitalWrite(SX1509_BAR_01, state);
+      break;
+    case 2:
+      io.digitalWrite(SX1509_BAR_02, state);
+      break;
+    case 3:
+      io.digitalWrite(SX1509_BAR_03, state);
+      break;
+    case 4:
+      io.digitalWrite(SX1509_BAR_04, state);
+      break;
+    case 5:
+      io.digitalWrite(SX1509_BAR_05, state);
+      break;
+    case 6:
+      io.digitalWrite(SX1509_BAR_06, state);
+      break;
+    case 7:
+      io.digitalWrite(SX1509_BAR_07, state);
+      break;
+    case 8:
+      io.digitalWrite(SX1509_BAR_08, state);
+      break;
+    case 9:
+      io.digitalWrite(SX1509_BAR_09, state);
+      break;
+    case 10:
+      io.digitalWrite(SX1509_BAR_10, state);
+      break;
+    case 11:
+      io.digitalWrite(SX1509_BAR_11, state);
+      break;
+    case 12:
+      io.digitalWrite(SX1509_BAR_12, state);
+      break;
+    case 13:
+      io.digitalWrite(SX1509_BAR_13, state);
+      break;
+    case 14:
+      io.digitalWrite(SX1509_BAR_14, state);
+      break;
+    case 15:
+      io.digitalWrite(SX1509_BAR_15, state);
+      break;
+  }
+}
+
+


Initial code for the official Victoria ros node. A work in progress.

error: pathspec 'Arduino/victoria_teensy_ros_node/victoria_teensy_ros_node.ino' did not match any file(s) known to git

--- Arduino/victoria_teensy_ros_node/victoria_teensy_ros_node.ino
+++ Arduino/victoria_teensy_ros_node/victoria_teensy_ros_node.ino
@@ -0,0 +1,175 @@
+/*
+ * Victoria Teensy ROS Node
+ *
+ * This code is the ROS node that executes on the Teensy processor
+ * for the Victoria RoboMagellan team. It uses the rosserial
+ * library to communicate with ROS. It uses Arduino and Teensy
+ * libraries to interact with systems and circuits connected to the
+ * Teensy processor. This code assumes that a Teensy 3.5 is used.
+ */
+
+// Teensy includes
+#define ENCODER_OPTIMIZE_INTERRUPTS
+#include <Encoder.h>  //
+#include <i2c_t3.h>
+
+// ROS includes
+#include <ros.h>
+#include <geometry_msgs/Twist.h>
+#include <nav_msgs/Odometry.h>
+#include <tf/transform_broadcaster.h>
+
+// Teensy pin definitions
+#define ENCODER_LEFT_PIN_1 29   // Teensy digital pin 29
+#define ENCODER_LEFT_PIN_2 30   // Teensy digital pin 30
+#define ENCODER_RIGHT_PIN_1 31  // Teensy digital pin 31
+#define ENCODER_RIGHT_PIN_2 32  // Teensy digital pin 32
+#define BUMPER_LEFT_PIN 14      // Teensy analog pin 14
+#define BUMPER_RIGHT_PIN 15     // Teensy analog pin 15
+
+// TRex motor controller
+HardwareSerial trex = HardwareSerial();
+
+// Motor encoders
+Encoder encoder_l(ENCODER_LEFT_PIN_1, ENCODER_LEFT_PIN_2);
+Encoder encoder_r(ENCODER_RIGHT_PIN_1, ENCODER_RIGHT_PIN_2);
+unsigned long encoder_l_pos;
+unsigned long encoder_r_pos;
+
+// Bumper sensors
+#define BUMPER_THRESHOLD 500  // Threshold that will indicate robot should stop
+unsigned int bumper_l_base;
+unsigned int bumper_r_base;
+
+// ROS node handle
+ros::NodeHandle ros_nh;
+
+// ROS cmd_vel subscriber
+void cmdVelCallback(const geometry_msgs::Twist& twist_msg);
+ros::Subscriber<geometry_msgs::Twist> ros_cmd_vel_sub("cmd_vel", cmdVelCallback);
+
+// ROS Odometry publisher
+nav_msgs::Odometry ros_odom_msg;
+ros::Publisher ros_odom_pub("odom", &ros_odom_msg);
+
+// ROS Odometry broadcaster
+geometry_msgs::TransformStamped ros_odom_transform;
+tf::TransformBroadcaster ros_odom_broadcaster;
+
+ros::Time current_time;
+ros::Time last_time;
+ros::Time last_cmd_vel_time;
+
+char ros_odom_header_frame_id[] = "/odom";
+char ros_odom_child_frame_id[] = "/base_link";
+
+void setup() {
+  current_time = ros_nh.now();
+  last_time = current_time;
+  last_cmd_vel_time = current_time;
+  encoder_l_pos = 0.0;
+  encoder_r_pos = 0.0;
+  bumper_l_base = analogRead(BUMPER_LEFT_PIN);
+  bumper_r_base = analogRead(BUMPER_RIGHT_PIN);
+
+  // Setup basic I2C master mode pins 18/19, external pullups, 400kHz, 200ms default timeout
+  Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000);
+  Wire.setDefaultTimeout(200000); // 200ms
+
+  // Start serial port to TRex
+  trex.begin(19200);
+
+  // Initialize ros node
+  ros_nh.initNode();
+
+  // Initialize broadcasters
+  ros_odom_transform.header.frame_id = ros_odom_header_frame_id;
+  ros_odom_transform.child_frame_id = ros_odom_child_frame_id;
+  ros_odom_broadcaster.init(ros_nh);
+
+  // Initialize ros publishers
+  ros_odom_msg.header.frame_id = ros_odom_header_frame_id;
+  ros_odom_msg.child_frame_id = ros_odom_child_frame_id;
+  ros_nh.advertise(ros_odom_pub);
+
+  // Initialize ros subscribers
+  ros_nh.subscribe(ros_cmd_vel_sub);
+}
+
+void loop() {
+  ros_nh.spinOnce();
+  current_time = ros_nh.now();
+
+  // If we have not received any cmd_vel messages for a while,
+  // something is wrong, stop the robot.
+
+  // Read bumper sensors
+  unsigned int new_bumper_l = analogRead(BUMPER_LEFT_PIN);
+  unsigned int new_bumper_r = analogRead(BUMPER_RIGHT_PIN);
+
+  // Check bumper thresholds to stop robot
+
+  // Read encoders
+  unsigned long new_encoder_l_pos = encoder_l.read();
+  unsigned long new_encoder_r_pos = encoder_r.read();
+
+  // Read imu data
+
+  // Broadcast odometry transform
+  ros_odom_transform.header.stamp = current_time;
+
+  // TODO: set all the transform data
+
+  ros_odom_broadcaster.sendTransform(ros_odom_transform);
+
+  // Publish Odometry
+  ros_odom_msg.header.stamp = current_time;
+
+  // TODO: Set all the odometry data
+
+  ros_odom_pub.publish(&ros_odom_msg);
+
+  last_time = current_time;
+}
+
+void cmdVelCallback(const geometry_msgs::Twist& twist_msg) {
+  last_cmd_vel_time = ros_nh.now();
+
+  // Do something interesting with the cmd_vel
+  setMotors(100, 100);
+}
+
+/*
+ * Sets the speed for the motors. Values are expected
+ * to be between -255 and 255. Values outside this range
+ * will be pinned.
+ */
+void setMotors(int motor_l_speed, int motor_r_speed) {
+  byte command_byte_l = 0xC4;
+  if (motor_l_speed < 0) {
+    command_byte_l = command_byte_l | 0x01;
+  } else {
+    command_byte_l = command_byte_l | 0x02;
+  }
+  motor_l_speed = abs(motor_l_speed);
+  if (motor_l_speed > 255) {
+    motor_l_speed = 255;
+  }
+
+  byte command_byte_r = 0xCC;
+  if (motor_r_speed < 0) {
+    command_byte_r = command_byte_r | 0x01;
+  } else {
+    command_byte_r = command_byte_r | 0x02;
+  }
+  motor_r_speed = abs(motor_r_speed);
+  if (motor_r_speed > 255) {
+    motor_r_speed = 255;
+  }
+
+  trex.write(command_byte_l);
+  trex.write((byte)motor_l_speed);
+  trex.write(command_byte_r);
+  trex.write((byte)motor_r_speed);
+}
+


add simple multithreading template using new thread syntax

error: pathspec 'examples-ltc/B.Threads/LTCthreads/SimpleMultithreadingTemplate.ino' did not match any file(s) known to git

--- examples-ltc/B.Threads/LTCthreads/SimpleMultithreadingTemplate.ino
+++ examples-ltc/B.Threads/LTCthreads/SimpleMultithreadingTemplate.ino
@@ -0,0 +1,124 @@
+// Love to Code
+
+// Simple multithread template
+//
+// Multithreading is the act of running multiple pieces of code at the same time.
+// Concurrency is the act of sharing variables between threads.
+//
+// Remember: Multithreading is easy; concurrency is hard.
+//
+// So, as long as you don't share any variables between threads, multithreading
+// is straightforward. This template allows you to put code in up to six
+// threads that execute in parallel.
+//
+// The easiest way to use this code is to imagine you are writing a separate program,
+// with differently named variable names and pin names, for each output pin on LTC.
+//
+// If you put "tN_" (e.g. t0_, t1_, t2_) in front of every variable name within
+// each thread, it will help make sure you don't accidentally share a simple variable
+// name between threads.
+
+#include "ChibiOS.h" // we need to include our special functions to enable threading
+#include "SimpleThreads.h"
+
+const int g_fadeAmount = 5; // this is global, mark as const to avoid modifications
+// "const" means a variable can only be read. Read-only variables can be safely shared
+// across all threads.
+
+///// thread 0
+int t0_brightness = 0;
+int t0_led = 0;
+int t0_fadeAmount;
+
+void setup0() {
+  // thread 0's specific setup stuff here
+  pinMode(t0_led, OUTPUT);
+  t0_fadeAmount = g_fadeAmount;
+}
+
+void loop0() {
+  // thread 0's loop here
+  analogWrite(t0_led, t0_brightness);
+
+  t0_brightness = t0_brightness + t0_fadeAmount;
+
+  if (t0_brightness <= 0 || t0_brightness >= 255) {
+    t0_fadeAmount = -t0_fadeAmount ;
+  }
+
+  delay(30);
+}
+
+///// thread 1
+int t1_brightness = 128;
+int t1_led = 1;
+int t1_fadeAmount;
+
+void setup1() {
+  // thread 1's specific setup stuff here
+  pinMode(t1_led, OUTPUT);
+  t1_fadeAmount = g_fadeAmount;
+}
+
+void loop1() {
+  // thread 1's loop here
+  analogWrite(t1_led, t1_brightness);
+
+  t1_brightness = t1_brightness + t1_fadeAmount;
+
+  if (t1_brightness <= 0 || t1_brightness >= 255) {
+    t1_fadeAmount = -t1_fadeAmount ;
+  }
+
+  delay(30);
+}
+
+
+///// thread 2
+void setup2() {
+  outputMode(2);
+}
+
+void loop2() {
+  on(2);
+  pause(500);
+  off(2);
+  pause(500);
+}
+
+///// thread 3
+void setup3() {
+  outputMode(3);
+}
+
+void loop3() {
+  on(3);
+  pause(400);
+  off(3);
+  pause(400);
+}
+
+///// thread 4
+void setup4() {
+  outputMode(4);
+}
+
+void loop4() {
+  on(4);
+  pause(600);
+  off(4);
+  pause(600);
+}
+
+///// thread 5
+void setup5() {
+  outputMode(5);
+}
+
+void loop5() {
+  on(5);
+  pause(1000);
+  off(5);
+  pause(1000);
+}
+


Firmware draft

Firmware draft

error: pathspec 'Ensembles/EnsembleOne/firmeware/EnsembleOne_firmware/EnsembleOne_firmware.ino' did not match any file(s) known to git

--- Ensembles/EnsembleOne/firmeware/EnsembleOne_firmware/EnsembleOne_firmware.ino
+++ Ensembles/EnsembleOne/firmeware/EnsembleOne_firmware/EnsembleOne_firmware.ino
@@ -0,0 +1,84 @@
+/* PHOBOS - EnsembleOne firmware v.0.1 (16.05.2017)
+ *
+ *
+ */
+
+#include <MIDI.h>
+
+// MOUSSE BOWLS' PINS
+#define A1 7
+#define A2 8
+#define A3 9
+#define A4 10
+// MEDALS' PINS
+#define B1 4
+#define B2 5
+#define B3 6
+// SHAKERS' PINS
+#define C1 44
+#define C2 2
+#define C3 3
+// WOOD BLOCKS' PINS
+#define D1 46
+#define D2 45
+
+// make note to pin array
+byte note2pin[38];
+byte vel, pitch;
+
+MIDI_CREATE_DEFAULT_INSTANCE();
+
+void setup() {
+  MIDI.begin(1); // Launch MIDI and listen to channel 1
+
+  // set output pins
+  pinMode(A1, OUTPUT);
+  pinMode(A2, OUTPUT);
+  pinMode(A3, OUTPUT);
+  pinMode(A4, OUTPUT);
+
+  pinMode(B1, OUTPUT);
+  pinMode(B2, OUTPUT);
+  pinMode(B3, OUTPUT);
+
+  pinMode(C1, OUTPUT);
+  pinMode(C2, OUTPUT);
+  pinMode(C3, OUTPUT);
+
+  pinMode(D1, OUTPUT);
+  pinMode(D2, OUTPUT);
+
+  // set note2pin array
+  note2pin[0] = A1;
+  note2pin[1] = A2;
+  note2pin[2] = A3;
+  note2pin[3] = A4;
+
+  note2pin[12] = B1;
+  note2pin[13] = B2;
+  note2pin[14] = B3;
+
+  note2pin[24] = C1;
+  note2pin[25] = C2;
+  note2pin[26] = C3;
+
+  note2pin[36] = D1;
+  note2pin[37] = D2;
+}
+
+void loop() {
+  if(MIDI.read()){
+      switch(MIDI.getType(){
+        case midi::NoteOn:
+          pitch = MIDI.getData1();
+          vel = MIDI.getData2();
+          analogWrite(note2pin[pitch], vel << 1);
+        break;
+
+        case midi::NoteOff:
+          pitch = MIDI.getData1();
+          analogWrite(note2pin[pitch], LOW);
+        break;
+      }
+  }
+}


Nuevo sketch principal adaptado a las nuevas funcionalidades.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/nverdicchio/soa-2017-bicicleta-inteligente.git/'


Remove extra Udp.parsePacket() from example, it should only be called once

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bsmr-arduino/Arduino.git/'


Error in analogWrite parameter

Error in analogWrite parameter

error: pathspec 'LCD' did not match any file(s) known to git
error: pathspec 'TFT' did not match any file(s) known to git
error: pathspec 'Screen/lcd_2/lcd_2.ino' did not match any file(s) known to git


hmm, a dedicated command to read back queue length is nice …

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/trinamic/T-Bone.git/'


Create moving_colored_bars.ino

Create moving_colored_bars.ino

Might be useful for Xmas!

error: pathspec 'moving_colored_bars.ino' did not match any file(s) known to git

--- moving_colored_bars.ino
+++ moving_colored_bars.ino
@@ -0,0 +1,117 @@
+//***************************************************************
+// Moving colored bars
+// Original code by Richard Bailey,  Feb. 2017
+//
+// Modified to allow a few other options (which might be
+// useful for Chrismas!)
+// You'll probably need to adjust stuff for longer strips.  I only
+// tested with a tiny 32 pixel setup.
+//
+// Marc Miller, Dec 2017
+//***************************************************************
+
+#include "FastLED.h"
+#define DATA_PIN    11
+#define CLK_PIN     13
+#define LED_TYPE    LPD8806
+#define COLOR_ORDER GRB
+#define NUM_LEDS    32
+#define BRIGHTNESS  64
+CRGBArray<NUM_LEDS> leds;
+
+
+#define FRAME_DELAY 80  //How fast to move (milliseconds)
+
+
+/* Specify your colors and the order of those colors.
+   You can create a longer section of a single color by
+   listing it several times (such as green in this first
+   example)
+   Note: I used Grey instead of White here so it's not
+   as bright compared to the other colors.
+*/
+long colorPallet[] = {CRGB::Green,CRGB::Grey,CRGB::Red,CRGB::Grey,CRGB::Red,CRGB::Grey,CRGB::Red,CRGB::Green,CRGB::Green,CRGB::Green};
+//long colorPallet[] = {CRGB::Black,CRGB::Green,CRGB::Red};
+//long colorPallet[] = {CRGB::Green,CRGB::Red};
+//long colorPallet[] = {CRGB::Black,CRGB::Blue,CRGB::Yellow,CRGB::Purple};  //Black can be used too of course.
+
+
+const int numberofColors = sizeof(colorPallet)/sizeof(int);  //Auto calculate your specified number of color bars
+
+
+/* Play with setting the colorBarLength in different ways for slightly different effects. */
+int colorBarLength = 10;  //Some specific length
+//int colorBarLength = NUM_LEDS-1;  //The full strip length per color
+//int colorBarLength = NUM_LEDS/2;  //Half the strip length per color
+//int colorBarLength = NUM_LEDS/numberofColors;  //Strip length divided by number of colors
+
+
+
+int frameCounter;  //These don't need to be changed
+int palletPosition;
+int colorBarPosition = 1;
+bool clearLEDS = false;
+
+
+//---------------------------------------------------------------
+void setup() {
+  Serial.begin(115200);  // Allows serial monitor output (check baud rate)
+  delay(1500); // startup delay
+  //FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
+  FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
+  FastLED.setBrightness(BRIGHTNESS);
+  FastLED.clear();
+  FastLED.show();
+  Serial.println("Setup done. \n");
+}
+
+
+//---------------------------------------------------------------
+void loop() {
+
+  EVERY_N_MILLISECONDS(FRAME_DELAY) {
+
+    for (int x=0; x<NUM_LEDS-1; x++)
+    {
+      leds[x] = leds[x+1];
+    }
+    if (clearLEDS)
+    {
+      leds[NUM_LEDS-1] = colorPallet[palletPosition];
+    }
+    if ((colorBarPosition <= colorBarLength) && !clearLEDS)
+    {
+      leds[NUM_LEDS-1] = colorPallet[palletPosition];
+      colorBarPosition++;
+    }
+    if ((palletPosition == numberofColors-1) && (colorBarPosition > colorBarLength) && !clearLEDS)
+    {
+      leds[NUM_LEDS-1]=colorPallet[palletPosition];
+      palletPosition = 0;
+      colorBarPosition = 1;
+      clearLEDS= true;
+    }
+    if ((colorBarPosition > colorBarLength) && !clearLEDS)
+    {
+      colorBarPosition = 1;
+      palletPosition = palletPosition+1;
+    }
+    //if (clearLEDS && !leds(0,NUM_LEDS-1))  //Not using this for of test any more
+    if (clearLEDS && leds[0]==(CRGB)(colorPallet[numberofColors-1]))  //restarts as soon as last color makes it past the end
+    {
+      //Serial.print( leds[0].r );  Serial.print("\t"), Serial.print( leds[0].g ); Serial.print("\t"), Serial.println( leds[0].b );  //Print out RGB colors it's triggering on
+      clearLEDS = false;
+    }
+
+  }//end_EVERY_N
+
+  FastLED.show();
+
+}//end_main_loop
+
+
+//---------------------------------------------------------------
+//TODO:
+//  Add option to run in reverse direction
+//  Make some hot chocolate
+


Code rewrite

Code rewrite

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/markwatneyy/ttt_arduino.git/'


Help Han With Her Project

Help Han With Her Project

This doesn’t belong to me… Came from:
http://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04
/

error: pathspec 'ultrasonicdistancesensorcode/ultrasonicdistancesensorcode.ino' did not match any file(s) known to git

--- ultrasonicdistancesensorcode/ultrasonicdistancesensorcode.ino
+++ ultrasonicdistancesensorcode/ultrasonicdistancesensorcode.ino
@@ -0,0 +1,34 @@
+/*
+* Ultrasonic Sensor HC-SR04 and Arduino Tutorial
+*
+* Crated by Dejan Nedelkovski,
+* www.HowToMechatronics.com
+*
+*/
+// defines pins numbers
+const int trigPin = 9;
+const int echoPin = 10;
+// defines variables
+long duration;
+int distance;
+void setup() {
+pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
+pinMode(echoPin, INPUT); // Sets the echoPin as an Input
+Serial.begin(9600); // Starts the serial communication
+}
+void loop() {
+// Clears the trigPin
+digitalWrite(trigPin, LOW);
+delayMicroseconds(2);
+// Sets the trigPin on HIGH state for 10 micro seconds
+digitalWrite(trigPin, HIGH);
+delayMicroseconds(10);
+digitalWrite(trigPin, LOW);
+// Reads the echoPin, returns the sound wave travel time in microseconds
+duration = pulseIn(echoPin, HIGH);
+// Calculating the distance
+distance= duration*0.034/2;
+// Prints the distance on the Serial Monitor
+Serial.print("Distance: ");
+Serial.println(distance);
+}


add arduino code on nano

add arduino code on nano

error: pathspec 'arduinocontrol/arduinocontrol.ino' did not match any file(s) known to git

--- arduinocontrol/arduinocontrol.ino
+++ arduinocontrol/arduinocontrol.ino
@@ -0,0 +1,120 @@
+/*
+  Blink
+  Turns on an LED on for one second, then off for one second, repeatedly.
+
+  This example code is in the public domain.
+ */
+
+// Pin 13 has an LED connected on most Arduino boards.
+// give it a name:
+int moto1_1 = 2;
+int moto1_2 = 3;
+int moto2_1 = 4;
+int moto2_2 = 5;
+int moto1_en = 6;
+int moto2_en = 9;
+
+
+// the setup routine runs once when you press reset:
+void setup() {
+  // initialize serial communication at 9600 bits per second:
+  Serial.begin(9600);
+  // initialize the digital pin as an output.
+  pinMode(moto1_1, OUTPUT);
+  pinMode(moto1_2, OUTPUT);
+  pinMode(moto2_1, OUTPUT);
+  pinMode(moto2_2, OUTPUT);
+  pinMode(moto1_en, OUTPUT);
+  pinMode(moto2_en, OUTPUT);
+  establishContact();  // send a byte to establish contact until receiver responds
+}
+
+// the loop routine runs over and over again forever:
+void loop() {
+
+   while (Serial.available() > 0) {
+       // look for the next valid integer in the incoming serial stream:
+      char cmd = Serial.read();
+      // do it again:
+      int param = Serial.parseInt();
+     // look for the newline. That's the end of your  sentence:
+      if (Serial.read() == '#') {
+
+         param = param*255/10;
+
+          if(cmd == 'F') {
+            goFront(param);
+          }
+          if(cmd == 'B') {
+            goBack(param);
+          }
+          if(cmd == 'L') {
+            goLeft(param);
+          }
+          if(cmd == 'R') {
+            goRight(param);
+          }
+          if(cmd == 'S') {
+            goStop();
+          }
+
+      }
+      //echo rx values:
+      Serial.print("-->");
+      Serial.print(cmd);
+      Serial.println(param,HEX);
+
+   }
+
+}
+
+void establishContact() {
+  while (Serial.available() <= 0) {
+    Serial.println("IC Welcome U!");   // send an initial string
+    delay(300);
+  }
+}
+
+//sp mean speed
+void goFront(int sp){
+  digitalWrite(moto1_1, HIGH);   // turn the LED on (HIGH is the voltage level)
+  digitalWrite(moto1_2, LOW);   // turn the LED on (HIGH is the voltage level)
+  digitalWrite(moto2_1, HIGH);   // turn the LED on (HIGH is the voltage level)
+  digitalWrite(moto2_2, LOW);   // turn the LED on (HIGH is the voltage level)
+  analogWrite(moto1_en, sp);   //
+  analogWrite(moto2_en, sp);   //
+}
+
+void goBack(int sp){
+  digitalWrite(moto1_1, LOW);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto1_2, HIGH);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto2_1, LOW);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto2_2, HIGH);    // turn the LED off by making the voltage LOW
+  analogWrite(moto1_en, sp);   //
+  analogWrite(moto2_en, sp);   //
+}
+
+void goLeft(int sp){
+  digitalWrite(moto1_1, LOW);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto1_2, HIGH);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto2_1, HIGH);   // turn the LED on (HIGH is the voltage level)
+  digitalWrite(moto2_2, LOW);   // turn the LED on (HIGH is the voltage level)
+  analogWrite(moto1_en, sp);   //
+  analogWrite(moto2_en, sp);   //
+}
+
+void goRight(int sp){
+  digitalWrite(moto1_1, HIGH);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto1_2, LOW);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto2_1, LOW);   // turn the LED on (HIGH is the voltage level)
+  digitalWrite(moto2_2, HIGH);   // turn the LED on (HIGH is the voltage level)
+  analogWrite(moto1_en, sp);   //
+  analogWrite(moto2_en, sp);   //
+}
+
+void goStop(){
+  digitalWrite(moto1_1, LOW);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto1_2, LOW);    // turn the LED off by making the voltage LOW
+  digitalWrite(moto2_1, LOW);   // turn the LED on (HIGH is the voltage level)
+  digitalWrite(moto2_2, LOW);   // turn the LED on (HIGH is the voltage level)
+}


Changed Baud rate

Changed Baud rate

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sassystacks/DASS.git/'


Added files via upload

Added files via upload

error: pathspec 'encoder.ino' did not match any file(s) known to git

--- encoder.ino
+++ encoder.ino
@@ -0,0 +1,39 @@
+/* Rotary encoder read example */
+#define ENC_A 14
+#define ENC_B 15
+#define ENC_PORT PINC
+
+void setup()
+{
+  /* Setup encoder pins as inputs */
+  pinMode(ENC_A, INPUT);
+  digitalWrite(ENC_A, HIGH);
+  pinMode(ENC_B, INPUT);
+  digitalWrite(ENC_B, HIGH);
+  Serial.begin (115200);
+  Serial.println("Start");
+}
+
+void loop()
+{
+ static uint8_t counter = 0;      //this variable will be changed by encoder input
+ int8_t tmpdata;
+ /**/
+  tmpdata = read_encoder();
+  if( tmpdata ) {
+    Serial.print("Counter value: ");
+    Serial.println(counter, DEC);
+    counter += tmpdata;
+  }
+}
+
+/* returns change in encoder state (-1,0,1) */
+int8_t read_encoder()
+{
+  static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
+  static uint8_t old_AB = 0;
+  /**/
+  old_AB <<= 2;                   //remember previous state
+  old_AB |= ( ENC_PORT & 0x03 );  //add current state
+  return ( enc_states[( old_AB & 0x0f )]);
+}


added beam effect for the strip lights

added beam effect for the strip lights

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stewartadam/lulzsaber.git/'


- initial GATT HID example

- initial GATT HID example

error: pathspec 'examples/GATT_HID/GATT_HID.ino' did not match any file(s) known to git

--- examples/GATT_HID/GATT_HID.ino
+++ examples/GATT_HID/GATT_HID.ino
@@ -0,0 +1,45 @@
+// Import libraries (BLEPeripheral depends on SPI)
+#include <SPI.h>
+#include <BLEPeripheral.h>
+#include <BLEHID.h>
+
+// define pins (varies per shield/board)
+#define BLE_REQ   6
+#define BLE_RDY   7
+#define BLE_RST   4
+
+BLEHID bleHID = BLEHID(BLE_REQ, BLE_RDY, BLE_RST);
+
+void setup() {
+  Serial.begin(9600);
+#if defined (__AVR_ATmega32U4__)
+  while(!Serial);
+#endif
+
+  bleHID.begin();
+
+  Serial.println(F("BLE HID"));
+}
+
+void loop() {
+  BLECentral central = bleHID.central();
+
+  if (central) {
+    // central connected to peripheral
+    Serial.print(F("Connected to central: "));
+    Serial.println(central.address());
+
+    while (bleHID.connected()) {
+      if (Serial.available() > 0) {
+        Serial.read();
+
+        bleHID.write(0x1E); // 'a'
+      }
+    }
+
+    // central disconnected
+    Serial.print(F("Disconnected from central: "));
+    Serial.println(central.address());
+  }
+}
+


Adding example

Adding example

error: pathspec 'teensy3/libraries/TeensyRTC/examples/TeensyRTCExample.ino' did not match any file(s) known to git

--- teensy3/libraries/TeensyRTC/examples/TeensyRTCExample.ino
+++ teensy3/libraries/TeensyRTC/examples/TeensyRTCExample.ino
@@ -0,0 +1,40 @@
+/*
+ * TeensyRTCExample
+ *
+ *  Created on: Nov 13, 2014
+ *      Author: Konstantin Gredeskoul
+ *        Code: https://github.com/kigster
+ *
+ *  (c) 2014 All rights reserved, MIT License.
+ */
+
+#include <Time.h>
+#include <TeensyRTC.h>
+
+TeensyRTC rtc;
+
+char stringBuffer[20];
+
+time_t getTeensy3Time() {
+	return Teensy3Clock.get();
+}
+
+void logTime() {
+	rtc.formatTime(stringBuffer, rtc.currentTime());
+	Serial.print("Current Time: ");
+	Serial.println(stringBuffer);
+}
+
+void setup() {
+	setSyncProvider(getTeensy3Time);
+
+	Serial.begin(115200);
+	Serial.println("Starting sketch TeensyRTCExample");
+
+	rtc.begin();
+}
+
+void loop() {
+    logTime();
+    delay(1000);
+}


This is the version of the sunrise alarm for Kristy.  This device has the RTC, the clock display, several buttons, and a constant current PWM power supply for a 12V LED that turned into an MR16 bulb.

error: pathspec 'SunriseAlarm.ino' did not match any file(s) known to git

--- SunriseAlarm.ino
+++ SunriseAlarm.ino
@@ -0,0 +1,826 @@
+// Sunrise Alarm
+// Todd Coffey
+// Prototype in bedroom 2013-03-26
+// 2x 2N3904 transistors connected to pin3 through 2x 10kOhm resistors
+// These transistors are connected to 4x white LEDs through 100Ohm resistors to 5V.
+#include "TimerOne.h"
+#include <Wire.h>
+#include "Adafruit_LEDBackpack.h"
+#include "Adafruit_GFX.h"
+#include "RTClib.h"
+#include "AT24Cxx.h"
+
+
+// 2013-04-06 TODO:  Add a temperature sensor to the lamp and if it exceeds a particular temperature, then turn it off or down
+// 2013-04-06 TODO:  Add three LEDs inside the enclosure to indicate which mode you are in.  E.g. green for alarm, blue for time, and red for sundown.
+// 2013-04-06 DONE 2013-04-06:  Store SunSet alarm setting in EEPROM
+// 2013-04-06 DONE 2013-04-06:  Store brigness level in EEPROM
+// 2013-04-06 DONE 2013-04-06:  Change Alarm, Time, and Sundown modes so they will automatically exit the mode after 60 seconds of inactivity.
+// 2013-04-01 TODO:  Box enclosure:  Consider a OLED display behind a thin veneer of wood or paper so that the display can print
+//                   the numbers in a particular font, e.g. the old Russian Nixie tube font, or a Victorian font.
+//                   Also:  Change all the switches to flip switches or knobs for a more retro feel.
+//                   Make sure each of the switches & knobs feels different so you can find them in the dark.
+//                   Alternative to the OLED display:  Invest in nixie tubes
+// 2013-04-01 TODO:  Change "OffButton" to allow you to see how much time is left and reset it
+// 2013-04-01 TODO:  Rework SunRISE alarm to match the way the SunSET alarm works.  Basically, use millis() instead of clock
+// DONE 2013-03-29:  Add alarm & time mode so you don't have to hold down the buttons.
+// DONE 2013-03-30:  Add SunSet mode
+// WONTFIX 2013-03-29:  Add AM/PM indicator
+// DONE 2013-03-29:  Add method to toggle alarm on/off
+// DONE 2013-03-28:  Add hardware buttons for setting time and alarm
+// TODO:  Add audio:  chirping birds at alarm time
+// TODO:  Add snooze button to delay chirping for 7 minutes or so
+// DONE 2013-04-17:  Change light alarm so it is based on millis() rather than RTC
+// TODO:  Get light updated more often, especially in third slope of alarm.
+
+namespace SunriseAlarm {
+
+struct ClockTime {
+  ClockTime() : hour(0), minute(0), second(0) {}
+  ClockTime(int h, int m) : hour(h), minute(m), second(0) {}
+  ClockTime(int h, int m, int s) : hour(h), minute(m), second(s) {}
+  ClockTime(DateTime dt) : hour(dt.hour()), minute(dt.minute()), second(dt.second()) {}
+  ClockTime(const ClockTime & ct) : hour(ct.hour), minute(ct.minute), second(ct.second) {}
+  ClockTime operator++(int) {
+    ClockTime result(*this);
+    ++this->minute;
+    fixTime();
+    return result;
+  }
+  ClockTime operator--(int) {
+    ClockTime result(*this);
+    --this->minute;
+    fixTime();
+    return result;
+  }
+  ClockTime & operator++() {
+    ++this->minute;
+    fixTime();
+    return *this;
+  }
+  ClockTime & operator--() {
+    --this->minute;
+    fixTime();
+    return *this;
+  }
+  void fixTime() {
+    while (this->second > 59) {
+      ++this->minute;
+      this->second -= 60;
+    }
+    while (this->minute > 59) {
+      ++this->hour;
+      this->minute -= 60;
+    }
+    while (this->hour > 23) {
+      this->hour -= 24;
+    }
+    while (this->second < 0) {
+      --this->minute;
+      this->second += 60;
+    }
+    while (this->minute < 0) {
+      --this->hour;
+      this->minute += 60;
+    }
+    while (this->hour < 0) {
+      this->hour += 24;
+    }
+  }
+  int hour;
+  int minute;
+  int second;
+};
+
+
+ClockTime operator+(ClockTime lhs, int minutes) {
+    lhs.minute+=minutes;
+    lhs.fixTime();
+    return lhs;
+}
+
+
+bool operator<(ClockTime lhs, ClockTime rhs) {
+  if (lhs.hour < rhs.hour) {
+    return true;
+  }
+  if (lhs.hour > rhs.hour) {
+    return false;
+  }
+  // lhs.hour == rhs.hour
+  if (lhs.minute < rhs.minute) {
+    return true;
+  }
+  if (lhs.minute > rhs.minute) {
+    return false;
+  }
+  // lhs.minute == rhs.minute
+  if (lhs.second < rhs.second) {
+    return true;
+  }
+  return false;
+}
+
+bool operator<=(ClockTime lhs, ClockTime rhs) {
+  if (lhs.hour < rhs.hour) {
+    return true;
+  }
+  if (lhs.hour > rhs.hour) {
+    return false;
+  }
+  // lhs.hour == rhs.hour
+  if (lhs.minute < rhs.minute) {
+    return true;
+  }
+  if (lhs.minute > rhs.minute) {
+    return false;
+  }
+  // lhs.minute == rhs.minute
+  if (lhs.second <= rhs.second) {
+    return true;
+  }
+  return false;
+}
+
+bool operator==(ClockTime lhs, ClockTime rhs) {
+  if ((lhs.hour == rhs.hour) && (lhs.minute == rhs.minute) && (lhs.second == rhs.second)) {
+    return true;
+  }
+  return false;
+}
+
+bool operator!=(ClockTime lhs, ClockTime rhs) {
+  return !(lhs == rhs);
+}
+
+const int LEDpinA = 9;
+
+const int AlarmButton = 2;
+const int TimeButton = 3;
+const int FwdButton = 4;
+const int RewButton = 5;
+const int OffButton = 6;
+
+bool alarmEnabled = true;
+bool alarmActive = false;
+
+TimerOne timer;
+const int16_t maxBright = 1024; // resolution of TimerOne::pwm (10 bits)
+const int thirtyminutes = 1800; // 1800 seconds = 30 minutes
+const int timerPeriod = 1000; // 1000us = 1 kHz flicker
+const int16_t maxTime = 3600; // 1.0 hours
+const int forward_delay = 15;
+const int rewind_delay = 150;
+
+int defaultSunSetDelta = 15; // minutes
+
+const unsigned long modeInactivePeriod = 30000; // 30 seconds
+
+AT24Cxx eeprom;
+// This is the time you want to get up.  Lights will start 30 minutes before.
+ClockTime alarmTime(5,00);
+ClockTime startTime(4,30);
+
+const int alarm_address = 0;
+const int sundown_address = 2;
+const int brightness_address = 3;
+
+Adafruit_7segment matrix = Adafruit_7segment();
+int matrixBrightness = 0;
+
+uint8_t raw_C = 0x39;
+uint8_t raw_l = 0x30;
+uint8_t raw_o = 0x5C;
+uint8_t raw_c = 0x58;
+uint8_t raw_A = 0x77;
+uint8_t raw_L = 0x38;
+uint8_t raw_r = 0x50;
+uint8_t raw_t = 0x78;
+uint8_t raw_d = 0x5E;
+uint8_t dot_bit = 0x80;
+
+RTC_DS1307 RTC;
+unsigned long synchronized_clock_millis;
+ClockTime synchronized_clock_time;
+ClockTime current_clock_time;
+
+bool readAlarmTimeFromEEPROM() {
+  if (eeprom.isPresent()) {
+    char buf[2];
+    eeprom.ReadMem(alarm_address,buf,2);
+    alarmTime.hour = static_cast<int>(buf[0]);
+    alarmTime.minute = static_cast<int>(buf[1]);
+    return true;
+  }
+  return false;
+}
+
+bool writeAlarmTimeToEEPROM() {
+  if (eeprom.isPresent()) {
+    char myBuf[2];
+    myBuf[0] = static_cast<char>(alarmTime.hour);
+    myBuf[1] = static_cast<char>(alarmTime.minute);
+    eeprom.WriteMem(alarm_address,myBuf,2);
+    return true;
+  }
+  return false;
+}
+
+bool readBrightnessFromEEPROM() {
+  if (eeprom.isPresent()) {
+    char buf[1];
+    eeprom.ReadMem(brightness_address,buf,1);
+    matrixBrightness = static_cast<int>(buf[0]);
+    return true;
+  }
+  return false;
+}
+
+bool writeBrightnessToEEPROM() {
+  if (eeprom.isPresent()) {
+    char myBuf[1];
+    myBuf[0] = static_cast<char>(matrixBrightness);
+    eeprom.WriteMem(brightness_address,myBuf,1);
+    return true;
+  }
+  return false;
+}
+
+
+bool readSunDownDeltaFromEEPROM() {
+  if (eeprom.isPresent()) {
+    char buf[1];
+    eeprom.ReadMem(sundown_address,buf,1);
+    defaultSunSetDelta = static_cast<int>(buf[0]);
+    return true;
+  }
+  return false;
+}
+
+bool writeSunDownDeltaToEEPROM() {
+  if (eeprom.isPresent()) {
+    char myBuf[1];
+    myBuf[0] = static_cast<char>(defaultSunSetDelta);
+    eeprom.WriteMem(sundown_address,myBuf,1);
+    return true;
+  }
+  return false;
+}
+
+
+
+int debounceInterval = 5;
+int debounceDigitalRead(int pin) {
+  int lastResult = digitalRead(pin);
+  unsigned long lastRead = millis();
+  while (static_cast<unsigned long>(millis() - lastRead) < debounceInterval) {
+    int result = digitalRead(pin);
+    if (result != lastResult) {
+      lastResult = result;
+      lastRead = millis();
+    }
+  }
+  return lastResult;
+}
+
+void turnLightOn(int currentLevel) {
+  for (int i=currentLevel ; i < maxBright ; ++i) {
+    timer.pwm(LEDpinA,i);
+    delay(1);
+  }
+  digitalWrite(LEDpinA,HIGH);
+}
+
+void turnLightOff(int currentLevel) {
+  for (int i=currentLevel ; i>0 ; --i) {
+    timer.pwm(LEDpinA,i);
+    delay(1);
+  }
+  digitalWrite(LEDpinA,LOW);
+}
+
+void waitForButtonDepress(int pin) {
+  while (debounceDigitalRead(pin)==LOW) {
+    delay(5);
+  }
+}
+
+// 10W LED with big heatsink:
+//const int minLightLevel = 176;
+//const int maxLightLevel = 1008;
+// MR16 LED light with 3x3W LEDs:
+const int minLightLevel = 320;
+const int maxLightLevel = 800;
+
+// (a1,b1) -> f_1 -> (a2,b2) -> f_2 -> (a3,b3) -> f_3 -> (a4,b4)
+double a1 = 0.0;
+double b1 = minLightLevel;
+double a2 = thirtyminutes-10*60; // 10 minutes before
+double b2 = maxLightLevel*.30; // 30%
+double a3 = thirtyminutes-5*60; // 5 minutes before
+double b3 = maxLightLevel*.40; // 40%
+double a4 = thirtyminutes;
+double b4 = maxLightLevel;
+
+double m1 = (b2-b1)/(a2-a1);
+double c1 = (b1-m1*a1);
+double m2 = (b3-b2)/(a3-a2);
+double c2 = (b2-m2*a2);
+double m3 = (b4-b3)/(a4-a3);
+double c3 = (b3-m3*a3);
+
+// This function maps the visible range of the LED to the time interval 0 to 1800 seconds.
+// Visible range on LED at TimerOne Period of 1000us (1 kHz flicker) is [176,1008] at increment of 16.
+// Therefore the two points are (0,176) and (1800,1008) which results in a slope of 0.4622222 and a y-intercept of 176.
+// 2014-03-11:  (0,minlightLevel) -> (1800,maxLightLevel), slope = (maxLightLevel-minLightLevel)/1800
+int lastAlarmLightLevel = 0;
+int32_t linearBright(int32_t level) {
+  //int linearLevel = ceil(maxBright*1.0/(1.0+exp(-(level*1.0-maxTime*0.5)/(maxTime/16.0))));
+  //int linearLevel = level;
+  //int linearLevel = 36.787944117144235*exp(exp(level*0.00075472484480368113));
+
+  // (0,176) -> (1800,1008)
+  //int linearLevel = 0.46222222*level + 176; // linear
+  //int linearLevel = 176.0*exp(0.000969577*level); // exponential
+  //int linearLevel = 64.746781646173858*exp(exp(0.00056103794655312409*level)); // exp(exp())
+
+  //This method seems to work well for MR16 9W LED
+  int linearLevel = ((maxLightLevel-minLightLevel)/1800.0)*level+minLightLevel;
+  //This method worked well for 10W LED
+//  int linearLevel = 0;
+//  if (level < a2) {
+//    linearLevel = m1*level+c1;
+//  } else if (level < a3) {
+//    linearLevel = m2*level+c2;
+//  } else {
+//    linearLevel = m3*level+c3;
+//  }
+
+  //Serial.print("linearLevel = ");
+  //Serial.println(linearLevel);
+  lastAlarmLightLevel = linearLevel;
+  timer.pwm(LEDpinA,lastAlarmLightLevel);
+  return linearLevel;
+}
+
+// DONE:  Update to display 12 hr time
+void updateTimeDisplay(ClockTime t, bool military, bool dots) {
+  matrix.print(0);
+  int hour = t.hour;
+  if (!military) {
+    hour = (t.hour > 12) ? t.hour-12 : t.hour ;
+    if (hour == 0) { hour += 12; }
+  }
+  int digit0 = hour / 10;
+  int digit1 = hour % 10;
+  int digit3 = t.minute / 10;
+  int digit4 = t.minute % 10;
+  if (digit0 > 0) {
+    matrix.writeDigitNum(0,digit0,dots);
+  }
+  matrix.writeDigitNum(1,digit1, dots);
+  matrix.writeDigitNum(2,1); // colon
+  matrix.writeDigitNum(3,digit3,dots);
+  matrix.writeDigitNum(4,digit4,dots);
+  matrix.writeDisplay();
+}
+
+// wait is in milliseconds
+// last is the last time this function returned true
+bool isTimeNow(unsigned long & last, unsigned wait) {
+  unsigned long time = millis();
+  if (static_cast<unsigned long>(time-last) > wait) {
+    last = time;
+    return true;
+  }
+  return false;
+}
+
+const unsigned long updateInterval = 1000; // every second
+unsigned long lastUpdate = millis();
+void updateCurrentTime(bool force=false) {
+  if (force || isTimeNow(lastUpdate,updateInterval)) {
+    current_clock_time = synchronized_clock_time;
+    const unsigned long seconds_delta = static_cast<unsigned long>(millis() - synchronized_clock_millis)/1000;
+    const unsigned long minutes_delta = seconds_delta/60;
+    current_clock_time.minute += minutes_delta;
+    current_clock_time.second += (seconds_delta - minutes_delta*60);
+    current_clock_time.fixTime();
+    updateTimeDisplay(current_clock_time,false,false);
+  }
+}
+
+const unsigned long clockUpdateInterval = 24*60*60*1000; // every 24 hours
+unsigned long lastClockUpdate = millis();
+void updateClockTime(bool force=false) {
+  if (force || isTimeNow(lastClockUpdate,clockUpdateInterval)) {
+    synchronized_clock_time = ClockTime(RTC.now());
+    synchronized_clock_millis = millis();
+    current_clock_time = synchronized_clock_time;
+  }
+}
+
+void updateStartTime() {
+  startTime = alarmTime;
+  startTime.minute -= 30;
+  startTime.fixTime();
+}
+
+
+void display_Cloc() {
+  matrix.clear();
+  matrix.writeDigitRaw(0,raw_C | dot_bit);
+  matrix.writeDigitRaw(1,raw_l | dot_bit);
+  matrix.writeDigitRaw(3,raw_o | dot_bit);
+  matrix.writeDigitRaw(4,raw_c | dot_bit);
+  matrix.writeDisplay();
+}
+
+
+
+void display_ALAr() {
+  matrix.clear();
+  matrix.writeDigitRaw(0,raw_A | dot_bit);
+  matrix.writeDigitRaw(1,raw_L | dot_bit);
+  matrix.writeDigitRaw(3,raw_A | dot_bit);
+  matrix.writeDigitRaw(4,raw_r | dot_bit);
+  matrix.writeDisplay();
+}
+
+void display_todd() {
+  matrix.setBrightness(15);
+  matrix.clear();
+  matrix.writeDigitRaw(0,raw_t);
+  matrix.writeDigitRaw(1,raw_o);
+  matrix.writeDigitRaw(3,raw_d);
+  matrix.writeDigitRaw(4,raw_d);
+  matrix.writeDisplay();
+  delay(5000);
+}
+
+void setup() {
+  //Serial.begin(9600);
+  Wire.begin();
+  RTC.begin();
+  //if (! RTC.isrunning()) {
+  //  Serial.println("RTC is NOT running!");
+  //}
+  //RTC.adjust(DateTime(__DATE__, __TIME__));
+  //RTC.adjust(
+  //  DateTime( 2013,
+  //            03,
+  //            24,
+  //            06,
+  //            14,
+  //            50
+  //          )
+  //);
+  pinMode(LEDpinA,OUTPUT); digitalWrite(LEDpinA,0);
+  pinMode(AlarmButton,INPUT);
+  pinMode(TimeButton,INPUT);
+  pinMode(RewButton,INPUT);
+  pinMode(FwdButton,INPUT);
+  pinMode(OffButton,INPUT);
+  timer.initialize(timerPeriod);
+  timer.pwm(LEDpinA, 0); //set up pin 9
+  matrix.begin(0x70);
+  display_todd();
+  readBrightnessFromEEPROM();
+  matrix.setBrightness(matrixBrightness); // 0-15
+  readSunDownDeltaFromEEPROM();
+  updateClockTime(true);
+  updateCurrentTime(true);
+  if (!readAlarmTimeFromEEPROM()) {
+    alarmTime = ClockTime(5,45);
+  }
+  updateStartTime();
+}
+
+int32_t secondsBtwDates(ClockTime currentTime, ClockTime alarm) {
+  int32_t s = (currentTime.hour - alarm.hour);
+  s *= 3600;
+  s += (currentTime.minute - alarm.minute)*60;
+  s += (currentTime.second - alarm.second);
+  //Serial.print("Seconds between dates:  currentTime = ");
+  //Serial.print(currentTime.hour);
+  //Serial.print(":");
+  //Serial.print(currentTime.minute);
+  //Serial.print(", startTime = ");
+  //Serial.print(alarm.hour);
+  //Serial.print(":");
+  //Serial.print(alarm.minute);
+  //Serial.print(", seconds = ");
+  //Serial.println(s);
+  return( s );
+}
+
+
+const unsigned lightUpdateInterval = 1000;
+unsigned long lastLightUpdate = millis();
+void updateLight() {
+  if (!isTimeNow(lastLightUpdate,lightUpdateInterval)) {
+    return;
+  }
+  //Serial.println("updateLight");
+  ClockTime current = current_clock_time;
+  int32_t seconds = secondsBtwDates(current,startTime);
+  //Serial.print("  seconds = ");
+  //Serial.println(seconds);
+  if ((seconds < 0) || (seconds >= maxTime)) {
+    //Serial.println("  outside alarm zone");
+    if (alarmActive) {
+      //Serial.println("  turning off light and setting alarmActive = false");
+      turnLightOff(maxBright-1);
+      alarmActive = false;
+    }
+    //Serial.println("  turning on alarmEnabled");
+    alarmEnabled = true;
+    return;
+  }
+  //Serial.println("inside alarm zone");
+  if (!alarmEnabled) {
+    //Serial.println("but alarmEnabled is false");
+    return;
+  }
+  //Serial.println("turning on alarmActive");
+  alarmActive = true;
+  if (seconds >= thirtyminutes) {
+    //Serial.println("past alarm time but still in alarm zone turning light on full and returning");
+    lastAlarmLightLevel = maxLightLevel;
+    digitalWrite(LEDpinA,HIGH);
+    return;
+  }
+  //Serial.println("in alarm zone during ramp-up, calling linearBright");
+  linearBright(seconds);
+}
+
+
+void forwardTime(ClockTime & t) {
+  while (digitalRead(FwdButton)==LOW) {
+    ++t.minute;
+    if (t.minute > 59) {
+      ++t.hour;
+      t.minute = 0;
+    }
+    if (t.hour > 23) {
+      t.hour = 0;
+    }
+    updateTimeDisplay(t,true,true);
+    delay(forward_delay);
+  }
+}
+
+void rewindTime(ClockTime & t) {
+  while (digitalRead(RewButton)==LOW) {
+    --t.minute;
+    if (t.minute < 0) {
+      --t.hour;
+      t.minute = 59;
+    }
+    if (t.hour < 0) {
+      t.hour = 23;
+    }
+    updateTimeDisplay(t,true,true);
+    delay(rewind_delay);
+  }
+
+}
+
+void forwardAlarm() {
+  while (digitalRead(FwdButton)==LOW) {
+    ++alarmTime;
+    updateTimeDisplay(alarmTime,true,true);
+    delay(forward_delay);
+  }
+}
+
+void rewindAlarm() {
+ while (digitalRead(RewButton)==LOW) {
+    --alarmTime;
+    updateTimeDisplay(alarmTime,true,true);
+    delay(rewind_delay);
+  }
+}
+
+
+
+void setTime() {
+  DateTime currentTime = RTC.now();
+  ClockTime t(currentTime);
+  display_Cloc();
+  delay(1000);
+  updateTimeDisplay(t,true,true);
+  waitForButtonDepress(TimeButton);
+  unsigned long modeActive = millis();
+  bool normalExit = true;
+  while (debounceDigitalRead(TimeButton)==HIGH) {
+    if (digitalRead(FwdButton)==LOW) {
+      forwardTime(t);
+      modeActive = millis();
+    } else if (digitalRead(RewButton)==LOW) {
+      rewindTime(t);
+      modeActive = millis();
+    }
+    if (static_cast<unsigned long>(millis() - modeActive) > modeInactivePeriod) {
+      normalExit = false;
+      break;
+    }
+  }
+  if (normalExit) {
+    waitForButtonDepress(TimeButton);
+  }
+  updateTimeDisplay(t,false,false);
+  RTC.adjust(
+    DateTime( currentTime.year(),
+              currentTime.month(),
+              currentTime.day(),
+              t.hour,
+              t.minute,
+              0
+            )
+  );
+  //updateClockTime(true);
+  // Avoid talking to RTC:
+  synchronized_clock_time = t;
+  synchronized_clock_millis = millis();
+  current_clock_time = synchronized_clock_time;
+  updateCurrentTime(true);
+}
+
+void setAlarm() {
+  display_ALAr();
+  delay(1000);
+  updateTimeDisplay(alarmTime,true,true);
+  waitForButtonDepress(AlarmButton);
+  unsigned long modeActive = millis();
+  bool normalExit = true;
+  while (debounceDigitalRead(AlarmButton)==HIGH) {
+    if (digitalRead(FwdButton)==LOW) {
+      forwardAlarm();
+      modeActive = millis();
+    } else if (digitalRead(RewButton)==LOW) {
+      rewindAlarm();
+      modeActive = millis();
+    }
+    if (static_cast<unsigned long>(millis() - modeActive) > modeInactivePeriod) {
+      normalExit = false;
+      break;
+    }
+  }
+  if (normalExit) {
+    waitForButtonDepress(AlarmButton);
+  }
+  updateStartTime();
+  //updateTimeDisplay(startTime,true,true);
+  //delay(2000);
+  updateCurrentTime(true);
+  updateTimeDisplay(current_clock_time,false,false);
+  writeAlarmTimeToEEPROM();
+}
+
+void forwardSunSet(int & minutes) {
+  while (digitalRead(FwdButton)==LOW) {
+    ++minutes;
+    matrix.print(minutes);
+    matrix.writeDisplay();
+    delay(forward_delay);
+  }
+}
+
+void rewindSunSet(int & minutes) {
+ while (digitalRead(RewButton)==LOW) {
+    --minutes;
+    if (minutes < 0) {
+      minutes = 0;
+    }
+    matrix.print(minutes);
+    if (minutes == 0) {
+      matrix.writeDigitNum(4,0);
+    }
+    matrix.writeDisplay();
+    delay(rewind_delay);
+  }
+}
+
+
+unsigned long millisAtStartOfSunSet = 0;
+bool sunSetActive = false;
+void setSunSet() {
+  matrix.print(defaultSunSetDelta);
+  if (defaultSunSetDelta == 0) {
+    matrix.writeDigitNum(4,0);
+  }
+  matrix.writeDisplay();
+  sunSetActive = true;
+  turnLightOn(0);
+  waitForButtonDepress(OffButton);
+  unsigned long modeActive = millis();
+  bool normalExit = true;
+  while (debounceDigitalRead(OffButton)==HIGH) {
+    if (digitalRead(FwdButton)==LOW) {
+      forwardSunSet(defaultSunSetDelta);
+      modeActive = millis();
+    }
+    else if (digitalRead(RewButton)==LOW) {
+      rewindSunSet(defaultSunSetDelta);
+      modeActive = millis();
+    }
+    if (static_cast<unsigned long>(millis() - modeActive) > modeInactivePeriod) {
+      normalExit = false;
+      break;
+    }
+  }
+  if (defaultSunSetDelta == 0) {
+    sunSetActive = false;
+    turnLightOff(maxBright-1);
+  }
+  if (normalExit) {
+    waitForButtonDepress(OffButton);
+  }
+  writeSunDownDeltaToEEPROM();
+  millisAtStartOfSunSet = millis();
+}
+
+
+unsigned long lastSunSetUpdate = millis();
+unsigned sunSetUpdateInterval = 5;
+int lastSunSetLightLevel = 0;
+void updateSunSet() {
+  if (!sunSetActive) {
+    return;
+  }
+  if (!isTimeNow(lastSunSetUpdate,sunSetUpdateInterval)) {
+    return;
+  }
+  unsigned long currentMillis = millis();
+  unsigned long delta = static_cast<unsigned long>(currentMillis - millisAtStartOfSunSet);
+  unsigned long finalMillis = defaultSunSetDelta;
+  finalMillis *= 60;
+  finalMillis *= 1000;
+  if (delta > finalMillis) {
+    sunSetActive = false;
+    digitalWrite(LEDpinA,0);
+  }
+  else {
+    double temp = -(1800.0*delta)/(finalMillis*1.0) + 1800.0;
+    linearBright(temp);
+  }
+}
+
+
+void loop() {
+  if (digitalRead(AlarmButton)==LOW && debounceDigitalRead(AlarmButton)==LOW) {
+    setAlarm();
+  }
+  else if (digitalRead(TimeButton)==LOW && debounceDigitalRead(TimeButton)==LOW) {
+    setTime();
+  }
+  else if (digitalRead(OffButton)==LOW && debounceDigitalRead(OffButton)==LOW) {
+    if (alarmActive) {
+      alarmActive = false;
+      alarmEnabled = false;
+      turnLightOff(lastAlarmLightLevel);
+      waitForButtonDepress(OffButton);
+    }
+    else if (sunSetActive) {
+      sunSetActive = false;
+      turnLightOff(lastSunSetLightLevel);
+      waitForButtonDepress(OffButton);
+    }
+    else {
+      setSunSet();
+    }
+  }
+  else if (digitalRead(FwdButton)==LOW && debounceDigitalRead(FwdButton)==LOW) {
+    matrixBrightness = max(min(15,matrixBrightness+1),0);
+    matrix.setBrightness(matrixBrightness); // 0-15
+    waitForButtonDepress(FwdButton);
+    writeBrightnessToEEPROM();
+  }
+  else if (digitalRead(RewButton)==LOW && debounceDigitalRead(RewButton)==LOW) {
+    matrixBrightness = max(min(15,matrixBrightness-1),0);
+    matrix.setBrightness(matrixBrightness); // 0-15
+    waitForButtonDepress(RewButton);
+    writeBrightnessToEEPROM();
+  }
+  updateLight();
+  updateCurrentTime();
+  updateClockTime();
+  updateSunSet();
+  // DONE 2013-03-30:  Add a feature so Fwd and Rew buttons adjust the display brightness
+  // DONE 2013-03-30:  Add a feature so the OffButton can be used for SunDown mode when the SunRise mode is not currently active.
+  //        Turn on light (ramp up quickly but not instantly) then slowly turn off after 15 minutes
+}
+
+} // namespace SunriseAlarm
+
+void setup()
+{
+  SunriseAlarm::setup();
+}
+
+void loop()
+{
+  SunriseAlarm::loop();
+}
+


Updated main file

Updated main file

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/essoplerck/Arduino-Drone.git/'


Cleaning up the IRRelay

Cleaning up the IRRelay

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tdmike/SASCHA.git/'


cleaned up vending machine code

cleaned up vending machine code

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/fishnsotong/straightflash.git/'


rewired everything

rewired everything

now:
thermino is pingable
temperature is sampled and displayed correctly

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tconstans/Thermino.git/'


Example from the Arduino - Servos video

Example from the Arduino - Servos video

error: pathspec 'Ard-Servos/Sweep/Sweep.ino' did not match any file(s) known to git

--- Ard-Servos/Sweep/Sweep.ino
+++ Ard-Servos/Sweep/Sweep.ino
@@ -0,0 +1,35 @@
+/* Sweep
+ by BARRAGAN <http://barraganstudio.com>
+ This example code is in the public domain.
+
+ modified 8 Nov 2013
+ by Scott Fitzgerald
+ http://www.arduino.cc/en/Tutorial/Sweep
+*/
+
+#include <Servo.h>
+
+Servo myservo;  // create servo object to control a servo
+// twelve servo objects can be created on most boards
+
+int pos = 0;    // variable to store the servo position
+
+void setup() {
+  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
+}
+
+void loop() {
+  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
+    // in steps of 1 degree
+    myservo.write(pos);              // tell servo to go to position in variable 'pos'
+    delay(15);                       // waits 15ms for the servo to reach the position
+  }
+  delay(500);                        // Wait half a second before going back
+
+  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
+    myservo.write(pos);              // tell servo to go to position in variable 'pos'
+    delay(15);                       // waits 15ms for the servo to reach the position
+  }
+  delay(500);                        // Wait half a second before starting over
+}
+