LCD code help

I’ve got my MSF60 receiver up and running (Thanks grumpy mike for the help) and to tidy it off I need a bit of help with the display output (LCD). I’d like the top line of the disply to show 'Waiting for MSF" and the bottom to say either “got carrier”, “waiting for sync” or “reading fix” dependent on the status.

At the moment it goes to ‘got carrier’ and then nothing else until it reads the time.

I’ve tried to adapt some code that worked in serial from (http://www.jarkman.co.uk/catalog/robots/msftime.htm but I’ve obviously done something a bit wrong. can anyone help? Code is below, once this is sorted then I’ll clean it up and make my first PCB…a bit excited that something works!

Thanks

Alex

// MSFTime samples program
// Jarkman, 01/2011
// http://www.jarkman.co.uk/catalog/robots/msftime.htm

// Prerequisites:
// An MSF time receiver, wired to analogue pin 0, like this: http://www.pvelectronics.co.uk/index.php?main_page=product_info&cPath=9&products_id=2
// Time library:  http://www.arduino.cc/playground/Code/Time
// LOLShield library: http://code.google.com/p/lolshield/source/browse/#svn%2Ftrunk%2Flib%253Fstate%253Dclosed


#include <Time.h>  // from http://www.arduino.cc/playground/Code/Time
#include "MSFTime.h" 
#include <LiquidCrystal.h>

MSFTime MSF;// = MSFTime();

time_t prevDisplay = 0; // when the digital clock was displayed
byte prevStatus = 255;

time_t msfTimeSync();
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

int backLight = 13; //pin 13 will control the backlight

void setup()
{
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(16,2);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)

   
   MSF.init( 255 ); // LED pin for status - pass 13 for the built-in LED on the Arduino, or 255 for no led at all
                   // For reasons I do not understand, you cannot use this when running with USE_AVR_INTERRUPTS
   
  
   lcd.print("Waiting for MSF");
   setSyncProvider(msfTimeSync);  // tell the Time library to ask for a new time value 
   
 
}
  
void loop()
{
  lcd.setCursor(0, 1);
  byte currStatus = MSF.getStatus();
  
  if(currStatus != prevStatus || currStatus & MSF_STATUS_FIX) 
  {
    if( currStatus != prevStatus )
    {
     if( currStatus & MSF_STATUS_CARRIER)
       lcd.println("Got carrier     ");
     if( (currStatus & MSF_STATUS_WAITING))
       lcd.println("Waiting for sync");
     if( (currStatus & MSF_STATUS_READING))
       lcd.println("Reading fix     "); 

     prevStatus = currStatus;
    }
    
   now();
    
    if( timeStatus()!= timeNotSet )
    {
     if( now() != prevDisplay) //update the display only if the time has changed
     {
       prevDisplay = now();
       digitalClockDisplay();  
     }
    }
  }	 
}



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);
}

void digitalClockDisplay(){
  // digital clock display of the time
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(4,0);           // set cursor to column 0, row 0 (the first row)
  lcd.print(hour());
  printDigits(minute());
  printDigits(second());
  lcd.print(" ");
  lcd.setCursor(3, 1);
  lcd.print(day());
  lcd.print(" ");
  lcd.print(month());
  lcd.print(" ");
  lcd.print(year());
   
}


time_t msfTimeSync() // called periodically by Time library to syncronise itself
{
   return MSF.getTime();
}

/***************************************************************************************/

I can't find the MSFTime.h or library to be sure but it looks like your problem may be with your if( currStatus & MSF_STATUS_xxxxxx) lines.

You are using the single & which is the bitwise AND operator. This will always make the if statement TRUE if you have even a single bit that is a one in either currStatus or MSF_STATUS_xxxxxx. I think what you want is the && which is the boolean AND operator which will simply compare the two values and only return TRUE if the comparison is true.

From the Reference for && (and)http://arduino.cc/en/Reference/Boolean

Warning

Make sure you don't mistake the boolean AND operator, && (double ampersand) for the bitwise AND operator & (single ampersand). They are entirely different beasts.

So because all three of the if( (currStatus & MSF_STATUS_xxxxxx)) lines are true then it will be the last one to run that you will see displayed on the LCD. In this case "Reading fix ".

Thanks for the help mstanley. I’ll give it a try and hopefully it’ll work out.

How come it worked ok when there was a serial output and not when I output to a LCD?

Alex

This will always make the if statement TRUE if you have even a single bit that is a one in either currStatus or MSF_STATUS_xxxxxx.

BZZZZZT!

2 & 5 is false. 2 && 5 is true.

So that means not to put the && in, right?

So that means not to put the && in, right?

Yes, it does. You could print on the lcd the value that you get from MSF.getStatus(). Show the value in hex, so that you can see the bits that are set. Perhaps a clue will reveal itself.

Ok so I'm getting somewhere.

With the MSF.getStatus() in place of "Got Carrier" The display shows the 2 phases of "Synchronising" and then "Reading Fix" at the correct times. So the problem lies with the "Got Carrier" part not being cleared by the subsequent phases. It aso shows a couple of 'characters' the first two character places which aren't letters or numbers just a collection of lit pixels. So something isn't right there either

I can frig it as I know I have a carrier because an LED flashes but I'd really like to get to the bottom of it.