/*****************************************************************************
* ej's o2 oled analyzer - v0.21
* http://ejlabs.net/arduino-oled-nitrox-analyzer
*
* License
* -------
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*****************************************************************************/
#include
#include
#include
#include
#include
#include
#define RA_SIZE 20
RunningAverage RA(RA_SIZE);
Adafruit_ADS1115 ads(0x48);
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
const int buttonPin=2; // push button
const int buzzer = 9; // buzzer
const int ledPin = 13; // led
double calibrationv;
float multiplier;
const int cal_holdTime = 2; // 2 sec button hold to calibration
const int mod_holdTime = 3; // 3 sec hold to po2 mod change
const int max_holdtime = 4; // 4 sec hold to reset max o2 result
long millis_held; // How long the button was held (milliseconds)
long secs_held; // How long the button was held (seconds)
long prev_secs_held; // How long the button was held in the previous check
byte previous = HIGH;
unsigned long firstTime; // how long since the button was first pressed
int active = 0;
double result_max = 0;
/*
Calculate MOD (Maximum Operating Depth)
*/
float max_po1 = 1.30;
const float max_po2 = 1.60;
float cal_mod (float percentage, float ppo2 = 1.4) {
return 10 * ( (ppo2/(percentage/100)) - 1 );
}
void beep(int x=1) { // make beep for x time
//digitalWrite(ledPin, HIGH); // led blink disable for battery save
for(int i=0; i> 0) & 0xFF);
byte highByte = ((p_value >> 8) & 0xFF);
EEPROM.write(p_address, lowByte);
EEPROM.write(p_address + 1, highByte);
}
unsigned int EEPROMReadInt(int p_address)
{
byte lowByte = EEPROM.read(p_address);
byte highByte = EEPROM.read(p_address + 1);
return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}
int calibrate(int x) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setCursor(0,0);
display.setTextSize(2);
display.print(F("Calibrate"));
display.display();
//RA.clear();
double result;
for(int cx=0; cx<= RA_SIZE; cx++) {
read_sensor(0);
}
result = RA.getAverage();
result = abs(result);
EEPROMWriteInt(x, result); // write to eeprom
beep(1);
delay(1000);
active = 0;
return result;
}
void analysing(int x, int cal) {
double currentmv=0;
double result;
double mv = 0.0;
read_sensor(0);
currentmv = RA.getAverage();
currentmv = abs(currentmv);
result = (currentmv / cal) * 20.9;
if (result > 99.9) result = 99.9;
mv = currentmv * multiplier;
display.clearDisplay();
display.setTextColor(WHITE);
display.setCursor(0,0);
if (mv < 0.02 || result <= 0) {
display.setTextSize(2);
display.println(F("Sensor"));
display.print(F("Error!"));
} else {
display.setTextSize(4);
display.print(result,1);
display.println(F("%"));
if (result >= result_max) {
result_max = result;
}
display.setTextSize(1);
display.setCursor(0,31);
display.setTextColor(BLACK, WHITE);
display.print(F("Max "));
display.print(result_max,1);
display.print(F("% "));
//display.setCursor(75,31);
display.print(mv,2);
display.print(F("mv"));
if (active % 4) {
display.setCursor(115,29);
display.setTextColor(WHITE);
display.print(F("."));
}
display.setTextColor(WHITE);
display.setCursor(0,40);
display.print(F("pO2 "));
display.print(max_po1,1);
display.print(F("/"));
display.print(max_po2,1);
display.print(F(" MOD"));
display.setTextSize(2);
display.setCursor(0,50);
display.print(cal_mod(result,max_po1),1);
display.print(F("/"));
display.print(cal_mod(result,max_po2),1);
display.print(F("m "));
// menu
if (secs_held < 5 && active > 16) {
display.setTextSize(2);
display.setCursor(0,31);
display.setTextColor(BLACK, WHITE);
if (secs_held >= cal_holdTime && secs_held < mod_holdTime) {
display.print(F(" CAL "));
}
if (secs_held >= mod_holdTime && secs_held < max_holdtime) {
display.print(F(" PO2 "));
}
if (secs_held >= max_holdtime && secs_held < 10) {
display.print(F(" MAX "));
}
}
}
display.display();
}
void lock_screen(long pause = 5000) {
beep(1);
display.setTextSize(1);
display.setCursor(0,31);
display.setTextColor(0xFFFF, 0);
display.print(F(" "));
display.setTextColor(BLACK, WHITE);
display.setCursor(0,31);
display.print(F("======= LOCK ======="));
display.display();
for (int i = 0; i < pause; ++i) {
while (digitalRead(buttonPin) == HIGH) {
}
}
active = 0;
}
void po2_change() {
if (max_po1 == 1.3) max_po1 = 1.4;
else if (max_po1 == 1.4) max_po1 = 1.5;
else if (max_po1 == 1.5) max_po1 = 1.3;
display.clearDisplay();
display.setTextColor(WHITE);
display.setCursor(0,0);
display.setTextSize(2);
display.println(F("pO2 set"));
display.print(max_po1);
display.display();
beep(1);
delay(1000);
active = 0;
}
void max_clear() {
result_max = 0;
display.clearDisplay();
display.setTextColor(WHITE);
display.setCursor(0,0);
display.setTextSize(2);
display.println(F("Max result"));
display.print(F("cleared"));
display.display();
beep(1);
delay(1000);
active = 0;
}
void loop(void) {
int current = digitalRead(buttonPin);
if (current == LOW && previous == HIGH && (millis() - firstTime) > 200) {
firstTime = millis();
active = 17;
}
millis_held = (millis() - firstTime);
secs_held = millis_held / 1000;
if (millis_held > 2) {
if (current == HIGH && previous == LOW) {
if (secs_held <= 0) {
lock_screen();
}
if (secs_held >= cal_holdTime && secs_held < mod_holdTime) {
calibrationv = calibrate(0);
}
if (secs_held >= mod_holdTime && secs_held < max_holdtime) {
po2_change();
}
if (secs_held >= max_holdtime && secs_held < 10) {
max_clear();
}
}
}
previous = current;
prev_secs_held = secs_held;
analysing(0,calibrationv);
delay(200);
active++;
}