diff --git a/lib/Board/Board.h b/lib/Board/Board.h new file mode 100644 index 0000000..8ad0a65 --- /dev/null +++ b/lib/Board/Board.h @@ -0,0 +1,109 @@ +#pragma once + +#include +#include + +#include "Cube.h" +#include "Color.h" + +template +class Board{ + public: + Board(); + ~Board() = default; + + constexpr uint32_t GetXSize() const{return X_SIZE;} + constexpr uint32_t GetYSize() const{return Y_SIZE;} + constexpr uint32_t GetZSize() const {return Z_SIZE;} + constexpr uint32_t GetNumberCubes() const{return X_SIZE * Y_SIZE * Z_SIZE;} + + /** + * @brief Returns a string in the format: + * !a,b,c,d,e,f,g,h,i; + * Where each letter is the number of cubes in a given position's stack + * @param stringBuffer the buffer to write the string into + */ + void ToStackString(String& stringBuffer) const; + + /** + * @brief Returns a bool array representing the board + */ + std::array &LinearizeBoard() const; + + void Update(); + + void FillColor(const Color &color); + + void SetCubeColor(uint32_t x_coord, uint32_t y_cord, uint32_t z_cord, const Color &color); + + private: + // this is a 3d array of cubes to represent the board. Good luck visualizing it + /* _____________ + / /| + / / | + / / | + /____________/ | + | | | + | | / + | | / + |____________|/ + */ + std::array, Y_SIZE>, X_SIZE> cubes; + + bool boardStateHasChanged; +}; + +template +Board::Board(){ + this->FillColor(Color(0,0,0)); +} + +template +void Board::ToStackString(String &stringBuffer) const{ + std::array linearizedBoard = this->LinearizeBoard(); + + stringBuffer += "!" + String(linearizedBoard[0]); + + for(uint32_t i = 0; i < X_SIZE * Y_SIZE; i++){ + stringBuffer += "," + String(linearizedBoard[i]); + } + + stringBuffer += ";"; +} + +template +std::array & Board::LinearizeBoard() const{ + // convert the board into one array where each entry represents the height of one stack + std::array linearizedBoard; + for(uint32_t x{0}; x < X_SIZE; x++){ + for(uint32_t y{0}; y < Y_SIZE; y++){ + for(uint32_t z{0}; z < Z_SIZE; z++){ + bool isOccupied{this->cubes[x][y][z].isOccupied}; + linearizedBoard[x + y*3] += static_cast(isOccupied); + } + } + } + return linearizedBoard; +} + +template +void Board::Update(){ + +} + +template +void Board::FillColor(const Color &color){ + for(uint32_t x{0}; x < X_SIZE; x++){ + for(uint32_t y{0}; y < Y_SIZE; y++){ + for(uint32_t z{0}; z < Z_SIZE; z++){ + this->cubes[x][y][z].SetColor(color); + } + } + } +} + +template +void Board::SetCubeColor(uint32_t x_coord, uint32_t y_cord, uint32_t z_cord, const Color &color){ + this->cubes[x][y][z].SetColor(color); +} + diff --git a/lib/Board/Color.h b/lib/Board/Color.h index 015bbfb..434b105 100644 --- a/lib/Board/Color.h +++ b/lib/Board/Color.h @@ -8,6 +8,7 @@ // store a color struct Color{ + public: // create a constructor for this struct Color(uint8_t red, uint8_t green, uint8_t blue) : red(red), diff --git a/lib/Board/CubeStack.cpp b/lib/Board/CubeStack.cpp index e8954c1..7af12ab 100644 --- a/lib/Board/CubeStack.cpp +++ b/lib/Board/CubeStack.cpp @@ -12,7 +12,7 @@ CubeStack::CubeStack(uint16_t ADCPin, uint16_t ledPin, uint8_t numLEDs){ } }; -uint8_t CubeStack::GetNumberCubes(){ +uint32_t CubeStack::GetNumberCubes(Cube &cube){ // read the ADC and return the number of cubes /* 0 cubes: 1 : 4095-3400 @@ -20,11 +20,8 @@ uint8_t CubeStack::GetNumberCubes(){ 2 cubes: 1/3 2500-1850 3 cubes: 1/4 1850-0 */ - uint16_t value = analogRead(this->ADCPin); - this->lowPassADCRead = static_cast((static_cast(this->lowPassADCRead) * 0.9) + (static_cast(value) * 0.1)); - if(this->lowPassADCRead < 2500 && false){ - Serial.println("ADC Pin:" + String(this->ADCPin) + " Value: " + String(value) + " Low Pass: " + String(this->lowPassADCRead)); - } + uint16_t value = analogRead(cube.ADCPin); + uint16_t lowPassADCRead = static_cast((static_cast(cube.lastADCReading) * 0.9) + (static_cast(value) * 0.1)); // temporary definitions to define value ranges: uint16_t zeroCubesHigh = 4095; @@ -35,37 +32,22 @@ uint8_t CubeStack::GetNumberCubes(){ uint8_t stackHeight = 0; - if(this->lowPassADCRead >= zeroCubesLow && this->lowPassADCRead <= zeroCubesHigh){ + if(lowPassADCRead >= zeroCubesLow && lowPassADCRead <= zeroCubesHigh){ stackHeight = 0; } - else if(this->lowPassADCRead >= oneCubeLow){ + else if(lowPassADCRead >= oneCubeLow){ stackHeight = 1; } - else if(this->lowPassADCRead >= twoCubesLow){ + else if(lowPassADCRead >= twoCubesLow){ stackHeight = 2; } - else if(this->lowPassADCRead >= threeCubesLow){ + else if(lowPassADCRead >= threeCubesLow){ stackHeight = 3; } - if(this->lastStackHeight != stackHeight){ - this->lastStackHeight = stackHeight; - this->SendLEDData(); - } return stackHeight; } -void CubeStack::SetLEDColors(Color * colors, uint8_t numColors){ - // copy the colors into the ledColors array - for(int i = 0; i < numColors; i++){ - this->ledColors[i].red = colors[i].red; - this->ledColors[i].green = colors[i].green; - this->ledColors[i].blue = colors[i].blue; - } - - this->SendLEDData(); -} - void CubeStack::SendLEDData(){ // we always initialize before we do anything because other CubeStacks could be hogging the hardware // between our writes diff --git a/lib/Board/CubeStack.h b/lib/Board/CubeStack.h index 634ef50..8a343e4 100644 --- a/lib/Board/CubeStack.h +++ b/lib/Board/CubeStack.h @@ -7,10 +7,10 @@ #include #include #include "Color.h" +#include "Cube.h" -class CubeStack{ - public: +namespace CubeStack{ /** * @brief Construct a new Cube Stack object * @param ADCPin the pin that the ADC is connected to @@ -22,31 +22,10 @@ class CubeStack{ * @brief Returns the number of cubes in the stack * @return the number of cubes in the stack */ - uint8_t GetNumberCubes(); - - /** - * @brief Set the led color array and then send the data to the LED strip - * @param colors the array of colors to set the LEDs to - * @param numColors the number of colors in the array - */ - void SetLEDColors(Color * colors, uint8_t numColors); + uint32_t GetNumberCubes(Cube &cube); /** * @brief sends the LED data to the LED strip */ void SendLEDData(); - - private: - - - uint8_t ADCPin; - // we will probably need a pointer to a fastled object here - Adafruit_NeoPixel blockLights; - - uint16_t lowPassADCRead{0}; - - // store the Color of each LED - Color * ledColors; - uint8_t numLEDs; - uint8_t lastStackHeight{0}; }; \ No newline at end of file diff --git a/lib/BoardReader/BoardDriver.h b/lib/BoardReader/BoardDriver.h new file mode 100644 index 0000000..5ff3d09 --- /dev/null +++ b/lib/BoardReader/BoardDriver.h @@ -0,0 +1,115 @@ +#pragma once + +#include +#include + +#include + +#include "Cube.h" + +namespace BoardDriverTypes{ + struct CubeStack{ + uint8_t adcPin; + uint8_t ledPin; + } +}; + +template +class BoardDriver{ +public: + + BoardDriver(std::array &stacks, Adafruit_NeoPixel &pixelController); + ~BoardDriver() = default; + + uint32_t GetNumberCubes(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD); + uint32_t GetNumberCubes(uint32_t stackIndex); + + void UpdateStackLEDs(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD, Cube cubes[], uint32_t numCubes); + void UpdateStackLEDs(uint32_t stackIndex, Cube cubes[], uint32_t numCubes); + + +private: + std::array &stacks; + Adafruit_NeoPixel &pixelController; + std::array filteredReadings; + + uint32_t xy2StackIndex(uint32_t x_coord, uint32_t y_coord, uint32_t numXStacks){ + return X_COORD + Y_COORD*numXStacks; + } +}; + +template +BoardDriver::BoardDriver(std::array &stacks, Adafruit_NeoPixel &pixelController): +stacks(stacks), +pixelController(pixelController) +{ + for(uint32_t i = 0; i < NUM_STACKS; i++){ + this->filteredReadings[i] = 0; + pinMode(this->stacks[i].ledPin, OUTPUT); + } + + // begin doesn't really do anything besides setting the pinmode + this->pixelController.begin(); +} + +template +void BoardDriver::UpdateStackLEDs(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD, Cube cubes[], uint32_t numCubes){ + this->UpdateStackLEDs(this->xy2StackIndex(X_COORD, Y_COORD, numXStacks), cubes, numCubes); +} + +template +void BoardDriver::UpdateStackLEDs(uint32_t stackIndex, Cube cubes[], uint32_t numCubes){ + this->pixelController.setPin(this->stacks[stackIndex].ledPin); + for(int i = 0; i < numCubes; i++){ + Color color{cubes[i].color}; + this->pixelController.setPixelColor(i*2, this->pixelController.Color(color.red, color.green, color.blue)); + this->pixelController.setPixelColor((i*2 + 1), this->pixelController.Color(color.red, color.green, color.blue)); + } + this->pixelController.show(); +} + +template +uint32_t BoardDriver::GetNumberCubes(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD){ + return this->GetNumberCubes(this->xy2StackIndex(x_coord, y_coord, numXStacks)); +} + +template +uint32_t BoardDriver::GetNumberCubes(uint32_t stackIndex){ + // read the ADC and return the number of cubes + /* + 0 cubes: 1 : 4095-3400 + 1 cube: 1/2 3400-2500 + 2 cubes: 1/3 2500-1850 + 3 cubes: 1/4 1850-0 + */ + uint16_t value = analogRead(cube.ADCPin); + uint16_t lowPassADCRead = + static_cast( + (static_cast(this->filteredReadings[stackIndex]) * 0.9) + + (static_cast(value) * 0.1) + ); + + // temporary definitions to define value ranges: + uint16_t zeroCubesHigh = 4095; + uint16_t zeroCubesLow = 3400; + uint16_t oneCubeLow = 2500; + uint16_t twoCubesLow = 1850; + uint16_t threeCubesLow = 0; + + uint8_t stackHeight = 0; + + if(lowPassADCRead >= zeroCubesLow && lowPassADCRead <= zeroCubesHigh){ + stackHeight = 0; + } + else if(lowPassADCRead >= oneCubeLow){ + stackHeight = 1; + } + else if(lowPassADCRead >= twoCubesLow){ + stackHeight = 2; + } + else if(lowPassADCRead >= threeCubesLow){ + stackHeight = 3; + } + + return stackHeight; +} \ No newline at end of file diff --git a/lib/Cube/Cube.cpp b/lib/Cube/Cube.cpp new file mode 100644 index 0000000..7a271ba --- /dev/null +++ b/lib/Cube/Cube.cpp @@ -0,0 +1,22 @@ +#include "Cube.h" + +Cube::Cube(uint8_t ADCPin, uint8_t ledPin) + : ADCPin(ADCPin), + ledPin(ledPin) +{ + Color black(0,0,0); + this->SetColor(black); +} + +Cube::Cube(uint8_t ADCPin, uint8_t ledPin, const Color &color) + : ADCPin(ADCPin), + ledPin(ledPin) +{ + this->SetColor(color); +} + +void Cube::SetColor(const Color &color){ + this->color.red = color.red; + this->color.green = color.green; + this->color.blue = color.blue; +} \ No newline at end of file diff --git a/lib/Cube/Cube.h b/lib/Cube/Cube.h new file mode 100644 index 0000000..516ac77 --- /dev/null +++ b/lib/Cube/Cube.h @@ -0,0 +1,21 @@ +/** + * @file Cube.h + * @brief An object to store the data of one cube + */ + +#pragma once + +#include "Color.h" + +class Cube{ + public: + Cube(); + Cube(); + + void SetColor(const Color &color); + + uint16_t lastADCReading{0}; + + Color color; + bool isOccupied{false}; +}; \ No newline at end of file