Ok. I can understand why that would work and it seems like a logical solution. I've not ever done anything like that so I'm going to learn some new skills if I go down this path - and that's never a bad thing.
I'm guessing that I would need one array for the battery voltage screen and another for the target counter information?
Currently I set up a template with the target information
0000000000111111
0123456789012345
H i : L o :
D b l: To t:
And then write the changing variables to referenced locations on the LCD to put numbers in the right spot. I'm guessing I can write those to a location in the array? Or do I need to rewrite all 16 x 2 locations in the array at the same time?
I'll go do some searching now, but if you have sample code that shows what you do that would be great. If not I'll find something on basic arrays and have a play in a separate sketch then try integrating it.
Cheers
Dave
Latest version of sketch below:
// V1-7 is last working version. Battery monitor in development.
/*
* ClayDelay to Eletronica Progetti interface
*
* SwitchManager skeleton
Uses SwitchManager library written by Nick Gammon
The library handles switch de-bouncing and provides timing and state change information in your sketch.
The SwitchManager.h file should be placed in your libraries folder, i.e.
C:\Users\YourName\Documents\Arduino\libraries\SwitchManager\SwitchManager.h
You can download the library at:
http://gammon.com.au/Arduino/SwitchManager.zip Thank you Nick!
In this example we have 2 normally open (N.O.) switches connected to the Arduino - HIGH and LOW.
The two switches are connected between VCC (3.3 or 5 volts) and an Arduino input pin.
The library enables pull-up resistors for your switch inputs.
Pushing a switch makes its pin LOW. Releasing a switch makes its pin HIGH.
The SwitchManager library provides 10ms de-bounce for switches.
i.e. enum { debounceTime = 10, noSwitch = -1 };
If you need more time, edit the SwitchManager.h file
i.e. enum { debounceTime = 50, noSwitch = -1 }; //here it is changed to 50ms
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DFRobot_MAX17043.h"
#include <SwitchManager.h>
#ifdef __AVR__
#define ALR_PIN 5
#else
#define ALR_PIN D5
#endif
#define BATT_INTERVAL 2000
#define COUNT_INTERVAL 5000
//object initiations
DFRobot_MAX17043 gauge;
uint8_t intFlag = 0;
SwitchManager mylowSkeetSwitch;
SwitchManager myhighSkeetSwitch;
unsigned long currentMillis;
unsigned long heartBeatMillis;
unsigned long heartFlashRate = 500UL; // time the led will change state
unsigned long incShortPress = 500UL; // 1/2 second
unsigned long incLongPress = 5000UL;// 2 seconds
unsigned long
tStart,
tEnd = 12000, // twelve seconds
elapsed;
const byte heartBeatLED = 13;
int myCounterTotal;
int newCounterTotal;
int myCounterHigh;
int myCounterLow;
int myCounterDouble;
int alternate;
const int HIGH_RELAY = A0; // was A0 but using that for low battery sense. May have to short 10k R5 to use 5
const int LOW_RELAY = A1;
const int DOUBLE_RELAY = 6;
const int lowSkRelease = 8;
const int highSkRelease = 9;
int highSkReleaseState = 0; // changed initial stat from 1 to 0 26.3.24 for 4ch relay board https://www.ebay.com.au/itm/131621839918
int lowSkReleaseState = 0; // changed initial stat from 1 to 0 26.3.24 for 4ch relay board https://www.ebay.com.au/itm/131621839918
int releaseState = 0;
int doubleTest = 0;
int relayState;
int ledState = LOW; // current state of the output pin
unsigned int totaliser = 0;
//======================================================================
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
//======================================================================
void interruptCallBack()
{
intFlag = 1;
}
//======================================================================
void setup()
{
// set up the LCD's number of columns and rows:
lcd.init();
lcd.init();
// Turn on the blacklight and print a message.
lcd.backlight();
//****
lcd.home(); //set cursor to top left corner
// Print a message to the LCD.
lcd.print("TrapTronix Aust"); //print the text to the lcd
lcd.setCursor(0,1);
lcd.print("(c) DJ 2024");
delay(3000);
lcd.clear();
lcd.print(" +61 407532232 "); //print the text to the lcd
lcd.setCursor(0,1);
lcd.print("(c) DJ 2024");
delay(3000);
// Initialize the serial port at a speed of 115200 baud
Serial.begin(115200);
//---
while(!Serial);
Serial.println();
Serial.println();
pinMode(ALR_PIN, INPUT_PULLUP);
attachInterrupt(ALR_PIN, interruptCallBack, FALLING); //default alert is 32%
while(gauge.begin() != 0) {
Serial.println("gauge begin faild!");
delay(2000);
}
delay(2);
Serial.println("gauge begin successful!");
gauge.setInterrupt(32); //use this to modify alert threshold as 1% - 32% (integer)
//---
Serial.println("Setup-Start");
PrintFileNameDateTime();
// set up the display with Hi, Lo, Dbl & Tot
LCDtemplate();
// Write relay outputs high so that when pinMode is set they don't briefly change state
digitalWrite(HIGH_RELAY, HIGH);
digitalWrite(LOW_RELAY, HIGH);
digitalWrite(DOUBLE_RELAY, HIGH);
//gives a visual indication if the sketch is blocking
pinMode(heartBeatLED, OUTPUT);
pinMode(highSkRelease, INPUT);
pinMode(lowSkRelease, INPUT);
pinMode(HIGH_RELAY, OUTPUT);
pinMode(LOW_RELAY, OUTPUT);
Serial.print("Double relay state: ");
Serial.println(doubleTest);
pinMode(DOUBLE_RELAY, OUTPUT);
//the handleSwitchPresses() function is called when a switch changes state
myhighSkeetSwitch.begin (highSkRelease, handleSwitchPresses);
mylowSkeetSwitch.begin (lowSkRelease, handleSwitchPresses);
} // E N D O F s e t u p ( )
//======================================================================
void loop()
{
//leave this line of code at the top of loop()
currentMillis = millis();
//***************************
//some code to see if the sketch is blocking
if (CheckTime(heartBeatMillis, heartFlashRate, true))
{
//toggle the heartBeatLED
digitalWrite(heartBeatLED,!digitalRead(heartBeatLED));
}
elapsed = millis() - tStart;
if(elapsed >= tEnd)
tStart += tEnd;
if(elapsed < COUNT_INTERVAL)
{
// do 10 second task
if(newCounterTotal > myCounterTotal){
LCDtemplate(); // sets LCD labels up for values printed below
myCounterTotal = newCounterTotal;
lcd.setCursor(4,0);
lcd.print(myCounterHigh);
lcd.setCursor(12,0);
lcd.print(myCounterLow);
lcd.setCursor(4,1);
lcd.print(myCounterDouble);
lcd.setCursor(12,1);
lcd.print(myCounterTotal);
static unsigned long lastMillisC = 0;
if((millis() - lastMillisC) >= COUNT_INTERVAL) {
lastMillisC = millis();
alternate = 1;
}
}
}
else
{
// do 2 second task
if(alternate == 1); {
lcd.setCursor(0,1);
LCDbattlevel();
static unsigned long lastMillisD = 0;
if((millis() - lastMillisD) >= BATT_INTERVAL) {
lastMillisD = millis();
alternate = 0;
}
// Serial monitor output
Serial.print("voltage: ");
Serial.print(gauge.readVoltage()/1000);
Serial.println(" V");
Serial.print("precentage: ");
Serial.print(gauge.readPercentage());
Serial.println(" %");
}
}
/*
static unsigned long lastMillisA = 0;
if((millis() - lastMillisA >= COUNT_INTERVAL)) { // was newCounterTotal > myCounterTotal OR >COUNT_INTERVAL && (newCounterTotal > myCounterTotal)
lastMillisA = millis();
LCDtemplate(); // sets LCD labels up for values printed below
myCounterTotal = newCounterTotal;
lcd.setCursor(4,0);
lcd.print(myCounterHigh);
lcd.setCursor(12,0);
lcd.print(myCounterLow);
lcd.setCursor(4,1);
lcd.print(myCounterDouble);
lcd.setCursor(12,1);
lcd.print(myCounterTotal);
}
// Battery monitor
static unsigned long lastMillisB = 0;
if((millis() - lastMillisB) >= BATT_INTERVAL) {
lastMillisB = millis();
Serial.println();
// Serial monitor output
Serial.print("voltage: ");
Serial.print(gauge.readVoltage()/1000);
Serial.println(" V");
Serial.print("precentage: ");
Serial.print(gauge.readPercentage());
Serial.println(" %");
LCDbattlevel();
}
*/
//**
if(intFlag == 1) {
intFlag = 0;
gauge.clearInterrupt();
Serial.println("Low power alert interrupt!");
//put your battery low power alert interrupt service routine here
}
///LCD
// Set cursor to start of line 2, print total targets since reset, move to end of line & blink
// lcd.setCursor(12,1);
// lcd.print(myCounterTotal);
lcd.setCursor(15,1);
lcd.blink();
//***************************
//check to see what's happening with the switches
//"Do not use delay()s" in your sketch as it will make switch changes unresponsive
//Use BlinkWithoutDelay (BWD) techniques instead.
myhighSkeetSwitch.check ();
mylowSkeetSwitch.check ();
//***************************
//put other non-blocking stuff here
// my code pasted here
// Check double switch activation
doubleTest = lowSkReleaseState + highSkReleaseState;
// Serial.println(doubleTest);
// double test & output to the high relay 1 when no double
if (doubleTest == 1 && highSkReleaseState ==1)
{
digitalWrite(HIGH_RELAY, LOW); // changed 22/4 for ebay Relay boards - neg state on
delay(500);
digitalWrite(HIGH_RELAY, HIGH); // changed 22/4 for ebay Relay boards - neg state on
delay(40);
newCounterTotal = myCounterTotal+1;
myCounterHigh++;
Serial.print("High total = ");
Serial.println(myCounterHigh);
lcd.setCursor(4,0);
lcd.print(myCounterHigh);
Serial.print("Total targets thrown = ");
Serial.println(myCounterTotal);
}
// double test & output to the low relay 2 when no double
if (doubleTest == 1 && lowSkReleaseState ==1)
{
digitalWrite(LOW_RELAY, LOW); // changed 22/4 for ebay Relay boards - neg state on
delay(500);
digitalWrite(LOW_RELAY, HIGH); // changed 22/4 for ebay Relay boards - neg state on
delay(40);
newCounterTotal = myCounterTotal+1;;
myCounterLow++;
Serial.print("Low total = ");
Serial.println(myCounterLow);
lcd.setCursor(12,0);
lcd.print(myCounterLow);
Serial.print("Total targets thrown = ");
Serial.println(myCounterTotal);
}
// skeet pair - test whether double switch activation has occurred. doubleTest may be redundant? Output to double relay 3
else if (doubleTest >= 2 && lowSkReleaseState == 1 && highSkReleaseState == 1)
{
digitalWrite(DOUBLE_RELAY, LOW); // changed 22/4 for ebay Relay boards - neg state on
delay(500);
Serial.println("Double relay triggered by this code section.");
digitalWrite(DOUBLE_RELAY, HIGH); // changed 22/4 for ebay Relay boards - neg state on
delay(40);
newCounterTotal = myCounterTotal +2;
myCounterDouble++;
Serial.print("Double total = ");
Serial.println(myCounterDouble);
Serial.print("Total targets thrown = ");
Serial.println(myCounterTotal);
lcd.setCursor(4,1);
lcd.print(myCounterDouble);
}
// reset both to low before repeating / waiting for next activation
lowSkReleaseState = LOW;
highSkReleaseState = LOW;
digitalWrite(HIGH_RELAY, !relayState); // ! changed 22/4 for ebay Relay boards - neg state on
digitalWrite(LOW_RELAY, !relayState); //! changed 22/4 for ebay Relay boards - neg state on
// Serial.println(relayState);
// Serial.println(dtlReleaseState);
delay(20); // delay in between reads for stability
} // E N D O F l o o p ( )
//======================================================================
// F U N C T I O N S
//======================================================================
// C h e c k T i m e ( )
//**********************************************************************
//Delay time expired function
//parameters:
//lastMillis = time we started
//wait = delay in ms
//restart = do we start again
boolean CheckTime(unsigned long & lastMillis, unsigned long wait, boolean restart)
{
//has time expired for this task?
if (currentMillis - lastMillis >= wait)
{
//should this start again?
if(restart)
{
//yes, get ready for the next iteration
lastMillis = millis();
}
return true;
}
return false;
}
// E N D o f C h e c k T i m e ( )
// Serial print Filename, Date & Time
//**********************************************************************
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// E N D o f PrintFileNameDateTime
// Serial print LCD Template
//**********************************************************************
void LCDtemplate(){
lcd.clear();
lcd.home();
lcd.print("Hi: Lo:");
lcd.setCursor(0,1);
lcd.print("Dbl: Tot:");
}
// Output battery to LCD
//***********************************************************************
void LCDbattlevel(){
// LCD monitor output
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Batt volt: ");
lcd.setCursor(13,0);
lcd.print(gauge.readVoltage()/1000);
lcd.setCursor(0,1);
lcd.print("Batt level: ");
lcd.setCursor(13,1);
lcd.print(gauge.readPercentage());
lcd.setCursor(15,1);
lcd.print("%");
}
//
// h a n d l e S w i t c h P r e s s e s ( )
//**********************************************************************
void handleSwitchPresses(const byte newState, const unsigned long interval, const byte whichPin)
{
// You get here "ONLY" if there has been a change in a switches state.
// 26/3/24 Switches in this project are NO switch. 10K pulls pin HIGH. press of switch pulls pin LOW
//When a switch has changed state, SwitchManager passes this function 3 arguments:
//"newState" this will be HIGH or LOW. This is the state the switch is in now.
//"interval" the number of milliseconds the switch stayed in the previous state
//"whichPin" is the switch pin that we are examining
switch (whichPin)
{
//***************************
/*
# ####### # # ####### # ###### ##### ####### #######
# # # # # # # # # # # # # # #
# # # # # # # # # # # # # #
# # # # # # # # # ###### # #### ##### #
# # # # # # # ####### # # # # # #
# # # # # # # # # # # # # # #
####### ####### ## ## # # # # # ##### ####### #
###### ####### # ####### # ##### #######
# # # # # # # # # #
# # # # # # # # #
###### ##### # ##### # # ##### #####
# # # # # ####### # #
# # # # # # # # # #
# # ####### ####### ####### # # ##### #######
*/
//are we dealing with this switch?
case lowSkRelease:
//has this switch gone from LOW to HIGH (gone from pressed to not pressed)
//this happens with normally open switches wired as mentioned at the top of this sketch
if (newState == HIGH)
{
//The incSwitch was just released
//was this a short press followed by a switch release
if(interval <= incShortPress)
{
}
}
//if the switch is a normally closed (N.C.) and opens on a press this section would be used
//the switch must have gone from HIGH to LOW
// THIS is our condition as pin is normally pulled high via 10k and is pulled low when switch closes.
else
{
Serial.println("The Low Skeet Release was just pushed");
// Set variable to write to token box
lowSkReleaseState = HIGH;
}
break; //End of case lowSkRelease
//***************************
/*
# # ### ##### # # ####### # ###### ##### ####### #######
# # # # # # # # # # # # # # # #
# # # # # # # # # # # # # #
####### # # #### ####### # # # ###### # #### ##### #
# # # # # # # # ####### # # # # # #
# # # # # # # # # # # # # # # #
# # ### ##### # # # # # # # ##### ####### #
###### ####### # ####### # ##### #######
# # # # # # # # # #
# # # # # # # # #
###### ##### # ##### # # ##### #####
# # # # # ####### # #
# # # # # # # # # #
# # ####### ####### ####### # # ##### #######
*/
//are we dealing with this switch?
case highSkRelease:
//has this switch gone from LOW to HIGH (gone from pressed to not pressed)
//this happens with normally open switches wired as mentioned at the top of this sketch
if (newState == HIGH)
{
//The incSwitch was just released
//was this a short press followed by a switch release
if(interval <= incShortPress)
{
}
}
//if the switch is a normally closed (N.C.) and opens on a press this section would be used
//the switch must have gone from HIGH to LOW
// THIS is our condition as pin is normally pulled high via 10k and is pulled low when switch closes.
else
{
Serial.println("The High Skeet Release was just pushed");
// Set variable to write to token box
highSkReleaseState = HIGH;
}
break; //End of case highSkRelease
//***************************
//Put default stuff here
//default:
//break; //END of default
} //End switch (whichPin)
} // E n d o f h a n d l e S w i t c h P r e s s e s ( )
//======================================================================
// E N D O F C O D E
//======================================================================