// Feather Power Meter // // Small Feather-based power monitor using an INA219 breakout and // monochrome OLED display. // // Author: Tony DiCola (modded by ladyada) // // Released under a MIT license: http://opensource.org/licenses/MIT #include #include #include #include #include #include // Configure orientation of the display. // 0 = none, 1 = 90 degrees clockwise, 2 = 180 degrees, 3 = 270 degrees CW #define ROTATION 0 #define NEO_PIN 6 // Create NeoPixel, OLED and INA219 globals. Adafruit_SSD1306 display; Adafruit_INA219 ina219; Adafruit_NeoPixel pixels = Adafruit_NeoPixel(144, NEO_PIN, NEO_GRB + NEO_KHZ800); // Keep track of total time and milliamp measurements for milliamp-hour computation. uint32_t total_sec = 0; float total_mA = 0.0; uint8_t counter = 0; void pixel_show_and_powerupdate() { pixels.show(); if (counter == 0) { update_power_display(); } else { counter = (counter+1) % 10 ; } } void setup() { Serial.begin(115200); while (!Serial) { // will pause Zero, Leonardo, etc until serial console opens delay(1); } pixels.begin(); pixels.show(); // Initialize all pixels to 'off' // Try to initialize the INA219 if (! ina219.begin()) { Serial.println("Failed to find INA219 chip"); while (1) { delay(10); } } // By default the INA219 will be calibrated with a range of 32V, 2A. // However uncomment one of the below to change the range. A smaller // range can't measure as large of values but will measure with slightly // better precision. //ina219.setCalibration_32V_1A(); //ina219.setCalibration_16V_400mA(); // Setup the OLED display. display.begin(SSD1306_SWITCHCAPVCC, 0x3C); Wire.setClock(400000); // Clear the display. display.clearDisplay(); display.display(); // Set rotation. display.setRotation(ROTATION); // Set text size and color. display.setTextSize(2); display.setTextColor(WHITE); } void loop() { // Some example procedures showing how to display to the pixels: colorWipe(pixels.Color(255, 0, 0), 50); // Red colorWipe(pixels.Color(0, 255, 0), 50); // Green colorWipe(pixels.Color(0, 0, 255), 50); // Blue //colorWipe(pixels.Color(0, 0, 0, 255), 50); // White RGBW // Send a theater pixel chase in... theaterChase(pixels.Color(127, 127, 127), 50); // White theaterChase(pixels.Color(127, 0, 0), 50); // Red theaterChase(pixels.Color(0, 0, 127), 50); // Blue rainbow(20); rainbowCycle(20); theaterChaseRainbow(50); } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i maxWidth) { // Fill width with dashes (and add extra dash for negative values); for (int i=0; i < maxWidth; ++i) { display.print('-'); } if (value < 0.0) { display.print('-'); } return; } // Compute actual precision for printed value based on space left after // printing digits and decimal point. Clamp within 0 to desired precision. int actualPrecision = constrain(maxWidth-digits-1, 0, precision); // Compute how much padding to add to right justify. int padding = maxWidth-digits-1-actualPrecision; for (int i=0; i < padding; ++i) { display.print(' '); } // Finally, print the value! display.print(value, actualPrecision); }