merging code, display multiple "screens" of info on LCD

ok so what im trying to do is display time and Temps from a DS1307 and LM35 on a 4x20 serial LCD. i can do them individually with a separate programs for each, but i would like to put them into one program and use a momentary switch to change what the LCD is displaying.

like when the Arduino starts it displays the time. then i would have two momentary switches below the LCD, one when pressed would show temps on the lcd, the other when pressed would show time.

the arduino code

////////TEMPS////////
#include <SoftwareSerial.h>

#define txPin 2

//LM35 Pin Variables
int sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
//the resolution is 10 mV / degree centigrade with a
//500 mV offset to allow for negative temperatures

SoftwareSerial LCD = SoftwareSerial(0, txPin);
// since the LCD does not send data back to the Arduino, we should only define the txPin
const int LCDdelay=10;  // conservative, 2 actually works

// wbp: goto with row & column
void goTo(int row, int col) {
  LCD.print(0xFE, BYTE);   //command flag
  LCD.print((col + row*64 + 128), BYTE);    //position 
  delay(LCDdelay);
}
void clearLCD(){
  LCD.print(0xFE, BYTE);   //command flag
  LCD.print(0x01, BYTE);   //clear command.
  delay(LCDdelay);
}
void backlightOn() {  //turns on the backlight
  LCD.print(0x7C, BYTE);   //command flag for backlight stuff
  LCD.print(157, BYTE);    //light level.
  delay(LCDdelay);
}
void backlightOff(){  //turns off the backlight
  LCD.print(0x7C, BYTE);   //command flag for backlight stuff
  LCD.print(128, BYTE);     //light level for off.
  delay(LCDdelay);
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  LCD.print(0xFE, BYTE);
}

void setup()
{
  pinMode(txPin, OUTPUT);
  LCD.begin(9600);
  clearLCD();
}

void loop()                     // run over and over again
{
  //getting the voltage reading from the temperature sensor
  int reading = analogRead(sensorPin);  

  // converting that reading to voltage, for 3.3v arduino use 3.3
  float voltage = reading * 5.0;
  voltage /= 1024.0; 

  // print out the voltage
  //Serial.print(voltage); Serial.println(" volts");

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  //to degrees ((volatge - 500mV) times 100)
  //Serial.print(temperatureC); Serial.println(" degress C");

  // now convert to Fahrenheight
  int temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
  goTo(0,0);
  LCD.print(temperatureF); 
  LCD.print(" degrees F");
  delay(900);
  clearLCD();
  delay(100);                                     //waiting a second
}
//////TIME//////
/*
 * TimeRTC.pde
 * example code illustrating Time library with Real Time Clock.
 * 
 */

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>// a basic DS1307 library that returns time as a time_t
#include <SoftwareSerial.h>
#define txPin 2

SoftwareSerial LCD = SoftwareSerial(0, txPin);
// since the LCD does not send data back to the Arduino, we should only define the txPin
const int LCDdelay=10;  // conservative, 2 actually works

// wbp: goto with row & column
void goTo(int row, int col) {
  LCD.print(0xFE, BYTE);   //command flag
  LCD.print((col + row*64 + 128), BYTE);    //position 
  delay(LCDdelay);
}
void clearLCD(){
  LCD.print(0xFE, BYTE);   //command flag
  LCD.print(0x01, BYTE);   //clear command.
  delay(LCDdelay);
}
void backlightOn() {  //turns on the backlight
  LCD.print(0x7C, BYTE);   //command flag for backlight stuff
  LCD.print(157, BYTE);    //light level.
  delay(LCDdelay);
}
void backlightOff(){  //turns off the backlight
  LCD.print(0x7C, BYTE);   //command flag for backlight stuff
  LCD.print(128, BYTE);     //light level for off.
   delay(LCDdelay);
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  LCD.print(0xFE, BYTE);
}


void setup()  {
  pinMode(txPin, OUTPUT);
  LCD.begin(9600);
  clearLCD();
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet)
  {
     goTo(0,0); 
     LCD.print("Unable to sync with the RTC");
  }   
  else
  {
     goTo(0,0);
     LCD.print("RTC has set the system time");     
     delay(250);
     clearLCD();
  }
  timeStatus_t timeStatus();   
}

void loop()
{
   digitalClockDisplay();  
   delay(1000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  goTo(0,0);
  LCD.print(hour());
  printDigits(minute());
  printDigits(second());
  LCD.print(" ");
  LCD.print(day());
  LCD.print(" ");
  LCD.print(month());
  LCD.print(" ");
  LCD.print(year()); 
  LCD.println(); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  LCD.print(":");
  if(digits < 10)
    LCD.print('0');
  LCD.print(digits);
}

thanks!

What is the question here? If you understand what each sketch does, combining them is rather easy.

i know, i think i can merge them easily. but i dont know how to use the buttons to switch what is being displayed on the screen.

but i dont know how to use the buttons to switch what is being displayed on the screen.

There are plenty of examples for reading the state of a pin with a switch attached. Determining whether or not to do something is done using an if statement.

Take a stab at the code, and post here if you have issues.

ok thats what i was asking, and i was already thinking about buttons and if statements.

//variables, display stuff, include.... etc

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  button2State = digitalRead(buttonPin);


  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) 
 {     
    //call get time stuff
    digitalClockDisplay();  
    delay(1000);
  } 

   if (button2State == HIGH) 
 {     
    //temp stuff
    //getting the voltage reading from the temperature sensor
  int reading = analogRead(sensorPin);  

  // converting that reading to voltage, for 3.3v arduino use 3.3
  float voltage = reading * 5.0;
  voltage /= 1024.0; 

  // print out the voltage
  //Serial.print(voltage); Serial.println(" volts");

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  //to degrees ((volatge - 500mV) times 100)
  //Serial.print(temperatureC); Serial.println(" degress C");

  // now convert to Fahrenheight
  int temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
  goTo(0,0);
  LCD.print(temperatureF); 
  LCD.print(" degrees F");
  delay(1000);                                     //waiting a second
  } 
}

but since it is only a momentary switch, it will only be "high" for a little bit, then when "void loop" loops again, it wont be "high" since its not still being pressed. would i need a sub loop under each if? this is why i asked my question.

maybe i could do this: when a switch is pressed it writes 1 to a variable for that switch, then makes sure the other button variable is 0 ( as off) then the first variable is put into the IF statement for its coordinating button. then if buttonvariable = 1 then do something... and the other IF would be like; if button2variable = 0 then dont do anything. so until the other button is pressed and then does the opposite as above.
but this would have to be separate void loop otherwise it would obviously not work because it would be looped when the button isnt being pressed. only run the code when a button is pressed. how to do this?

thanks

but since it is only a momentary switch, it will only be "high" for a little bit, then when "void loop" loops again, it wont be "high" since its not still being pressed.

True. So, increment a counter every time the switch is pressed. Reset the value when it exceeds 1. Then, base your action on the value in the counter, not the current state of the switch.

int counter = 0; // switch not pressed
int currState = LOW;
int prevState = LOW;
void loop()
{
   currState = digitalRead(pinNum);
   if(currState == HIGH && prevState == LOW) // State just changed
      counter++;

   prevState = currState;

   if(counter > 1) counter = 0;

   // Here, counter will be 0 or 1. Do something if counter is 1. Do nothing if it is 0
}

awesome, so that takes care of my temps and time, now i just have to finish the code that receives the serial data.

and i have a question on that code...

void loop()      
   {  
     while(Serial.available() > 0)
       {
        char aChar = Serial.read();
        if(aChar == '<')
          {
            started = true;
            index = 0;
            inData[index] = '\0';
          }
        else if(aChar == '>')
          {
            ended = true;
          }
      
          else if(started)
          {
            inData[index] = aChar;
            index++;
            inData[index] = '\0';             
            }
        
          else if (aChar =='*')
            {
              final = true;
            }
       }
 

     if(started && ended)
       {
   // ------[i][b]will have to modify this part for my use[/b][/i]------
        // Convert the string to an integer
        int inInt = atoi(inData);
          Serial.println(inInt);
        // Use the value
          serialValues [serialIndex] = inInt;
        serialIndex++;
        
          // Get ready for the next time
        started = false;
        ended = false;

        index = 0;
        inData[index] = '\0';      
       }

so the first part says, if it has a < at the beginning and a > at the end, then the whole string has been revived. then the second part gets the data (if all data has been recieved) through atoi(inData); then writes it to serial, correct? with or without the < >?

but then what is this doing?:

          serialValues [serialIndex] = inInt;
        serialIndex++;

and how would i change the below code so that it instead reads: atoi(inData);? it currently reads data coming through serial like: 23,45,67 and writes them to chars. and also i would have to take into account the < > that now exists before and after the data which the code below isnt meant for.

if(Serial.available() >= 0){
   char number1[3] = { Serial.read(), Serial.read() , '\0'};
   Serial.read();//flush the delim
   char number2[3] = { Serial.read(), Serial.read() , '\0' };
   Serial.read();//flush the delim
   char number3[3] = { Serial.read(), Serial.read() , '\0' };
 
   Serial.println("Debug: ");
   Serial.print("number1: ");
   Serial.println(number1);
   Serial.print("number2: ");
   Serial.println(number2);
   Serial.print("number3: ");
   Serial.println(number3);
 }

im not quite sure how this code works, i understand what it does just not how. does it read up to the first comma then stores the data in a char, then reads up to the next comma and so on?

thanks

so the first part says, if it has a < at the beginning and a > at the end, then the whole string has been revived.

Revived? Why, was it dead?

It says that the start of a packet begins with a <. Anything before that can be ignored. It says that once a < has been received, the following data should be stored in an array, until the > is received. When the > arrives, stop reading and recording the data, as a complete packet has been received.

then the second part gets the data (if all data has been recieved) through atoi(inData); then writes it to serial, correct? with or without the < >?

The data is received in the first part. It is processed, without the < and >, in the second part. That processing, in this snippet, consists of converting the packet to an int, printing the value, and storing it in an array.

but then what is this doing?

Storing the int in an array.

if(Serial.available() >= 0){
   char number1[3] = { Serial.read(), Serial.read() , '\0'};
   Serial.read();//flush the delim
   char number2[3] = { Serial.read(), Serial.read() , '\0' };
   Serial.read();//flush the delim
   char number3[3] = { Serial.read(), Serial.read() , '\0' };

If there is at least one byte of data in the serial buffer, read 8 characters. Hmmm, something fishy, here.

A better proposition, in my opinion, is to send the data between packet markers, like the other code.
<123,6,89>.

This way, the data for each number is not limited to exactly 2 characters.

Then, use strtok() to get each token ("123", "6", and "89"), and pass each token to atoi(), to get 123, 6, and 89.

does it read up to the first comma then stores the data in a char, then reads up to the next comma and so on?

It has no awareness of the data that it is reading. It reads and stores two characters, although there may only be one available. Then it reads and discards a character, although there may none available. Then, it reads and stores two characters, although there may none available. Then it reads and discards a character, although there may none available. Finally, it reads and stores two characters, although there may none available.

sorry typo i meant receive.
so this is what i have so far.

void loop()      
   {  
     while(Serial.available() > 0)
       {
        char aChar = Serial.read();
        if(aChar == '<')
          {
            started = true;
            index = 0;
            inData[index] = '\0';
          }
        else if(aChar == '>')
          {
            ended = true;
          }
      
          else if(started)
          {
            inData[index] = aChar;
            index++;
            inData[index] = '\0';             
            }
        
          else if (aChar =='*')
            {
              final = true;
            }
       }
 

     if(started && ended)
       {
        const char  strDelimiter = ","

        char*   p;
        char    str[] = atoi(inData); //34,50,333,
        int     CPU = 0, GPU = 0, FrMem = 0,

        if ( p = strtok(str, strDelimiter) )     { CPU = atoi(p); }
        if ( p = strtok(NULL, strDelimiter) )    { GPU = atoi(p); }
        if ( p = strtok(NULL, strDelimiter) )    { FrMem = atoi(p); }
        
          // Get ready for the next time
        started = false;
        ended = false;

        index = 0;
        inData[index] = '\0';      
       }

#include <stdlib.h> need that for it to work

this would go under "if(started && ended)" correct? is this input code correct? "char str[] = atoi(inData);"

then i could do a LCD.print(CPU); and it would print 34?

thanks

so this is what i have so far.

The code looks good.

this would go under "if(started && ended)" correct?

What would?

is this input code correct? "char str[] = atoi(inData);"

The atoi() function returns an int that you are trying to store in a character array. No, that won't work.

then i could do a LCD.print(CPU); and it would print 34?

Not is CPU contained 87. Try it and see.

if(counter2 > 1) counter2 = 0;
   {  
     while(Serial.available() > 0)
       {
        char aChar = Serial.read();
        if(aChar == '<')
          {
            started = true;
            index = 0;
            inData[index] = '\0';
          }
        else if(aChar == '>')
          {
            ended = true;
          }
      
          else if(started)
          {
            inData[index] = aChar;
            index++;
            inData[index] = '\0';             
            }
        
          else if (aChar =='*')
            {
              final = true;
            }
       }
 

     if(started && ended)
       {
        const char*  strDelimiter = ",";

        char* p;
        char str[12] = {index}; //34,50,333,
        int CPU = 0;
        int GPU = 0;
        int FrMem = 0;

        if ( p = strtok(str, strDelimiter) )     { CPU = atoi(p); }
        if ( p = strtok(str, strDelimiter) )    { GPU = atoi(p); }
        if ( p = strtok(str, strDelimiter) )    { FrMem = atoi(p); }
        
          // Get ready for the next time
        started = false;
        ended = false;

        index = 0;
        inData[index] = '\0';      
       }  
   }

and these are my values at the beginning of the code

int started = 0;
int inData[12];
int ended = 0;
char index = 0;
int final = 0;

does everything thing look fine?

thanks