Hi All not sure where to put this I ahve browsed the categories and this seemed the best place for it. I have finished (well mostly finished I'm waiting on other parts) the software side of my first project. Everything seems to work as it should on the bench. I was hoping some more experienced users could look at it and tell me how to improve the really naff bits. I'm not that happy with the menu 'system' but it is functional and my initial plan didn;t include a menu!
In short my project controls an Intercooler Sprayer for my car, at high temperature it will spray water on the Intercooler(a radiator) to aid in cooling air going into the engine. I have ordered a pressure(Boost) sensor from China and will be adding that in as another criteria to build the strategy when it arrives.
Only thing I am functionally not happy with is the encoder often clicks multiple intervals. Have tried adding delays and increasing the delay for bouncing but it does not seem to make much difference.
Inputs
Button to enable the sprayer
Temp sensor (IAT Intake Air Temperature)
Level Switch from the water tank (closed is empty)
Encoder
Output
Pump 5v to relay
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
const int tempPin = 0; //temp sensor
const int PinCLK = 2; // Generating interrupts using CLK signal
const int PinDT = 3; // Reading DT signal
const int PinSW = 4; // Reading Push Button switch
const int buttonPin = 5; //on/off button
const int levelPin = 6;//tank level
const int pumpPin = 13;// pump trigger
//eeprom addresses
const int startTempAdd = 0;
const int sprayTimeAdd = 4;
const int delayTimeAdd = 8;
LiquidCrystal_I2C lcd(0x27, 16, 2);
volatile boolean TurnDetected; // need volatile for Interrupts
volatile boolean rotationdirection; // CW or CCW rotation
float tempC;
float startTemp = 25.0; //temp to start spraying
int sprayTime = 2000; //length of spray
int delayTime = 10000; //delay between sprays
//Menu variables
int startTempMenu = 0;
float sprayTimeMenu = 0.0;
float delayTimeMenu = 0.0;
//eeprom variables
int startTempEep = 0;
int sprayTimeEep = 0;
int delayTimeEep = 0;
int menuDelayTime = 20000; // time before droping out of the menu
//flags
boolean sprayFlag = 0;
boolean saveFlag = 0;
boolean emptyTankFlag = 0;
//time counters
unsigned long previousInput = 0; //Last input from encoder
unsigned long previousSpray = 0; //Last Spray
unsigned long previousScreenRefresh = 0; // Last Screen Refresh
unsigned long previousEmptyTank = 0; // Last Time Empty Tank Set
// Interrupt routine runs if CLK goes from HIGH to LOW
void isr () {
delay(4); // delay for Debouncing
if (digitalRead(PinCLK)) {
rotationdirection = digitalRead(PinDT);
} else {
rotationdirection = !digitalRead(PinDT);
}
TurnDetected = true;
previousInput = millis();
}
void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
lcd.backlight();
lcd.clear();
pinMode(buttonPin, INPUT_PULLUP);
pinMode(levelPin, INPUT_PULLUP);
pinMode(pumpPin, OUTPUT);
pinMode(PinCLK, INPUT);
pinMode(PinDT, INPUT);
pinMode(PinSW, INPUT);
digitalWrite(PinSW, HIGH);
attachInterrupt (0, isr, FALLING);
//get values from eeprom check if they are sensible and if so apply them
EEPROM.get(startTempAdd,startTempEep);
EEPROM.get(sprayTimeAdd,sprayTimeEep);
EEPROM.get(delayTimeAdd,delayTimeEep);
if (startTempEep >= 20 && startTempEep <= 90)
{
startTemp = startTempEep;
}
if (sprayTimeEep >= 100 && sprayTimeEep <= 5000)
{
sprayTime = sprayTimeEep;
}
if (delayTimeEep >= 1000 && delayTimeEep <= 99000)
{
delayTime = delayTimeEep;
}
startTempMenu = startTemp;
sprayTimeMenu = sprayTime;
sprayTimeMenu = sprayTimeMenu/ 1000;
delayTimeMenu = delayTime;
delayTimeMenu = delayTimeMenu / 1000;
}
void loop()
{
//enter menu
if (digitalRead(PinSW) == LOW) {
previousInput = millis();
menuMain();
}
//get temp reading
int tempReading = analogRead(tempPin);
tempC = tempCalc(tempReading);
tempPrint();
//checks if the tank is empty
if (digitalRead(levelPin) == LOW) {
emptyTank();
} else {
if (emptyTankFlag && millis() - previousEmptyTank > 20000) {
clearLcdRow(1);
emptyTankFlag = 0;
}
}
//try to spray
sprayStrat();
}
void sprayStrat() {
if (!emptyTankFlag && digitalRead(buttonPin) == LOW && millis() - previousSpray >= delayTime) {
if (tempC > startTemp)
{
digitalWrite(pumpPin, HIGH);
previousSpray = millis();
sprayFlag = 1;
lcd.setCursor(0, 1);
lcd.print("Spraying");
}
}
if (sprayFlag && millis() - previousSpray >= sprayTime) {
digitalWrite(pumpPin, LOW);
clearLcdRow(1);
sprayFlag = 0;
}
}
void emptyTank()
{
digitalWrite(pumpPin, LOW);
lcd.setCursor(0, 1);
lcd.print("Tank Empty");
emptyTankFlag = 1;
previousEmptyTank = millis();
}
//temp sensor interpretation
float tempCalc(int tempReading) {
double tempK = log(10000.0 * ((1024.0 / tempReading - 1)));
tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
float tempC = tempK - 273.15;
return tempC;
}
void clearLcdRow(int row) {
lcd.setCursor(0, row);
lcd.print(" ");
}
void tempPrint() {
if (millis() - previousScreenRefresh >= 500) {
lcd.setCursor(0, 0);
lcd.print("IAT C");
lcd.setCursor(5, 0);
lcd.print(tempC);
previousScreenRefresh = millis();
}
}
//
void menuMain() {
menuTemp();
menuSpray();
menuDelay();
menuSave();
delay(500);
}
void menuTemp() {
lcd.clear();
delay(500);
while (millis() - previousInput < menuDelayTime) {
menuTempPrint();
if (TurnDetected) {
if (rotationdirection) {
if (startTempMenu <= 90)//max value
{
startTempMenu = startTempMenu + 1;
}
}
else {
if (startTempMenu > 10)//minvalue
{
startTempMenu = startTempMenu - 1;
}
}
TurnDetected = false;
delay(100);
}
if (digitalRead(PinSW) == LOW) {
break;
}
}
lcd.clear();
}
void menuTempPrint() {
if (millis() - previousScreenRefresh >= 500) {
lcd.setCursor(0, 0);
lcd.print("Temp Set");
lcd.setCursor(0, 1);
lcd.print(startTempMenu);
lcd.print("C");
previousScreenRefresh = millis();
}
}
void menuSpray() {
lcd.clear();
delay(500);
while (millis() - previousInput < menuDelayTime) {
menuSprayPrint();
if (TurnDetected) {
if (rotationdirection) {
if (sprayTimeMenu <= 5.0)//max value
{
sprayTimeMenu = sprayTimeMenu + 0.1;
}
}
else {
if (sprayTimeMenu > 0.1)//min value
{
sprayTimeMenu = sprayTimeMenu - 0.1;
}
}
TurnDetected = false;
delay(100);
}
if (digitalRead(PinSW) == LOW) {
break;
}
}
lcd.clear();
}
void menuSprayPrint() {
if (millis() - previousScreenRefresh >= 500) {
lcd.setCursor(0, 0);
lcd.print("Spray Set");
lcd.setCursor(0, 1);
lcd.print(sprayTimeMenu);
lcd.print(" Seconds");
previousScreenRefresh = millis();
}
}
void menuDelay() {
lcd.clear();
delay(500);
while (millis() - previousInput < menuDelayTime) {
menuDelayPrint();
if (TurnDetected) {
if (rotationdirection) {
if (delayTimeMenu <= 99)//max value
{
delayTimeMenu = delayTimeMenu + 0.5;
}
}
else {
if (delayTimeMenu > 1)//min value
{
delayTimeMenu = delayTimeMenu - 0.5;
}
}
TurnDetected = false;
delay(100);
}
if (digitalRead(PinSW) == LOW) {
break;
}
}
lcd.clear();
}
void menuDelayPrint() {
if (millis() - previousScreenRefresh >= 500) {
lcd.setCursor(0, 0);
lcd.print("Spray Delay Set");
lcd.setCursor(0, 1);
lcd.print(delayTimeMenu);
lcd.print(" Seconds");
previousScreenRefresh = millis();
}
}
void menuSave() {
lcd.clear();
saveFlag = 0;
delay(500);
while (millis() - previousInput < menuDelayTime) {
Serial.println("callmsp");
menuSavePrint();
if (TurnDetected) {
if (rotationdirection) {
saveFlag = 1;
}
else {
saveFlag = 0;
}
TurnDetected = false;
}
if (digitalRead(PinSW) == LOW) {
if (saveFlag) {
//updates the variables
startTemp = startTempMenu;
sprayTime = sprayTimeMenu * 1000;
delayTime = delayTimeMenu * 1000;
//save info to eeprom all saved as ints for ease (hence why startTempMenu)
EEPROM.put(startTempAdd, startTempMenu);
EEPROM.put(sprayTimeAdd,sprayTime);
EEPROM.put(delayTimeAdd,delayTime);
}
break;
}
}
lcd.clear();
}
void menuSavePrint() {
if (millis() - previousScreenRefresh >= 500) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Save Changes");
lcd.setCursor(0, 1);
if (saveFlag) {
lcd.print(" /Yes");
} else {
lcd.print("No/ ");
}
previousScreenRefresh = millis();
}
}