1

I have two different codes. The first one makes a LCD screen count the time and print it, then when one of the buttons on the LCD shield itself is pressed, it prints the time on the top line that it was pressed. That's the one below, I apologize that it has a lot of notes though it so unless it's in the Arduino program it looks confusing.

/*--------------------------------------------------------------------------    ------------
 Includes
 --------------------------------------------------------------------------------------*/
#include <Wire.h>
#include <LiquidCrystal.h>   // include LCD library
/*--------------------------------------------------------------------------------------
 Defines
 --------------------------------------------------------------------------------------*/
// Pins in use
#define MILLIS_OVERFLOW 34359738
#define BUTTON_ADC_PIN           A0  // A0 is the button ADC input
#define LCD_BACKLIGHT_PIN         3  // D3 controls LCD backlight
// ADC readings expected for the 5 buttons on the ADC input
#define RIGHT_10BIT_ADC           0  // right
#define UP_10BIT_ADC            145  // up
#define DOWN_10BIT_ADC          329  // down
#define LEFT_10BIT_ADC          505  // left
#define SELECT_10BIT_ADC        741  // right
#define BUTTONHYSTERESIS         10  // hysteresis for valid button sensing           window
//return values for ReadButtons()
#define BUTTON_NONE               0  // 
#define BUTTON_RIGHT              1  // 
#define BUTTON_UP                 2  // 
#define BUTTON_DOWN               3  // 
#define BUTTON_LEFT               4  // 
#define BUTTON_SELECT             5  // 
//some example macros with friendly labels for LCD backlight/pin control, tested and can be swapped into the example code as you like
#define LCD_BACKLIGHT_OFF()     digitalWrite( LCD_BACKLIGHT_PIN, LOW )
#define LCD_BACKLIGHT_ON()      digitalWrite( LCD_BACKLIGHT_PIN, HIGH )
#define LCD_BACKLIGHT(state)    { if( state ){digitalWrite(     LCD_BACKLIGHT_PIN, HIGH );}else{digitalWrite( LCD_BACKLIGHT_PIN, LOW );} }
/*--------------------------------------------------------------------------------------
 Variables
 --------------------------------------------------------------------------------------*/
unsigned long currentMillis, previousMillis, elapsedMillis;
int seconds = 0, minutes = 34, hours = 8;

byte buttonJustPressed  = false;         //this will be true after a          ReadButtons() call if triggered
byte buttonJustReleased = false;         //this will be true after a         ReadButtons() call if triggered
    byte buttonWas          = BUTTON_NONE;   //used by ReadButtons() for     detection of button events
        /*--------------------------------------------------------------------------------------
     Init the LCD library with the LCD pins to be used
 --------------------------------------------------------------------------------------*/
       LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );   //Pins for the freetronics 16x2 LCD     shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )
/*--------------------------------------------------------------------------------------
     setup()
     Called by the Arduino framework once, before the main loop begins
 --------------------------------------------------------------------------------------*/
    void setup()
    {
  //button adc input
      pinMode( BUTTON_ADC_PIN, INPUT );         //ensure A0 is an input
      digitalWrite( BUTTON_ADC_PIN, LOW );      //ensure pullup is off on A0
  //lcd backlight control
  digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  //backlight control pin D3 is         high (on)
  pinMode( LCD_BACKLIGHT_PIN, OUTPUT );     //D3 is an output
  //set up the LCD number of columns and rows: 
  lcd.begin( 16, 2 );

  //Print some initial text to the LCD.
  Serial.begin(9600);
  lcd.begin( 16, 2 ); 



}
/*--------------------------------------------------------------------------------------
 loop()
 Arduino main loop
 --------------------------------------------------------------------------------------*/
void loop()
{
  setClock();
  byte button;


  button = ReadButtons();


  /**
   * After set clock now you have 3 int variables with the current time
   */
  //seconds
  //minutes
  //hours
  lcd.setCursor ( 0, 1);
  lcd.print(hours);
  lcd.print(":");
  lcd.print(minutes);
  lcd.print(":");
  lcd.print(seconds);
  lcd.print(":");
  lcd.print(elapsedMillis);


      //get the latest button pressed, also the buttonJustPressed,     buttonJustReleased flags

  //blank the demo text line if a new button is pressed or released, ready for a new label to be written

  //show text label for the button pressed
   if(buttonJustPressed || buttonJustReleased)
  switch( button )
  {

  case BUTTON_LEFT:
    {
      lcd.setCursor( 0, 0 );
               lcd.print(hours);
               lcd.print(":");
               lcd.print(minutes);
               lcd.print(":");
               lcd.print(seconds);
               lcd.print(":");
               lcd.print(elapsedMillis);

      break;         

    }
  default:
    {
      break;
    }
  }

  if( buttonJustPressed )
    buttonJustPressed = false;
  if( buttonJustReleased )
    buttonJustReleased = false;
}
     /*--------------------------------------------------------------------------------------
     ReadButtons()
     Detect the button pressed and return the value
     Uses global values buttonWas, buttonJustPressed, buttonJustReleased.
 --------------------------------------------------------------------------------------*/
        byte ReadButtons()
    {
  unsigned int buttonVoltage;
  byte button = BUTTON_NONE;   // return no button pressed if the below         checks don't write to btn

  //read the button ADC pin voltage
  buttonVoltage = analogRead( BUTTON_ADC_PIN );
  //sense if the voltage falls within valid voltage windows
  if( buttonVoltage < ( RIGHT_10BIT_ADC + BUTTONHYSTERESIS ) )
  {
    button = BUTTON_RIGHT;
  }
  else if(   buttonVoltage >= ( UP_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( UP_10BIT_ADC + BUTTONHYSTERESIS ) )
  {
    button = BUTTON_UP;
  }
  else if(   buttonVoltage >= ( DOWN_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( DOWN_10BIT_ADC + BUTTONHYSTERESIS ) )
  {
    button = BUTTON_DOWN;
  }
  else if(   buttonVoltage >= ( LEFT_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( LEFT_10BIT_ADC + BUTTONHYSTERESIS ) )
  {
    button = BUTTON_LEFT;
  }
  else if(   buttonVoltage >= ( SELECT_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( SELECT_10BIT_ADC + BUTTONHYSTERESIS ) )
  {
    button = BUTTON_SELECT;
  }
  //handle button flags for just pressed and just released events
  if( ( buttonWas == BUTTON_NONE ) && ( button != BUTTON_NONE ) )
  {
    //the button was just pressed, set buttonJustPressed, this can optionally be used to trigger a once-off action for a button press event
//it's the duty of the receiver to clear these flags if it wants to detect a new button change event
    buttonJustPressed  = true;
    buttonJustReleased = false;
  }
  if( ( buttonWas != BUTTON_NONE ) && ( button == BUTTON_NONE ) )
  {
    buttonJustPressed  = false;
    buttonJustReleased = true;
  }

  //save the latest button value, for change event detection next time round
  buttonWas = button;

  return( button );
}
void setClock()
{
  currentMillis = millis();
      /**
   * The only moment when currentMillis will be smaller than previousMillis
   * will be when millis() oveflows
   */
  if (currentMillis < previousMillis){
    elapsedMillis += MILLIS_OVERFLOW - previousMillis + currentMillis;
  } 
  else {
    elapsedMillis += currentMillis - previousMillis;
  }

  /**
   * If we use equals 1000 its possible that because of the mentioned loop     limitation
   * you check the difference when its value is (999) and on the next loop its value is (1001)
   */
  if (elapsedMillis > 999){
    seconds++;
    elapsedMillis = elapsedMillis - 1000;
  }

  if (seconds == 60){
    minutes++;
    seconds = 0;
  }
  if (minutes == 60){
    hours++;
    minutes = 0;
  }
  if (hours == 24){
    hours = 0;
  }

  previousMillis = currentMillis;
    }

The next code is to control the speaker and makes it play happy birthday when the a proximity sensor is set off. I need to somehow merge the two codes so that when the proximity sensor is set off the speaker plays the sound, but so that the clock continues to still count. Does anyone know how I can do this?

#include <Wire.h>
#include <LiquidCrystal.h>

int timer = 1000;
int C = 262;
int D = 294;
int E = 330;
int F = 349;
int G = 392;
int A = 440;
int B = 494;
int Bflat = 466;
int Chigh = 523;


LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );
const int analogPin = A1;    // pin that the sensor is attached to
const int threshold = 400;

void setup() 
{
     // initialize serial communications at 9600 bps:
     Serial.begin(9600);
     pinMode(10, OUTPUT); // Red LED
     pinMode(12, OUTPUT); // Yellow LED
     pinMode(11, OUTPUT); // Green LED
     pinMode(13, OUTPUT); // Speaker
         lcd.begin(16, 2);
 }
void loop()
{
 int analogValue = analogRead(analogPin);

  if (analogValue > threshold) {

tone(13,C,timer/2);// Happy Bday to You
delay(200);
tone(13,C,timer/2);
delay(200);
tone(13,D,timer/2);
delay(400);
tone(13,C,timer/2);
delay(400);
tone(13,F,timer/2);
delay(400);
tone(13,E,timer);
delay(750);

 }
else {
}
}
  • 1
    Step one is to do away with all those horrible delay() calls – Majenko May 30 '15 at 8:23
  • 1
    Just change if (elapsedMillis > 999){ to while (elapsedMillis > 999){ and add the loop code of the music to the loop code of the lcd. The only downside is that the display will not update while the melody is playing. But it will update after the 5 tones are played. But it won't miss any seconds. – Gerben May 30 '15 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.