problem in Code for GLCD !

IM using a GLCD JHD12864 for my speedometer console and im using the CD4021BCN shiftin register to compensate for the loss of pins to run the GLCD but my code is giving me 242 to 282 km/h of reading even when no hall sensor to shoot the interrupt is there ,i have tried linking the interrupt pin #2 to GnD when no reed switch or Hall sensor is there but it didn’t help, also this started happening since i connected shift register prior to that it was giving a fine reading even when no hall sensor on pin #2 was there and it was also left open without connecting to ground.

Is clock causing this?

here is the code:

#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <glcd.h>
#include "fonts/allFonts.h"         // system and arial14 fonts are used
#include <glcd_Buildinfo.h>
#include "speedo4.h"
#include <glcd_Config.h>
#include "DreamRiding.h"     // bitmap 
#include "bitmaps/allBitmaps.h" 
#include "right.h"
#include "left.h"

const int inpin = 2;
int writeCounter = 0;
int x;
int y;
volatile unsigned long currInterrupt = 0;
volatile unsigned long prevInterrupt = 0;
volatile unsigned long interruptInterval = 0;
unsigned long odoIncrement;
int speed_kmh = 0;
int Rotation_count; 
int latchPin = 12;
int dataPin = 13;
int clockPin = 3;
byte switchVar1 = 72;  //01001000
char note2sing[] = {'C', 'd', 'e', 'f', 'g', 'a', 'b', 'c'}; 

void hallgetterHIGH()
{
  rotationCount();
  Differential_Calc();
}

void rotationCount()//this fu
{
  Rotation_count ++;
  if (Rotation_count == 53) {//code here to update odo every 100 mtrs
      odoIncrement = odoIncrement + 100;//53.2 is exact value for,will be used for EEPROM Feed     
      Rotation_count = 0;
      writeCounter ++;
      if (writeCounter == 10) {
        //code here to write to eeprom
        EEPROM_writeAnything(0, odoIncrement); 
      }
  }
}
void Differential_Calc()
{   
   currInterrupt = micros();
   if(prevInterrupt > 0)
   {
      interruptInterval = currInterrupt - prevInterrupt;
   }
   prevInterrupt = currInterrupt; 
   //Serial.println(interruptInterval);
}  
void setup() {
  Serial.begin(9600);
  interrupts();
  pinMode(inpin, INPUT);// using the pin as an input(hall sensor acts as a switch)
  digitalWrite(inpin, HIGH);
  attachInterrupt(1, hallgetterHIGH, CHANGE); 
  EEPROM_readAnything(0, odoIncrement);/*odoIncrement will be used 
  in LCD Display ,read it here and use it to display in loop where
  the coding for LCD rests  */
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
  GLCD.Init(NON_INVERTED);   // initialise the library, non inverted writes pixels onto a clear screen
  GLCD.ClearScreen();  
  GLCD.DrawBitmap(DreamRiding, 1,0, BLACK); //draw the bitmap at the given x,y position 
  countdown(5); 
  GLCD.ClearScreen();  
}

void loop() {
  speed_kmh = (1884*3.6)/interruptInterval;//1.884 is Circumference of the Wheel
  //Serial.println(speed_kmh);//to get Speed in Kmh i have divided with 1000/3600
  //odometer code to Display to come soon
  if (speed_kmh >= 100) {
     x = 30;
     y = 20;
  }
  if (speed_kmh < 10) {
     x = 50;
     y = 20;
  }
  if (speed_kmh > 10 && speed_kmh < 100) {
     x = 40;
     y = 20;
  }
  GLCD.ClearScreen();
  GLCD.SelectFont(speedo4); // you can also make your own fonts, see playground for details   
  GLCD.CursorToXY(x, y);
  GLCD.print(speed_kmh);
  GLCD.SelectFont(Arial14);
  GLCD.print("Km/h"); 
  shiftreg_pins(); 
}

void countdown(int count){
    while(count--){  // do countdown  
     GLCD.CursorTo(0,1);   // first column, second row (offset is from 0)
     GLCD.PutChar(count + '0');
     delay(1000);  
  }  
}

void shiftreg_pins() {
  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);

  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  switchVar1 = shiftIn(dataPin, clockPin, MSBFIRST);
  Serial.println(switchVar1, BIN);
  for (int n=0; n<=7; n++)
  {
   
    if (switchVar1 & (1 << n) ){
      //print the value of the array location
        Serial.println(note2sing[n]);
        if(note2sing[n] == 'd') 
        {
          GLCD.DrawBitmap(right, 90,45, BLACK);
        }
        if(note2sing[n] == 'e') 
        {
          GLCD.DrawBitmap(left, 5,45, BLACK);
        }
    }
  }

//white space
Serial.println("-------------------");
//delay so all these print satements can keep up. 
 delay(100);
}

I probably can't help you much with the code but, I have a troubleshooting idea. If you have a spot, connect an LED to a pin and light the LED when the hall effect interrupt is triggered. Then, add a few more prints followed by a delay(500); to the GLCD and see if the LED start flickering. Of course, try to change the existing code as little as possible while doing this test.

This will show if the GLCD is triggering the interrupt.

I don't believe that this is a GLCD library problem.

Have a close look at the external interrupt you are attaching to and the pins you are using. It appears that you are attaching to an external interrupt on pin 3 (vs the hall sensor on pin2) and also using pin 3 for clocking which probably triggers the external interrupt.

My guess is that if this was previously working, then when you added additional code for clocking, you also changed the pins and/or attach interrupt number as well.

--- bill

@ Cycle Gadget thanks a lot trying to digout the problem.

@ Bill you got it thanks! yes i remembered to change the pin number of external interrupt to 3 but forgot to change the interrupt handler to handle interrupts on pin 3 that i need to change and i think wil sort the whole problem.

regards,
Nishant

another problem , there is screen flickering in the screen (VIDEO>>http://www.facebook.com/v/363751356971046) - i have removed any delays in between the code just leaving a 20 microsecond delay that is i think is not making any problem.

On an LCD clearing the screen can make it flicker. On your GLCD I see you are using this:GLCD.ClearScreen();...it is necessary when you want to print a new character. However, unless I missed it, you are printing the a new character constantly even if the character is the same as the last. I think you should only clearing and printing to the screen if(newcharacter does not == oldcharacter) You might also think about how often you must update the screen. Such as update every 500ms or every 1 second.

Also it might be better to not clear the whole screen but, rather just the area that needs to change. I would love to tell you how but, I still need to learn all of the GLCD tricks.

cyclegadget: On an LCD clearing the screen can make it flicker. On your GLCD I see you are using this:GLCD.ClearScreen();

For sure. Even if you clear the screen and immediately redraw the same thing, there can be flicker from the clear.

...it is necessary when you want to print a new character.

This is not necessarily the case. When fonts are rendered to the display the transparent pixels of the character are written as well. For example if you write the letter "0" all the pixels are written including the "non black" ones. So if you write a character on top of an existing character you don't necessarily have to clear the previous character. I say "not necessarily" because it depends on the font. If the font is a fixed sized font then you can draw characters on top of other characters and never have to erase them as long as the strings are the same length. If the fonts are variable in size then this won't work if the second character drawn is narrow than the first since it will not overwrite any pixels beyond its width.

However, unless I missed it, you are printing the a new character constantly even if the character is the same as the last. I think you should only clearing and printing to the screen if(newcharacter does not == oldcharacter) You might also think about how often you must update the screen. Such as update every 500ms or every 1 second.

Also it might be better to not clear the whole screen but, rather just the area that needs to change.

This is very true. If you want to prevent flicker, you need to update the screen as little as possible. And definitely avoid clearing the screen. Text areas would be good for what you are doing. That way you can update the individual area or even clear that individual area. Also with Text areas, you can assign different fonts to each text area, so you don't have to keep changing the default font.

The units ( "Km/h" ) could have its own text area and would only have to written once.

If you use a fixed width font, then you shouldn't ever have to clear the screen or text area. You can simply overwrite the text.

If you can affort the 1.8k or so of code an easy way to print adjusted/filled numbers when using fixed width fonts is to use the xxprintf() functions.

The glcd library supports using printf() function to a text area. That way the you things like:

GLCD.Printf("%3d", speed_kmh);
textarea.Printf("%3d", speed_kmh);

And not have to worry about all the x coordinate stuff. The text will always start in the same location since there will be leading spaces in the output string.

And if you want zero filled the you can simply use:

GLCD.Printf("%03d", speed_kmh);
textarea.Printf("%03d", speed_kmh);

See the documentation on text areas and the "BigNums" example for more on text areas.

--- bill