-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStatusmonitor.ino
195 lines (177 loc) · 5.69 KB
/
Statusmonitor.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <Adafruit_MCP9808.h>
#include <SimpleTimer.h>
#include <wire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
//Digital pin layout:
int resetswitch_pin = 3;
int go_to_surface_pin = 13; //Must be set to a reasonable and available digital pin
//Analog pin layout:
int shunt_pin = 0; //This is the pin where you read the voltage input from the shunt resistor. Must be a analog input.
int humidity_front_pin = 1;
int humidity_back_pin = 2;
int voltage_pin = 3; //This is the pin where you read the voltage input from voltage divider, from the battery v++. 42 V(max) = 5 V
//I2C bus: Pin 4 is SDA
//I2C bus: Pin 5 is SCL
int cell_voltage_pin = 6; //Reads the value of each batterycell througt a decoder.
SimpleTimer timer;
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();
volatile double cell_voltage_alarm = 3.1;
volatile int alarm_temperature = 50; // This should be a safe temperature for the batteries to operate under
volatile int initial_watt_hours = 530; // Total capasity of batteries.
volatile int minimum_battery = 25; // Should represent a 5% value of the batteries becoming empty
volatile int humidity_alarm_value = 1; // Needs to be updated to sensible value
volatile double ampere_calibration_constant = 1; // This is the constant for calculating the amp draw from the voltage across a shunt resistor
double voltage = 0;
double battery_temp;
double dt;
double watt_minutes_left; //bør settes til double
double humidity_front = 0;
double humidity_back = 0;
boolean temp_alarm_trigged = 0;
boolean humidity_alarm_trigged = 0;
boolean battery_low_triggered = 0;
double pastMillis = 0;
double lowest_cell_voltage = 3.7;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void setup()
{
//Connect I2C pins to A4 (SDA)and A5 (SCL).
pinMode(humidity_front_pin, INPUT);
pinMode(humidity_back_pin, INPUT);
pinMode(resetswitch_pin, INPUT);
pinMode(cell_voltage_pin, INPUT);
pinMode(go_to_surface_pin, OUTPUT);
digitalWrite(go_to_surface_pin, HIGH);
timer.setInterval(3000, save_to_eeprom); //Must be set to 30000!
timer.setInterval(200, update_display); //Must be set to 30000!
digitalWrite(go_to_surface_pin, HIGH); //May be convertet into serial data..
Serial.begin(9600); //Opens serial port, sets data rate to 9600 bps
read_from_eeprom(); //Loading previous variable batery capasity.
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" UiS Subsea ");
if (!tempsensor.begin())
{
Serial.println("Couldn't find MCP9808!");
lcd.setCursor(0, 1);
lcd.print("Couldn't find MCP9808!");
delay(1500);
}
else
{
Serial.println("MCP9808 connected");
lcd.setCursor(0, 1);
lcd.print("MCP9808 connected");
delay(1500);
}
lcd.setCursor(0, 1);
lcd.print("Initial setup ok");
Serial.println("Initial setup ok");
delay(2500);
}
void loop()
{
timer.run();
update_watt_minutes_left();
check_battery_cells();
check_temp();
check_humidity();
check_switches();
}
void update_display()
{
//Must make methode for rolling text, and implement folliowing variables: Volt, Highest temp, Battery %, Ampere, Minimum cell voltage
lcd.setCursor(0, 0); //Start at character 0 on line 0
lcd.print("Temp:");
lcd.setCursor(9, 0);
lcd.print("Battery:");
lcd.setCursor(0, 1); //Start at character 0 on line 0
lcd.print(tempsensor.readTempC());
lcd.setCursor(9, 1);
int percent = (int)(watt_minutes_left / 3600) / initial_watt_hours * 100; //Must be tested.
lcd.print(percent + "%");
}
void check_battery_cells()
{
for (int i = 0; i < 5; i++)
{
//dekoder/mux position = i;
if (lowest_cell_voltage > analogRead(cell_voltage_pin)/1024*5)
{
lowest_cell_voltage = analogRead(cell_voltage_pin)/1024*5;
}
}
}
void check_switches()
{
if (digitalRead(resetswitch_pin))
{
watt_minutes_left = (float)initial_watt_hours*3600;
}
if (humidity_alarm_trigged && temp_alarm_trigged && battery_low_triggered && (lowest_cell_voltage < cell_voltage_alarm))
{
digitalWrite(go_to_surface_pin, LOW);
//Alternative, send variables and alarm via bus/ip,
}
}
void check_humidity()
{
humidity_front = analogRead(humidity_front_pin);
humidity_back = analogRead(humidity_back_pin);
if (humidity_front > humidity_alarm_value)
{
humidity_alarm_trigged = 1;
}
else if (humidity_back > humidity_alarm_value)
{
humidity_alarm_trigged = 1;
}
}
void update_watt_minutes_left()
{
voltage = analogRead(voltage_pin);
dt = millis()-pastMillis; //Calculates timestamp for integration
pastMillis = millis(); //Reset counter value
double ampere = analogRead(shunt_pin)*ampere_calibration_constant / (1024 * 5);
double watt = ampere * voltage;
watt_minutes_left = watt_minutes_left - (watt*dt/(1000));
if (watt_minutes_left < minimum_battery)
{
battery_low_triggered = 1;
}
}
void read_from_eeprom()
{
Serial.println("Reading eeprom memory:");
lcd.setCursor(0, 1);
lcd.write("Reading memory:");
int mod = EEPROM.read(0);//Read from eeprom memory
int base = EEPROM.read(1);
int watt_hours_left = base*256+mod;
watt_minutes_left = (double)watt_hours_left*3600;
delay(1000);
Serial.println(watt_hours_left);
lcd.setCursor(0, 1);
lcd.write("WattHours: " + watt_hours_left);
}
void save_to_eeprom()
{
Serial.println("Saving to eerpom!:");
int watt_hours_left = watt_minutes_left/3600;
Serial.println(watt_hours_left);
int mod = (int)(watt_hours_left%256);
int base = (int)(watt_hours_left/256);
EEPROM.write(0, mod);//Save to eeprom memory position 0, arduino has total of 512byte eeprom and is rated to 100 000 cycles (May have to be very careful here)
EEPROM.write(1, base);
Serial.println(watt_hours_left);
}
void check_temp()
{
battery_temp = tempsensor.readTempC();
if (battery_temp > alarm_temperature)
{
temp_alarm_trigged = 1;
}
}