#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
enum { bufferSize = 6 };
static unsigned char buffer[bufferSize] = { '\0' };
static int serialDataReceived = 0;
const int CYAN_LED_PIN = 3;
const int BD_LED_PIN = 4; /* ORANGE LED */
const int GREEN_LED_PIN = 5;
const int Temp_LED_PIN = 6; /* YELLOW LED */
const int Puls_LED_PIN = 7; /* RED LED */
const int buzzer = 9;
const int POT_PULSE = A0;
const int POT_BLOOD = A1;
const int POT_TEMP = A2;
static const int PULS_MIN = 40;
static const int PULS_MAX = 150;
static const int BLOOD_PRESURE_MIN = 80;
static const int BLOOD_PRESURE_MAX = 160;
static const int TEMPERATURE_MIN = 35;
static const int TEMPERATURE_MAX = 42;
static const int PULS_MIN_ALLOWED = 60;
static const int PULS_MAX_ALLOWED = 85;
static const int BLOOD_PRESURE_MIN_ALLOWED = 100;
static const int BLOOD_PRESURE_MAX_ALLOWED = 140;
static const int TEMPERATURE_MIN_ALLOWED = 36;
static const int TEMPERATURE_MAX_ALLOWED = 39;
static int StopAlarm = 0;
static double Puls = 0;
static double BloodP = 0;
static double Temp = 0;
const int INTERRUPT_PIN = 2;
/* muss auf pin 2 oder 3 sein sonst geht nicht*/
static volatile int pinFromLowToHighEvent = 0;
void isrForInterruptPin();
typedef struct {
double puls;
double bloodPressure;
double temperature;
} VitalValue;
/*creatin VitalV variable*/
VitalValue VitalV;
void readVitalValues(VitalValue* VitalV);
typedef enum { C1 = 1, C2 = (1 << 1), C3 = (1 << 2) } Condition;
typedef enum {
R1 = 0,
R2 = C1, /* C1 = Puls OK */
R3 = C2, /* C2 = BD OK */
R4 = C1 | C2,
R5 = C3, /* C3 = Temp OK */
R6 = C1 | C3,
R7 = C2 | C3,
R8 = C1 | C2 | C3,
IMPOSSIBLE
} Rule;
Rule getRule(const VitalValue* );
void setup() {
Serial.begin(9600);
pinMode(CYAN_LED_PIN, OUTPUT);
pinMode(BD_LED_PIN, OUTPUT);
pinMode(Puls_LED_PIN, OUTPUT);
pinMode(Temp_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(POT_PULSE, INPUT);
pinMode(POT_BLOOD, INPUT);
pinMode(POT_TEMP, INPUT);
digitalWrite(GREEN_LED_PIN, HIGH);
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN),isrPushButton, RISING);
/* ISR = Interrupt Service Routine; RISING = to trigger when the pin goes from low to high*/
Serial.println("Das Program hat gestartet. \n");
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("Puls: " );
lcd.setCursor(1,1);
lcd.print("Blutdruck:");
lcd.setCursor(1,2);
lcd.print("Temperatur:");
}
void loop() {
/* setup, we start with everything OK for first loop */
static Rule OldRule = R8;
static int PreviousLEDs[4] = {GREEN_LED_PIN, '\0', '\0', '\0'};
static int CurrentLEDs[4];
Rule rule = getRule(&VitalV);
readVitalValues(&VitalV);
/* printing the values on the LCD screen */
Puls = VitalV.puls;
lcd.setCursor(13, 0);
lcd.print(Puls);
BloodP = VitalV.bloodPressure;
lcd.setCursor(13, 1);
lcd.print(BloodP);
Temp = VitalV.temperature;
lcd.setCursor(13, 2);
lcd.print(Temp);
if (OldRule != rule){
noTone(buzzer);
switch (rule) {
case R1:
cleanLastLineLCD();
digitalWrite(BD_LED_PIN , HIGH);
digitalWrite(Puls_LED_PIN , HIGH);
digitalWrite(Temp_LED_PIN , HIGH);
tone(buzzer,400);
CurrentLEDs[0] = CYAN_LED_PIN;
CurrentLEDs[1] = BD_LED_PIN;
CurrentLEDs[2] = Puls_LED_PIN;
CurrentLEDs[3] = Temp_LED_PIN;
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("Alles im roten.");
break;
case R2:
cleanLastLineLCD();
digitalWrite(BD_LED_PIN , HIGH);
digitalWrite(Temp_LED_PIN , HIGH);
CurrentLEDs[0] = CYAN_LED_PIN;
CurrentLEDs[1] = BD_LED_PIN;
CurrentLEDs[2] = Temp_LED_PIN;
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("BlutD und Temp NOK.");
break;
case R3:
cleanLastLineLCD();
digitalWrite(Puls_LED_PIN , HIGH);
digitalWrite(Temp_LED_PIN , HIGH);
CurrentLEDs[0] = CYAN_LED_PIN;
CurrentLEDs[1] = Puls_LED_PIN;
CurrentLEDs[2] = Temp_LED_PIN;
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("Puls und Temp NOK.");
break;
case R4:
cleanLastLineLCD();
digitalWrite(Temp_LED_PIN , HIGH);
CurrentLEDs[0] = Temp_LED_PIN;
CurrentLEDs[1] = '\0';
CurrentLEDs[2] = '\0';
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("Temperatur NOK.");
break;
case R5:
cleanLastLineLCD();
digitalWrite(BD_LED_PIN , HIGH);
digitalWrite(Puls_LED_PIN , HIGH);
CurrentLEDs[0] = CYAN_LED_PIN;
CurrentLEDs[1] = Puls_LED_PIN;
CurrentLEDs[2] = BD_LED_PIN;
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("BlutD und Puls NOK.");
break;
case R6:
cleanLastLineLCD();
digitalWrite(BD_LED_PIN , HIGH);
CurrentLEDs[0] = BD_LED_PIN;
CurrentLEDs[1] = '\0';
CurrentLEDs[2] = '\0';
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("Blutdruck NOK.");
break;
case R7:
cleanLastLineLCD();
digitalWrite(Puls_LED_PIN , HIGH);
CurrentLEDs[0] = Puls_LED_PIN;
CurrentLEDs[1] = '\0';
CurrentLEDs[2] = '\0';
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("Puls NOK.");
break;
case R8:
cleanLastLineLCD();
digitalWrite(GREEN_LED_PIN , HIGH);
CurrentLEDs[0] = GREEN_LED_PIN;
CurrentLEDs[1] = '\0';
CurrentLEDs[2] = '\0';
CurrentLEDs[3] = '\0';
TurnOffOldLEDs(CurrentLEDs,PreviousLEDs);
lcd.setCursor(1, 3);
lcd.print("Alles in Ordnung.");
break;
}
}
/* if two or more problems = blink cyan LED */
if (rule == R1 || rule == R2 ||rule == R3 ||rule == R5){
blink(CYAN_LED_PIN);
}
// hardware interrupt
if (pinFromLowToHighEvent == 1) {
noTone(buzzer);
pinFromLowToHighEvent = 0;
}
/* serielle Schnittstelle, recognizing the stop message */
enum { messageSize = 128 };
static char message[messageSize] = { '\0' };
if (serialDataReceived) {
sprintf(message, "%s\n", buffer);
Serial.write(message);
serialDataReceived = 0;
if (strcmp(buffer, "stop") == 0){
noTone(buzzer);
}
}
/* the new becomes the old for the next loop */
OldRule = rule;
for (int j = 0; j <= 3; j++) {
PreviousLEDs[j] = CurrentLEDs[j];
}
}
/* change Potentiometer values to physical values*/
double PotValueToRealValue (int RealMinValue, int RealMaxValue, int PotValue) {
double RealValue = (PotValue / 1023.0 ) * (RealMaxValue - RealMinValue) + RealMinValue;
return RealValue;
}
/* getting the vitalvilues and storing them */
void readVitalValues(VitalValue* VitalV) {
static int currentPuls = 0;
static int currentBlood = 0;
static int currentTemp = 0;
/* mit vitalvalue arbeiten wo alle drei variablen drin gespeichert sind macht strukturierter */
currentPuls = analogRead(POT_PULSE);
currentBlood = analogRead(POT_BLOOD);
currentTemp = analogRead(POT_TEMP);
VitalV->puls = PotValueToRealValue (PULS_MIN, PULS_MAX, currentPuls);
VitalV->bloodPressure= PotValueToRealValue (BLOOD_PRESURE_MIN, BLOOD_PRESURE_MAX, currentBlood);
VitalV->temperature = PotValueToRealValue (TEMPERATURE_MIN, TEMPERATURE_MAX, currentTemp);
}
void blink(int pin) {
static const int BLINK_DURATION_MS = 250;
digitalWrite(pin, HIGH);
delay(BLINK_DURATION_MS);
digitalWrite(pin, LOW);
delay(BLINK_DURATION_MS);
}
/* Hardware interrupt */
void isrPushButton() {
pinFromLowToHighEvent = 1;
static const int BOUNCE_DURATION_MS = 250;
static unsigned long lastPushButtonPressedTime = 0;
unsigned long now = millis();
if (now - lastPushButtonPressedTime > BOUNCE_DURATION_MS) {
pinFromLowToHighEvent = 1;
lastPushButtonPressedTime = now;
}
}
void TurnOffOldLEDs(int ArrayNew[4],int ArrayOld[4]) {
for (int i = 0; i <= 3; i++) {
int k = ArrayOld[i];
for (int j = 0; j <= 3; j++) {
int m = ArrayNew[j];
if (k == m) {
ArrayOld[i] = '\0';
}
}
if(ArrayOld[i] != '\0' ) {
digitalWrite(ArrayOld[i],LOW);
}
}
}
/* Bitmanipulation to get the Rule */
Rule getRule(const VitalValue* vv) {
if (vv == 0) { return IMPOSSIBLE; }
int c1 = ((PULS_MIN_ALLOWED <= vv->puls) && (vv->puls <= PULS_MAX_ALLOWED));
int c2 = ((BLOOD_PRESURE_MIN_ALLOWED <= vv->bloodPressure)
&& (vv->bloodPressure <= BLOOD_PRESURE_MAX_ALLOWED));
int c3 = ((TEMPERATURE_MIN_ALLOWED <= vv->temperature)
&& (vv->temperature <= TEMPERATURE_MAX_ALLOWED));
return (Rule)( (c1) | (c2 << 1) | (c3 << 2) );
}
void serialEvent() {
int readPosition = 0;
int c = -1;
while ( (c = Serial.read()) != -1 && readPosition < (bufferSize - 1) ) {
buffer[readPosition++] = c;
}
buffer[readPosition] = '\0';
serialDataReceived = 1;
}
void cleanLastLineLCD() {
for (int i = 0; i <= 20; i++) {
lcd.setCursor(i, 3);
lcd.print(" ");
}
}