Skip to content

Dancebot Eyes #3

@dimembermatt

Description

@dimembermatt

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 .

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions