This was my capstone project; we were tasked to improve energy management systems in railways. Railways face numerous challenges such as long wait times, inefficient regenerative energy capture, connectivity issues with the catenary system, and grid instability. My solution to these issues is to add hybrid energy storage on the train. Specifically, my system uses a combination of supercapacitors and LiFePO₄ (lithium iron phosphate) batteries. The supercapacitors will be used to handle the large inrush currents of the train when accelerating and to capture low energy regenerative braking. The batteries will be used to power the train if there is a disconnect with the grid or if the grid voltage dips; the batteries will also be used to capture high-energy regenerative braking. Keep in mind my solution is meant for DC-powered trains only, as AC trains have little issue collecting regenerative energy since transformers are reversible and the entire power grid uses AC. I will describe a quick use case for our system. Let's say the overhead lines of this certain train were slightly skewed; this could cause the train's pantograph to poorly connect to the grid, which creates unstable power for the train. This train may suddenly stop as a safety precaution, thinking there is a short on the line; this would lead to long delays if the connection lasts long enough. My system will detect this fault and switch to battery power instead to keep the train on schedule. If the connection to the pantograph is secure (its voltage is in the correct range for a certain time), the system will switch back to grid power. Another use case would be if the train needed to capture regenerative energy; my system would simply absorb this power while other systems can't since you can't send DC back to the power grid as that uses AC, unless you use costly high-power inverters.
This video shows the functions and interactions of the scale model.
#include "MCP41HVX1.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono12pt7b.h>
#include <INA226_WE.h>
#include <ServoTimer2.h>
#include <RH_ASK.h>
#include <SPI.h>
// Define the pins used on the Arduino
#define WLAT_PIN 2 // If set to Low "transfer and use"
#define SHDN_PIN 3 // Set high to enable the resistor network
#define CS_PIN 53 // Set to low to select chip for SPI
#define OLED_RESET 4
MCP41HVX1 Digipot( CS_PIN, SHDN_PIN, WLAT_PIN);
ServoTimer2 ESC;
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET);
Adafruit_SSD1306 display3(OLED_RESET);
Adafruit_SSD1306 display4(OLED_RESET);
INA226_WE grid = INA226_WE(0x40);
INA226_WE batt = INA226_WE(0x41);
INA226_WE cap = INA226_WE(0x44);
INA226_WE regen = INA226_WE(0x45);
RH_ASK driver;
float grid_V = 0.000;
float grid_I = 0.000;
float grid_P = 0.000;
float batt_V = 0.000;
float batt_I = 0.000;
float batt_P = 0.000;
float cap_V = 0.000;
float cap_I = 0.000;
float cap_P = 0.000;
float regen_V = 0.000;
float regen_I = 0.000;
float regen_P = 0.000;
int x_cursor;
int x_cursor2;
int x_cursor3;
int x_cursor4;
int x_cursor5;
int x_cursor6;
int x_cursor7;
int x_cursor8;
int p = 0;
int c = 0;
int start = 200;
int start2 = 50;
float pt = 0;
int B;
int B2;
int B3 ;
int B4 ;
int SW ;
int powerValues[] = {0, 2, 5, 7, 10, 13, 15, 18, 20, 23, 25, 28, 31, 33, 36, 38, 41, 44, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 7, 10, 13, 15, 18, 20, 23, 25, 28, 31, 33, 36, 38, 41, 44, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 10, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 42, 44, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float previousTime = 0;
int val = 0;
int PWMvalue = 0;
float charge_V = 0.000;
void TCA9548A(uint8_t bus)
{
Wire.beginTransmission(0x70); // TCA9548A address is 0x70
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
}
void setup() {
Serial.begin(9600);
if (!driver.init())
Serial.println("init failed");
pinMode(13,OUTPUT);
pinMode(7,OUTPUT);
pinMode(4,OUTPUT);
pinMode(29,OUTPUT);
pinMode(31,OUTPUT);
pinMode(33,OUTPUT);
pinMode(35,OUTPUT);
pinMode(37,OUTPUT);
pinMode(28,OUTPUT);
pinMode(30,OUTPUT);
pinMode(32,OUTPUT);
pinMode(34,OUTPUT);
pinMode(39,INPUT);
pinMode(A3,INPUT);
pinMode(41,INPUT);
pinMode(43,INPUT);
pinMode(45,INPUT);
pinMode(47,INPUT);
pinMode(25,OUTPUT);
pinMode(27,OUTPUT);
pinMode(5,OUTPUT);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
analogWrite(7,0);
analogWrite(4,0);
analogWrite(13,0);
Wire.begin();
Digipot.WiperSetPosition(0);
TCA9548A(0);
display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
TCA9548A(1);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C);
TCA9548A(2);
display3.begin(SSD1306_SWITCHCAPVCC, 0x3C);
TCA9548A(3);
display4.begin(SSD1306_SWITCHCAPVCC, 0x3C);
TCA9548A(0);
display1.clearDisplay();
TCA9548A(1);
display2.clearDisplay();
TCA9548A(2);
display3.clearDisplay();
TCA9548A(3);
display4.clearDisplay();
digitalWrite(29,LOW);
digitalWrite(31,LOW);
digitalWrite(33,LOW);
digitalWrite(35,LOW);
digitalWrite(37,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
grid.init();
batt.init();
cap.init();
regen.init();
grid.setResistorRange(0.005,10.0);
batt.setResistorRange(0.005,10.0);
cap.setResistorRange(0.005,10.0);
regen.setResistorRange(0.005,10.0);
grid.setConversionTime(INA226_CONV_TIME_140);
batt.setConversionTime(INA226_CONV_TIME_140);
cap.setConversionTime(INA226_CONV_TIME_140);
regen.setConversionTime(INA226_CONV_TIME_140);
grid.setAverage(INA226_AVERAGE_256);
batt.setAverage(INA226_AVERAGE_256);
cap.setAverage(INA226_AVERAGE_256);
regen.setAverage(INA226_AVERAGE_256);
batt.setMeasureMode(INA226_CONTINUOUS);
ESC.attach(6);
ESC.write(0);
}
void loop() {
digitalWrite(31,LOW);
digitalWrite(33,LOW);
Digipot.WiperSetPosition(127);
//const char *msg = "1";
//driver.send((uint8_t *)msg, strlen(msg));
//driver.waitPacketSent();
while(cap_P > 0.1 || batt_P > 0.1){
digitalWrite(29,LOW);
display_Results();
}
if(grid_V > 12){
digitalWrite(29,HIGH);
}
else{
digitalWrite(29,LOW);
}
digitalWrite(28,LOW);
digitalWrite(30,LOW);
digitalWrite(32,LOW);
digitalWrite(34,LOW);
B = digitalRead(39);
B2 = digitalRead(41);
B3 = digitalRead(43);
B4 = digitalRead(45);
SW = digitalRead(47);
ESC.write(1000);
display_Results();
simulate(grid_V);
analogWrite(4,196);
if(regen_P > 0.1){
digitalWrite(35,LOW);
}
else {
digitalWrite(35,HIGH);
}
charge(grid_V);
analogWrite(5,p);
analogWrite(8,c);
Serial.print("p =");
Serial.println(p);
Serial.print("c =");
Serial.println(c);
Serial.println(batt_I);
if(B == 1){
if(SW == 1){
accelerateNEW();
}
else {
accelerateOLD();
}
}
if(B2 == 1){
if(SW == 1){
stopNEW();
}
else{
stopOLD();
}
}
if(B3 == 1){
if(SW == 1){
gridspikeNEW();
}
else {
gridspikeOLD();
}
}
if(B4 == 1){
if(SW == 1){
gridoutageNEW();
}
else {
gridoutageOLD();
}
}
}
void display_Results(){
grid.setCorrectionFactor(1);
batt.setCorrectionFactor(1);
cap.setCorrectionFactor(1);
regen.setCorrectionFactor(1);
grid.readAndClearFlags();
batt.readAndClearFlags();
cap.readAndClearFlags();
regen.readAndClearFlags();
grid_V = grid.getBusVoltage_V();
grid_I = grid.getCurrent_mA()/1000;
grid_P = grid_V*grid_I;
batt_V = batt.getBusVoltage_V();
batt_I = batt.getCurrent_mA()/1000;
batt_P = batt_V*batt_I;
cap_V = cap.getBusVoltage_V();
cap_I = cap.getCurrent_mA()/1000;
cap_P = cap_V*cap_I;
regen_V = regen.getBusVoltage_V();
regen_I = regen.getCurrent_mA()/1000;
regen_P = regen_V*regen_I;
if (grid_V >= 10){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor = 11; // them passes 10 as this would make the display look even
}
else {
x_cursor = 25;
}
if (grid_P >= 10 || grid_P < 0 ){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor2 = 11; // them passes 10 as this would make the display look even
}
else if (grid_P >= 10 && grid_P < 0 ){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor2 = 0; // them passes 10 as this would make the display look even
}
else {
x_cursor2 = 25;
}
if (batt_V >= 10){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor3 = 11; // them passes 10 as this would make the display look even
}
else {
x_cursor3 = 25;
}
if (batt_P >= 10 || batt_P < 0 ){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor4 = 11; // them passes 10 as this would make the display look even
}
else if (batt_P >= 10 && batt_P < 0 ){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor4 = 0; // them passes 10 as this would make the display look even
}
else {
x_cursor4 = 25;
}
if (cap_V >= 10 ){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor5 = 11; // them passes 10 as this would make the display look even
}
else {
x_cursor5 = 25;
}
if (cap_P >= 10 || cap_P < 0){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor6 = 11; // them passes 10 as this would make the display look even
}
else if (cap_P >= 10 && cap_P < 0){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor6 = 0; // them passes 10 as this would make the display look even
}
else {
x_cursor6 = 25;
}
if (regen_V >= 10){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor7 = 11; // them passes 10 as this would make the display look even
}
else {
x_cursor7 = 25;
}
if (regen_P >= 10 || regen_P < 0){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor8 = 11; // them passes 10 as this would make the display look even
}
else if (regen_P >= 10 && regen_P < 0){ //these if else statments are to align the cursors for the voltage and current if one of
x_cursor8 = 0; // them passes 10 as this would make the display look even
}
else {
x_cursor8 = 25;
}
TCA9548A(0);
display1.clearDisplay();
display1.setTextColor(WHITE);
display1.setFont(&FreeMono12pt7b);
display1.setTextSize(1);
display1.setCursor(x_cursor,14); // sets where the display starts writing
display1.print(grid_V,3); // prints and sets loadvoltage to be measured to the third decimal
display1.setCursor(110,14);
display1.print("V ");
display1.setCursor(x_cursor2,31);
display1.print(grid_P,3);
display1.setCursor(110,31);
display1.print("W ");
display1.display();
TCA9548A(1);
display2.clearDisplay();
display2.setTextColor(WHITE);
display2.setFont(&FreeMono12pt7b);
display2.setTextSize(1);
display2.setCursor(x_cursor7,14); // sets where the display starts writing
display2.print(regen_V,3); // prints and sets loadvoltage to be measured to the third decimal
display2.setCursor(110,14);
display2.print("V ");
display2.setCursor(x_cursor8,31);
display2.print(regen_P,3);
display2.setCursor(110,31);
display2.print("W ");
display2.display();
TCA9548A(2);
display3.clearDisplay();
display3.setTextColor(WHITE);
display3.setFont(&FreeMono12pt7b);
display3.setTextSize(1);
display3.setCursor(x_cursor3,14); // sets where the display starts writing
display3.print(batt_V,3); // prints and sets loadvoltage to be measured to the third decimal
display3.setCursor(110,14);
display3.print("V ");
display3.setCursor(x_cursor4,31);
display3.print(batt_P,3);
display3.setCursor(110,31);
display3.print("W ");
display3.display();
TCA9548A(3);
display4.clearDisplay();
display4.setTextColor(WHITE);
display4.setFont(&FreeMono12pt7b);
display4.setTextSize(1);
display4.setCursor(x_cursor5,14); // sets where the display starts writing
display4.print(cap_V,3); // prints and sets loadvoltage to be measured to the third decimal
display4.setCursor(110,14);
display4.print("V ");
display4.setCursor(x_cursor6,31);
display4.print(cap_P,3);
display4.setCursor(110,31);
display4.print("W ");
display4.display();
}
void simulate(float bus_V){
float currentTime = millis();
if (currentTime - previousTime >= 1000){
Serial.println(powerValues[val]);
val++;
previousTime = currentTime;
}
if(powerValues[val] > 0){
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
if (bus_V > 7.5){
PWMvalue = ((powerValues[val]/bus_V)*0.39)*(255/5);
}
else{
PWMvalue = 0;
}
}
if(powerValues[val] == 0){
PWMvalue = 0;
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
}
if(val == 324){
val = 0;
Serial.println("resetTime");
}
Serial.print("PWM Value = ");
Serial.println(PWMvalue);
analogWrite(13,PWMvalue);
}
void accelerateNEW(){
float timeNow = millis();
while(millis() <= 5000 + timeNow){
digitalWrite(28,HIGH);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(29,LOW);
digitalWrite(33,LOW);
digitalWrite(35,LOW);
digitalWrite(37,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
display_Results();
while(grid_P > 0.1 || -0.1 > batt_P > 0.1 || regen_P > 0.1){
display_Results();
digitalWrite(31,LOW);
digitalWrite(28,HIGH);
}
Serial.println("Accelerate Function Activated");
digitalWrite(31,HIGH);
digitalWrite(28,HIGH);
const char *msg = "2";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
if(cap_V > 9){
int PWMval = ((48/cap_V)*0.39)*(255/5);
analogWrite(13,PWMval);
display_Results();
}
else{
analogWrite(13,0);
display_Results();
}
}
timeNow = millis();
digitalWrite(31,LOW);
analogWrite(13,0);
analogWrite(4,196);
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
analogWrite(5,200);
analogWrite(8,c);
}
void accelerateOLD(){
float timeNow = millis();
while(millis() <= 5000 + timeNow) {
digitalWrite(31,LOW);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(33,LOW);
digitalWrite(35,LOW);
digitalWrite(37,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(28,HIGH);
//analogWrite(4,75);
display_Results();
while(cap_P > 0.1 || batt_P > 0.1 || regen_P > 0.1) {
digitalWrite(29,LOW);
digitalWrite(28,HIGH);
display_Results();
}
digitalWrite(29,HIGH);
digitalWrite(28,HIGH);
const char *msg = "2";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
if(grid_V > 8){
int PWMval = ((48/grid_V)*0.39)*(255/5);
analogWrite(13,PWMval);
display_Results();
}
else{
analogWrite(13,0);
display_Results();
}
float t = millis();
//analogWrite(4,0);
if(t - pt >= 50){
int ledPWM = random(0,196);
analogWrite(4,ledPWM);
pt = t;
}
}
analogWrite(13,0);
digitalWrite(28,LOW);
digitalWrite(29,LOW);
timeNow = millis();
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
analogWrite(4,196);
analogWrite(5,200);
analogWrite(8,c);
}
void stopNEW(){
digitalWrite(30,HIGH);
digitalWrite(35,LOW);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(33,LOW);
digitalWrite(31,LOW);
digitalWrite(29,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(37,LOW);
analogWrite(7,0);
display_Results();
float timeNow = millis();
while(millis() <= 5000 + timeNow){
while(-0.1 > cap_P > 0.1 || -0.1 > batt_P > 0.1 || grid_P > 0.1){
digitalWrite(37,LOW);
digitalWrite(30,HIGH);
display_Results();
}
ESC.write(2000);
digitalWrite(37,HIGH);
digitalWrite(30,HIGH);
display_Results();
if(regen_V > 12 && batt_V < 8 || cap_V < 9){
display_Results();
analogWrite(7,0);
charge(regen_V);
}
else{
digitalWrite(25,LOW);
digitalWrite(27,LOW);
if(cap_P < -0.1 || batt_P < -0.1){
analogWrite(7,0);
display_Results();
}
else{
analogWrite(7,10);
display_Results();
}
}
if(millis() > timeNow + 4400) {
const char *msg = "3";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
}
}
const char *msg = "3";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
digitalWrite(37,LOW);
analogWrite(5,200);
analogWrite(7,0);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(30,LOW);
ESC.write(1000);
timeNow = millis();
analogWrite(8,c);
}
void stopOLD(){
digitalWrite(30,HIGH);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(35,LOW);
digitalWrite(33,LOW);
digitalWrite(31,LOW);
digitalWrite(29,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(37,LOW);
analogWrite(7,0);
display_Results();
float timeNow = millis();
while(millis() <= 5000 + timeNow){
while(-0.1 > cap_P > 0.1 || -0.1 > batt_P > 0.1 || grid_P > 0.1){
ESC.write(1000);
analogWrite(5,0);
analogWrite(7,0);
display_Results();
}
ESC.write(2000);
analogWrite(7,10);
display_Results();
digitalWrite(30,HIGH);
if(millis() > timeNow + 4400) {
const char *msg = "3";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
}
}
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
digitalWrite(37,LOW);
analogWrite(7,0);
digitalWrite(25,LOW);
analogWrite(5,200);
digitalWrite(27,LOW);
digitalWrite(30,LOW);
ESC.write(1000);
timeNow = millis();
analogWrite(8,c);
}
void charge(float charge_V){
display_Results();
int BM = analogRead(A3);
Serial.println(BM);
while (batt_P > 0.1 || cap_P > 0.1){
digitalWrite(25,LOW);
digitalWrite(27,LOW);
display_Results();
}
if(batt_V < 8.21 && charge_V > 11){
digitalWrite(25,HIGH);
}
if(batt_V > 8.29 || charge_V < 11 || BM > 870){
digitalWrite(25,LOW);
}
if(cap_V < 9.9){
digitalWrite(27,HIGH);
}
if(cap_V > 10){
digitalWrite(27,LOW);
}
while(batt_I < -2 || cap_I < -3){
digitalWrite(27,LOW);
digitalWrite(25,LOW);
digitalRead(B1);
digitalWrite(28,HIGH);
digitalWrite(30,HIGH);
digitalWrite(32,HIGH);
digitalWrite(34,HIGH);
if(B1 == 1){
break;
}
}
if(batt_I < -1){
p--;
}
else{
if (-0.1 < batt_I){
p = start;
}
else if (batt_I <= -0.1 && p < 255){
p++;
}
else if (batt_I <= -0.1 && p >= 255){
p = 255;
}
}
if(cap_I < -1){
c--;
}
else{
if (-0.1 < cap_I){
c = start2;
}
else if (cap_I <= -0.1 && c < 255){
c++;
}
else if (cap_I <= -0.1 && c >= 255){
c = 255;
}
}
}
void gridspikeNEW(){
digitalWrite(32,HIGH);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(35,LOW);
digitalWrite(33,LOW);
digitalWrite(31,LOW);
digitalWrite(29,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(37,LOW);
display_Results();
float timeNow = millis();
while(millis() <= 15000 + timeNow){
B3 = digitalRead(43);
if(B3 == 0){
Digipot.WiperSetPosition(127);
digitalWrite(33,LOW);
analogWrite(4,196);
while(batt_P > 0.1){
digitalWrite(29,LOW);
display_Results();
}
if(grid_V > 12){
digitalWrite(29,HIGH);
display_Results();
simulate(grid_V);
B3 = digitalRead(43);
}
else{
digitalWrite(29,LOW);
display_Results();
analogWrite(13,0);
B3 = digitalRead(43);
}
}
else{
digitalWrite(29,LOW);
Digipot.WiperSetPosition(50);
analogWrite(4,0);
while(-0.1 > cap_P > 0.1 || batt_P < -0.1 || grid_P > 0.1){
digitalWrite(33,LOW);
display_Results();
}
digitalWrite(33,HIGH);
Digipot.WiperSetPosition(50);
display_Results();
simulate(batt_V);
B3 = digitalRead(43);
}
}
digitalWrite(33,LOW);
digitalWrite(29,LOW);
Digipot.WiperSetPosition(127);
digitalWrite(32,LOW);
analogWrite(5,200);
analogWrite(13,0);
analogWrite(4,196);
timeNow = millis();
analogWrite(8,c);
}
void gridspikeOLD(){
digitalWrite(32,HIGH);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(35,LOW);
digitalWrite(33,LOW);
digitalWrite(31,LOW);
digitalWrite(29,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(37,LOW);
display_Results();
B3 = digitalRead(43);
float timeNow = millis();
while(millis() <= 10000 + timeNow){
B3 = digitalRead(43);
if(B3 == 0){
Digipot.WiperSetPosition(127);
analogWrite(4,196);
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
while(batt_P > 0.1 || cap_P > 0.1){
digitalWrite(29,LOW);
display_Results();
}
if(grid_V > 12){
digitalWrite(29,HIGH);
display_Results();
simulate(grid_V);
B3 = digitalRead(43);
}
else{
digitalWrite(29,LOW);
display_Results();
analogWrite(13,0);
B3 = digitalRead(43);
}
}
else{
Digipot.WiperSetPosition(50);
digitalWrite(29,LOW);
analogWrite(13,0);
analogWrite(4,0);
Digipot.WiperSetPosition(50);
display_Results();
const char *msg = "3";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
}
}
digitalWrite(32,LOW);
digitalWrite(29,LOW);
Digipot.WiperSetPosition(127);
analogWrite(13,0);
analogWrite(5,200);
analogWrite(4,196);
analogWrite(8,c);
timeNow = millis();
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
}
void gridoutageNEW(){
Digipot.WiperSetPosition(50);
digitalWrite(34,HIGH);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(35,LOW);
digitalWrite(33,LOW);
digitalWrite(31,LOW);
digitalWrite(29,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(37,LOW);
display_Results();
Digipot.WiperSetPosition(50);
float timeNow = millis();
while(millis() <= 10000 + timeNow){
Digipot.WiperSetPosition(50);
while(-0.1 > cap_P > 0.1 || batt_P < -0.1 || grid_P > 0.1){
digitalWrite(33,LOW);
display_Results();
}
digitalWrite(33,HIGH);
analogWrite(4,0);
display_Results();
simulate(batt_V);
}
digitalWrite(33,LOW);
Digipot.WiperSetPosition(127);
digitalWrite(34,LOW);
analogWrite(13,0);
analogWrite(8,c);
analogWrite(5,200);
display_Results();
timeNow = millis();
analogWrite(4,196);
}
void gridoutageOLD(){
digitalWrite(34,HIGH);
analogWrite(5,0);
analogWrite(8,0);
digitalWrite(35,LOW);
digitalWrite(33,LOW);
digitalWrite(31,LOW);
digitalWrite(29,LOW);
digitalWrite(25,LOW);
digitalWrite(27,LOW);
digitalWrite(37,LOW);
display_Results();
Digipot.WiperSetPosition(50);
float timeNow = millis();
while(millis() <= 10000 + timeNow){
Digipot.WiperSetPosition(50);
display_Results();
const char *msg = "3";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
analogWrite(4,0);
}
Digipot.WiperSetPosition(127);
display_Results();
digitalWrite(34,LOW);
analogWrite(5,200);
analogWrite(8,c);
const char *msg = "1";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
analogWrite(4,196);
}