diff --git a/README.md b/README.md index 368f630..832e943 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,5 @@ This is library that works alongside the companion [Android app](https://github.com/jaredoconnell/SmartLights) to control the colors and brightness of LED strips over Bluetooth Low Energy. -For documentation on the packet protocol, see [this](docs/protocol_specification.md) -For documentation on the ESP32 pins usable for PWM, see [this](docs/gpio-pins.txt) \ No newline at end of file +For documentation on the packet protocol, see [this](docs/protocol_specification.md) \ +For documentation on the ESP32 pins usable for PWM, see [this](docs/gpio-pins.txt) diff --git a/include/Controller.h b/include/Controller.h index f6310cc..5d28cda 100644 --- a/include/Controller.h +++ b/include/Controller.h @@ -31,10 +31,24 @@ class Controller : public BLEServerCallbacks, public BLECharacteristicCallbacks public: Controller(); + + /** + * Initializes the controller. + * That mostly entails setting up bluetooth. + */ void init(); + /** + * Saves the LED strip to the controller. + * That will result in it being saved and updated every tick. + */ void addLEDStrip(LEDStrip * strip); + + /** + * Saves the color sequence to the controller. + */ void addColorSequence(ColorSequence * seq); + ColorSequence * getColorSequence(int id); LEDStrip * getLEDStrip(int id); @@ -48,10 +62,25 @@ class Controller : public BLEServerCallbacks, public BLECharacteristicCallbacks void saveLEDStrips(); void loadLEDStrips(); + /** + * Sends all LED Strips in as many packets as needed. + */ void sendLEDStrips(); + + /** + * Sends all color sequences in as many packets as needed. + */ void sendColorSequences(); + + /** + * Queues the packet. It will be deleted after it is successfully recieved by the + * phone. + */ void queuePacket(SendablePacket *); + /** + * Called 60 times per second for updating the colors. + */ void onTick(int time); // Bluetooth stuff diff --git a/include/LEDStrip.h b/include/LEDStrip.h index d70b808..da26127 100644 --- a/include/LEDStrip.h +++ b/include/LEDStrip.h @@ -17,10 +17,20 @@ class LEDStripComponent { std::shared_ptr pin; std::shared_ptr color; public: + /** + * Constructs a new LED strip component for the pin that + * reproduces the given color. + */ LEDStripComponent(std::shared_ptr pin, Color * color); + /** + * Gets the pin that this LED strip component uses. + */ std::shared_ptr getPin(); + /** + * Gets the color this LED strip component is capable of reproducing. + */ std::shared_ptr getColor(); /** @@ -50,27 +60,92 @@ class LEDStrip { ColorSequence * colorSequence = nullptr; // Methods + /** + * Turns on the white components to the appropriate brightness. + */ void displayWhiteComponents(double &red, double &green, double &blue); + + /** + * Giving the LED strip component's output, this function sets its output + * to the maximum appropriate level that maintains color accuracy. + */ void updateLEDStripComponent(double &red, double &green, double &blue, LEDStripComponent *); + + /** + * Sets all components to off + */ void turnOff(); public: LEDStrip(int id, int numColors, LEDStripComponent ** components, std::string name); + /** + * @return The ID of the LED strip. + */ int getID(); + + /** + * @return The number of components in the LED strip. + */ int getNumColors(); + + /** + * Note: Do not exceed an index of 1 - getNumColors() + * @param index: The index of the LED strip component. + * @return A pointer to the component. + */ LEDStripComponent * getComponent(int index); + + /** + * @return a reference to the name of the LED strip. + */ std::string& getName(); + + /** + * @return true if on, false if off. + */ bool isOn(); + + /** + * @return the current brightness of the LED strip. + */ int getCurrentBrightness(); + + /** + * Sets whether the LED strip is on or off. + */ void setOnState(bool on); + + /** + * Sets the current brightness. + */ void setCurrentBrightness(int brightness); + + /** + * Sets the current color sequence. + */ void setColorSequence(ColorSequence * colorSequence); + /** * Gets the current color sequence, or null if it does not have one set. */ ColorSequence * getCurrentColorSequence(); + + /** + * Sets the color the LED strip currently displays, with the current + * brightness and on-state. + */ void displayColor(Color * color); + + /** + * Determines whether the color needs to be changed, + * and changes it if it does. + */ void update(int tick); + + /** + * A simple method that toggles all components on and off based + * on the current time. Used for when there are no color sequences. + */ void flash(int tick); }; diff --git a/include/Serialization.h b/include/Serialization.h index 91fa5db..9276e38 100644 --- a/include/Serialization.h +++ b/include/Serialization.h @@ -6,12 +6,66 @@ class ColorSequence; class Color; class Controller; -int getShort(std::istream&); -std::string getString(std::istream&); -ColorSequence * getColorSequence(std::istream&); -LEDStrip * getLEDStrip(std::istream&, Controller& controller); +/** + * Used for getting a short from two bytes from the stream + * that are big-endian. + * @param stream: A stream that has a short (2 bytes). + */ +int getShort(std::istream& stream); +/** + * This string is in the form of one byte specifying the length, + * and the rest of the bytes representing the string itself. + * + * @param stream: An istream that has the string data. + * @return The string from the data. + */ +std::string getString(std::istream& stream); + +/** + * Gets the color represented by the stream. + * + * @param stream: The stream that contains the color data. + * + * @return the new color object. + */ +Color * getColor(std::istream& stream); + +/** + * @param stream: An istream that has the data for a color sequence. + * + * @return A new color sequence that reflects what the binary data specified. + */ +ColorSequence * getColorSequence(std::istream& stream); + +/** + * Condition: The pins must be accessible, and the color sequence must + * exist if the binary data specifies one. + * + * @param stream: The istream that has the binary data for an LED Strip. + * @param controller: The controller object. This is needed for getting + * the pins and color sequences. + * + * @return A pointer to the newly constructed LED strip + */ +LEDStrip * getLEDStrip(std::istream& stream, Controller& controller); + +/** + * @return the binary representation of the given short int. + */ std::string shortToStr(int val); + +/** + * @return the binary representation of the given color. + */ std::string colorToStr(Color * color); + +/** + * @return the binary representation of the given LED strip. + */ std::string ledStripToStr(LEDStrip * strip); + +/** + * @return the binary representation of the given Color Sequence. + */ std::string colorSequenceToStr(ColorSequence *); diff --git a/include/pins/PinManager.h b/include/pins/PinManager.h index 2dbe1ab..63201fe 100644 --- a/include/pins/PinManager.h +++ b/include/pins/PinManager.h @@ -17,11 +17,19 @@ class PinManager { std::map, std::shared_ptr> existingPins; public: PinManager(); + /** + * Used for I2C PWM drivers. This function allows the manager to + * initialize the code that controls the PWM driver at the specified + * address. + */ void initializePWMDriver(int addr); const std::unordered_map& getPwmDrivers(); /** * Gets or creates the pin. + * + * Will return null if no channels are available or + * if the PWM driver doesn't exist. */ std::shared_ptr getPin(int i2cAddr, int pinNum); }; diff --git a/src/Controller.cpp b/src/Controller.cpp index 4b220c2..61cfec9 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -19,7 +19,7 @@ #include // NOTE: These NEED to be uppercase. -#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID +#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID #define CHARACTERISTIC_UUID_RX "6EED7E34-9F2A-4F0F-B1D6-70CD04E8E581" #define CHARACTERISTIC_UUID_TX "1CF8D309-11A3-46FB-9378-9AFFF7DCE3B4" diff --git a/src/LEDStrip.cpp b/src/LEDStrip.cpp index 745abf5..145b598 100644 --- a/src/LEDStrip.cpp +++ b/src/LEDStrip.cpp @@ -126,10 +126,16 @@ void LEDStrip::updateLEDStripComponent(double &red, double &green, double &blue, std::shared_ptr componentColor = component->getColor(); + // This calculation uses the dimmest non-zero components. To make calculations easier, it sets 0 + // values to 1.0 to basically ignore them in the part of the code that determines the dimmest part. double brightnessToMatchRed = componentColor->getRed() > 0 ? red / componentColor->getRed() : 1.0; double brightnessToMatchGreen = componentColor->getGreen() > 0 ? green / componentColor->getGreen() : 1.0; double brightnessToMatchBlue = componentColor->getBlue() > 0 ? blue / componentColor->getBlue() : 1.0; double brightness; + // In this part, it's using the limiting factor and using its brightness + // For example, if displaying RGB(255, 255, 10), which is a mostly-saturated yellow, + // If the warm white LED strip can output RGB(255, 240, 210), the limiting factor + // is the blue, since if it's too bright it will output too much blue. if (brightnessToMatchRed < brightnessToMatchGreen) { if (brightnessToMatchRed < brightnessToMatchBlue) { brightness = brightnessToMatchRed; @@ -143,15 +149,15 @@ void LEDStrip::updateLEDStripComponent(double &red, double &green, double &blue, brightness = brightnessToMatchBlue; } } - if (brightness > 1.0) + if (brightness > 1.0) // If the LED strip component isn't bright enough to display it. brightness = 1.0; component->setBrightness(brightness); // Now subtract this strip's affect on the color components. - // (strip color brightness) * (strip set brightness) = (actual brightness) * 255 - // (strip color brightness) * (strip set brightness) / 255 = (actual brightness) - + // This is to allow several LED strip colors to contribute + // to the overall color reproduction. + // (strip color brightness) * (strip set brightness) = (actual brightness) red -= componentColor->getRed() * brightness; green -= componentColor->getGreen() * brightness; blue -= componentColor->getBlue() * brightness; diff --git a/src/Serialization.cpp b/src/Serialization.cpp index f8f6469..eb921bd 100644 --- a/src/Serialization.cpp +++ b/src/Serialization.cpp @@ -12,11 +12,15 @@ #include int getShort(std::istream& data) { + // Big endian, so the first byte is the one + // representing the more significant number. return data.get() * 255 + data.get(); } std::string getString(std::istream& data) { + // The first byte is the length of the string (0-255) int strLen = data.get(); + // The rest of them are the bytes. std::string result = ""; for (int i = 0; i < strLen; i++) { result += data.get(); @@ -24,6 +28,14 @@ std::string getString(std::istream& data) { return result; } +Color * getColor(std::istream& data) { + int red = data.get(); + int green = data.get(); + int blue = data.get(); + + return new Color(red, green, blue); +} + ColorSequence * getColorSequence(std::istream& data) { // These values are one more than the color sequence data // index due to the canOverwrite value. @@ -47,11 +59,7 @@ ColorSequence * getColorSequence(std::istream& data) { std::vector colors; for (int i = 0; i < numItems; i++) { - int red = data.get(); - int green = data.get(); - int blue = data.get(); - - colors.push_back(new Color(red, green, blue)); + colors.push_back(getColor(data)); } Serial.print("Added colors: "); Serial.println(numItems); @@ -72,9 +80,7 @@ LEDStrip * getLEDStrip(std::istream& data, Controller& controller) { uint8_t driverID = data.get(); // May be 0 if not using PWMServoController uint8_t driverPin = data.get(); - uint8_t red = data.get(); - uint8_t green = data.get(); - uint8_t blue = data.get(); + Color * color = getColor(data); std::shared_ptr pin = controller.getPinManager().getPin(driverID, driverPin); if (!pin) { @@ -82,7 +88,6 @@ LEDStrip * getLEDStrip(std::istream& data, Controller& controller) { throw new std::runtime_error("Pin not found"); // TODO: Proper error packet response. } - Color * color = new Color(red, green, blue); LEDStripComponent * component = new LEDStripComponent(pin, color); @@ -104,10 +109,9 @@ LEDStrip * getLEDStrip(std::istream& data, Controller& controller) { return strip; } - - std::string shortToStr(int val) { std::string result = ""; + // Big endian. unsigned char lowerBytes = static_cast(val); unsigned char higherBytes = static_cast(val >> 8); result += higherBytes;