I'm making a counter for work that counts the number of times a micro (limit) switch is pressed using an Arduino nano. The problem is that the machine has adjustable speed, and seems to skip a count every once in a while when going at higher speeds. I assume this is because the code is too slow? Anyways, I tried to solve this problem by attaching the count function to an interrupt. This however makes it count multiple times per switch press even with the deboucing code I have written. Would it be better to use an interrupt or not in my case? I think the fastest the micro switch will be pressed is 100-200ms. Also, I have the micro switch wired COM to pin 3, 5v to NC, and gnd to NO. I've seen that a 10k resistor would be good to add to connect the ground to NO, but I have it soldered together already and don't want to de-solder to add a resistor, but will this help?
I am starting to lose hope that this will work 100% of the time, should I give up instead of hoping i'll be able to make this work well enough for only a few miscounts per few thousand counts?
I attached the full code below:
//Sets the total you want for each count
float Total = 1000;
float Cup = 20;
int Batch = 100;
// ON=1; OFF=0
int CupOn = 0;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//Pin assignments
const int SwitchPin = 3;
const int ButtonPin = 9;
const int CounterIntPin = 12;
const int ClutchPin = 6;
const int FiveVThirteen = 13;
#define baudRate 9600
//Variables
float TotalCount = 0;
float CupCount = 0;
int BatchCount = 0;
int TotalLength = "";
int CupLength = "";
int BatchLength = "";
int ButtonState = "";
int SwitchState = "";
int CounterState = "";
int ButtonHold = 0;
int StopCount = 0;
int add = 0;
void setup() {
//Initialize digital pins used for 5v sources
pinMode(FiveVThirteen, OUTPUT);
digitalWrite(FiveVThirteen, HIGH);
//Set Switch pin and Button pin as inputs
pinMode(SwitchPin, INPUT);
attachInterrupt(1,Count,RISING);
pinMode(ButtonPin, INPUT);
pinMode(CounterIntPin, INPUT);
//Set Clutch pin as output
pinMode(ClutchPin, OUTPUT);
digitalWrite(ClutchPin, HIGH);
//Start serial communication @9600 bps
Serial.begin(baudRate);
uint32_t timeout = 5000;
uint32_t startTime = millis();
while (!Serial && millis() - startTime < timeout) {
continue;
}
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Total: *=HIT");
lcd.setCursor(0, 1);
lcd.print("0000000 of 9999999 ");
lcd.setCursor(0, 2);
lcd.print("Cup:00000 of 99999 ");
lcd.setCursor(0, 3);
lcd.print("Batch:0000 of 9999 ");
}
void loop() {
// put your main code here, to run repeatedly:
if (ClutchPin == LOW) {
} else {
digitalWrite(ClutchPin, HIGH);
}
Processing();
Clutch();
ResetButton();
LimitSet();
CountSet();
}
void Processing() {
Serial.flush();
if (Serial.available()) { //serial data is available to read
char val = Serial.read(); //stores character read
//Code for recieving total amount from processing
if (val == 't') {
delay(5);
int m = Serial.read();
int n = int(m) - '0';
int value[n + 1];
int falue[n + 1];
for (int i = 1; i <= n; i++) {
value[i] = Serial.read();
falue[i] = int(value[i]) - '0';
}
if (n == 2) {
Total = (falue[1] * 10.0) + (falue[2] * 1.0);
} else if (n == 3) {
Total = (falue[1] * 100.0) + (falue[2] * 10.0) + (falue[3] * 1.0);
} else if (n == 4) {
Total = (falue[1] * 1000.0) + (falue[2] * 100.0) + (falue[3] * 10.0) + (falue[4] * 1.0);
} else if (n == 5) {
Total = (falue[1] * 10000.0) + (falue[2] * 1000.0) + (falue[3] * 100.0) + (falue[4] * 10.0) + (falue[5] * 1.0);
} else if (n == 6) {
Total = (falue[1] * 100000.0) + (falue[2] * 10000.0) + (falue[3] * 1000.0) + (falue[4] * 100.0) + (falue[5] * 10.0) + (falue[6] * 1.0);
} else if (n == 7) {
Total = (falue[1] * 1000000.0) + (falue[2] * 100000.0) + (falue[3] * 10000.0) + (falue[4] * 1000.0) + (falue[5] * 100.0) + (falue[6] * 10.0) + (falue[7] * 1.0);
} else if (n == 1) {
Total = falue[1] * 1.0;
}
Serial.println(Total); //Line 6
}
//Code for recieving cup amount from processing
else if (val == 'c') {
delay(5);
int q = Serial.read();
int r = int(q) - '0';
int Walue[r + 1];
int calue[r + 1];
for (int i = 1; i <= r; i++) {
Walue[i] = Serial.read();
calue[i] = int(Walue[i]) - '0';
}
if (r == 2) {
Cup = (calue[1] * 10.0) + (calue[2] * 1.0);
} else if (r == 3) {
Cup = (calue[1] * 100.0) + (calue[2] * 10.0) + (calue[3] * 1.0);
} else if (r == 4) {
Cup = (calue[1] * 1000.0) + (calue[2] * 100.0) + (calue[3] * 10.0) + (calue[4] * 1.0);
} else if (r == 5) {
Cup = (calue[1] * 10000.0) + (calue[2] * 1000.0) + (calue[3] * 100.0) + (calue[4] * 10.0) + (calue[5] * 1.0);
} else if (r == 1) {
Cup = calue[1] * 1.0;
}
}
//Code for recieving batch amount from processing
else if (val == 'b') {
delay(5);
int o = Serial.read();
int p = int(o) - '0';
int Value[p];
int balue[p];
for (int i = 1; i <= p; i++) {
Value[i] = Serial.read();
balue[i] = int(Value[i]) - '0';
}
if (p == 2) {
Batch = (balue[1] * 10) + balue[2];
} else if (p == 3) {
Batch = (balue[1] * 100) + (balue[2] * 10) + balue[3];
} else if (p == 4) {
Batch = (balue[1] * 1000) + (balue[2] * 100) + (balue[3] * 10) + balue[4];
} else if (p == 1) {
Batch = balue[1];
}
}
//Code for recieving cup or no cup from processing
else if (val == 'y') {
CupOn = 1;
lcd.setCursor(0, 2);
lcd.print("Cup: of ");
} else if (val == 'n') {
CupOn = 0;
}
}
Serial.flush();
}
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 10; // Adjust debounce delay as needed
int lastCounterState = LOW; // Initialize the last counter state
int lastSwitchState = LOW; // Initialize the last switch state
void Count() {
if (StopCount == 0) {
unsigned long currentTime = millis();
// Read the state of the counter pin
int counterState = digitalRead(CounterIntPin);
// Check if the counter state has changed since the last read
if (counterState != lastCounterState) {
lastDebounceTime = currentTime; // Reset the debounce timer
}
// Check if the debounce delay has elapsed
if ((currentTime - lastDebounceTime) >= debounceDelay) {
// If enough time has passed, and the counter state is HIGH, register a count
if (counterState == HIGH) {
// Read the state of the switch
int switchState = digitalRead(SwitchPin);
// If the switch is HIGH (pressed), and it wasn't pressed before, register a count
if (switchState == HIGH) {
TotalCount++;
CupCount++;
BatchCount++;
}
// Update the last switch state
lastSwitchState = switchState;
}
}
// Remember the current counter state for the next iteration
lastCounterState = counterState;
}
}
void Clutch() {
//Turn off clutch when total count equals the total limit
if (TotalCount == Total) {
digitalWrite(ClutchPin, LOW);
StopCount = 1;
lcd.setCursor(18, 1);
lcd.print(" *");
}
//Turn off clutch when cup count equals the cup limit
if (CupOn == 1) {
if (CupCount == Cup) {
digitalWrite(ClutchPin, LOW);
StopCount = 1;
lcd.setCursor(18, 2);
lcd.print(" *");
}
}
//Turn off clutch when batch count equals the batch limit
if (BatchCount == Batch) {
digitalWrite(ClutchPin, LOW);
StopCount = 1;
lcd.setCursor(18, 3);
lcd.print(" *");
}
}
void ResetButton() {
//Reset Button Code
ButtonState = digitalRead(ButtonPin);
if (ButtonState == HIGH) {
if (CupOn == 1) {
if (TotalCount >= Total) {
while (ButtonHold <= 2) {
ButtonState = digitalRead(ButtonPin);
if (ButtonState == HIGH) {
ButtonHold = ButtonHold + 1;
delay(1000);
} else {
ButtonHold = 0;
}
}
ButtonHold = 0;
TotalCount = 0;
CupCount = 0;
BatchCount = 0;
lcd.setCursor(18, 3);
lcd.print(" ");
lcd.setCursor(18, 2);
lcd.print(" ");
lcd.setCursor(18, 1);
lcd.print(" ");
StopCount = 0;
ButtonState = digitalRead(ButtonPin);
while (ButtonState == HIGH) {
ButtonState = digitalRead(ButtonPin);
}
delay(200);
digitalWrite(ClutchPin, HIGH);
} else if (CupCount >= Cup) {
while (ButtonHold <= 1) {
ButtonState = digitalRead(ButtonPin);
if (ButtonState == HIGH) {
ButtonHold = ButtonHold + 1;
delay(500);
} else {
ButtonHold = 0;
}
}
ButtonHold = 0;
CupCount = 0;
BatchCount = 0;
lcd.setCursor(19, 2);
lcd.print(" ");
lcd.setCursor(19, 3);
lcd.print(" ");
StopCount = 0;
ButtonState = digitalRead(ButtonPin);
while (ButtonState == HIGH) {
ButtonState = digitalRead(ButtonPin);
}
delay(200);
digitalWrite(ClutchPin, HIGH);
} else {
BatchCount = 0;
lcd.setCursor(19, 3);
lcd.print(" ");
StopCount = 0;
ButtonState = digitalRead(ButtonPin);
while (ButtonState == HIGH) {
ButtonState = digitalRead(ButtonPin);
}
delay(200);
digitalWrite(ClutchPin, HIGH);
}
} else {
if (TotalCount >= Total) {
while (ButtonHold <= 2) {
ButtonState = digitalRead(ButtonPin);
if (ButtonState == HIGH) {
ButtonHold = ButtonHold + 1;
delay(1000);
} else {
ButtonHold = 0;
}
}
ButtonHold = 0;
TotalCount = 0;
CupCount = 0;
BatchCount = 0;
lcd.setCursor(19, 3);
lcd.print(" ");
lcd.setCursor(19, 2);
lcd.print(" ");
lcd.setCursor(19, 1);
lcd.print(" ");
StopCount = 0;
ButtonState = digitalRead(ButtonPin);
while (ButtonState == HIGH) {
ButtonState = digitalRead(ButtonPin);
}
delay(200);
digitalWrite(ClutchPin, HIGH);
} else {
BatchCount = 0;
lcd.setCursor(19, 3);
lcd.print(" ");
StopCount = 0;
ButtonState = digitalRead(ButtonPin);
while (ButtonState == HIGH) {
ButtonState = digitalRead(ButtonPin);
}
delay(200);
digitalWrite(ClutchPin, HIGH);
}
}
}
}
void LimitSet() {
//Total limit Set
if (Total <= 9999999.9) {
lcd.setCursor(11, 1);
if (Total <= 9.9) {
lcd.print("000000");
lcd.setCursor(17, 1);
} else if (Total <= 99.9) {
lcd.print("00000");
lcd.setCursor(16, 1);
} else if (Total <= 999.9) {
lcd.print("0000");
lcd.setCursor(15, 1);
} else if (Total <= 9999.9) {
lcd.print("000");
lcd.setCursor(14, 1);
} else if (Total <= 99999.9) {
lcd.print("00");
lcd.setCursor(13, 1);
} else if (Total <= 999999.9) {
lcd.print("0");
lcd.setCursor(12, 1);
}
lcd.print(Total, 0);
} else {
lcd.setCursor(11, 1);
lcd.print("0000000");
}
//Cup Limit Set
if (CupOn == 1) {
lcd.setCursor(13, 2);
if (Cup <= 99999.9) {
if (Cup <= 9.9) {
lcd.print("0000");
lcd.setCursor(17, 2);
} else if (Cup <= 99.9) {
lcd.print("000");
lcd.setCursor(16, 2);
} else if (Cup <= 999.9) {
lcd.print("00");
lcd.setCursor(15, 2);
} else if (Cup <= 9999.9) {
lcd.print("0");
lcd.setCursor(14, 2);
}
lcd.print(Cup, 0);
} else {
lcd.print("00000");
}
}
//Batch Limit Set
lcd.setCursor(14, 3);
if (Batch <= 9999.9) {
if (Batch <= 9.9) {
lcd.print("000");
lcd.setCursor(17, 3);
} else if (Batch <= 99.9) {
lcd.print("00");
lcd.setCursor(16, 3);
} else if (Batch <= 999.9) {
lcd.print("0");
lcd.setCursor(15, 3);
}
lcd.print(Batch);
} else {
lcd.print("0000");
}
}
void CountSet() {
// Find length of Total limit float
TotalLength = TotalCount == 0 ? 0 : (int)log10(TotalCount) + 1;
// Find length of Cup limit float
CupLength = CupCount == 0 ? 0 : (int)log10(CupCount) + 1;
// Find length of Batch limit integer
BatchLength = BatchCount == 0 ? 0 : (int)log10(BatchCount) + 1;
//Displays new total count
if (TotalLength == 0) {
lcd.setCursor(0, 1);
lcd.print("0000000 ");
} else {
lcd.setCursor((7 - TotalLength), 1);
lcd.print(TotalCount, 0);
lcd.setCursor(7,1);
lcd.print(" ");
}
//Displays new cup count
if (CupOn == 1) {
if (CupLength == 0) {
lcd.setCursor(4, 2);
lcd.print("00000 ");
} else {
lcd.setCursor((9 - CupLength), 2);
lcd.print(CupCount, 0);
lcd.setCursor(9,2);
lcd.print(" ");
}
} else {
lcd.setCursor(0, 2);
lcd.print(" ");
}
//Displays new batch count
if (BatchLength == 0) {
lcd.setCursor(6, 3);
lcd.print("0000 ");
} else {
lcd.setCursor((10 - BatchLength), 3);
lcd.print(BatchCount);
lcd.setCursor(10,3);
lcd.print(" ");
}
}