Need help in coding timer to be display in lcd and timer in relay


#1

Please help :sweat_smile: How can I display the countdown timer in the screen and at the same time how can I put the relay on for 5 minutes.
(for example i put a coin then the relay will let the current flow in a certain period of time and in the lcd you can see the remaining time the relay will be on)
It is already working once you put a coin the relay will on but only 1 sec.
The problem is I dont have the knowledge how to put those logic into codes.
Thank you in advance.

CZONEofficial.ino (966 Bytes)


#2

Hi Adrian

Worth remembering: The loop function is going to run over and over as quickly as it can (many many times per second).

With the following lines of code you’re turning the LCD off and on, as well as delaying the loop by around 1 second:

  lcd.noDisplay();
  delay(500);
  // Turn on the display:
  lcd.display();
  delay(500);

Before you turn the display on with “lcd.Display()” you should print something on the display as follows:

lcd.setCursor(0, 0);
lcd.print("Countdown: ");

You can simplify this code:

   if (digitalRead( Coinpin) == LOW)
   {     
     digitalWrite(Relaypin, LOW);
   }
   else if  (digitalRead( Coinpin) == HIGH)
   {
     digitalWrite(Relaypin, HIGH);
     delay (1);
   }

Because the coin pin can only be high or low:

   int coinInserted = digitalRead(Coinpin);
   if (coinInserted == LOW)
   {     
     digitalWrite(Relaypin, LOW);
   }
   else
   {
     digitalWrite(Relaypin, HIGH);
     delay (1);
   }

Now we need to know whether you want the “system” to respond to other things when the countdown happens, or whether you do the countdown ignoring more coins or other inputs. This will determine whether the countdown happens in the “else” block or outside it, and whether we can use delays or whether we use millis to determine the time since a coin was inserted.

Can you describe the expected behaviour when a coin is inserted? How long is the countdown, how frequently do you want to update the display, and what should happen if another coin is inserted during the countdown phase?


#3

everytime the user insert coin the lcd will update 5 mins at the same time the the relay will be on for also 5 mins. If the user inserts another coin it will add 5 mins again so if the user had a remaining time of 3 minutes and the user inserts a coin the time will top up so it will be going to be 8 mins.

Thank you for your help Sir bhofmann :sob:


#4

I’m not the best at programming and I’m still a noob if you will. So, I was wondering, what’s the purpose of putting delay(1); if “1” is such a short delay time?


#5

Unless you’re multi-threading, delay(1) is almost pointless. I left it in because I didn’t want to modify functionality. But as you say, it’ll delay things by about 1 millisecond which humans don’t notice.

Aside: When running on a multi-threaded operating system, sleep(0), or sleep(1) will let the CPU run another thread/process at that point.


#6

Could you provide an example of Multi-Threading? Thanks in advance.


#7

Not on Arduino. That’s more the domain of desktop or Pi programming that I won’t go into here.


#8

this is the project that i’m trying to do


#9

Looks nice. I’m still working through the code; I should be done soon (20-30 minutes)…


#10

Thank you for helping sir bhofmann really appreciate it :smiley:


#11

This is going to be a little more complicated. I’ll try explain as I go or include comments in the code to explain what’s going on.

Looking at the loop function which the Arduino code will run over and over as quickly as it can, your most important functionality is to notice and register coins being inserted. You also don’t want much delay between a coin being inserted and the user seeing the result of that coin insert. So we don’t want long delays in the loop. Long delays would wait that long before seeing something. I’ve noticed that the coin insert is done as an interrupt which is brilliant - you don’t need to worry about the timing. I would suggest changing the coin counter to zero though by changing this line:

volatile int pulse = 1;

to this:

volatile int pulse = 0;

Because the loop will start and finish many times before we’re done with the state of the user credit and count down, we’ll store their values outside the loop in global variables. You already have a coin counter in pulse and bInserted so you can just add this above the setup() method:

// We need to track when the count down ends.
unsigned long countdownEndTimeMs = 0;
unsigned long fiveMinutes = 5 * 60 * 1000;

