struct holding LCD menu items -> errors?

Thread Starter

geotech1

Joined May 18, 2013
4
Hi everyone, my name is James, this is my first post on this forum. I am here because i have been driven nuts
trying to find why my pic project has stopped working! I am trying to implement a simple menu on an LCD, 3 push buttons, PIC16F1507, Hi-Tech C, MPLAB v8.84. I have declared an array of structs, each element holds a struct that contains a text string and an int, each time a menu button is pressed it displays the text string and int value of the next element in the array, looping back to the begining of the array when it reaches the end. There is also a plus and minus buttons that allow the int value in the selected struct to be incremented or decremented.
This worked fine for a while, but after i changed some other unrelated code, it has ceased to display the contents of the struct. I cannot for the life of me figure out why. I have wondered if there may be an issue with the struct spanning across memory page boundries? BTW I have RTFM and STFW, but it seems on this occasion Google is not my friend :(
Here's the key parts of my code, if anyone can spot the problem, i will be so very grateful.

MAIN.C

Rich (BB code):
//****************************Global Variables**********************//
struct aMenu {
  unsigned char label[11];
  unsigned int val;
}menu[3] = {{"Speed    \0", 25}, {"Threshold\0", 5}, {"unused   \0", 20}};

void main()
{
 
/*********************** Button Event Handlers ********************/
if(ButtonEvent && B1_flag) //////////////////////// Down Handler
{
 menu[MenuIndex].val--;
 lcd_goto(LINE2+12);
 LCDWriteInt(menu[MenuIndex].val, 3);
 ButtonEvent = FALSE;
}
if(ButtonEvent && B2_flag) /////////////////////// Up Handler
{
 menu[MenuIndex].val++;
 lcd_goto(LINE2+12);
 LCDWriteInt(menu[MenuIndex].val, 3);
 ButtonEvent = FALSE;
}
if(ButtonEvent && B3_flag) /////////////////////// Menu Handler
{
 MenuIndex++;
 if(MenuIndex > 2) MenuIndex = 0;
 lcd_clear();
 lcd_goto(LINE1); 
 lcd_puts("Adjustment Menu");
 lcd_goto(LINE2); 
 lcd_puts(menu[MenuIndex].label);
 lcd_goto(LINE2+12);
 LCDWriteInt(menu[MenuIndex].val, 3);
 ButtonEvent = FALSE;
}
}// end main
LCD.C

Rich (BB code):
/* write a byte to the LCD in 4 bit mode */
void
lcd_write(unsigned char c)
{
 if(c & 0x80) LCD_D7=1; else LCD_D7=0;
 if(c & 0x40) LCD_D6=1; else LCD_D6=0;
 if(c & 0x20) LCD_D5=1; else LCD_D5=0;
 if(c & 0x10) LCD_D4=1; else LCD_D4=0;
 LCD_STROBE;
 if(c & 0x08) LCD_D7=1; else LCD_D7=0;
 if(c & 0x04) LCD_D6=1; else LCD_D6=0;
 if(c & 0x02) LCD_D5=1; else LCD_D5=0;
 if(c & 0x01) LCD_D4=1; else LCD_D4=0;
 LCD_STROBE; 
 __delay_us(40);
}
/* Clear and home the LCD */
void
lcd_clear(void)
{
 LCD_RS = 0;
 lcd_write(0x1);
 __delay_ms(2);
}
/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
 LCD_RS = 1; // write characters
 while(*s) lcd_write(*s++);
}
/* write one character to the LCD */
void
lcd_putch(unsigned char c)
{
 LCD_RS = 1; // write characters
 lcd_write(c);
}

/* Go to the specified position*/
void
lcd_goto(unsigned char pos)
{
 LCD_RS = 0;
 lcd_write(pos);
}
 
/* initialise the LCD - put into 4 bit mode */
void
lcd_init(void)
{
 LCD_RS = 0; // write control bytes
 __delay_ms(15);// power on delay
 LCD_D4 = 1; // init! 
 LCD_D5 = 1; //
 LCD_STROBE; 
 __delay_ms(5);
 LCD_STROBE; // init! 
 __delay_us(100);
 LCD_STROBE; // init! 
 __delay_ms(5);

 LCD_D4 = 0; // set 4 bit mode
 LCD_STROBE; 
 __delay_us(40);
 
 lcd_write(0x28);// 4 bit mode, 1/16 duty, 5x8 font, 2lines
 lcd_write(0x0C);// display on
 lcd_write(0x06);// entry mode advance cursor
 lcd_write(0x01);// clear display and reset cursor
}
void LCDWriteInt(int val,unsigned int field_length)
{
 /***************************************************************
 This function writes a integer type value to LCD module
 Arguments:
 1)int val : Value to print
 2)unsigned int field_length :total length of field in which the value is printed
 must be between 1-5 if it is -1 the field length is no of digits in the val
 ****************************************************************/
LCD_RS = 1; // write characters
 char str[5]={0,0,0,0,0};
 int i=4,j=0;
 while(val)
 {
 str=val%10;
 val=val/10;
 i--;
 }
 if(field_length==-1)
  while(str[j]==0) j++;
 else
  j=5-field_length;
 if(val<0) lcd_write('-');
 for(i=j;i<5;i++)
 {
 lcd_write(48+str);
 }
}


Kind Regards, J.
 

ErnieM

Joined Apr 24, 2011
8,377
Hi everyone, my name is James, this is my first post on this forum. I am here because i have been driven nuts
trying to find why my pic project has stopped working!
Oh dear, that sounds serious!

Does it display anything at all?

Hi James! Welcome to the forums!
 
Last edited:

Brownout

Joined Jan 10, 2012
2,390
My guess is none of the code is being executed. I don't see where BX_flag is being set (X= 1, 2, 3). So, I'm going to assume for now that's the problem, as I don't really see anything else.

I'm also assuming that you're testining your hardware with working code to insure it is OK.
 

Thread Starter

geotech1

Joined May 18, 2013
4
Hi guys, Thanks for taking a look at my post. I have omitted some portions of the code that i know for sure are working OK - i.e the button debounce section that sets the Bx flag, and the ADC stuff for example. The menuIndex int rolls round 0,1,2 and back to zero as it should, the display shows on line1 "Adjustment Menu", everything else works as it should, just none of the contents of the struct are displayed. They used to be! Sometimes a char or two of junk is displayed.

I noticed the problem earlier in development and thought i'd fixed it. Originally the struct was declared globally after a small number of other variables and all was well until i added some more code and more variables. Then the LCD output of the structure contents started to play up, so i moved the struct declaration to be first declaration in the list. After the struct was declared as the first item in the variable declarations it worked again. Now i've added more code and variables, it's failed again. Declaring it after a bunch of other stuff (ints, chars & bits) made the ouput to the LCD fail. This is why i am wondering if its a memory issue???

Has anyone got a suggestion for how to go about investigating what this problem is??? I am stumped :confused:

Many Thanks, J.
 

ErnieM

Joined Apr 24, 2011
8,377
ICSP is shorthand for In Circuit Serial Programming and debugging!

How well does HTC play inside MPLAB? These things can be simple to track down when I used C18 inside MPLAB and a PICkit 2 or 3 to single step code inside the target from the IDE and see what is going on (and going wrong).

Occasionally I have to make a buffer or pointer a global so it is still readable in the watch window but that's minor.
 

Thread Starter

geotech1

Joined May 18, 2013
4
Haven't modified anything in LCD.C for a long time. When checking that the menuIndex int was behaving correctly I output it on line 2, it displayed fine.
 

Brownout

Joined Jan 10, 2012
2,390
I just ran the following code on my PIC18F45K20, compiled with c18. It uses your struct and displays it just fine. I displayed the struct on line 1 of the LCD.

Rich (BB code):
//****************************Global Variables**********************// 
struct aMenu 
{ unsigned char label[11]; 
unsigned int val; }menu[3] = {{"Speed \0", 25}, {"Threshold\0", 5}, {"unused \0", 20}};
 
 
void main(void){
  char istringconvert[16];
  int menu_indx = 1;
 
  //initialize the LCD
  LCD_init();
 
  WriteStringXldc(menu[menu_indx].label);
  itoa(menu[menu_indx].val, istringconvert, 10);
  WriteStringXldc(istringconvert);
  while(1);
  }
 
Last edited:

Thread Starter

geotech1

Joined May 18, 2013
4
Thank you for taking the time to test that. This is a very strange problem! Last night I replaced the structure with a const char * array[] to hold the strings, and an unsigned int[] to hold the values. Worked fine! Would still like to use the structure as it makes the code so much simpler.
 

Brownout

Joined Jan 10, 2012
2,390
I had weird problems like this because in my program, I had #include <xlcd.h> and also had my custom #include "LCD.h" file too. When I got rid of the <xlcd.h> in all my code, wierd problems like this cleared up.
 
Top