Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Written by M. Padovani in Jan 2018, adapting Arduino Mega Sketch for the ESP32 with additional features
- * Monitor high side voltage/current/power via TWO INA219, TWO OLED, LEDs, and SD card reader
- * One INA219 (0x40) will be to measure up to 32V/2000mA while the second (0x41) will measure up to 16V/400mA
- * One OLED (0x3C) will display VCP while the second (0x3D) will display the refresh interval
- * Refresh interval will be determined from feedback via a Pot connected to A2
- * Refresh interval will range from "0ms" (as fast as the program will run, which is ~140ms) to 60000ms
- * See "SGS3_VCP_allTimers.xls" for more details concerning timing
- * Recommend resisitor values: 220 Red, 220 Green, 220 Blue (3.3V supply)
- * Serial Print has been omitted (not needed) to increase speed of sketch
- * SD card file is "VCP.txt" (Voltage, Current, Power)
- * Can log data as CSV to Serial Monitor as well (currently commented out)
- * Sketch uses 304655 bytes (23%) program space, 29232 bytes (9%) dynamic memory
- */
- #include <Wire.h>
- #include <Adafruit_INA219.h>
- #include <Adafruit_SSD1306.h>
- #include <SPI.h>
- #include "SdFat.h"
- SdFat SD;
- #define OLED_RESET 4
- Adafruit_SSD1306 VCP_display(OLED_RESET); //displays Voltage(V), Current(mA), and Power(mW)
- Adafruit_SSD1306 Refresh_display(OLED_RESET); //displayed refresh interval(ms)
- Adafruit_INA219 ina219_A(0x40); //on red sense LED pin, 32V/2000mA, default address
- Adafruit_INA219 ina219_B(0x41); //on blue sense LED pin, 16V/400mA
- #define red1_pin 14 //GPIO 14
- #define green1_pin 33 //GPIO 33
- #define blue1_pin 15 //GPIO 27
- #define red2_sensePin 27 //GPIO 27
- #define blue2_sensePin 21 //GPIO 21
- #define refresh_PotPin A2
- #define white1_pin 13 //GPIO 13
- #define white2_sensePin A5 //A5 or GPIO 4
- int bluePinState; //holds value of blue button state (0 or 1 / LOW or HIGH)
- int redPinState; //holds value of red button state (0 or 1 / LOW or HIGH)
- //Timer function
- unsigned long currentMillis; //subtract out so the program updates at 250ms
- unsigned long previousMillis = 0;
- unsigned long refreshInterval; //depends on Pot value on A2
- //SPI SD Card Pins
- int SDpin = 32; //SD card cs pin
- //Store ID # of data record
- unsigned long id = 1;
- //Create files to store on SD card
- File VolCurPowFile;
- //Variables needed to get refresh interval
- int refreshValue;
- int newPotValue; //depends on Pot value on A2
- int previousPotValue = 0;
- int rawRefreshValue; //raw analogRead on A2
- int refreshRate;
- void setup() {
- Serial.begin(115200);
- pinMode(red1_pin, OUTPUT);
- pinMode(green1_pin, OUTPUT);
- pinMode(blue1_pin, OUTPUT);
- pinMode(red2_sensePin, INPUT);
- pinMode(blue2_sensePin, INPUT);
- digitalWrite(red1_pin, LOW);
- digitalWrite(green1_pin, LOW);
- digitalWrite(blue1_pin, LOW);
- pinMode(white1_pin, OUTPUT);
- pinMode(white2_sensePin, INPUT);
- digitalWrite(white1_pin, LOW);
- VCP_display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
- VCP_display.clearDisplay();
- VCP_display.display();
- Refresh_display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
- Refresh_display.clearDisplay();
- Refresh_display.display();
- pinMode(SDpin, OUTPUT); //defined as global variable, set as output
- SD.begin(SDpin);
- uint32_t currentFrequency;
- ina219_A.begin();
- ina219_B.begin();
- /*********** NOT USED -- DID NOT SHOW A NOTICABLE DIFFERENCE COMPARED TO 32V/2A ***********/
- //ina219.setCalibration_32V_1A();
- ina219_A.setCalibration_32V_2A(); //red LED
- ina219_B.setCalibration_16V_400mA(); //blue LED
- Serial.println("Time(ms),Gain(mA),id(#),BusVolt(V),ShuntVolt(mV),LoadVolt(V),Current(mA),LoadPower(mW)");
- VolCurPowFile = SD.open("VCP.txt",FILE_WRITE);
- if (VolCurPowFile) {
- VolCurPowFile.println("Time(ms),Gain(mA),id(#),BusVolt(V),ShuntVolt(mV),LoadVolt(V),Current(mA),LoadPower(mW)");
- VolCurPowFile.close();
- }
- /*********** GET THE REFRESH RATE FROM POT CONNECTED TO A2 ***********/
- getRefreshRate();
- refreshRateDisplay();
- }
- void loop() {
- /******* ZERO CLOCK STARTS HERE *******/
- currentMillis = millis();
- //set variable refresh rate (0ms to 60000ms). 0ms will go as fast as the program can run.
- if (currentMillis - previousMillis >= refreshInterval) {
- /***** SAVE THE "CURRENT" TIME *****/
- previousMillis = currentMillis;
- /***** SAVE THE STATE OF THE RED AND BLUE LED *****/
- redPinState = digitalRead(red2_sensePin);
- bluePinState = digitalRead(blue2_sensePin);
- /***** CHECK STATE OF RED LED AND CALCULATE VIA 36V/2000mA *****/
- if (redPinState == HIGH && bluePinState == LOW) {
- digitalWrite(red1_pin, HIGH);
- digitalWrite(blue1_pin, LOW);
- float shuntvoltage = 0;
- float busvoltage = 0;
- float current_mA = 0;
- float loadvoltage = 0;
- float loadpower = 0;
- shuntvoltage = ina219_A.getShuntVoltage_mV();
- busvoltage = ina219_A.getBusVoltage_V();
- current_mA = ina219_A.getCurrent_mA();
- loadvoltage = busvoltage + (shuntvoltage / 1000);
- loadpower = ((loadvoltage)*(current_mA/1000))*1000;
- /****** SERIAL PRINT NOT NEEDED *******/
- // Serial.print(currentMillis);
- // Serial.print(',');
- // Serial.print("32V_2000mA");
- // Serial.print(',');
- // Serial.print(id);
- // Serial.print(',');
- // Serial.print(busvoltage);
- // Serial.print(',');
- // Serial.print(shuntvoltage);
- // Serial.print(',');
- // Serial.print(loadvoltage);
- // Serial.print(',');
- // Serial.print(current_mA);
- // Serial.print(',');
- // Serial.println(loadpower);
- VolCurPowFile = SD.open("VCP.txt",FILE_WRITE);
- if (VolCurPowFile) {
- digitalWrite(green1_pin, HIGH);
- VolCurPowFile.print(currentMillis);
- VolCurPowFile.print(',');
- VolCurPowFile.print("32V_2000mA");
- VolCurPowFile.print(',');
- VolCurPowFile.print(id++);
- VolCurPowFile.print(',');
- VolCurPowFile.print(busvoltage);
- VolCurPowFile.print(',');
- VolCurPowFile.print(shuntvoltage);
- VolCurPowFile.print(',');
- VolCurPowFile.print(loadvoltage);
- VolCurPowFile.print(',');
- VolCurPowFile.print(current_mA);
- VolCurPowFile.print(',');
- VolCurPowFile.println(loadpower);
- VolCurPowFile.close();
- digitalWrite(green1_pin, LOW);
- }
- VCP_display.setTextColor(WHITE);
- VCP_display.clearDisplay();
- VCP_display.setTextSize(2);
- VCP_display.setCursor(0, 0);
- VCP_display.println(loadvoltage);
- VCP_display.setCursor(100, 0);
- VCP_display.println("V");
- VCP_display.setCursor(0, 20);
- VCP_display.println(current_mA);
- VCP_display.setCursor(100, 20);
- VCP_display.println("mA");
- VCP_display.setCursor(0, 40);
- VCP_display.println(loadpower);
- VCP_display.setCursor(100, 40);
- VCP_display.println("mW");
- VCP_display.display();
- }
- /***** CHECK STATE OF BLUE LED AND CALCULATE VIA 16V/400mA *****/
- if (redPinState == LOW && bluePinState == HIGH) {
- digitalWrite(blue1_pin, HIGH);
- digitalWrite(red1_pin, LOW);
- float shuntvoltage = 0;
- float busvoltage = 0;
- float current_mA = 0;
- float loadvoltage = 0;
- float loadpower = 0;
- shuntvoltage = ina219_B.getShuntVoltage_mV();
- busvoltage = ina219_B.getBusVoltage_V();
- current_mA = ina219_B.getCurrent_mA();
- loadvoltage = busvoltage + (shuntvoltage / 1000);
- loadpower = ((loadvoltage)*(current_mA/1000))*1000;
- /****** SERIAL PRINT NOT NEEDED *******/
- // Serial.print(currentMillis);
- // Serial.print(',');
- // Serial.print("16V_400mA");
- // Serial.print(',');
- // Serial.print(id);
- // Serial.print(',');
- // Serial.print(busvoltage);
- // Serial.print(',');
- // Serial.print(shuntvoltage);
- // Serial.print(',');
- // Serial.print(loadvoltage);
- // Serial.print(',');
- // Serial.print(current_mA);
- // Serial.print(',');
- // Serial.println(loadpower);
- VolCurPowFile = SD.open("VCP.txt",FILE_WRITE);
- if (VolCurPowFile) {
- digitalWrite(green1_pin, HIGH);
- VolCurPowFile.print(currentMillis);
- VolCurPowFile.print(',');
- VolCurPowFile.print("16V_400mA");
- VolCurPowFile.print(',');
- VolCurPowFile.print(id++);
- VolCurPowFile.print(',');
- VolCurPowFile.print(busvoltage);
- VolCurPowFile.print(',');
- VolCurPowFile.print(shuntvoltage);
- VolCurPowFile.print(',');
- VolCurPowFile.print(loadvoltage);
- VolCurPowFile.print(',');
- VolCurPowFile.print(current_mA);
- VolCurPowFile.print(',');
- VolCurPowFile.println(loadpower);
- VolCurPowFile.close();
- digitalWrite(green1_pin, LOW);
- }
- VCP_display.setTextColor(WHITE);
- VCP_display.clearDisplay();
- VCP_display.setTextSize(2);
- VCP_display.setCursor(0, 0);
- VCP_display.println(loadvoltage);
- VCP_display.setCursor(100, 0);
- VCP_display.println("V");
- VCP_display.setCursor(0, 20);
- VCP_display.println(current_mA);
- VCP_display.setCursor(100, 20);
- VCP_display.println("mA");
- VCP_display.setCursor(0, 40);
- VCP_display.println(loadpower);
- VCP_display.setCursor(100, 40);
- VCP_display.println("mW");
- VCP_display.display();
- }
- /***** IF RED AND BLUE LED SENSE PINS ARE LOW, THEN DO NOTHING *****/
- if (bluePinState == LOW && redPinState == LOW) {
- digitalWrite(red1_pin, LOW);
- digitalWrite(blue1_pin, LOW);
- VCP_display.clearDisplay();
- VCP_display.display();
- }
- }
- }
- int getRefreshRate() {
- /****** ADC really stinks on the ESP32! Did not want to use ADS1115, so I tweaked these threshold numbers appropriately ******/
- newPotValue = map(analogRead(refresh_PotPin), 0, 4095, 65000, 0);
- if (newPotValue != previousPotValue) {
- if (newPotValue <=400) {
- return(0);
- //Serial.println(0);
- }
- if (newPotValue >400 && newPotValue <=8000) {
- return(250);
- //Serial.println(250);
- }
- if (newPotValue >8000 && newPotValue <=18000) {
- return(500);
- //Serial.println(500);
- }
- if (newPotValue >18000 && newPotValue <=26000) {
- return(1000);
- //Serial.println(1000);
- }
- if (newPotValue >26000 && newPotValue <=32000) {
- return(5000);
- //Serial.println(5000);
- }
- if (newPotValue >32000 && newPotValue <=38000) {
- return(10000);
- //Serial.println(10000);
- }
- if (newPotValue >38000 && newPotValue <=44000) {
- return(20000);
- //Serial.println(20000);
- }
- if (newPotValue >44000 && newPotValue <=50000) {
- return(30000);
- //Serial.println(30000);
- }
- if (newPotValue >50000 && newPotValue <=56000) {
- return(40000);
- //Serial.println(40000);
- }
- if (newPotValue >56000 && newPotValue <=62000) {
- return(50000);
- //Serial.println(50000);
- }
- if (newPotValue >62000 && newPotValue <=65000) {
- return(60000);
- //Serial.println(60000);
- }
- else {return(00000); //Serial.println(00000);}
- }
- previousPotValue = newPotValue;
- }
- }
- void refreshRateDisplay() {
- /****** Had problems with floating ground...instead of reading 0 it read 0-120. May be fixed once connections are soldered *****/
- //while (white2_sensePin == LOW);
- /***** USED THIS INSTEAD TO RAISE THE GROUND LEVEL FOR BETTER CODE STABILITY *****/
- while (analogRead(white2_sensePin) <= 200) {
- refreshRate = getRefreshRate();
- digitalWrite(white1_pin, HIGH);
- Refresh_display.setTextColor(WHITE);
- Refresh_display.clearDisplay();
- Refresh_display.setTextSize(2);
- Refresh_display.setCursor(0, 0);
- Refresh_display.println("SetRefresh");
- Refresh_display.setCursor(40, 20);
- Refresh_display.println("Rate!");
- Refresh_display.setCursor(100, 40);
- Refresh_display.println("ms");
- Refresh_display.setCursor(30, 40);
- Refresh_display.println(refreshRate);
- Refresh_display.display();
- digitalWrite(white1_pin, LOW);
- //Serial.print("Set Refresh Rate! "); Serial.println(refreshRate);
- delay(50); //Needed to blink white LED
- }
- /***** BUTTON IS PRESSED AT THIS POINT ("white2_sensePin" GOES HIGH) *****/
- digitalWrite(white1_pin, HIGH); //keep white LED lit
- refreshInterval = getRefreshRate();
- /***** KEEP DISPLAY ON *****/
- Refresh_display.setTextColor(WHITE);
- Refresh_display.clearDisplay();
- Refresh_display.setTextSize(2);
- Refresh_display.setCursor(20, 0);
- Refresh_display.println("Refresh");
- Refresh_display.setCursor(15, 20);
- Refresh_display.println("Rate Set");
- Refresh_display.setCursor(100, 40);
- Refresh_display.println("ms");
- Refresh_display.setCursor(30, 40);
- Refresh_display.println(refreshRate);
- Refresh_display.display();
- //Serial.print("Refresh Rate Set! "); Serial.println(refreshRate);
- delay(50); //Needed to blink white LED
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement