PDA

View Full Version : ADC and SEEPROM on 16F877A



Digitaldood
- 7th January 2013, 13:36
I am having a problem combining using ADC on channel A0 and saving data to a SEEPROM on portB.0 and 1. Individually I can get each to work, displaying the results on an LCD (on PortC). But when I try to combine them using the following code, I only get 255 read back as what is being stored in the SEEPROM (which is a 24LC512). But the Temperature readings are being read properly, which tells me I have the ADC part working, but not the I2C part. It seems as though the ADCON1 statement is what is causing it, but I don't know why that would have anything to do with I2C.
I am still learning, and I've looked for a similar program but could not find anything that resembles my program. Any help would be appreciated.

Thank you,

' Define A/D converter and LCD parameters
'
DEFINE ADC_BITS 8 ' A/D number of bits
DEFINE ADC_CLOCK 3 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us


Define LCD_DREG PORTC
Define LCD_DBIT 4
Define LCD_RSREG PORTC
Define LCD_RSBIT 3
Define LCD_EREG PORTC
Define LCD_EBIT 2
'
' Variables used
'
Res Var Byte ' A/D converter result
Temp1 Var Byte ' Temperature in degrees F
Addr Var Byte ' Address of EEPROM
CPin var PortB.0 'Pin for the SEEPROM Clock
DPin var PortB.1 'Pin for the SEEPROM Data
I var byte 'Variable for Collecting Data For/Next Loop
RI var byte 'Variable for Results Reading For/Next Loop
WB var word 'Varable for Waiting for Button Loop
TRISB.7 = 1 'Pin used for Button
'
'
PAUSE 500 ' Wait 0.5sec for LCD to initialize
'
' Clear display and display message "COLLECTING DATA…"
'
lcdout 254,0
lcdout 254,1,"Collecting DATA>"
'
' Initialize the A/D converter
'
TRISA = %11111111
ADCON1 = %00000010


'==========================Colect Data======================================


CollectData:


FOR I = 0 TO 60

ADCIN 0, Res ' Read Channel 0 data
Temp1 = Res - 40 ' Calc Adjustment to degrees F
I2CWrite DPin,CPin,$A0,Addr,[Temp1]
lcdout 254,192,dec3 Addr, " : ", dec3 Temp1
PAUSE 10 ' Wait 1 msecond
gosub WaitForButton
NEXT I ' Repeat
lcdout 254,0
lcdout 254,1, "Results"
goto DoneCollecting


'===========================Wait For Button=================================


WaitForButton:


For WB = 1 to 600
if PortB.7 = 1 then Results
pause 10
Next WB
Return


'=============================Done Collecting================================


DoneCollecting:


if PortB.7 = 1 then Results
pause 10
goto DoneCollecting


'===============================Results=========== ==========================


Results:


lcdout 254,0
lcdout 254,1, "Results"
FOR RI = 0 TO 60
I2CRead DPin,CPin,$A0,Addr,[Temp1]
lcdout 254,192,dec3 Addr, " : ", dec3 Temp1
pause 1000 'Wait one second
NEXT RI


END ' End of program

mackrackit
- 7th January 2013, 15:24
Addr Var Byte ' Address of EEPROM
I do not see a value assigned to the Addr variable.

Digitaldood
- 7th January 2013, 17:13
Yes, I did see that, and corrected it, and now what it is reading back after the 60 readings are taken, is numbers that don't match what I saw when the readings were being taken. For example, the readings start out at about 75 and I cause the thermistor to go up to about 85 and slowly come back down, to have some variation. The readings being read back are 255, 7, 9, 13, 255...255.

I have update my code to read as follows:



' Define A/D converter and LCD parameters
'
DEFINE ADC_BITS 8 ' A/D number of bits
DEFINE ADC_CLOCK 3 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us

Define LCD_DREG PORTC
Define LCD_DBIT 4
Define LCD_RSREG PORTC
Define LCD_RSBIT 3
Define LCD_EREG PORTC
Define LCD_EBIT 2
' Variables used
Res Var Byte ' A/D converter result
Temp1 Var Byte ' Temperature in degrees F
Addr Var Byte ' Address of EEPROM
CPin var PortB.0 'Pin for the SEEPROM Clock
DPin var PortB.1 'Pin for the SEEPROM Data
I var byte 'Variable for Collecting Data For/Next Loop
RI var byte 'Variable for Results Reading For/Next Loop
RAddr var byte 'Variable for Address of SEEPROM Results
WB var word 'Varable for Waiting for Button Loop
TempR var byte
TRISB.7 = 1 'Pin used for Button
'
PAUSE 500 ' Wait 0.5sec for LCD to initialize
' Clear display and display message "COLLECTING DATA…"
lcdout 254,0
lcdout 254,1,"Collecting DATA>"
' Initialize the A/D converter
TRISA = 111111
ADCON1 = 000010
'ADCON1 = 7

'==========================Colect Data======================================

CollectData:

FOR I = 0 TO 60

ADCIN 0, Res ' Read Channel 0 data
Temp1 = Res - 40 ' Calc Adjustment to degrees F
Addr = I
I2CWrite DPin,CPin,$A0,Addr,[Temp1]
lcdout 254,192,dec3 Addr, " : ", dec3 Temp1
PAUSE 10 ' Wait 1 msecond
gosub WaitForButton
NEXT I ' Repeat
lcdout 254,0
lcdout 254,1, "Results"
goto DoneCollecting

'===========================Wait For Button=================================

WaitForButton:

For WB = 1 to 600
if PortB.7 = 1 then Results
pause 10
Next WB
Return

'=============================Done Collecting================================

DoneCollecting:

if PortB.7 = 1 then Results
pause 10
goto DoneCollecting

'===============================Results=========== ===========================

Results:

lcdout 254,0
lcdout 254,1, "Results"
FOR RI = 0 TO 60
RAddr = RI
I2CRead DPin,CPin,$A0,RAddr,[TempR]
lcdout 254,192,dec3 RAddr, " : ", dec3 TempR
pause 1000 'Wait one second
NEXT RI

END ' End of program

mackrackit
- 8th January 2013, 05:11
Addr Var Byte
Should be
Addr Var WORD

I think....

Chirpy
- 8th January 2013, 10:02
I did see this in your code and maybe it's just me, but in your new code, I saw this part:

' Initialize the A/D converter
TRISA = 111111
ADCON1 = 000010

try changing it to and see if it helps:

' Initialize the A/D converter
TRISA = %11111111
ADCON1 = %00000010

also, I thought you could use byte for that also due to being able to count clear up to 255 with 8 bits.

:p

HenrikOlsson
- 8th January 2013, 11:05
That's most likely the forum messing up the posts.
You can switch between two different editors when making posts in the forum, one of them keeps messing up like up that no matter what you do.

If you look in the Forum Requests section you'll find requests for a fix. It's just a bit sad that a forum dedicated to PBP code can't show PBP code properly. Yes, the problem is known, yes the fix is to use the "correct" editor but new users and users who normally only come here when they're in trouble doesn't know that, makes a post with the "wrong" editor and the code in their post gets messed up. Then a year from now someone else finds the thread when looking for something, copy-pastes the messed up code which then doesn work and....

/Henrik.

Digitaldood
- 8th January 2013, 16:36
Yes, HenrikOlsson , if you look at my original post, (the one that I forgot to put the CODE quotes around) you'll see the ADC Initialize part correct, and that is how it should have appeared in my subsequent post.

mackrackit , I'm with Chirpy - I didn't think I would need to use WORD instead of BYTE unless I was using 10 bit, but after changing it in my code, it isn't the case. I would have thought that I only would have to change the WB var to a WORD since it counts up to 600, but I changed all var's associated with the address as well, and it is now working perfectly!! Not sure I understand why though. I first tried just changing WB to a WORD, and still had the same incorrect results. I know I also need to clean up the code a little too - not sure why I have 2 var's for the address, but I did need to change them both in both the I2CWrite and I2CRead commands.

Thank you all for your help!!

mackrackit
- 8th January 2013, 16:51
The address is 16 bit on this EEPROM, that is why the variable for it needs to be WORD size. It has to have all the places filled. It is in the data sheet.

Digitaldood
- 8th January 2013, 17:49
Awesome!! Thank you!! Gotta read the Data Sheets!!!