Rotaries,LCDs and menu. How should one approach?

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi. I have recently succesfully uploaded a small program that reads a rotary encoder (2bit Grayscale)with interrupts and a timer to detect speed. This is all displayed as numbers on a 16x2 LCD along with the switchpress. Which, when one presses the switch on the rotary, the message "Pressed!" pops up on the LCD. I would now like to tackle scrolling thru a menu and clicking the switch to select the menu. I was hoping that someone could point me in the direction I have to go as regards the language i.e. how is menu stuff done...arrays? pointers? I don't know. Any help would be again appreciated though. I'm not asking for code or for someone others program.. Just some pointers.. :)
Cheers,
Steve.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have a look at the Butterfly source code as a starting point.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I usually use a table/array driven approach, with a function pointer to a handler when the item is selected (or any other events) and a pointer to a submenu or another menu. I refrain from hardcoding these things with code.

If you have system with multiple pages of information I tend to put these into tables too, with function pointers to event handlers for display update, button input etc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HiYa! :]
Thanks for the tips , I found a nice simple menu example on this site: http://zaidpirwani.com/799/selection-menu-for-text-lcd-avr/
Which works nicely. ( I re routed Peter Fleurys nice LCD library to work on PortC only and used the STK500 buttons to change menu selections.)
I then proceeded to cobble together a section of code from the P.F LCD library and a rotary library. Here's the code:

#include 
#include 
#include 
#include 
#include 
#include "lcd.h"
#include "rotary.h"

const char LEFT[] PROGMEM="LEFT TURN";
const char RIGHT[] PROGMEM="RIGHT TURN";
const char BUTTON[] PROGMEM="BUTTON CLICK";
const char DEMO[] PROGMEM="Encoder Demo"; 
#ifndef F_CPU
//define cpu clock speed if not defined
#define F_CPU 16000000
#endif

int enc=1000;

//init timer2
void Timer2_Init(void)
{
	TCNT2=0x00;
} 
//start timer2
void Timer2_Start(void)
{
	TCCR2|=(1<<CS22)|(1<<CS21); //prescaller 256 ~122 interrupts/s
	TIMSK|=(1<<TOIE2);//Enable Timer0 Overflow interrupts
}
//timer ISR check for rotarry encoder status
ISR(TIMER2_OVF_vect)
{
//reading rotary and button
RotaryCheckStatus();
if (PINB & _BV(PD2))
// increase enc
enc++;
else 
// decrease enc
enc--;
}



void MainInit(void)
{
	// Wait a little while the display starts up
	for(volatile uint16_t i=0; i<15000; i++);
	// Initialize the LCD
lcd_init(LCD_DISP_ON);
	lcd_clrscr();
	//startup
	
	lcd_gotoxy(0,1);
	lcd_puts_p(DEMO);
	//init rotary
	RotaryInit();;
	//taimerio 2 nustatymas
	Timer2_Init();
	//Taimerio 2 paleidimas
	Timer2_Start();
	//enable global interrupts
	sei();
}
void MainScreenUpdate(void)
{
		//update encoder status on screen
		if (RotaryGetStatus() ==3) // button press
		{
			lcd_clrscr();
		
			lcd_gotoxy(0,0);
			lcd_puts_p(BUTTON);
			
			RotaryResetStatus();	
		}
		if (RotaryGetStatus() == 1) // left turn
		{	
			lcd_clrscr();
			
			lcd_gotoxy(0,0);
			lcd_puts_p(LEFT);
			lcd_gotoxy(1,0);
			lcd_putc(enc);
			RotaryResetStatus();
		}
		if (RotaryGetStatus() == 2) // right turn
		{	
			lcd_clrscr();
			
			lcd_gotoxy(0,0);
			lcd_puts_p(RIGHT);
			lcd_gotoxy(1,0);
			lcd_putc(enc);
			RotaryResetStatus();
		}
}

int main(void) {


MainInit();



while(1)
	{
		//update LCD information on status change
		MainScreenUpdate();
	}

}

It basically displays right and left rotary encoder turns and button presses. Now I would like to add a number that increments or decrements and is displayed in the LCD alongside the direction. I've started with the "enc" variable and have had success in the LCD reading it but...it comes out as garbage.
How do I display the data as an integer?
I can't see an LCD command that does this. I am guessing it has something to do with atoi in the std library but I'm not sure how to implement it..Could someone advise me on this?
Thanks again,
Steve.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IIRC Dean Camera (abcminiuser) did implement a menu system a few years back. I do not recall the details but if he was up to his normal "par" it should be good stuff.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OOh! MicroMenu. Found it. Thanks Johan.:)
By the way, do you know how I write a variable integer to Peter fleury's LCD lib by any chance? I can only see how to write characters and strings...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Solved: Reading thru stdlib info file.
1.Create a string:

2. itoa requires variable, array and index type.

char str [1];
lcd_puts(itoa(enc,str,10));

Now I have it working.
Whole program:

#include 
#include 
#include 
#include 
#include 
#include "lcd.h"
#include "rotary.h"

const char LEFT[] PROGMEM="LEFT TURN";
const char RIGHT[] PROGMEM="RIGHT TURN";
const char BUTTON[] PROGMEM="BUTTON CLICK";
const char DEMO[] PROGMEM="Encoder Demo"; 
#ifndef F_CPU
//define cpu clock speed if not defined
#define F_CPU 16000000
#endif
char str[1];
int  enc=10;

//init timer2
void Timer2_Init(void)
{
	TCNT2=0x00;
} 
//start timer2
void Timer2_Start(void)
{
	TCCR2|=(1<<CS22)|(1<<CS21); //prescaller 256 ~122 interrupts/s
	TIMSK|=(1<<TOIE2);//Enable Timer0 Overflow interrupts
}
//timer ISR check for rotarry encoder status
ISR(TIMER2_OVF_vect)
{
//reading rotary and button
RotaryCheckStatus();
//if (PINB & _BV(PD2))
// increase enc
//enc++;
//else 
// decrease enc
//enc--;
}



void MainInit(void)
{
	// Wait a little while the display starts up
	for(volatile uint16_t i=0; i<15000; i++);
	// Initialize the LCD
lcd_init(LCD_DISP_ON);
	lcd_clrscr();
	//startup
	
	lcd_gotoxy(0,1);
	lcd_puts_p(DEMO);
	//init rotary
	RotaryInit();;
	//taimerio 2 nustatymas
	Timer2_Init();
	//Taimerio 2 paleidimas
	Timer2_Start();
	//enable global interrupts
	sei();
}
void MainScreenUpdate(void)
{
		//update encoder status on screen
		if (RotaryGetStatus() ==3) // button press
		{
			lcd_clrscr();
		
			lcd_gotoxy(0,0);
			lcd_puts_p(BUTTON);
			
			RotaryResetStatus();	
		}
		if (RotaryGetStatus() == 1) // left turn
		{	
			lcd_clrscr();
			
			lcd_gotoxy(0,0);
			lcd_puts_p(LEFT);
			lcd_gotoxy(1,6);
			
			enc--;
			lcd_puts(itoa(enc,str,10));
			RotaryResetStatus();
		}
		if (RotaryGetStatus() == 2) // right turn
		{	
			lcd_clrscr();
			
			lcd_gotoxy(0,0);
			lcd_puts_p(RIGHT);
			lcd_gotoxy(1,6);
			enc++;
			lcd_puts(itoa(enc,str,10));
			RotaryResetStatus();
		}
}

int main(void) {


MainInit();



while(1)
	{
		//update LCD information on status change
		MainScreenUpdate();
	}

}

Jolls.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You'd better make that str[1] a bit bigger ;) It must hold the entire string that results from the conversion from integer to string. Or 6 bytes: 5 digits plus the zero terminator.

If you don't, the itoa() function will overwrite memory that belong to other variables, or even worse, it overwrites return addresses. Exit the function and your program crashes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My original MicroMenu was horrendous, as it completely ignored something called "type safety". Funnily enough I re-wrote it about two months ago to be much better, but never posted it as 'Freaks wouldn't accept the updated zip. If you want it, I can attach it here tonight when I get home.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:
If you want it ...
... what a silly precondition ... of course he will want it Dean :lol:

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
do you know how I write a variable integer to Peter fleury's LCD lib by any chance? I can only see how to write characters and strings...
[...]
Solved: Reading thru stdlib info file.

A good search here at 'freaks should also have revealed the answer. We've had that question at least once a week, lately. :wink:

Quote:
You'd better make that str[1] a bit bigger

+1. Time to pick up your C textbook and read up on arrays and strings in C.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Micro-menu V2 attached.

Attachment(s): 

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jayjay. I see the point. I've changed it to [4].:)

Quote:
Time to pick up your C textbook and read up on arrays and strings in C.

The book I'm using is:
C Programming: A Modern Approach, 2nd Edition [Paperback]
K. N. King

Thanks Dean, for V2 of the library.
Jollibs :s

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the Dean's example.

 

"We trained hard... but it seemed that every time we were beginning to form up into a team, we would be reorganized. I was to learn later in life that we tend to meet any new situation by reorganizing. And a wonderful method it can be of creating the illusion of progress while producing confusion, inefficiency and demoralization." Petronius Arbiter, approx. 2000 years ago.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The book I'm using is:
C Programming: A Modern Approach, 2nd Edition [Paperback]
K. N. King

I suffer rather severely from BAS (Book Acquisition Syndrome). Lately it has been under control, but I'm more or less on the edgen and vacations are upcoming. I've been looking at this book several times, and am tempted to get it.

So... What is your opinion of it?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
I suffer rather severely from BAS (Book Acquisition Syndrome).

+1 :D

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius