Browse Source

Revamped the pulses

Fred Damstra (Macbook 2015) 5 months ago
parent
commit
a33ed16031
3 changed files with 196 additions and 154 deletions
  1. 167 18
      BackgroundRingClass.cpp
  2. 29 3
      BackgroundRingClass.h
  3. 0 133
      background_rings_demo.ino

+ 167 - 18
BackgroundRingClass.cpp

@@ -14,6 +14,7 @@ void BackgroundRingClass::tick() {
     case Idle:  this->tick_idle(); break;
     case Solid: this->tick_solid(); break;
     case Pulse: this->tick_pulse(); break;
+    case PulseAndBeep: this->tick_pulse_and_beep(); break;
     case Spin:  this->tick_spin(); break;
     case Flip:  this->tick_flip(); break;
     case Slowroll: this->tick_slowroll(); break;
@@ -102,37 +103,185 @@ void BackgroundRingClass::init_pulse(unsigned long color, uint8_t maxbrightness,
   Serial.println("Initializing pulse");
   this->action = Pulse;
   this->pulseinfo.color = color;
-  this->pulseinfo.increasing = true;
+  this->pulseinfo.maxbrightness = maxbrightness;
+  this->pulseinfo.ms = ms * 1000;
+
   this->pulseinfo.starttime = micros();
-  this->pulseinfo.steptime = (ms * 1000) / ((2 * (unsigned long)maxbrightness) - 1);
-  this->pulseinfo.maxbrightness = maxbrightness;;
   this->pulseinfo.curbrightness = 1;
+  this->pulseinfo.steptime = (ms * 1000) / (2 * (unsigned long)maxbrightness);
 
-  this->setColor(this->pulseinfo.color, brightness, true); // dimmest setting
+  this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true); // dimmest setting
 }
 
 void BackgroundRingClass::tick_pulse() {
-    if((micros() - this->pulseinfo.starttime) < this->pulseinfo.steptime) {
-      return;
+  unsigned long elapsed = micros() - this->pulseinfo.starttime;
+  int newbrightness;
+
+  if(elapsed < this->pulseinfo.ms/2) {
+    // increasing
+    newbrightness = (elapsed / this->pulseinfo.steptime) + 1;
+    //Serial.print("Increasing. elapsed="); Serial.print(elapsed);
+    //Serial.print("; steptime="); Serial.print(this->pulseinfo.steptime);
+    //Serial.print("; curbrightness="); Serial.print(this->pulseinfo.curbrightness);
+    //Serial.print("; newbrightenss="); Serial.println(newbrightness);
+  } else if(elapsed < this->pulseinfo.ms) {
+    // decreasing
+    newbrightness = ((this->pulseinfo.ms - elapsed) / this->pulseinfo.steptime) + 1;
+    //Serial.print("Decreasing. elapsed="); Serial.print(elapsed);
+    //Serial.print("; steptime="); Serial.print(this->pulseinfo.steptime);
+    //Serial.print("; curbrightness="); Serial.print(this->pulseinfo.curbrightness);
+    //Serial.print("; newbrightenss="); Serial.println(newbrightness);
+  } else {
+    // done
+    //Serial.print("DONE. elapsed="); Serial.print(elapsed);
+    this->init_idle();
+    return;
+  }
+  if(newbrightness != this->pulseinfo.curbrightness) {
+    this->pulseinfo.curbrightness = newbrightness;
+    this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true);
+    this->show();
+  }
+  return;
+}
+
+
+///////////////////////// Pulse and Beep
+//
+// We can't call show() while beeping because it disabled interrupts,
+// so we beep at the peak of the pulse.
+//
+void BackgroundRingClass::init_pulse_and_beep(
+        unsigned long color,
+        uint8_t maxbrightness,
+        unsigned long ms,
+        int pin,
+        unsigned int frequency,
+        unsigned long duration
+) {
+  Serial.println("Initializing pulse and beep");
+  this->action = PulseAndBeep;
+  this->pulseinfo.color = color;
+  this->pulseinfo.maxbrightness = maxbrightness;
+  this->pulseinfo.ms = ms * 1000;
+
+  this->pulseinfo.starttime = micros();
+  this->pulseinfo.curbrightness = 1;
+  this->pulseinfo.steptime = ( (ms - duration) * 1000) / ((2 * (unsigned long)maxbrightness) - 1);
+
+  this->beepinfo.pin = pin;
+  this->beepinfo.frequency = frequency;
+  this->beepinfo.duration = duration;
+  this->beepinfo.state = Beeping;
+
+  this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true); // dimmest setting
+}
+
+void BackgroundRingClass::tick_pulse_and_beep() {
+  // What we're doing should be based on time.
+  // Increasing: 0 to (ms - duration)/2))
+  // Beeping:    (ms - duration)/2 to (ms - duration/2)+duration
+  // Decreasing: (ms - duration/2)+duration - ms
+  unsigned long elapsed = micros() - this->pulseinfo.starttime;
+  int newbrightness;
+
+  if(elapsed < (this->pulseinfo.ms/2 - 1000*this->beepinfo.duration/2)) {
+    // increasing
+    this->beepinfo.state = Increasing;
+    newbrightness = (elapsed / this->pulseinfo.steptime) + 1;
+    //Serial.print("Increasing. elapsed="); Serial.print(elapsed);
+    //Serial.print("; ms="); Serial.print(this->pulseinfo.ms);
+    //Serial.print("; duration="); Serial.print(this->beepinfo.duration);
+    //Serial.print("; steptime="); Serial.print(this->pulseinfo.steptime);
+    //Serial.print("; curbrightness="); Serial.print(this->pulseinfo.curbrightness);
+    //Serial.print("; newbrightenss="); Serial.println(newbrightness);
+  } else if(elapsed < (this->pulseinfo.ms/2 + 1000*this->beepinfo.duration/2)) {
+    if(this->beepinfo.state != Beeping && this->beepinfo.frequency != 0) {
+      tone(this->beepinfo.pin, this->beepinfo.frequency, this->beepinfo.duration);
+      this->beepinfo.state = Beeping;
     }
-    this->pulseinfo.starttime = micros();
-    if(this->pulseinfo.increasing && this->pulseinfo.curbrightness == this->pulseinfo.maxbrightness) {
-      this->pulseinfo.increasing = false;
+    //Serial.print("Beeping. elapsed="); Serial.print(elapsed);
+    //Serial.print("; steptime="); Serial.print(this->pulseinfo.steptime);
+    //Serial.print("; curbrightness="); Serial.println(this->pulseinfo.curbrightness);
+    return;
+  } else if(elapsed < this->pulseinfo.ms) {
+    // decreasing
+    this->beepinfo.state = Decreasing;
+    //newbrightness = ((this->pulseinfo.ms - this->beepinfo.duration/2) / this->pulseinfo.steptime) + 1;
+    newbrightness = ((this->pulseinfo.ms - elapsed) / this->pulseinfo.steptime) + 1;
+    //Serial.print("Decreasing. elapsed="); Serial.print(elapsed);
+    //Serial.print("; ms="); Serial.print(this->pulseinfo.ms);
+    //Serial.print("; duration="); Serial.print(this->beepinfo.duration);
+    //Serial.print("; steptime="); Serial.print(this->pulseinfo.steptime);
+    //Serial.print("; curbrightness="); Serial.print(this->pulseinfo.curbrightness);
+    //Serial.print("; newbrightenss="); Serial.println(newbrightness);
+  } else {
+    // done
+    //Serial.print("DONE. elapsed="); Serial.print(elapsed);
+    this->init_idle();
+    return;
+  }
+  if(newbrightness != this->pulseinfo.curbrightness) {
+    this->pulseinfo.curbrightness = newbrightness;
+    this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true);
+    this->show();
+  }
+  return;
+}
+
+/*
+void BackgroundRingClass::tick_pulse_and_beep() {
+  int stepspassed = 0;
+  if(this->beepinfo.state == Beeping && (micros() - this->beepinfo.beepstart < 1000*this->beepinfo.duration)) {
+    return;
+  } else if(this->beepinfo.state == Beeping) {
+    Serial.print("Beep Duration was: "); Serial.println((micros() - this->beepinfo.beepstart)/1000);
+    Serial.print("Stopping beeping at t="); Serial.println((micros() - this->beepinfo.truestart)/1000);
+    this->beepinfo.state = Decreasing;
+    this->pulseinfo.starttime = micros() + this->pulseinfo.steptime;
+  }
+  if((micros() - this->pulseinfo.starttime) < this->pulseinfo.steptime) {
+    return;
+  } else {
+    stepspassed = (micros() - this->pulseinfo.starttime)/this->pulseinfo.steptime;
+  }
+  //Serial.print("Taking action at t="); Serial.print(micros() - this->beepinfo.truestart);
+  //Serial.print("; brightness="); Serial.print(this->pulseinfo.curbrightness);
+  //Serial.print("; Steps to take="); Serial.println(stepspassed);
+  this->pulseinfo.starttime = micros();
+  if(this->beepinfo.state == Increasing && this->pulseinfo.curbrightness == this->pulseinfo.maxbrightness) {
+    this->beepinfo.state = Beeping;
+    this->beepinfo.beepstart = micros();
+    if(this->beepinfo.frequency != 0) {
+      Serial.print("Beginning beeping at t="); Serial.println((micros() - this->beepinfo.truestart)/1000);
+      tone(this->beepinfo.pin, this->beepinfo.frequency, this->beepinfo.duration);
+      return;
     }
-    if(this->pulseinfo.increasing) {
-      this->pulseinfo.curbrightness++;
+  }
+  if(this->beepinfo.state == Increasing) {
+    if(this->pulseinfo.curbrightness < this->pulseinfo.maxbrightness - stepspassed) {
+      this->pulseinfo.curbrightness += stepspassed;
     } else {
-      this->pulseinfo.curbrightness--;
+      this->pulseinfo.curbrightness = this->pulseinfo.maxbrightness;
     }
-    if(this->pulseinfo.curbrightness == 0) {
-      // We are done
-      this->init_idle();
+  } else {
+    if(this->pulseinfo.curbrightness > stepspassed) {
+      this->pulseinfo.curbrightness -= stepspassed;
     } else {
-      //Serial.print("Setting Brightness: "); Serial.println(this->pulseinfo.curbrightness);
-      this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true);
-      this->show();
+      this->pulseinfo.curbrightness = 0;
     }
+  }
+  if(this->pulseinfo.curbrightness == 0) {
+    // We are done
+    Serial.print("Stopping pulse at t="); Serial.println((micros() - this->beepinfo.truestart)/1000);
+    this->init_idle();
+  } else {
+    //Serial.print("Setting Brightness: "); Serial.println(this->pulseinfo.curbrightness);
+    this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true);
+    this->show();
+  }
 }
+*/
 
 ///////////////////////// Spin
 void BackgroundRingClass::init_spin(unsigned long color1, unsigned long color2, unsigned long ms, unsigned long tickdelay) {

+ 29 - 3
BackgroundRingClass.h

@@ -10,11 +10,18 @@ typedef enum Action {
   Idle,
   Solid,
   Pulse,
+  PulseAndBeep,
   Spin,
   Flip,
   Slowroll
 };
 
+typedef enum BeepState {
+  Increasing,
+  Beeping,
+  Decreasing
+};
+
 class BackgroundRingClass : public Adafruit_NeoPixel {
   public:
     int led_count;
@@ -39,17 +46,36 @@ class BackgroundRingClass : public Adafruit_NeoPixel {
 
     // Pulse
     struct {
-      bool increasing;
       unsigned long color;
       unsigned long starttime;
-      unsigned long steptime;
-      uint8_t maxbrightness;
+      unsigned long steptime;;
+      unsigned long ms;
       uint8_t curbrightness;
+      uint8_t maxbrightness;
     } pulseinfo;
 
     void init_pulse(unsigned long color, uint8_t maxbrightness, unsigned long ms);
     void tick_pulse();
 
+    // Pulse and Beep
+    struct {
+      int pin;
+      unsigned int frequency;
+      unsigned long duration;
+      unsigned long beepstart;
+      BeepState state;
+    } beepinfo;
+
+    void init_pulse_and_beep(
+        unsigned long color,
+        uint8_t maxbrightness,
+        unsigned long ms,
+        int pin,
+        unsigned int frequency,
+        unsigned long duration
+    );
+    void tick_pulse_and_beep();
+
     // Spin
     struct {
       unsigned long color1;

+ 0 - 133
background_rings_demo.ino

@@ -1,133 +0,0 @@
-
-#include <SoftwareSerial.h>
-#include "WS2812_Definitions.h"
-#include <eRCaGuy_ButtonReader.h>
-#include "BackgroundRingClass.h"
-
-const int LED_COUNT = 24;
-const int MAXBRIGHTNESS = 80;
-
-const int leftFSRSimPin = A7;
-const int rightFSRSimPin = A0;
-
-/* Start Button */
-const int leftReadyButtonPin = 13;
-const int rightReadyButtonPin = 8;
-
-/* WS2812 Christmas Tree Setup:
-    Two strips of 6 LEDs connected to 5V and Ground, plus the signal pin
-*/
-const int ledPinRight = 12;
-const int ledPinLeft  = 11;
-
-const int randomPin = A5;
-
-BackgroundRingClass rightRing = BackgroundRingClass(LED_COUNT, ledPinRight);
-BackgroundRingClass leftRing  = BackgroundRingClass(LED_COUNT, ledPinLeft);
-
-eRCaGuy_ButtonReader leftReadyButton = eRCaGuy_ButtonReader(leftReadyButtonPin);
-eRCaGuy_ButtonReader rightReadyButton = eRCaGuy_ButtonReader(rightReadyButtonPin);
-eRCaGuy_ButtonReader leftFSRButton = eRCaGuy_ButtonReader(leftFSRSimPin);
-eRCaGuy_ButtonReader rightFSRButton = eRCaGuy_ButtonReader(rightFSRSimPin);
-
-
-void setup() {
-  // put your setup code here, to run once:
-  Serial.begin(115200); // Serial used for logging
-
-  randomSeed(analogRead(randomPin));
-
-  /* WS2812 LED Setup */
-  //rightRing.begin();
-  //leftRing.begin();
-
-  pinMode(leftReadyButtonPin, INPUT_PULLUP);
-  pinMode(rightReadyButtonPin, INPUT_PULLUP);
-  pinMode(leftFSRSimPin, INPUT_PULLUP);
-  pinMode(rightFSRSimPin, INPUT_PULLUP);
-
-  Serial.println("Testing Solids");
-  rightRing.init_solid(DARKRED, MAXBRIGHTNESS);
-  leftRing.init_solid(DARKGREEN, MAXBRIGHTNESS);
-  delay(1000);
-  leftRing.init_idle();
-  rightRing.init_idle();
-  Serial.println("Begin.");
-}
-
-
-
-void loop() {
-  static bool button_released = true;
-
-  rightRing.tick();
-  leftRing.tick();
-  
-  if(button_pressed(rightFSRButton)) {
-    Serial.println("Right button pressed. Switching.");
-    //rightRing.init_pulse(random(0, 0xFFFFFF), 255, 2000);
-    //rightRing.init_pulse(DARKRED, MAXBRIGHTNESS, 2000);
-    //rightRing.init_spin(DARKRED, DARKGREEN);
-    rightRing.init_flip(DARKRED, DARKGREEN);
-    //rightRing.init_slowroll(DARKRED, DARKGREEN);
-  }
-
-  if(button_pressed(leftFSRButton)) {
-    Serial.println("Right button pressed. Switching.");
-    //leftRing.init_pulse(random(0, 0xFFFFFF), 255, 2000);
-    //leftRing.init_pulse(DARKGREEN, MAXBRIGHTNESS, 2000);
-    //leftRing.init_spin(DARKGREEN, DARKRED);
-    leftRing.init_flip(DARKGREEN, DARKRED);
-    //leftRing.init_slowroll(DARKGREEN, DARKRED);
-  }
-
-  //test_solids();
-  //test_pulses();
-  //test_random_pulses();
-}
-
-bool button_pressed(eRCaGuy_ButtonReader& button)
-{
-  int8_t buttonaction;
-  boolean buttonstate;
-
-  button.readButton(&buttonaction, &buttonstate);
-  return buttonaction == 1;
-}
-
-
-void test_pulses() {
-  if(rightRing.action == Idle) {
-    Serial.println("Changing right");
-    rightRing.init_pulse(DARKGREEN, MAXBRIGHTNESS, 2000);
-  }
-  if(leftRing.action == Idle) {
-    Serial.println("Changing left");
-    leftRing.init_pulse(DARKGREEN, MAXBRIGHTNESS, 2000);
-  }
-}
-
-void test_random_pulses() {
-  if(rightRing.action == Idle) {
-    Serial.println("Changing right");
-    rightRing.init_pulse(random(0, 0xFFFFFF), MAXBRIGHTNESS, 2000);
-  }
-  if(leftRing.action == Idle) {
-    Serial.println("Changing left");
-    leftRing.init_pulse(random(0, 0xFFFFFF), MAXBRIGHTNESS, 2000);
-  }
-}
-
-void test_random_solids() {
-  if(rightRing.action == Idle) {
-    Serial.println("Changing right");
-    rightRing.init_solid(random(0, 0xFFFFFF), MAXBRIGHTNESS);
-  }
-  if(leftRing.action == Idle) {
-    Serial.println("Changing left");
-    leftRing.init_solid(random(0, 0xFFFFFF), MAXBRIGHTNESS);
-  }
-  delay(500);
-  leftRing.init_idle();
-  rightRing.init_idle();
-}