Last active
July 18, 2020 23:55
-
-
Save savannahostrowski/c775568ab5aed675549c075a6a69b059 to your computer and use it in GitHub Desktop.
HCDE 598 - Assignment 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Assignment 1 - A Sensor Platform | |
* | |
* A PHYSICAL COLOUR PICKER | |
* | |
This sketch does a couple of different things: | |
- Uses an APDS9600 sensor to detect changes in hand gesture direction to choose a colour | |
- A hand gesture toward the right loops over a set of colours (red, green, blue, yellow, purple, aqua) | |
- The colour name is logged to an 128x32 I2C OLED, to an Adafruit IO dashboard and to an RGB LED | |
- On the Adafruit dashboard, you can hit a "Pick a random colour button". That button press is | |
logged and sent back to the Feather Huzzah to display the colour on an RGB LED | |
Dashboard link: https://io.adafruit.com/sostrows/dashboards/a1-sensor-platform | |
Savannah Ostrowski | |
*/ | |
/************************** Configuration ***********************************/ | |
// edit the config.h tab and enter your Adafruit IO credentials | |
// and any additional configuration needed for WiFi, cellular, | |
// or ethernet clients. | |
#include "config.h" | |
/************************ Code Starts Here *******************************/ | |
#include <Adafruit_SSD1306.h> | |
#include "Adafruit_APDS9960.h" | |
Adafruit_APDS9960 apds; //Instantiates an APDS9960 object | |
#define SCREEN_WIDTH 128 // OLED display width, in pixels | |
#define SCREEN_HEIGHT 32 // OLED display height, in pixels | |
#define DEBUG 0 // DEBUG mode: if 1 we are not logging to Adafruit, if 0 we are posting data! | |
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) | |
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) | |
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Configure display | |
// Set up the colour feed for Adafruit IO | |
AdafruitIO_Feed *colour = io.feed("colour"); // This is the feed to track the current colour | |
AdafruitIO_Feed *newColour = io.feed("newColour"); // This is the feed to track the button press to randomize the colour | |
// Configures the pins for the RGB LED | |
int bluePin = 12; | |
int greenPin = 13; | |
int redPin = 14; | |
// Stores all the RGB values for the LED | |
int colours[6][3] = { | |
{255, 0, 0}, //red | |
{0, 255, 0}, //green | |
{0, 0, 255}, //blue | |
{255, 255, 0}, //yellow | |
{80, 0, 80}, // purple | |
{0, 255, 255} // aqua | |
}; | |
// Stores the colour names to display on the OLED and on Adafruit | |
String colourNames[6] = {"red", "green", "blue", "yellow", "purple", "aqua"}; | |
int colourCounter = 0; // Initialize a counter to iterate over the colours; starting at 0 (aka red) | |
// A function that takes in the RGB values to render a colour to set the pins on the LED | |
void setColour(int arr[3]) | |
{ | |
analogWrite(redPin, arr[0]); // Grabs the 0th index in the array (the red value) | |
analogWrite(greenPin, arr[1]); // Grabs the 1st index in the array (the green value) | |
analogWrite(bluePin, arr[2]); // Grabs the 2nd index in the array (the blue value) | |
} | |
// The setup function runs once when you press reset or power the board | |
void setup() { | |
Serial.begin(115200); // Set the data rate in bits per second for serial data transmission and print that the program is starting | |
Serial.println("Starting!"); | |
while(! Serial); // Wait for serial monitor to open then print build details | |
// If not in debug mode | |
if (!DEBUG){ | |
Serial.print("Connecting to Adafruit IO"); // Print and then connect to io.adafruit.com | |
io.connect(); // Connect to Adafruit IO | |
newColour->onMessage(newColourButtonPressed); // Track the newColour feed to see if there is new input; if there is, we call the newColourButtonPressed function | |
// Wait for a connection | |
while(io.status() < AIO_CONNECTED) { | |
// print a dot every 500ms | |
Serial.print("."); | |
delay(500); | |
} | |
// We are connected (print the status) | |
Serial.println(); | |
Serial.println(io.statusText()); | |
newColour->get(); // I believe this is to grab the latest feed value? No API documentation? | |
// Set up pins for the RGB LED | |
pinMode(redPin, OUTPUT); // red LED | |
pinMode(bluePin, OUTPUT); // blue LED | |
pinMode(greenPin, OUTPUT); // green LED | |
} | |
// If the ADPS9960 sensor fails to initialize | |
if(!apds.begin()){ | |
// Log that there was an issue in the serial monitor | |
Serial.println("failed to initialize device! Please check your wiring."); | |
} | |
else { | |
// Otherwise, we are all good! | |
Serial.println("Device initialized!"); | |
} | |
// Gesture mode will be entered once proximity mode senses something close; enable both capabilities | |
apds.enableProximity(true); | |
apds.enableGesture(true); | |
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally | |
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 | |
Serial.println(F("SSD1306 allocation failed")); | |
for (;;); // Don't proceed, loop forever | |
} | |
// Set up the OLED display | |
// by default, we'll generate the high voltage from the 3.3v line internally | |
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize with the I2C addr 0x3C (for the 128x32) | |
display.setTextSize(1); // Normal 1:1 pixel scale | |
display.setTextColor(SSD1306_WHITE); // Draw white text | |
display.clearDisplay(); // clear the display | |
display.setCursor(0, 0); // Set the cursor to start printing in the top-left corner (at 0,0) | |
delay(500); // Delay after clearing | |
setColour(colours[colourCounter % 6]); // Set the RGB colour | |
Serial.println(colourNames[colourCounter % 6]); // Log the colour name to the serial monitor for debugging | |
display.println("Colour: "); // Update the OLED with the new colour name; prints "Colour: <some colour>" | |
display.println(colourNames[colourCounter % 6]); | |
delay(200); // Delay by 200ms | |
} | |
// the loop function runs over and over again forever | |
void loop() { | |
// io.run(); is required for all sketches. | |
// it should always be present at the top of your loop | |
// function. it keeps the client connected to | |
// io.adafruit.com, and processes any incoming data. | |
if (!DEBUG){ | |
io.run(); | |
} | |
//read a gesture from the device | |
uint8_t currentGesture = apds.readGesture(); // Get gesture value | |
if (currentGesture != 0) { // If the gesture is not null | |
display.clearDisplay(); // Clear the display at the beginning of the loop (we are writing new data to the OLED) | |
display.setCursor(0, 0); // Start at top-left corner | |
if(currentGesture == APDS9960_RIGHT) { // If the gesture is right, we want to move to the next colour | |
colourCounter++; // So we increment the counter which we use to access an index in the array | |
} | |
changeColour(colourCounter); // Call the changeColor helper function | |
} | |
delay(5); // Delay by an ultra small amount :) | |
} | |
void changeColour(int index) { | |
// Call our setColour function to pass in the array of RGB values to render on the LED a particular colour | |
// Note that we mod 6 the colourCounter to allow us to circularly traverse the array (and never hit out of range) | |
setColour(colours[index % 6]); | |
Serial.println(colourNames[index % 6]); // Print to serial monitor the new colour name | |
display.print("Colour: "); // Print the colour name to the OLED display | |
display.println(colourNames[index % 6]); | |
display.display(); // Push OLED display update | |
// Write to our Adafruit dashboard | |
colour->save(colourNames[index % 6]); // Saves the colour name to the Adafruit dashboard | |
} | |
// Called when a new input comes in from the Adafruit dashboard to the Feather Huzzah | |
void newColourButtonPressed(AdafruitIO_Data *data) { | |
int buttonPressed = data->toInt(); // Cast the data to integer; We know it's an integer because it's a button presse (so it only has two states) | |
if (buttonPressed) { // If the button was pressed (aka it was 1 so it was truthy) | |
int colourIndex = rand()%(6-1 + 1) + 1; // We randomly generate a new index to use to pick a colour | |
colourCounter = colourIndex; // Reassign the current colour counter (which is used to track the index) to the randomly generated index | |
display.clearDisplay(); // Clear the display at the beginning of the loop (we are writing new data to the OLED) | |
display.setCursor(0, 0); // Start printing at top-left corner of the OLED | |
changeColour(colourIndex); // Call the change colour function to update | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment