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.

Outputting PORTA to LCD

Status
Not open for further replies.

stagnant7

New Member
Hi.

I am making a DIY 8-bit Gray-code optical absolute rotary encoder project and I'm 3 days into programming the PIC18LF4520 MCU with MPLAB IDE and the C18 compiler.

I have the 8 photo transistor output signal lines (one for each code 'ring' of the disc) as inputs to PORTA (RA0-7 LSB to MSB) of a PIC18LF4520. I am reading voltages on each of the PORTA pins (checked with multimeter).

What I want and have tried to do is basically convert/decode PORTA, which is receiving Gray-code input, to a decimal angular position. I wish to then print this value to a 16X2 LCD.

For now I'm not calculating the angular position, I just want to output the position of the disc in binary ie. position 0 (00000000), 1 (00000001), 2 (00000010) etc etc up to 255 (11111111).

e.g. at any given position PORTA will contain a positional Gray-code:

*PORTA = 0b00110101 (8-bit Gray-code) ......which is decimal 53
*convert to binary = 0b00100110 ......which is decimal 38
*output this decimal number to LCD connected to port D (I already have the LCD working to output strings and numbers),

The problem is I'm not quite getting the output I'm after on the LCD...and I don't think its just LCD formatting problems. I have at one time got a clean number 0-255 (8-bit) but the increment was not as expected is jumping from say 10 to 53, thus making me think I needed to adjust the disc/sensor alignment. But after carefully re-adjusting the disc and checking that I'm getting expected voltage on each pin of PORTA, I now have output like this: 227, 36:, 2:3, 236 and so on.....

View attachment LCD2.c

I have attached the code above. I know its a drag looking at other peoples code, so here is a summary of what I think are possible problem areas in my project/code:

(1)
Is the following permissable?

unsigned char GrayWindDir=0;
GrayWindDir=PORTA;

In my mind this will store the 8-bit gray number occuring on PORTA in variable GrayWindDir.....but im not convinced :)

(2)
I have tested the function LCDWriteInt(); but all variables holding the 8-bit numbers (like GrayWindDir and BinaryWindDir) I have made of type unsigned char. but LCDWriteInt() accepts integers....it did seem to work though.

Anyway any help or direction will be most appreciated :)
 
Hi.

I am making a DIY 8-bit Gray-code optical absolute rotary encoder project and I'm 3 days into programming the PIC18LF4520 MCU with MPLAB IDE and the C18 compiler.

I have the 8 photo transistor output signal lines (one for each code 'ring' of the disc) as inputs to PORTA (RA0-7 LSB to MSB) of a PIC18LF4520. I am reading voltages on each of the PORTA pins (checked with multimeter).

What I want and have tried to do is basically convert/decode PORTA, which is receiving Gray-code input, to a decimal angular position. I wish to then print this value to a 16X2 LCD.



For now I'm not calculating the angular position, I just want to output the position of the disc in binary ie. position 0 (00000000), 1 (00000001), 2 (00000010) etc etc up to 255 (11111111).

e.g. at any given position PORTA will contain a positional Gray-code:

*PORTA = 0b00110101 (8-bit Gray-code) ......which is decimal 53
*convert to binary = 0b00100110 ......which is decimal 38
*output this decimal number to LCD connected to port D (I already have the LCD working to output strings and numbers),

After converting a code from gray to binary, you need to convert it in to ascii to display it on the LCD. If you want the binary value displayed them use something like this.

Binarycode=0b00100110;

for(i=0;i<8;i++)
{
Scratchcode=Binarycode && 0x80;
if(scratchcode==1)
{
here send LCD the ascii code of 1
}
else
{
send LCD the ascii code of 1
}
Binarycode=Binarycode<1);
}


The problem is I'm not quite getting the output I'm after on the LCD...and I don't think its just LCD formatting problems. I have at one time got a clean number 0-255 (8-bit) but the increment was not as expected is jumping from say 10 to 53, thus making me think I needed to adjust the disc/sensor alignment. But after carefully re-adjusting the disc and checking that I'm getting expected voltage on each pin of PORTA, I now have output like this: 227, 36:, 2:3, 236 and so on.....

View attachment 42311

I have attached the code above. I know its a drag looking at other peoples code, so here is a summary of what I think are possible problem areas in my project/code:

(1)
Is the following permissable?

unsigned char GrayWindDir=0;
GrayWindDir=PORTA;

In my mind this will store the 8-bit gray number occuring on PORTA in variable GrayWindDir.....but im not convinced :)

No problem with this, you even dont need to initialize it to 0, it will be set to PORTA.
(2)
I have tested the function LCDWriteInt(); but all variables holding the 8-bit numbers (like GrayWindDir and BinaryWindDir) I have made of type unsigned char. but LCDWriteInt() accepts integers....it did seem to work though.


Anyway any help or direction will be most appreciated :)


A question though about your function LCDWriteInt(), why have you used the integer data format? Data to the LCD is 8 bits. Why dont you write your own code for the LCD, its not that difficult. If you want to send strings than just use an array. If you want i can hook up a LCD code for you using the C18 libraries.

You are using a 1 MHZ crystal? or iis it a 4Mhz one in to the divider. If its the later case i already have an example using the 18f1320.
 
Thanks for your reply Wond3rboy, much appreciated. :)

Thanks for the code idea below:

After converting a code from gray to binary, you need to convert it in to ascii to display it on the LCD. If you want the binary value displayed them use something like this.

Binarycode=0b00100110;

for(i=0;i<8;i++)
{
Scratchcode=Binarycode && 0x80;
if(scratchcode==1)
{
here send LCD the ascii code of 1
}
else
{
send LCD the ascii code of 1 **I'm assuming you mean 0 here**
}
Binarycode=Binarycode<1);
}

While I am debugging the optical encoder (hardware/sensor alignment/program etc) it will be much better to see the 8-bit positional data in binary '01000110' format. Once it is working properly i will print out a decimal angular position....This project is going to indicate wind direction (wind vane will be connected to the shaft), so a '23deg' angular position ,for example, on the LCD will mean 23deg from the 0deg origin.

I have now set my PIC to operate off the internal oscillator, set to 8Mhz... I just randomly chose this frequency but perhaps I could set it to the default 1Mhz internal oscillator speed and thus increase battery life? 1Mhz osc freq should suffice for this project but I'm not sure, perhaps you might be able to confirm this?

Also I'm wondering if using interrupts to check the PORTA inputs from the Optical encoder will be a better way of going about it, rather than continuously bombarding the LCD with PORTA positional data. From the Microchip document "PIC Tips and Tricks":

TIP #7 Periodic Interrupts.
Generating interrupts at periodic intervals
is a useful technique implemented in many
applications. This technique allows the main
loop code to run continuously, and then, at
periodic intervals, jump to the interrupt service
routine to execute specific tasks

A question though about your function LCDWriteInt(), why have you used the integer data format? Data to the LCD is 8 bits. Why dont you write your own code for the LCD, its not that difficult. If you want to send strings than just use an array. If you want i can hook up a LCD code for you using the C18 libraries.

You are using a 1 MHZ crystal? or iis it a 4Mhz one in to the divider. If its the later case i already have an example using the 18f1320.

Yes I'd better customise the LCDwriteInt() function for my needs. Also I'd be grateful if you do have any helpful code for my type of project thanks for the offer :D
 
Sorry for the late reply. i just have been too busy. Here is the promised example using the 18f1320. Use Microchip's Libraries. Use proteus to see the simulation.
 

Attachments

  • software lcd.zip
    5.4 KB · Views: 144
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top