Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dancebot Eyes #3

Open
dimembermatt opened this issue Sep 12, 2020 · 0 comments
Open

Dancebot Eyes #3

dimembermatt opened this issue Sep 12, 2020 · 0 comments

Comments

@dimembermatt
Copy link
Contributor

dimembermatt commented Sep 12, 2020

Context

We want to write the driver that controls the eye color and expressions for the Dancebot 2.0.
We are currently using NeoPixel Jewels, which require a single digital pin.
image

Usage

The Dancebot Eyes needs to be encapsulated in a header and cpp file called by the DemobotAPI like the Dancing Servos class in the diagram.
image

We want to have an exposed API for the DancebotAPI to use (primarily updateState() in DancebotAPI.cpp); this includes the following:

  • A function to turn the eyes on (maybe a default color of RED for all LEDs)
  • A function to turn the eyes off
  • A function to set the eyes to a specific expression
  • A function to set the eyes to a specific color

API

If we define the class name as LedEye, the relevant function signatures are as follows:

  • LedEye::LedEye(int pinNumber) - initializes the class instance with this pin number
  • LedEye::on() - starts sending the LED Eye signals using an internal data buffer
  • LedEye::off() - stops sending the LED Eye signals
  • LedEye::set_expression(in expression) - updates the internal data buffer
  • LedEye::set_eye_color(int red, int green, int blue, int white) - updates the internal data buffer

Internal data buffer and example

An internal variable will hold the data for the state of the LED Eye object.
The variable can be an array of structs, where each struct contains the following members:

  • Pixel ID (which LED does this struct belong to) (int)
  • State (On or Off) (bool)
  • Color (R, G, B, W) (int, int, int, int)

An example of what this struct would look like in code is

struct Pixel {
   int pixelID;
   bool state;
   int color[3];
};

// ID = 0; state is false (OFF);  color is [255, 255, 255] (white)
Pixel a = {0, false, [255, 255, 255]}; 

Implementation of setting a series of pixels

Presented is an annotated example of how to set a bunch of these pixels.

#include<stdio.h>

// this code creates an array of pixel objects and sets all of them to blue.
struct Pixel {
   int pixelID;
   bool state;
   int color[3];
};

// define the LedEye class
class LedEye {
    // functions or variables under protected cannot be accessed unless through a public function
    protected:
        // create 7 pixel structs (we have 7 LEDs on the Jewel)
        Pixel pixels[7];
        int pinNumber;
    public:
        /**
         * constructor for a LedEye object.
         * 
         * @param pinNumber (int)
         *      pin to send data to
         */
        LedEye(int pinNumber) {
            this->pinNumber = pinNumber;
            // sets all the pixels to off and white by default
            for (int i = 0; i < 7; i++) {
                pixels[i] = {.pixelID = i, .state = false, .color = {255, 255, 255}};
            }
        }

        // sets all of the pixels to blue
        void set_to_blue() {
           // sets all the pixels to blue
           for (int i = 0; i < 7; i++) {
               pixels[i].color[0] = 0;
               pixels[i].color[1] = 0;
               pixels[i].color[2] = 255;
           }
        }
        
        // for debugging purposes. Prints out the state of the eye.
        void print_eye() {
            printf("Eye pin: %i\n", pinNumber);
            for (int i = 0; i < 7; i++) {
                printf("LED ID: %i\n", pixels[i].pixelID);
                printf("LED State: %i\n", pixels[i].state); // note that true is 1, false is 0
                printf("LED R|G|B: %i|%i|%i\n", 
                    pixels[i].color[0], 
                    pixels[i].color[1], 
                    pixels[i].color[2]
                );
            }
        }
};

// main program
int main() {
    // construct two eye objects
    LedEye leftEye(12);
    LedEye rightEye(13);
    
    leftEye.set_to_blue();
    
    printf("Left Eye State\n");
    leftEye.print_eye();
    printf("\nRight Eye State\n");
    rightEye.print_eye();
    
    return 0; // return success
}

Try copying this code in https://www.onlinegdb.com/online_c++_debugger and see if it runs and what the output is.

Wiring API to the actual Jewels

We want to send actual signals to these jewels instead of our virtual data storage, so we'll use this library developed by Adafruit.
To use, we'll look at once off calls - in set_expression and set_eyecolor, after updating the Pixels structs we'll call their setPixels() function.

... set internal buffer
pixels.setPixelColor(i, pixels.Color(0, 150, 0)); // do this for each pixel
pixels.show(); // update all of the pixels

For any further questions, please ask @dimembermatt .

@dimembermatt dimembermatt changed the title Write Drivers for the Dancebot Eyes Dancebot Eyes Sep 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants