So I tried the interrupt function and its really good for capturing the press of the button, but since it can't update the menu (cause it takes too long for the interrupt) there will be a lag until the menu reacts. I have now made a small prototype where the mega handles all sensors and the uno handles the lcd and menu. They communicate through serial connection. I put in delays up to 20 sec in the mega and this does not affect the menu update time, i.e the menu changes immediately when I press the button. However it affects the update of the values that are displayed in the menu of course but this is not so critical, I don't need it updated so often. Many things are copied from other people, so thanks for that! Its still work in progress and I will tidy it up down the road, but feel free to suggest improvements.
This is on the display arduino (uno). Pin 2 is the button.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 2,1,0,4,5,6,7,3,POSITIVE);
int i, s, MessageLength, Message0[100], Message1[100], tempChar[1];
byte low, high;
const byte up = 2;
const int menuSize = 4;
bool upLastState = HIGH;
int currentMenu = 1;
float fuel_percent;
char var_menu0[10];
char var_menu1[10];
char var_menu2[10];
char var_menu3[10];
unsigned long DisplayTimer = 0;
unsigned long SerialTimer = 0;
void setup(){
pinMode(up, INPUT_PULLUP);
lcd.begin(16,2);
Serial.begin(115200);
}
void loop(){
if(millis()-SerialTimer<30000){
menuSwitcher();
// How often the display should be updated
if(millis()-DisplayTimer > 1000){
DisplayTimer = millis();
menuDispatch(currentMenu);
}
}else{
lcd.setCursor(0,1);
lcd.print("Lost connection");
}
// Here we wait until all n bytes has arrived
if(Serial.available()>=14){
if(Serial.read() == '
This is on the sensor arduino (mega)
byte counter;
float testFloat = 10.23545466;
char * testChar;
void setup(){
pinMode(3, OUTPUT);
Serial2.begin(115200);
Serial.begin(9600);
}
void loop(){
testChar = float2Ascii(testFloat);
Serial.print(testChar);
delay(20000);
// Make sure that the message is not longer than 100 characters, else we need to change it int the LCD_arduino sketch
Serial2.print("$");
Serial2.print(float2Ascii(random(0,100)));
Serial2.print(",");
Serial2.print(float2Ascii(random(0,100)));
Serial2.print('#');
// this can probably be removed
counter++;
}
char* float2Ascii(double temp)
{
char ascii[32];
int frac;
frac=(unsigned int)(temp*1000)%1000; //get three numbers to the right of the deciaml point
itoa((int)temp,ascii,10);
strcat(ascii,".");
itoa(frac,&ascii[strlen(ascii)],10); //put the frac after the deciaml
return ascii;
}
){
SerialTimer = millis();
int varCounter = 0;
s = 0;
for(i=0; i<100; i++){
delay(1);
tempChar[0] = Serial.read();
// Check if we should enter it in the next variable
if(tempChar[0]==','){
s = 0;
varCounter++;
tempChar[0] = Serial.read();
delay(1);
}
switch(varCounter){
case 0:
Message0[s] = tempChar[0];
var_menu0[s] = char(tempChar[0]);
s++;
break;
case 1:
Message1[s] = tempChar[0];
var_menu1[s] = char(tempChar[0]);
s++;
break;
case 2:
Message1[s] = tempChar[0];
var_menu2[s] = char(tempChar[0]);
s++;
break;
case 3:
Message1[s] = tempChar[0];
var_menu3[s] = char(tempChar[0]);
s++;
break;
}
if(tempChar[0]=='#')
break;
}
}
}
MessageLength = i;
}//loop
void menuSwitcher(){
if (digitalRead(up) != upLastState) {
upLastState = !upLastState;
if (!upLastState){
// Just pressed
if (currentMenu > 0){
currentMenu--;
} else {
// Go around the menu from 0
currentMenu = menuSize - 1;
}
//SerialMon.println("Menu changed");
//SerialMon.println(currentMenu);
lcd.clear();
menuDispatch(currentMenu);
}
}
}
void menuDispatch(int _currentMenu){
switch (_currentMenu) {
case 0:
menu0(atof(var_menu0));
break;
case 1:
menu1(atof(var_menu1));
break;
case 2:
lcd.setCursor(0, 0);
lcd.print("Menu 2");
break;
case 3:
lcd.setCursor(0, 0);
lcd.print("Menu 3");
break;
default:
lcd.setCursor(0,0);
lcd.println("Default");
}
}
void menu0(float waste_percent){
lcd.print("Waste: ");
if(waste_percent<10){
lcd.setCursor(13, 0);
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print(round(waste_percent));
lcd.print("%");
}else{
lcd.setCursor(13, 0);
lcd.print(round(waste_percent));
lcd.print("%");
}
progressBar(waste_percent, "");
}
void menu1(float fuel_percent){
lcd.print("Fuel: ");
if(fuel_percent<10){
lcd.setCursor(13, 0);
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print(round(fuel_percent));
lcd.print("%");
}else{
lcd.setCursor(13, 0);
lcd.print(round(fuel_percent));
lcd.print("%");
}
progressBar(fuel_percent, "");
}
void menu2(float fuel_percent){
lcd.print("Menu 2");
}
void menu3(float fuel_percent){
lcd.print("Menu 3");
}
void progressBar(double percent, String textIn){
#define lenght 16.0
unsigned char b;
unsigned int peace;
// custom charaters for the progress bar
// each one is a vertical line
byte p1[8] = {
0x10,
0x10,
0x10,
0x10,
0x10,
0x10,
0x10,
0x10};
byte p2[8] = {
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18};
byte p3[8] = {
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C};
byte p4[8] = {
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E};
byte p5[8] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F};
lcd.createChar(0, p1);
lcd.createChar(1, p2);
lcd.createChar(2, p3);
lcd.createChar(3, p4);
lcd.createChar(4, p5);
lcd.setCursor(0, 0);
// calculate time until reached target
//percent = (millis() - startTime)/(1000*targetTime)*100.0;
lcd.print(textIn);
lcd.setCursor(0,1);
double a=lenght/100*percent;
// drawing black rectangles on LCD
if (a>=1) {
for (int i=1;i<a;i++) {
lcd.write(byte(4));
b=i;
}
a=a-b;
}
peace=a*5;
// drawing charater's colums
switch (peace) {
case 0:
break;
case 1:
lcd.write(byte(0));
break;
case 2:
lcd.write(byte(1));
break;
case 3:
lcd.write(byte(2));
break;
case 4:
lcd.write(byte(3));
break;
}
//clearing line
for (int i =0;i<(lenght-b);i++) {
lcd.print(" ");
}
}
void pressedButton(){
lcd.clear();
lcd.println("Button pressed");
//menuDispatch(3);
}
This is on the sensor arduino (mega)
§DISCOURSE_HOISTED_CODE_1§