Let’s start by building the skeleton of the logic. Starting like this gives you a better overview of what’s going to happen when. If you start immediately with the code, you’re more likely to end up with a mess of code that doesn’t work.

Note: I’m using K&R indentation (https://en.wikipedia.org/wiki/Indentation_style#K&R_style) here to save lines but it doesn’t matter if you put the opening brace ({) on the same line as the function or statement, or below it.

void loop () {
	// If a coin has been inserted, increment the coin count

	// If the remaining countdown is more than 0, show it on the LCD, otherwise turn it off

	// Let the Arduino sleep for a bit to save battery
}

Turning that into actual code:

void loop () {
	// If a coin has been inserted, reset the timeout
	if (pulse > 0) {
		// Reset the remaining count down to 5 minutes
		countdownEndTime = millis() + fiveMinutes;

		// If we don't decrement the coin counter, it'll just keep resetting the count down
		pulse--;
	}

	// If the remaining countdown is more than 0, show it on the LCD, otherwise turn it off
	unsigned long nowMs = millis();
	long remainingTimeMs = countdownEndTimeMs - nowMs;
	if (remainingTimeMs > 0) {
		// Switch the relay on
		digitalWrite(Relaypin, HIGH);

		// Create the LCD message
		int remainingTimeSeconds = remainingTimeMs / 1000;
		String message = String(String(remainingTimeSeconds, DEC) + " Seconds ");
		// Notice the space after "Seconds" - they'll clear the "s" on the display when the numbers decrease to make the message shorter. Otherwise you'd end up with this:
		// 300 Seconds
		// 99 Secondss
		// 9 Secondsss

		// Print the message
		lcd.setCursor(0,0);
		lcd.print(message);

		// Turn the LCD on
		lcd.display();

		// Since we're showing seconds remaining, we might as well sleep for a second
		delay(1000);
	} else {
		// Switch the relay off and display off
		digitalWrite(Relaypin, LOW);
		lcd.noDisplay();

		// Block the loop until a coin is inserted
		while (pulse < 1) {
			// Let the Arduino sleep for a bit to save battery
			delay(100);
		}
	}
}

I’ve not tested or even tried to compile this code; I wrote it in Notepad++. Please let me know if it doesn’t compile or if it doesn’t work as expected.


#12

Thank you sir im working on it :slight_smile:


#13

How should I declare this line?
unsigned long countdownEndTimeMs = 0;


#14

The compiling is done

// in the top of the void set up
unsigned long countdownEndTimeMs = 0;
// in the loop
countdownEndTimeMs = millis() + fiveMinutes;
the code in the loop does not have ‘Ms’ so i decided to add ‘Ms’ to codes in the loop and it compile, but nothing is happening when I insert a coin the relay does not open.
CZONEofficial2.ino (2.0 KB)


#15

Delete line 4 - it’s not needed now.


#16

Sorry, that was my mistake (missing Ms).

Can you post your code again so I can review it please?


#17

Here are the codes, Thank you sir bhofmann :slight_smile:
CZONEofficial2.ino (2.0 KB)


#18

I’d suggest you put some serial printing in there to understand where the code path is going in the loop. As the first line in your loop method, add these two lines:

Serial.print("Pulse: ");
Serial.println(pulse, DEC);

After this line:

long remainingTimeMs = countdownEndTimeMs - nowMs;

add this line:

Serial.print("Remaining ms: ");
Serial.println(remainingTimeMs, DEC);

Then run the program with a serial monitor on your USB port.

EDIT!

I just noticed that the interrupt has been removed! You need this in your setup:

attachInterrupt(digitalPinToInterrupt(Coinpin), coinInterrupt, RISING);

And then add the interrupt function at the bottom of your file again:

void coinInterrupt(){
    pulse++;
    bInserted = true;
}

#19

Thank you sir will work on it, :slight_smile:


#20

I really hope it does work; that code took me about an hour to write! :smiley: I’d really like to see a video of the prototype working with this code. :nerd_face: