Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help about LCD code.

Status
Not open for further replies.

bentro

New Member
Hi,

I found this code from another forum. I tried posting for help but the forum is dead. It's about Coin Acceptor control of video feed. I want to use/add an LCD instead of a 7segment. Here's the LCD info. https://www.adafruit.com/products/398

I am not a programmer, I hope someone could help. Thanks in advance.
P.S. If you want the link of source/forum, please let me know.





int coinPin = 2; //can change to anything you need
int relayPin = 5; //can change to anything you need

long time; //will keep track of the time the video should be turned off at
long timeToAddPerCoin = 420000; //420000 ms = 7min
long countdownDisplaytimer; //will keep track of when we should display

boolean isPlaying;

void setup(){
pinMode(coinPin, INPUT);
digitalWrite(coinPin, HIGH); // turn on pullup resistor

pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);

pinMode(13, OUTPUT); //for the LED

Serial.begin(9600);

time = millis(); //set to right now, as the video should start off
countdownDisplaytimer = millis(); //set to right now
isPlaying = false;
}


void loop(){
if(digitalRead(coinPin) == LOW){ //assuming it goes high on coin insert
delay(500); //just to debounce

if(isPlaying){ //is video playing already?



time += timeToAddPerCoin; //add 7 minutes (420000 ms) to the time we need to turn the video off at

Serial.print("playing for ");
Serial.print(time / 60000);
Serial.println(" minutes");
}else{
time = millis() + timeToAddPerCoin; //set time to 7 minutes from now.
Serial.println("playing for 7 minutes");
isPlaying = true;
}

}

long timeLeft = time - millis();
long timeLeftInSeconds = timeLeft / 1000;
long timeSinceLastDisplay = millis() - countdownDisplaytimer;

if(timeLeft > 0){ //is there time left, and should keep playing the video?
//Serial.println(timeLeft); //DEBUGGING ONLY!!!
digitalWrite(relayPin, HIGH); //turn on the relay
digitalWrite(13, HIGH); // turn the LED next to pin 13
isPlaying = true;

if(countdownDisplaytimer > 1000){ //has it been a second since last diaplay?
countdownDisplaytimer = millis(); //reset timer
Serial.print(timeLeftInSeconds);
Serial.println(" seconds left");
}


}else{
digitalWrite(relayPin, LOW); //time ran out, turn off the relay
digitalWrite(13, LOW); // turn off LED next to pin 13
isPlaying = false;
}


}
 
Yeah, several edits has been done on their forum but the final code outputs to sparkfun 7segment Display.
I just copied the code with an RS232 output.
 
This **broken link removed** uses the same LCD.

I want something similar to that but with fewer states.
 
Welcome to ETO, bentro!

This **broken link removed** uses the same LCD
OK. The sketch in this example makes use of "LiquidCrystal.h". That will work with the LCD you posted.

If you were to use the code you first posted, you would have had to add the i2c and SPI input/output expander offered by Adafruit to interface the serial output of the Arduino to the LCD. Fewer connections, to be sure, but added expense and hardware.

<EDIT>Just noticed I misspelled "Crystal".
 
Last edited:
Thanks

Yeah, I want the first code implemented. The two states are enough.
It's simple.

The second code is really nice. It works on my arduino and LCD. If only I know how to edit, I want to remove choretime, start button, over ride, time limit, pause, coin. And to be able to increment time anytime.
 
I can also use the second code, but I want to remove those states in RED


his sketch was written to work with a simple arcade style coin mechanism in conjunction with an HDMI switch to allow
you to require the inserting of a coin in order to use the XBOX. While I used this for an XBOX there is nothing XBOX
specific about the code and it should work swimmingly with any device that outputs video over HDMI.

For more information see - **broken link removed** or ping adam@adambyers.com

Coin Operated XBOX
Copyright (C) 2013 Adam Byers

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
C:
**********************************************************************************************************************/

// include the Arduino LCD libraries
#include <LiquidCrystal.h>

