Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

ST7066U 20x4 LCD problems(Solved)

Status
Not open for further replies.
Well, I have isolated the weirdness to the encoder polling section, why, when it has absolutely nothing to do with the display routines, is beyond me at the moment.

Still works fine on a 16x2 but throws a hissy fit when the 20x4 is plugged in.

Going to give it a rest for a couple of days as it is making my brain hurt.
 
Your encoder routine isn't right... I simulated YOUR code last night and it works fine with RA0 incrementing and RA1 decrementing BUT!! that's not how encoders work. It has to see a pattern so yours will be up-down-up-down and not incrementing at all..

Encoders are quadrature... Read the state of the two pins, check against last state of the two pins, then process..
 
I use a table when using a quadrature encoder. I rotate a variable left (twice) add the two inputs to bits 1 & 0, logical AND with 15 and index into the table to get -1,0 or +1.

The table is, lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};

Even in assembly it's very easy to implement.

Mike.
 
In my defense it's not my code but came from the Pic-El series software.

It did the job and I have looked for other encoder software solutions but haven't found anything anywhere near reasonable.

I particularly have been trying to get a proper variable rate routine ie, the faster you turn the bigger the steps until you slow down again but the ability to run faster without missing steps or even occasionally going in the opposite direction seem to be at odds with each other.

Add to that the fact that people seem happy to use the cheap crappy mechanical encoders that keep contact bouncing all the way to Christmas and back rather than a half decent opto encoder doesn't help.

Still doesn't explain why it screws with one type of LCD and not the other though.:confused:
 
I don't understand why it would act different with a different LCD either. However, crappy cheap mechanical encoders work perfectly happily with the algorithm I posted above as any bounce will cause an increment and then a decrement and no error will occur. The important thing is to read it as fast as possible. I could write the encoder routine in asm if it will help?

Mike.
 
I don't understand why it would act different with a different LCD either. However, crappy cheap mechanical encoders work perfectly happily with the algorithm I posted above as any bounce will cause an increment and then a decrement and no error will occur. The important thing is to read it as fast as possible. I could write the encoder routine in asm if it will help?

Mike.
If the pins are a slight different in impedance it would.. As I said... The code works, so its definitely in hardware..
 
If the pins are a slight different in impedance it would..
The LCD pins or the encoder pins? Are pullups turned on? I've never had a problem with mechanical rotary encoder. Debounce just gets taken care of by the algorithm.

Mike.
 
Mike - that would be appreciated re the encoder software.

Pull-ups are turned off, they are not available anyway on PORT A of the 628.

The encoder uses external resistors with debounce capacitors.

Just so we are all on the same page, I am in the process of getting the basics to work first - LCD display and loading the right data to the SAA1057 and am using my DDS test bed to do the initial testing/development of the software - so in the schematic below - where it shows the DDS module the FU_UD line - RB7 - is DLEN (enable) for the SAA1057 and clock and data going to the DDS are clock and data on the SAA1057, but note that while trying to sort this problem, the SAA1057 is not connected (and it doesn't make any difference connected or not, to the problem).

The encoder is on RA0 & 1 with 10k pull-ups and 100n caps to ground.

To add - thankyou for the help from all who have replied, I'm away tomorrow morning and possibly the afternoon as well as possibly the next day.
VK5TM DDS Test Bed SCH.jpg
 
but note that while trying to sort this problem, the SAA1057 is not connected (and it doesn't make any difference connected or not, to the problem).
Ok... The SA1057 is an FM transmitter?? You have a DDS module.. Is it an AD9850?? Confused... An FM transmitter is a different beasty..
 
I am using my DDS test bed for prototyping - the DDS module is removed and the clock, data and enable lines are connected to the SAA1057.

And the SAA1057 is an old PLL chip once commonly used in FM transmitters - this project is the control and monitoring part for a FM transmitter.
 
Long time since I did any assembly so this is from memory. Ian, can you give this a quick once over to make sure I've not made any stupid mistakes.

This will use A0 & A1 as the decoder inputs and will return -1,0 or +1 depending on which way the encoder is turned. Note, because of the use of a table you need to ensure it's all on one 256 byte page. Also, previous needs to be preserved.
Code:
getEncoder           
                rlf      previous,f
                rlf      previous,w
                andlw    0x0c                ;keep only bits 2 & 3
                btfss    PORTA,0             ;move encoder bits
                iorlw    1                   ;to bits 0 & 1
                btfss    PORTA,1
                iorlw    2
                movwf    previous            ;keep for next time
                addwf    PCL,f               ;index into table
                dt       0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0

Mike.
 
Last edited:
The encoder you are using is awful for bounce so it needs more filtering than a resistor+capacitor on the A and B channels can provide.

So debounce these inputs like they are push buttons with a 2 millisecond bounce time.

Then every 5 milliseconds get another debounced sample of the A and B inputs.

With ab = previous debounced sample and AB = current debounced sample.

Uses this table to decide the direction:
Code:
abAB
0000 = 0
0001 = +1
0010 = -1
0011 = invalid, treat as zero
0100 = -1
0101 = 0
0110 = invalid, treat as zero
0111 = +1
1000 = +1
1001 = invalid, treat as zero
1010 = 0
1011 = -1
1100 = invalid, treat as zero
1101 = -1
1110 = +1
1111 = 0
When a new debounced sample arrives withing 100 milliseconds of the last AND the displacement is in the same direction double the displacement "enhancement" to be added to the position to a maximum displacement of + or - 128 for each update.

When the displacement changes direction reset the displacement "enhancement" to + or - 1.

When the displacement change is zero for 10 milliseconds divide the displacement "enhancement" by 2 to a minimum of + or - 1 for each update.
 
The encoder you are using is awful for bounce so it needs more filtering than a resistor+capacitor on the A and B channels can provide.
As I explained above, debounce is not required. If a contact bounces then it's exactly the same as going one step in one direction and one in the other - end result - zero. The code I've posted above works perfectly without debounce and contains the table you posted (only negative).

Mike.
BTW, where was the encoder details mentioned?
 
Last edited:
Not mentioned specifically other than my rant about how crappy they are, but it is the type I am using because everybody else uses them.

Turns out the machine I was waiting for for a job wont be available 'til the weekend, so I'm back until then (so much for being retired).

I'll wait until Ian comments on your code Mike, then integrate it to see what happens.

Dan, in the my current code there is a 1mS delay to help with the bounce problem and seems to work ok along with the cap/resistor arrangement.
 
I've used hardware rotary encoders on many projects and have never had a problem with contact bounce. Seems, if code isn't working as expected then blame bouncing contacts and add delays everywhere until you don't notice the problem anymore because you have to turn it extra slow.

With the above code (but in C) I am unable to turn it fast enough that it gets confused and counts the wrong way or miscounts.

Mike.
 
I've actually put these things on the 'scope and watched them ringing, anyway, they are what they are.

OK, dumb question time: I'm assuming I need to read the state of the encoder inputs at start-up and save them and, do I need to clear the C bit of the Status register before the RLF at the beginning of the routine?
 
You could set previous to zero at startup but it's not really needed. In fact, simplest way to initialize stuff is to call the routine at startup (after setting TRISA) as this will transfer the current state (do what you said) to previous. There is no need to clear the carry at the beginning of the routine as any bits shifted in will be zeroed by the AND with 0x0C (0b00001100). The contacts may bounce badly but it doesn't matter due to how the code works.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top