Hi, I´m new on arduino world. My first project is take info from sensor added to my car. I´m trying to collect info about oil temperature, oil pressure and fuel pressure and print in an lcd. In addition I have added some alarms, that makes the printed numbers blink.
The problem is that, sometimes the screen is full of estrange characters and stop working fine. Then I have to reset the arduino. I have been searching for the cause but this behaviour is always random.
Here is my code, I hope you could help me understand what is going on. By the way I´m using a arduino mega.
Thanks a lot
#include <Ethernet.h>
#include <Arduino.h>
#include <math.h>
#include <LiquidCrystal_I2C.h>
//Crear el objeto lcd dirección 0x3F y 16 columnas x 2 filas
LiquidCrystal_I2C lcd(0x27,20,4); //
int sensorValue;
// These constants won't change. They're used to give names to the pins used:
const int oilPressInPin = A0; // Sensor de Presion de Aceite
const int oilTempInPin = A1; // Sensor de Temperatura de Aceite
const int fuelPressInPin = A2; // Sensor de Presion de Gasolina
//rango presion aceite de 1.4 bar a 7.5 bar
//rango temperatura de 80 a 95 Cº
// rango presion combustible constante 3.5 - 4 bar
float oilPress,oilTemp,fuelPress,oilPressMax=1,oilPressMin=1,fuelPressMax=1,fuelPressMin=1;
int oilTempMax=18,oilTempMin=10;
boolean oilTempAlarm = false,oilPressAlarm = false,fuelPressAlarm = false;
uint32_t resistencia;
#define MaxSensorPresionAceite 10340 // miliBares
#define MaxSensorPresionGasolina 6890 // miliBares
// configurar el valor de la resistencia que va en serie con el termistor NTC en ohms
#define CONFIG_THERMISTOR_RESISTOR 3000
#define PAUSE 500
//#define DEBUG 1
/**
* @brief Obtiene la resistencia del termistor resolviendo el divisor resistivo.
*
* @param adcval Valor medido por el convertidor analógico a digital.
* @return int32_t Resistencia electrica del termistor.
*/
int32_t thermistor_get_resistance(uint16_t adcval)
{
// calculamos la resistencia del NTC a partir del valor del ADC
return (CONFIG_THERMISTOR_RESISTOR * ((1023.0 / adcval) - 1));
}
/**
* @brief Obtiene la temperatura en grados centigrados a partir de la resistencia
* actual del componente.
*
* @param resistance Resistencia actual del termistor.
* @return float Temperatura en grados centigrados.
*/
float thermistor_get_temperature(int32_t resistance)
{
// variable de almacenamiento temporal, evita realizar varias veces el calculo de log
float temp;
// calculamos logaritmo natural, se almacena en variable para varios calculos
temp = log(resistance);
// resolvemos la ecuacion de STEINHART-HART
// http://en.wikipedia.org/wiki/Steinhart–Hart_equation
temp = 1 / (0.0006114743282473224 + (0.0002559996393842654 * temp) + (-2.2622413719689033e-8 * temp * temp * temp));
// convertir el resultado de kelvin a centigrados y retornar
return temp - 273.15;
}
/**
* clear txt function
*/
void Clear(int type, int col, int row){
if (type == 0){
lcd.setCursor(col, row);
lcd.print(" ");
}else if (type == 1){
lcd.setCursor(col, row);
lcd.print(" ");
}else if (type == 2){
lcd.setCursor(col, row);
lcd.print(" ");
}
}
/**
* blink txt function
*/
void FlashMessage(int value, int type, int col, int row, int repeat)
{
char temp[] = ""; // Enough spaces to fill one display line
lcd.setCursor(col, row);
if (type == 0){
lcd.print("OL");lcd.print((char) 223);lcd.print(":");lcd.print(value);
for (int i = 0; i < repeat; i++) {
lcd.setCursor(col, row);
lcd.print(" ");
delay(PAUSE);
lcd.setCursor(col, row);
lcd.print("OL");lcd.print((char) 223);lcd.print(":");lcd.print(value);
delay(PAUSE);
}
}else if (type == 1){
lcd.print("OLp");lcd.print(":");lcd.print(value);
for (int i = 0; i < repeat; i++) {
lcd.setCursor(col, row);
lcd.print(" ");
delay(PAUSE);
lcd.setCursor(col, row);
lcd.print("OILp");lcd.print(":");lcd.print(value);
delay(PAUSE);
}
}else if (type == 2){
lcd.print("GAS");lcd.print(":");lcd.print(value);
for (int i = 0; i < repeat; i++) {
lcd.setCursor(col, row);
lcd.print(" ");
delay(PAUSE);
lcd.setCursor(col, row);
lcd.print("GAS");lcd.print(":");lcd.print(value);
delay(PAUSE);
}
}
}
void setup() {
#ifdef DEBUG
Serial.begin(9600);
#endif
// Inicializar el LCD
lcd.init();
//Encender la luz de fondo.
lcd.backlight();
// Escribimos el Mensaje en el LCD.
lcd.print("Mazda Rx8 Sensor Map");
delay(2000);
lcd.clear();
}
void loop() {
// Leemos sensor de Presion de Aceite
sensorValue = analogRead(oilPressInPin);
// Calculamos la Presion de Aceite
oilPress = map(sensorValue, 0, 1023, 0, MaxSensorPresionAceite);
//oilPress = (sensorValue*MaxSensorPresionAceite)/1023;
// change the analog out value:
oilPress=oilPress/1000; //mbar ->bar
if (oilPressMax < oilPress) {oilPressMax = oilPress;}//max oil press
if (oilPressMin > oilPress) {oilPressMin = oilPress;}//max oil press
if (oilPress >= 5.60 || oilPress <= 2.50) { //alarm
oilPressAlarm = true;
}else{
oilPressAlarm = false;
}
#ifdef DEBUG
Serial.println("oilPressAlarm: ");
Serial.println(oilPressAlarm);
Serial.println(oilPress);
#endif
// Leemos sensor de Presion de Gasolina
sensorValue = analogRead(fuelPressInPin);
// Calculamos la Presion de Aceite
fuelPress = map(sensorValue, 0, 1023, 0, MaxSensorPresionGasolina);
//fuelPress = (sensorValue*MaxSensorPresionGasolina)/1023;
// change the analog out value:
fuelPress=fuelPress/1000; //mbar ->bar
if (fuelPressMax < fuelPress) {fuelPressMax = fuelPress;}//max fuel press
if (fuelPressMin > fuelPress) {fuelPressMin = fuelPress;}//max fuel press
if (fuelPress > 4.60 || fuelPress <= 3.40 ) { //alarm
fuelPressAlarm = true;
}else{
fuelPressAlarm = false;
}
#ifdef DEBUG
Serial.println("fuelPressAlarm: ");
Serial.println(fuelPressAlarm);
Serial.println(fuelPress);
#endif
// Leemos sensor de temperatura de aceite
// calcular la resistencia electrica del termistor usando la lectura del ADC
resistencia = thermistor_get_resistance(analogRead(oilTempInPin));
// luego calcular la temperatura segun dicha resistencia
oilTemp = thermistor_get_temperature(resistencia);
if (oilTempMax < oilTemp) {oilTempMax = round(oilTemp);}//max oil temp
if (oilTempMin > oilTemp) {oilTempMin = round(oilTemp);}//max oil temp
if (oilTemp >= 101 || oilTemp < 10 ) { //alarm
oilTempAlarm = true;
}else{
oilTempAlarm = false;
}
#ifdef DEBUG
Serial.println("oilTempAlarm: ");
Serial.println(oilTempAlarm);
Serial.println(oilTemp);
#endif
//mostramos las lecturas en pantalla
lcd.setCursor(0, 0);
lcd.print("OIL");lcd.print((char) 223);lcd.print(":");
lcd.print((float)oilTemp,1);
//lcd.print(oilTemp);
lcd.print(" M:");
lcd.print(oilTempMax);
lcd.print(" m:");
lcd.print(oilTempMin);
lcd.setCursor(0, 1);
lcd.print("OILp");lcd.print(":");
lcd.print((float)oilPress,1);
lcd.print(" M:");
lcd.print((float)oilPressMax,1);
lcd.print(" m:");
lcd.print((float)oilPressMin,1);
lcd.setCursor(0, 2);
lcd.print("GAS");lcd.print(":");
lcd.print(fuelPress);
lcd.print(" M:");
lcd.print((float)fuelPressMax,1);
lcd.print(" m:");
lcd.print((float)fuelPressMin,1);
if (oilTempAlarm){
FlashMessage(round(oilTemp), 0, 0, 3, 5);
#ifdef DEBUG
Serial.println("Entra en pintar alarma oil temp");
#endif
}else{
Clear(0, 0, 3);
#ifdef DEBUG
Serial.println("Elimina alarma oil");
#endif
}
if (oilPressAlarm){
FlashMessage(round(oilPress), 1, 8, 3, 5);
#ifdef DEBUG
Serial.println("Entra en pintar alarma oil press");
#endif
}else{
Clear(1, 8, 3);
#ifdef DEBUG
Serial.println("Elimina alarma oil press");
#endif
}
if (fuelPressAlarm){
FlashMessage(round(fuelPress), 2, 15, 3, 5);
#ifdef DEBUG
Serial.println("Entra en pintar alarma fuel");
#endif
}else{
Clear(2, 15, 3);
#ifdef DEBUG
Serial.println("Elimina alarma fuel");
#endif
}
// wait 2 milliseconds before the next loop for the analog-to-digital
// converter to settle after the last reading:
delay(7500);
//delay(1000);
}