// States
#define S_ready 1
[COLOR=#ff0000]#define S_coin 2
#define S_pause 3
#define S_override 4
#define S_limit 5[/COLOR]
#define S_countdown 6
[COLOR=#ff0000]#define S_choretime 7[/COLOR]

// Default start up state
int state = S_ready;

// LCD PINs
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// Display back-light pins
const int LCDr = 3;
const int LCDg = 5;
const int LCDb = 6;

// Other PINs
const int CoinSW = 2;
const int VideoSW = 4;
const int StartSW = A0;
const int PauseSW = A1;
const int CoinLED = A2;
const int OverrideSW = A3;
const int VideoDetect  = A4;
const int Speaker = A5;

// Button debounce vars
int buttonState;
int lastButtonState = HIGH;
long lastDebounceTime = 0;
long debounceDelay = 40; // May have to play with this value to get coins to register properly.

// Coin counting and time vars
unsigned long AllowedPlaytime;
unsigned long ChoreTime = 30; // How long (in miniutes) do you want the chore time (manditory pause) to last.
unsigned long ChoreCountdown;
unsigned long CurrentMillis;
int CoinCount = 0;
int CoinTimeValue = 30; // Amount of time (in minutes) that the coin is worth.
int DepositStringIndex = 0;
int TimeStringIndex = 0;

// Video on/off switching vars
int VideoSwitchState = LOW;
long VideoSwitchBuffer = 2000; // Used to add some seconds (2 seconds to be precise) to AllowedPlaytime after video ON switching event to compensate for TV sync time.
unsigned long SwitchPreviousMillis = 0;
long VideoSwitchInterval = 1000; // How long (in milliseconds) we "hold down" the HDMI input selector button when switching inputs.

// Warning beep vars
unsigned long LastWarningTime = 0;
long WarningBeepInterval1 = 60000; // 60 seconds
long WarningBeepInterval2 = 1000; // 1 seconds

// Used to get the LCD to clear properly when switching between states.
bool ClearLCD = false;
bool PauseRun = false;
bool OverrideRun = false;
bool CountdownRun = false;

// Used for selection of time values to dislayu depending on what state the system is running in.
bool PlaytimeRun = false;
bool ChoretimeRun = false;

// Arms up characters for display on the LCD.
byte armsUp[8] = {
  0b00100,
  0b01010,
  0b00100,
  0b10101,
  0b01110,
  0b00100,
  0b00100,
  0b01010
};

// Strings for the deposit display
char* DepositStrings[]= {
"$0.00", // Place holder does not display.
"$0.25", // 30 min
"$0.50", // 1 hour - does not display
};

char* TimeStrings[]= {
"$0.00", // Place holder does not display.
"30m  ",
"1h  ", // 1 hour - does not display
};

void setup() {
// Initialize the LCD
lcd.begin(16, 2);

// Set PINs as inputs or outputs.
pinMode(LCDr, OUTPUT);
pinMode(LCDg, OUTPUT);
pinMode(LCDb, OUTPUT);
pinMode(VideoSW, OUTPUT);
pinMode(Speaker, OUTPUT);
pinMode(CoinSW, INPUT);
pinMode(StartSW, INPUT);
pinMode(PauseSW, INPUT);
pinMode(CoinLED, OUTPUT);
pinMode(OverrideSW, INPUT);
pinMode(VideoDetect,INPUT);

// Enable internal resistors (set inputs as HIGH) on button PINs so we don't have to use external resistors.
digitalWrite(CoinSW, HIGH);
digitalWrite(StartSW, HIGH);
digitalWrite(PauseSW, HIGH);
digitalWrite(OverrideSW, HIGH);
digitalWrite(VideoDetect, HIGH);

// Initialize special LCD characters.
lcd.createChar(1, armsUp);

}

void loop() {

  switch(state) {
 
  case S_ready:
  F_ready();
  break;
   
  case S_override:
  F_override();
  break;
 
  case S_coin:
  F_coin();
  break;
 
  case S_limit:
  F_limit();
  break;
 
  case S_countdown:
  F_countdown();
  break;
 
  case S_choretime:
  F_choretime();
  break;
 
  case S_pause:
  F_pause();
  break; 
  }
 
}

// Functions //

////////////////////////////////////////////////////////////

void F_ready() {

  // Because the HDMI switch will automatically switch from an inactive input to an active input we have to make sure that the video is off and stays off in every state to prevent abuse.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(0, 255, 0); // Green
  lcd.setCursor(4, 0);
  lcd.write(1);
  lcd.print(" READY ");
  lcd.write(1);
  lcd.setCursor(2, 1);
  lcd.print("Insert Coins");

  DepositStringIndex = 0; // Reset
  TimeStringIndex = 0; // Reset
  CoinCount = 0; // Reset

  // Only state the override can be turned on is here.
  if (digitalRead(OverrideSW) == LOW){
  lcd.clear();
  state = S_override;
  }

  digitalWrite(CoinLED, HIGH);

  if (digitalRead(CoinSW) == LOW) {
  lcd.clear();
  state = S_coin;
  }

}

////////////////////////////////////////////////////////////

void F_override() {

  // Turn the video on.
  while (digitalRead(VideoDetect) == HIGH) {
  F_video_on();
  }

  if (ClearLCD == true) {
  ClearLCD = false;
  lcd.clear();
  }

  OverrideRun = true;

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(3, 0);
  lcd.print("Override On");
  lcd.setCursor(2, 1);
  lcd.print(" Lucky You ");

  digitalWrite(CoinLED, LOW);

  if (digitalRead(OverrideSW) == HIGH){
  lcd.clear();
  state = S_ready;
  } 

}

////////////////////////////////////////////////////////////

void F_coin() {

  // If it's on, turn the video off.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(0, 0, 255); // Blue
  lcd.setCursor(0, 0);
  lcd.print("Deposited:");
  lcd.print(DepositStrings[DepositStringIndex]);
  lcd.setCursor(0, 1);
  lcd.print("Playtime:");
  lcd.print(TimeStrings[TimeStringIndex]);

  // We need to debounce the coin counting switch. Otherwise we'd count several coins when only one was deposited.
  int reading = digitalRead(CoinSW) == LOW;

  if (reading != lastButtonState) {
  lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
  if (reading != buttonState) {
  buttonState = reading;
  if (buttonState == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  CoinCount = CoinCount + CoinTimeValue; // Count the coin deposit.
  DepositStringIndex++;
  TimeStringIndex++;
  }
  }
  }

  lastButtonState = reading;
  // Done debouncing and depositing.

  if (DepositStringIndex == 2) { // We only allow 1 hour of playtime. Player can deposit more coins if they want but the system won't count them after this point.
  lcd.clear();
  digitalWrite(CoinLED, LOW);
  state = S_limit;
  }

  if (digitalRead(StartSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  digitalWrite(CoinLED, LOW);
  AllowedPlaytime = CoinCount * 60000; // Multiply the CoinCount by 60000 (milliseconds) to get the AllowedPlaytime.
  AllowedPlaytime = AllowedPlaytime + VideoSwitchBuffer; // Add some time (VideoSwitchBuffer) to make up for the time it took the TV to sync back up and display video.
  state = S_countdown;
  }

}

////////////////////////////////////////////////////////////

void F_limit() {

  // If it's on, turn the video off.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(2, 0);
  lcd.print("1 Hour Limit");
  lcd.setCursor(3, 1);
  lcd.print("Press START");

  if (digitalRead(StartSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  AllowedPlaytime = CoinCount * 60000; // Multiply the CoinCount by 60000 (milliseconds) to get the AllowedPlaytime.
  AllowedPlaytime = AllowedPlaytime + VideoSwitchBuffer; // Add some time (VideoSwitchBuffer) to make up for the time it took the TV to sync back up and display video.
  state = S_countdown;
  }

}

////////////////////////////////////////////////////////////

void F_countdown() {

  // Turn the video on.
  while (digitalRead(VideoDetect) == HIGH) {
  F_video_on();
  }

  if (ClearLCD == true) {
  lcd.clear();
  ClearLCD = false;
  }

  CountdownRun = true; // Used to get the LCD to clear properly when switching between states.
  PlaytimeRun = true; // Used to set the correct time values to display.

  LCDBacklight(0, 0, 255); // Blue
  lcd.setCursor(2, 0);
  lcd.print("Time Started:");

  // If second has passed then we subtract that from the AllowedPlaytime
  if (millis() - CurrentMillis > 1000) {
  AllowedPlaytime = AllowedPlaytime - 1000;
  CurrentMillis = millis();
  F_timeDisplay();
 
  // If there is less than 5 minutes of playtime left start sounding an audible alarm at the interval defined.
  if (AllowedPlaytime <= 300000) { // 5 min
  if (millis() - LastWarningTime > WarningBeepInterval1) {
  F_warning1();
  }

  // Or if there is less than 10 seconds of playtime left start sounding an audible alarm at the interval defined.
  else if (AllowedPlaytime <= 10000) { // 10 seconds
  if (millis() - LastWarningTime > WarningBeepInterval2) {
  F_warning2();
  }
  }
  }
  }

  if (digitalRead(PauseSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  state = S_pause;
  }

  if (AllowedPlaytime == 0) {
  lcd.clear();
  PlaytimeRun = false;
  ChoreCountdown = ChoreTime * 60000;
  F_warning3();
  state = S_choretime;
  }

}

////////////////////////////////////////////////////////////

void F_pause() {

  // Turn the video off to prevent abuse of the pause.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(2, 0);
  lcd.print("Time Paused:");
  F_timeDisplay();
 
  if (digitalRead(StartSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  AllowedPlaytime = AllowedPlaytime + VideoSwitchBuffer; // Add some time (VideoSwitchBuffer) to make up for the time it took to turn the video on.
  state = S_countdown;
  }

}

////////////////////////////////////////////////////////////
void F_choretime() {

  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  ChoretimeRun = true;

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(1, 0);
  lcd.write(1);
  lcd.print(" Chore Time ");
  lcd.write(1);

  // If second has passed then we subtract that from the ChoreTime
  if (millis() - CurrentMillis > 1000) {
  ChoreCountdown = ChoreCountdown - 1000;
  CurrentMillis = millis();
  F_timeDisplay();
 
  // If there is less than 5 minutes of ChoreTime left start sounding an audible alarm at the interval defined.
  if (ChoreCountdown <= 300000) { // 5 min
  if (millis() - LastWarningTime > WarningBeepInterval1) {
  F_warning1();
  }

  // Or if there is less than 10 seconds of ChoreTime left start sounding an audible alarm at the interval defined.
  else if (ChoreCountdown <= 10000) { // 10 seconds
  if (millis() - LastWarningTime > WarningBeepInterval2) {
  F_warning2();
  }
  }
  }
  }

  if (ChoreCountdown == 0) {
  lcd.clear();
  F_warning3();
  state = S_ready;
  }

}

////////////////////////////////////////////////////////////

void F_timeDisplay() {

  lcd.setCursor(4, 1);

  if (PlaytimeRun == true) {
  int seconds = AllowedPlaytime / 1000;
  int minutes = seconds / 60;
  int hours = minutes / 60;
 
  seconds = seconds % 60;
  minutes = minutes % 60;
 
  if (hours < 10) {
  lcd.print("0");
  lcd.print(hours);
  lcd.print(":");
 
  if (minutes < 10)
  lcd.print("0");
  lcd.print(minutes);
  lcd.print(":");
 
  if (seconds < 10) 
  lcd.print("0"); 
  lcd.print(seconds);
  }
  }

  else if (ChoretimeRun == true) {
  int seconds = ChoreCountdown / 1000;
  int minutes = seconds / 60;
  int hours = minutes / 60;
 
  seconds = seconds % 60;
  minutes = minutes % 60;

  if (hours < 10) {
  lcd.print("0");
  lcd.print(hours);
  lcd.print(":");
 
  if (minutes < 10)
  lcd.print("0");
  lcd.print(minutes);
  lcd.print(":");
 
  if (seconds < 10) 
  lcd.print("0"); 
  lcd.print(seconds);
  }
  }

}

////////////////////////////////////////////////////////////

void F_video_on() {

  if (OverrideRun == true) {
  OverrideRun = false;
  lcd.clear();
  }

  if (CountdownRun == true) {
  CountdownRun = false;
  lcd.clear();
  }

  LCDBacklight(0, 255, 0); // Green
  lcd.setCursor(5, 0);
  lcd.print("Standby");
  lcd.setCursor(0, 1);
  lcd.print("Turning Video On");

  unsigned long CurrentMillis = millis();
 
  if(CurrentMillis - SwitchPreviousMillis > VideoSwitchInterval) {
  SwitchPreviousMillis = CurrentMillis; 
  if (VideoSwitchState == LOW)
  VideoSwitchState = HIGH;
  else
  VideoSwitchState = LOW;
  digitalWrite(VideoSW, VideoSwitchState);
  }

  ClearLCD = true;

}

////////////////////////////////////////////////////////////

void F_video_off() {

  unsigned long CurrentMillis = millis();
 
  if(CurrentMillis - SwitchPreviousMillis > VideoSwitchInterval) {
  SwitchPreviousMillis = CurrentMillis; 
  if (VideoSwitchState == LOW)
  VideoSwitchState = HIGH;
  else
  VideoSwitchState = LOW; 
  digitalWrite(VideoSW, VideoSwitchState);
  }

}

////////////////////////////////////////////////////////////

void F_warning1() {

  tone(Speaker, 500, 1000);
  LastWarningTime = millis();

}

////////////////////////////////////////////////////////////

void F_warning2() {

  tone(Speaker, 1000, 200);
  LastWarningTime = millis();

}

////////////////////////////////////////////////////////////

void F_warning3() {

  tone(Speaker, 2000, 1000);
  LastWarningTime = millis();
}

////////////////////////////////////////////////////////////

// Taken from the adafruit LCD turorial
void LCDBacklight(uint8_t r, uint8_t g, uint8_t b) {

  // common anode so invert!
  r = map(r, 0, 255, 255, 0);
  g = map(g, 0, 255, 255, 0);
  b = map(b, 0, 255, 255, 0);
  analogWrite(LCDr, r);
  analogWrite(LCDg, g);
  analogWrite(LCDb, b);

}
 
Last edited by a moderator:
I want to remove those states in RED


his sketch was written to work with a simple arcade style coin mechanism in conjunction with an HDMI switch to allow
you to require the inserting of a coin in order to use the XBOX. While I used this for an XBOX there is nothing XBOX
specific about the code and it should work swimmingly with any device that outputs video over HDMI.

For more information see - **broken link removed** or ping adam@adambyers.com

Coin Operated XBOX
Copyright (C) 2013 Adam Byers

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
C:
**********************************************************************************************************************/

// include the Arduino LCD libraries
#include <LiquidCrystal.h>

// States
#define S_ready 1
[COLOR=#ff0000]#define S_coin 2
#define S_pause 3
#define S_override 4
#define S_limit 5[/COLOR]
#define S_countdown 6
[COLOR=#ff0000]#define S_choretime 7[/COLOR]

// Default start up state
int state = S_ready;

// LCD PINs
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// Display back-light pins
const int LCDr = 3;
const int LCDg = 5;
const int LCDb = 6;

// Other PINs
const int CoinSW = 2;
const int VideoSW = 4;
const int StartSW = A0;
const int PauseSW = A1;
const int CoinLED = A2;
const int OverrideSW = A3;
const int VideoDetect  = A4;
const int Speaker = A5;

// Button debounce vars
int buttonState;
int lastButtonState = HIGH;
long lastDebounceTime = 0;
long debounceDelay = 40; // May have to play with this value to get coins to register properly.

// Coin counting and time vars
unsigned long AllowedPlaytime;
unsigned long ChoreTime = 30; // How long (in miniutes) do you want the chore time (manditory pause) to last.
unsigned long ChoreCountdown;
unsigned long CurrentMillis;
int CoinCount = 0;
int CoinTimeValue = 30; // Amount of time (in minutes) that the coin is worth.
int DepositStringIndex = 0;
int TimeStringIndex = 0;

// Video on/off switching vars
int VideoSwitchState = LOW;
long VideoSwitchBuffer = 2000; // Used to add some seconds (2 seconds to be precise) to AllowedPlaytime after video ON switching event to compensate for TV sync time.
unsigned long SwitchPreviousMillis = 0;
long VideoSwitchInterval = 1000; // How long (in milliseconds) we "hold down" the HDMI input selector button when switching inputs.

// Warning beep vars
unsigned long LastWarningTime = 0;
long WarningBeepInterval1 = 60000; // 60 seconds
long WarningBeepInterval2 = 1000; // 1 seconds

// Used to get the LCD to clear properly when switching between states.
bool ClearLCD = false;
bool PauseRun = false;
bool OverrideRun = false;
bool CountdownRun = false;

// Used for selection of time values to dislayu depending on what state the system is running in.
bool PlaytimeRun = false;
bool ChoretimeRun = false;

// Arms up characters for display on the LCD.
byte armsUp[8] = {
  0b00100,
  0b01010,
  0b00100,
  0b10101,
  0b01110,
  0b00100,
  0b00100,
  0b01010
};

// Strings for the deposit display
char* DepositStrings[]= {
"$0.00", // Place holder does not display.
"$0.25", // 30 min
"$0.50", // 1 hour - does not display
};

char* TimeStrings[]= {
"$0.00", // Place holder does not display.
"30m  ",
"1h  ", // 1 hour - does not display
};

void setup() {
// Initialize the LCD
lcd.begin(16, 2);

// Set PINs as inputs or outputs.
pinMode(LCDr, OUTPUT);
pinMode(LCDg, OUTPUT);
pinMode(LCDb, OUTPUT);
pinMode(VideoSW, OUTPUT);
pinMode(Speaker, OUTPUT);
pinMode(CoinSW, INPUT);
pinMode(StartSW, INPUT);
pinMode(PauseSW, INPUT);
pinMode(CoinLED, OUTPUT);
pinMode(OverrideSW, INPUT);
pinMode(VideoDetect,INPUT);

// Enable internal resistors (set inputs as HIGH) on button PINs so we don't have to use external resistors.
digitalWrite(CoinSW, HIGH);
digitalWrite(StartSW, HIGH);
digitalWrite(PauseSW, HIGH);
digitalWrite(OverrideSW, HIGH);
digitalWrite(VideoDetect, HIGH);

// Initialize special LCD characters.
lcd.createChar(1, armsUp);

}

void loop() {

  switch(state) {
  
  case S_ready:
  F_ready();
  break;
    
  case S_override:
  F_override();
  break;
  
  case S_coin:
  F_coin();
  break;
  
  case S_limit:
  F_limit();
  break;
  
  case S_countdown:
  F_countdown();
  break;
  
  case S_choretime:
  F_choretime();
  break;
  
  case S_pause:
  F_pause();
  break;  
  }
  
}

// Functions //

////////////////////////////////////////////////////////////

void F_ready() {

  // Because the HDMI switch will automatically switch from an inactive input to an active input we have to make sure that the video is off and stays off in every state to prevent abuse.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(0, 255, 0); // Green
  lcd.setCursor(4, 0);
  lcd.write(1);
  lcd.print(" READY ");
  lcd.write(1);
  lcd.setCursor(2, 1);
  lcd.print("Insert Coins");

  DepositStringIndex = 0; // Reset
  TimeStringIndex = 0; // Reset
  CoinCount = 0; // Reset

  // Only state the override can be turned on is here.
  if (digitalRead(OverrideSW) == LOW){
  lcd.clear();
  state = S_override;
  }

  digitalWrite(CoinLED, HIGH);

  if (digitalRead(CoinSW) == LOW) {
  lcd.clear();
  state = S_coin;
  }

}

////////////////////////////////////////////////////////////

void F_override() {

  // Turn the video on.
  while (digitalRead(VideoDetect) == HIGH) {
  F_video_on();
  }

  if (ClearLCD == true) {
  ClearLCD = false;
  lcd.clear();
  }

  OverrideRun = true;

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(3, 0);
  lcd.print("Override On");
  lcd.setCursor(2, 1);
  lcd.print(" Lucky You ");

  digitalWrite(CoinLED, LOW);

  if (digitalRead(OverrideSW) == HIGH){
  lcd.clear();
  state = S_ready;
  }  

}

////////////////////////////////////////////////////////////

void F_coin() {

  // If it's on, turn the video off.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(0, 0, 255); // Blue
  lcd.setCursor(0, 0);
  lcd.print("Deposited:");
  lcd.print(DepositStrings[DepositStringIndex]);
  lcd.setCursor(0, 1);
  lcd.print("Playtime:");
  lcd.print(TimeStrings[TimeStringIndex]);

  // We need to debounce the coin counting switch. Otherwise we'd count several coins when only one was deposited.
  int reading = digitalRead(CoinSW) == LOW;

  if (reading != lastButtonState) {
  lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
  if (reading != buttonState) {
  buttonState = reading;
  if (buttonState == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  CoinCount = CoinCount + CoinTimeValue; // Count the coin deposit.
  DepositStringIndex++;
  TimeStringIndex++;
  }
  }
  }

  lastButtonState = reading;
  // Done debouncing and depositing.

  if (DepositStringIndex == 2) { // We only allow 1 hour of playtime. Player can deposit more coins if they want but the system won't count them after this point.
  lcd.clear();
  digitalWrite(CoinLED, LOW);
  state = S_limit;
  }

  if (digitalRead(StartSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  digitalWrite(CoinLED, LOW);
  AllowedPlaytime = CoinCount * 60000; // Multiply the CoinCount by 60000 (milliseconds) to get the AllowedPlaytime.
  AllowedPlaytime = AllowedPlaytime + VideoSwitchBuffer; // Add some time (VideoSwitchBuffer) to make up for the time it took the TV to sync back up and display video.
  state = S_countdown;
  }

}

////////////////////////////////////////////////////////////

void F_limit() {

  // If it's on, turn the video off.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(2, 0);
  lcd.print("1 Hour Limit");
  lcd.setCursor(3, 1);
  lcd.print("Press START");

  if (digitalRead(StartSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  AllowedPlaytime = CoinCount * 60000; // Multiply the CoinCount by 60000 (milliseconds) to get the AllowedPlaytime.
  AllowedPlaytime = AllowedPlaytime + VideoSwitchBuffer; // Add some time (VideoSwitchBuffer) to make up for the time it took the TV to sync back up and display video.
  state = S_countdown;
  }

}

////////////////////////////////////////////////////////////

void F_countdown() {

  // Turn the video on.
  while (digitalRead(VideoDetect) == HIGH) { 
  F_video_on();
  }

  if (ClearLCD == true) {
  lcd.clear();
  ClearLCD = false;
  }

  CountdownRun = true; // Used to get the LCD to clear properly when switching between states.
  PlaytimeRun = true; // Used to set the correct time values to display.

  LCDBacklight(0, 0, 255); // Blue
  lcd.setCursor(2, 0);
  lcd.print("Time Started:");

  // If second has passed then we subtract that from the AllowedPlaytime
  if (millis() - CurrentMillis > 1000) {
  AllowedPlaytime = AllowedPlaytime - 1000;
  CurrentMillis = millis();
  F_timeDisplay();
  
  // If there is less than 5 minutes of playtime left start sounding an audible alarm at the interval defined. 
  if (AllowedPlaytime <= 300000) { // 5 min
  if (millis() - LastWarningTime > WarningBeepInterval1) {
  F_warning1();
  }

  // Or if there is less than 10 seconds of playtime left start sounding an audible alarm at the interval defined.
  else if (AllowedPlaytime <= 10000) { // 10 seconds
  if (millis() - LastWarningTime > WarningBeepInterval2) {
  F_warning2();
  }
  }
  }
  }

  if (digitalRead(PauseSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  state = S_pause;
  }

  if (AllowedPlaytime == 0) {
  lcd.clear();
  PlaytimeRun = false;
  ChoreCountdown = ChoreTime * 60000;
  F_warning3();
  state = S_choretime;
  }

}

////////////////////////////////////////////////////////////

void F_pause() {

  // Turn the video off to prevent abuse of the pause.
  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(2, 0);
  lcd.print("Time Paused:");
  F_timeDisplay();
  
  if (digitalRead(StartSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
  lcd.clear();
  AllowedPlaytime = AllowedPlaytime + VideoSwitchBuffer; // Add some time (VideoSwitchBuffer) to make up for the time it took to turn the video on.
  state = S_countdown;
  }

}

////////////////////////////////////////////////////////////
void F_choretime() {

  while (digitalRead(VideoDetect) == LOW) {
  F_video_off();
  }

  ChoretimeRun = true;

  LCDBacklight(255, 0, 0); // Red
  lcd.setCursor(1, 0);
  lcd.write(1);
  lcd.print(" Chore Time ");
  lcd.write(1);

  // If second has passed then we subtract that from the ChoreTime
  if (millis() - CurrentMillis > 1000) {
  ChoreCountdown = ChoreCountdown - 1000;
  CurrentMillis = millis();
  F_timeDisplay();
  
  // If there is less than 5 minutes of ChoreTime left start sounding an audible alarm at the interval defined. 
  if (ChoreCountdown <= 300000) { // 5 min
  if (millis() - LastWarningTime > WarningBeepInterval1) {
  F_warning1();
  } 

  // Or if there is less than 10 seconds of ChoreTime left start sounding an audible alarm at the interval defined.
  else if (ChoreCountdown <= 10000) { // 10 seconds
  if (millis() - LastWarningTime > WarningBeepInterval2) {
  F_warning2();
  }
  }
  }
  }

  if (ChoreCountdown == 0) {
  lcd.clear();
  F_warning3();
  state = S_ready;
  }

}

////////////////////////////////////////////////////////////

void F_timeDisplay() {

  lcd.setCursor(4, 1);

  if (PlaytimeRun == true) {
  int seconds = AllowedPlaytime / 1000;
  int minutes = seconds / 60;
  int hours = minutes / 60;
  
  seconds = seconds % 60;
  minutes = minutes % 60;
  
  if (hours < 10) {
  lcd.print("0");
  lcd.print(hours);
  lcd.print(":");
  
  if (minutes < 10)
  lcd.print("0");
  lcd.print(minutes);
  lcd.print(":");
  
  if (seconds < 10)  
  lcd.print("0");  
  lcd.print(seconds);
  }
  }

  else if (ChoretimeRun == true) {
  int seconds = ChoreCountdown / 1000;
  int minutes = seconds / 60;
  int hours = minutes / 60;
  
  seconds = seconds % 60;
  minutes = minutes % 60;

  if (hours < 10) {
  lcd.print("0");
  lcd.print(hours);
  lcd.print(":");
  
  if (minutes < 10)
  lcd.print("0");
  lcd.print(minutes);
  lcd.print(":");
  
  if (seconds < 10)  
  lcd.print("0");  
  lcd.print(seconds);
  }
  }

}

////////////////////////////////////////////////////////////

void F_video_on() {

  if (OverrideRun == true) {
  OverrideRun = false;
  lcd.clear();
  }

  if (CountdownRun == true) {
  CountdownRun = false;
  lcd.clear();
  }

  LCDBacklight(0, 255, 0); // Green
  lcd.setCursor(5, 0);
  lcd.print("Standby");
  lcd.setCursor(0, 1);
  lcd.print("Turning Video On");

  unsigned long CurrentMillis = millis();
  
  if(CurrentMillis - SwitchPreviousMillis > VideoSwitchInterval) {
  SwitchPreviousMillis = CurrentMillis;  
  if (VideoSwitchState == LOW)
  VideoSwitchState = HIGH;
  else
  VideoSwitchState = LOW;
  digitalWrite(VideoSW, VideoSwitchState);
  }

  ClearLCD = true;

}

////////////////////////////////////////////////////////////

void F_video_off() {

  unsigned long CurrentMillis = millis();
  
  if(CurrentMillis - SwitchPreviousMillis > VideoSwitchInterval) {
  SwitchPreviousMillis = CurrentMillis;  
  if (VideoSwitchState == LOW)
  VideoSwitchState = HIGH;
  else
  VideoSwitchState = LOW;  
  digitalWrite(VideoSW, VideoSwitchState);
  }

}

////////////////////////////////////////////////////////////

void F_warning1() {

  tone(Speaker, 500, 1000);
  LastWarningTime = millis();

}

////////////////////////////////////////////////////////////

void F_warning2() {

  tone(Speaker, 1000, 200);
  LastWarningTime = millis();

}

////////////////////////////////////////////////////////////

void F_warning3() {

  tone(Speaker, 2000, 1000);
  LastWarningTime = millis();
}

////////////////////////////////////////////////////////////

// Taken from the adafruit LCD turorial
void LCDBacklight(uint8_t r, uint8_t g, uint8_t b) {

  // common anode so invert!
  r = map(r, 0, 255, 255, 0);
  g = map(g, 0, 255, 255, 0);
  b = map(b, 0, 255, 255, 0);
  analogWrite(LCDr, r);
  analogWrite(LCDg, g);
  analogWrite(LCDb, b);

}
 
Last edited by a moderator:
Hi, I found a C code related to LCD, hope it help
Code:
#include<16f877a.h>
#device *=16 adc=10
#include <math.h>
#include <string.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <LCD4bit.h>
#use i2c(Master,Slow,sda=PIN_B1,scl=PIN_B0)
int set=0;
int mod=0;
byte giay,phut,gio, ngay,thang, nam;
byte BCD2DEC(byte bcd)// Function converts BCD to Decimal
{
byte h;
byte l;
byte dec;
h = bcd / 16;
l = bcd % 16;
dec = (h * 10) + l;
return dec;
}
byte DEC2BCD(byte dec)//Function converts Decimal to BCD
{
byte h;
byte l;
byte bcd;
h = dec / 10;
l = dec % 10;
bcd = (h << 4) + l;
return bcd;
}
void hienthi(int8 dec)// Function displays a number on LCD
{
LCD_Char(dec/10 + 48);
LCD_Char(dec%10 + 48);
}
void ghidl(byte address, BYTE data)// Function writes data to DS1307
{
i2c_start();
i2c_write(0xd0);// Send the address
i2c_write(address);// Pointer to address
i2c_write(data);// Write data to the address
i2c_stop();
}
BYTE docdl(byte address)
{
BYTE data;
i2c_start();
i2c_write(0xd0);//Send the address
i2c_write(address);// Pointer to addr
i2c_stop();
i2c_start();
i2c_write(0xd1);// Send read data command
data=i2c_read(0);
i2c_stop();
return(data);
}
void update_Ds1307()
{
ghidl(0, 0); // update second
delay_ms(5);
ghidl(1, DEC2BCD(phut));// update minute
delay_ms(5);
ghidl(2, DEC2BCD(gio));// update hour
delay_ms(5);
ghidl(4, DEC2BCD(ngay));// update day
delay_ms(5);
ghidl(5, DEC2BCD(thang)); // update month
delay_ms(5);
ghidl(6, DEC2BCD(nam));// update year
delay_ms(5);
}
#int_RB
void chinh_gio()
{
if (input(PIN_B4)==0)// adjust time
{
if (set==0)// start adjusting time
{
set=1;
mod=1;
}
else // update DS1307
{
set=0;
mod=0;
}
}
else if (input(PIN_B5)==0)// set required time
{
mod++;
if (mod==7) mod=1;
}
else if (input(PIN_B6)==0)// increase
{
if (set==1)
switch(mod)
{
case 1:
gio++;
if (gio==24) gio=0;
break;
case 2:
phut++;
if (phut==60) phut=0;
break;
case 3:
ngay++;
if((ngay==30)&(thang==4)||(thang==6)||(thang==9)||(thang==11))
ngay=1;
else if((thang==2)&&(nam%4==0)&&(ngay==30)) ngay=1;
else if ((thang==2)&&(nam%4!=0)&&(ngay==29)) ngay=1;
else if (ngay==32) ngay=1;
break;
case 4:
thang++;
if (thang==13) thang=1;
break;
case 5:
nam++;
if (nam==100) nam=0;
break;
}
}
else if (input(PIN_B7)==0)// giam
{
switch(mod)
{
case 1:
if (gio==0) gio=24;
gio--;
break;
case 2:
if (phut==0) phut=60;
phut--;
break;
case 3:
ngay--;
if((ngay==0)&(thang==4)||(thang==6)||(thang==9)||(thang==11))
ngay=30;
else if((thang==2)&&(nam%4==0)&&(ngay==0)) ngay=29;
else if ((thang==2)&&(nam%4!=0)&&(ngay==0)) ngay=28;
else if (ngay==0) ngay=31;
break;
case 4:
thang--;
if (thang==0) thang=12;
break;
case 5:
nam--;
if (nam==0) nam=99;
break;
}
}
else return;
}
void main()
{
enable_interrupts(INT_RB);
enable_interrupts(global);
LCD_init();// khoi tao LCD
LCD_Position(0x84);
LCD_Char("LE MINH HA");
LCD_Position(0xC5);
LCD_char("TC2052");
delay_ms(200);
LCD_cmd(0x01);// xoa man hinh
LCD_Position(0x80);
LCd_char("Time");
LCD_Position(0xc0);
LCD_char("Date");
While (TRUE)
{
if (set == 0)// lay thoi gian
{
giay=BCD2DEC(docdl(0));
delay_us(100);
phut=BCD2DEC(docdl(1));
delay_us(100);
gio =BCD2DEC(docdl(2));
delay_us(100);
ngay=BCD2DEC(docdl(4));
delay_us(100);
thang=BCD2DEC(docdl(5));
delay_us(100);
nam=BCD2DEC(docdl(6));
delay_us(100);
}
if (set==1)
update_ds1307();
// hien thi
LCD_Position(0x85);
hienthi(gio);
LCD_char(":");
hienthi(phut);
LCD_char(":");
hienthi(giay);
LCD_Position(0xc5);
hienthi(ngay);
LCD_char(":");
hienthi(thang);
LCD_char(":");
hienthi(nam);
// twinkling while adjust time
switch(mod)
{
case 1: // config hour
LCD_Position(0x85);
LCD_char(" ");
delay_ms(30);
break;
case 2: // configure minute
LCD_Position(0x88);
LCD_Char(" ");
delay_ms(30);
break;
case 3: // configure year
LCD_Position(0xc5);
LCD_char(" ");
delay_ms(30);
break;
case 4: // configure month
LCD_Position(0xc8);
LCD_char(" ");
delay_ms(30);
break;
case 5: // configure day
LCD_Position(0xcb);
LCD_char(" ");
delay_ms(30);
break;
}
}
}
Source for reference: https://electel.blogspot.com/2015/03/digital-watch-clock-circuit-using-lcd-pic16F877a.html
 
I did this like three years ago I think I still have code for both LCD and 7 seg.
 
bentro,

I want to remove those states in RED

Are you simple asking for help to "remove those states in RED" or did you mean something else?

If so, which group are you referring to: those in post #9 or those on post #10?

In either case, are you saying that you don't know how to remove the code or are you asking should you remove the code?

If I may ask, are you familiar with the Arduino IDE (integrated development environment) that can be downloaded for free from here: https://www.arduino.cc/en/Main/Software. This will provide you (if you use one of the Arduino mico-controllers) with the tool(s) to edit, recreate, upload and debug the code (sketches) that you listed above.

Just not sure what it is you are asking for...
 
There are 7 states in which those in red are not really needed for me.

I just want a ready state, where it accepts coins and start the count down right away and can be incremented when another coin is accepted.

I have here the board, the LCD and the coin acceptor. Arduino IDE on my PC.

The code works, the LCD displays every states.

But when I try to edit it just won't work. ( I am not a programmer)
 
I'll fix the code you posted maybe by today when I get up I work at night right now see what I can do.
It probably be easier to just write it all new.
 
I was looking back to the code you first posted it wouldn't take a much at all to change to use a LCD
Code:
int coinPin = 2; //can change to anything you need
int relayPin = 5; //can change to anything you need

long time; //will keep track of the time the video should be turned off at
long timeToAddPerCoin = 420000; //420000 ms = 7min
long countdownDisplaytimer; //will keep track of when we should display

boolean isPlaying;

void setup(){
pinMode(coinPin, INPUT);
digitalWrite(coinPin, HIGH); // turn on pullup resistor

pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);

pinMode(13, OUTPUT); //for the LED

Serial.begin(9600);

time = millis(); //set to right now, as the video should start off
countdownDisplaytimer = millis(); //set to right now
isPlaying = false;
}


void loop(){
if(digitalRead(coinPin) == LOW){ //assuming it goes high on coin insert
delay(500); //just to debounce

if(isPlaying){ //is video playing already?



time += timeToAddPerCoin; //add 7 minutes (420000 ms) to the time we need to turn the video off at

Serial.print("playing for ");
Serial.print(time / 60000);
Serial.println(" minutes");
}else{
time = millis() + timeToAddPerCoin; //set time to 7 minutes from now.
Serial.println("playing for 7 minutes");
isPlaying = true;
}

}

long timeLeft = time - millis();
long timeLeftInSeconds = timeLeft / 1000;
long timeSinceLastDisplay = millis() - countdownDisplaytimer;

if(timeLeft > 0){ //is there time left, and should keep playing the video?
//Serial.println(timeLeft); //DEBUGGING ONLY!!!
digitalWrite(relayPin, HIGH); //turn on the relay
digitalWrite(13, HIGH); // turn the LED next to pin 13
isPlaying = true;

if(countdownDisplaytimer > 1000){ //has it been a second since last diaplay?
countdownDisplaytimer = millis(); //reset timer
Serial.print(timeLeftInSeconds);
Serial.println(" seconds left");
}


}else{
digitalWrite(relayPin, LOW); //time ran out, turn off the relay
digitalWrite(13, LOW); // turn off LED next to pin 13
isPlaying = false;
}


}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top