I2C write - value too big


Closed Thread
Results 1 to 20 of 20
  1. #1

    Default I2C write - value too big

    Hi all,

    i have found a bug in my temperature logger (16F88 + 24LC512+LM35).
    I works pretty well until it reaches temp values of 124șC, for values above it are displayed as 0șC or 0,5șC.

    I've looked at my code and i think a know what the problem is: I need to separate the variable into lowbyte and highbyte.

    The problem is that i'm not being able to get this working that way. Here's why :


    This way does not work:
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR,[tempe.highbyte]
    pause 10
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR,[tempe.lowbyte]
    This way does not work:
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe.highbyte]
    pause 10    
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe.LOWBYTE]
    Only this way one works:
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
    pause 10    
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
    Long story short:
    I can make it work with the eeprom BUT only with Address high and low. If i try to separate the variable tempe into high and low it doesnt work

    Any ideas ?
    Thanks
    .
    Last edited by ruijc; - 5th April 2008 at 16:43.

  2. #2
    Join Date
    Mar 2008
    Location
    Texas, USA
    Posts
    114


    Did you find this post helpful? Yes | No

    Default

    Use a word size variable. PBP will read the two bytes. Check PBP manual for the loading order. You may have to flip .highbyte and .lowbyte outside the I2CREAD statement.
    No, I'm not Superman, but I did stay at a Holiday Inn Express last night!

  3. #3


    Did you find this post helpful? Yes | No

    Default

    Thanks for the help JD123,

    The variable is already a word sized.

    You may have to flip .highbyte and .lowbyte outside the I2CREAD statement
    Outside ? How is this done ?

    .

  4. #4


    Did you find this post helpful? Yes | No

    Default

    checked the PBP manual and did some changes to the code but did not worked ( not sure this is what you mean ):

    what i did:

    Added alias
    Code:
    tempe   var  word
    
    temp1   var tempe.highbyte
    temp2   var tempe.lowbyte
    saving data to eeprom
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[temp1]
    pause 10    
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[temp2]
    .

  5. #5
    Join Date
    Mar 2008
    Location
    Texas, USA
    Posts
    114


    Did you find this post helpful? Yes | No

    Default

    Just the use of a word size variable, invokes PBP to read two bytes. It places the first byte in the var.highbyte and the second in the var.lowbyte. EDIT: Sorry, I didn't see that you were not writing, not reading - this is for reading)

    If this is not the order you want, you'll have to exchange the two bytes outside the I2C instruction. I'm not sure of all the techniques (like using PBP SWAP) will work, but it's a standard process that can be done using a temporary 'working' word size variable.

    temp.highbyte = var.lowbyte
    temp.lowbyte = var.highbyte
    var = temp
    Last edited by JD123; - 5th April 2008 at 17:41.
    No, I'm not Superman, but I did stay at a Holiday Inn Express last night!

  6. #6
    Join Date
    Mar 2008
    Location
    Texas, USA
    Posts
    114


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by ruijc View Post
    checked the PBP manual and did some changes to the code but did not worked ( not sure this is what you mean ):

    what i did:

    Added alias
    Code:
    tempe   var  word
    
    temp1   var tempe.highbyte
    temp2   var tempe.lowbyte
    saving data to eeprom
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[temp1]
    pause 10    
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[temp2]
    .
    Just use:

    I2CWRITE SDA,SCL,CTW,ADDR,[TEMP]

    In both ADDR and TEMP they are word size and PBP will send each byte out for the word - no need to bust them up and send them individually.
    No, I'm not Superman, but I did stay at a Holiday Inn Express last night!

  7. #7


    Did you find this post helpful? Yes | No

    Default

    Just use:
    I2CWRITE SDA,SCL,CTW,ADDR,[TEMP]
    This was my first option, but for some reason the eeprom does not store the data this way.

    Actually, with the 12F675 chip this eeprom works well with :
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR,[temp.highbyte]
    pause 10
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR,[temp.lowbyte]

    But not with the 16F88.

    I got it working with :
    Code:
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
    pause 10    
    ADDR=ADDR+1
    I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
    The problem now is for the lenght of the tempe value when over 125șC

    .

  8. #8
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    something don't make sense... could you post your whole code for the 16F88?
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  9. #9


    Did you find this post helpful? Yes | No

    Default

    Here's the code:

    Code:
    OSCCON  =  $7e  'Internal RC w/ I/Os
    CMCON = 7      'comparators off
    CVRCON = 0     'Vref Off
    CCP1CON=0
    T1CON  = 0
    
    OSCTUNE=0
       
    '*****************************************************************************
    'DEFINEs
    '*****************************************************************************
     
    @ DEVICE INTRC_OSC
    @ DEVICE MCLR_OFF
    @ DEVICE PROTECT_OFF
    
    DEFINE OSC 8
    
    @ DEVICE CPD_OFF
    @ DEVICE LVP_OFF
    @ DEVICE BOD_OFF
    @ DEVICE PWRT_OFF
    @ DEVICE WDT_OFF
    
    '*****************************************************************************
    'ADC
    
    DEFINE ADC_BITS 10 
    DEFINE ADC_CLOCK 3 
    DEFINE ADC_SAMPLEUS 50
    
    '*****************************************************************************
    'ADC parameters
    
    ADCON1  =%10000000      'right justify 
    ANSEL   =%00000110 
    ADCON0  =%11000001     
    
    '*****************************************************************************
    
    INCLUDE "modedefs.bas" 
    DEFINE debug_reg PORTA  
    DEFINE debug_bit 1
    DEFINE debug_baud 9600
    DEFINE debug_mode 1
    
    '*****************************************************************************
    ' variables
    
    va       var word
    tempe    var word
    mem      var word
    state    var byte
    st       var word
    ed       var word
    ADDR     var word
    m1       var word
    m2       var word
    m3       var word
    m4       var word
    slot     var byte
    w        var byte
    RA       var word              
    x        var word
    ps1      var word
    ps2      var word
    ps3      var word
    ps4      var word
    temp1   var tempe.highbyte
    temp2   var tempe.lowbyte
    
    rm con 8
    ps1=1 
    ps2=4 
    ps3=7 
    ps4=10 
    
    p1a  con $10     
    p1b  con $e20   
    p2a  con $e2a 
    p2b  con $1c3a 
    p3a  con $1c44 
    p3b  con $2a54 
    p4a  con $2a5e 
    p4b  con $386e 
    
    'CLEAR
    
    ctw CON $A0
    
    '*****************************************************************************
    
    PORTA=0
    PORTB=0
    TRISA=%00100101
    TRISB=%00001111
    
    '*****************************************************************************
    'PINS
    
    temp      var PORTA.0 
    out       var PORTA.1 
    volt      var PORTA.2 
    a3        var PORTA.3 
    jumper    var PORTA.4 
    but1      var PORTA.5  'read
    led2      var PORTA.6 
    led1      var PORTA.7 
    but2      var PORTB.0  ' record 
    p1         var PORTB.1  
    SCL       var PORTB.2  ' eeprom  
    SDA       var PORTB.3  ' eeprom
    green     var PORTB.4  ' bicolor led (green)
    red       var PORTB.5  ' bicolor led (red)
    led4      var PORTB.6  
    led3      var PORTB.7
    
    '*****************************************************************************
    startmenu:
    st=p1a
    ed=p1b
    
    if but1=1
    While but1=1
    Wend ' Wait here for Button to be released
    gosub readmenu
    endif
    if but2=1
    While but2=1
    Wend ' Wait here for Button to be released
    gosub recordmenu
    endif
    goto startmenu
    
    '*****************************************************************************
    
    readmem:
    led2=1
    led3=0
    'debug "Reading Memory",13,10
    'debug "Address: ",dec mem," start at ",dec st, " and finish at ",dec ed,13,10
    'debug " Memory # ",dec mem,13,10
    FOR ADDR =st TO ed
    toggle led2
    toggle led3
    
            I2CREAD SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
            PAUSE 10
            toggle green
    debug dec3 tempe/10,",",dec1 tempe//10,13,10 
            ADDR=ADDR+1
            NEXT 
            green=1
            return
    
    '*************************************************
    
    FOR ADDR=st TO ed
         
       		adcin temp,va
     
    tempe=(va*/5000 )>>2
    
            toggle red
            toggle green
            pause   418    ' calibration to get  1200  readings  ( 2 per second ) in 10 minutes   - 
            debug " Valor Gravado: ", dec tempe," Na posiçăo  ", dec ADDR, 13,10 
            I2CWRITE SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
            pause 10    
            ADDR=ADDR+1
            I2Cread SDA,SCL,CTW,mem.highbyte,mem.lowbyte,[x]
            pause 10
            'debug "Address: ",dec mem," started at ",dec st, "finish value ",dec x,13,10
            debug "  ",13,10
            if but1=1 then      'stop recording
            pause 600
            goto timing
            goto startmenu
            endif
            NEXT
            red=1
            return
    *************************************************

  10. #10
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Ruijc,

    I did not check the code in detail but at first look there is something that should not be done.

    Code:
    ....
            goto timing
            goto startmenu
            endif
            NEXT
            red=1
            return

    1. You have two "goto" s one after the other. When the first one runs, the second one will not run!

    2. When the first one runs, then you will have a return address on stack; Thus, the next time you hit a return, where ever it is, it will ruin your logic flow. You must organize a logic flow that will clear the return address of the subroutine you are in. Example: set a flag and then exit the subroutine with "return".
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  11. #11
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    i'm a bit surprised you don't have any compilation errors...
    a) 2 mistyped IF statements,
    b) it miss Readmenu, recordmenu, timing section,
    c) and as Sayzer point-out.. those goto are a bit weird... and in case you remove Goto timing... it will branch to the startMenu indeed... but you will always add 1 on the Stack.. shortly it will overflow...

    Code:
    OSCTUNE=0
    why? You don't need to do it unless you want to calibrate the internal OSC, just remove it. Almost sure your Serial comm wasn't working really well huh? (DEFINES aren't in caps either.. but it can be a paste error)

    Code:
    I2CREAD SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]
    Why do you split addr in 2 ?
    Code:
    I2CREAD SDA,SCL,CTW,ADDR,[tempe]
    This have to be changed in ALL I2CREAD AND I2CWRITE lines

    This must be written the right way.. unless YOU will have problem indeed.
    Last edited by mister_e; - 6th April 2008 at 11:23.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  12. #12
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,620


    Did you find this post helpful? Yes | No

    Lightbulb

    Hi,

    I wonder the '675 was running @ 4Mhz , the '88 is running @ 8Mhz ... which is the limit for using " I2C SLOW" ...

    Did you try that DEFINE ???

    Just an idea ...
    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  13. #13
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Not a problem for the 24LC512 unless the pull-up resistor are way to high... it can run up to 400KHz, 1MHz for FC version.

    But there's few mistakes in the code.... sure i missed a few
    Last edited by mister_e; - 6th April 2008 at 11:34.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  14. #14


    Did you find this post helpful? Yes | No

    Default

    Hello sayzer, Mister-e and Acetronics

    1. You have two "goto" s one after the other. When the first one runs, the second one will not run!
    this is true. I sampled this section from the hole code to test your help but there are some " ' " missing there.

    However, removing the missing links and compiling errors the final result is the same.


    Code:

    I2CREAD SDA,SCL,CTW,ADDR.highbyte,addr.lowbyte,[tempe]

    Why do you split addr in 2 ?
    Code:

    I2CREAD SDA,SCL,CTW,ADDR,[tempe]

    This have to be changed in ALL I2CREAD AND I2CWRITE lines
    This is my biggest problem. What you suggested was my first written code and it didnt worked.

    This was my problem in the past and resolved with the help of Skimask.
    (see post...)
    http://www.picbasic.co.uk/forum/showthread.php?t=8153

    Frankly,i didnt understood then as i still dont now, but it worked.

    The problem now is that it's not returning good values after the 127 mark and i believe that it's related with 1111111 going to 10000000 since that i read nothing but 000.x from there.

    ( see attached pic )

    .
    Attached Images Attached Images  

  15. #15


    Did you find this post helpful? Yes | No

    Default

    Well, i think i just fixed one problem and found a new one

    I have sucessfuly use the code " I2CREAD SDA,SCL,CTW,ADDR,[tempe] ".

    After several changes i tryed Mister-e's suggestion and removed the OSCTUNE=0 line.

    It doesnt make sense to me ( or does it ? ), but it's working this way now.

    The new problem that i found is that while debugging i found out that the problem related with getting low values passed the 120'ich mark IS NOT related with the eeprom/low-highbytes.

    I got a variable resistor to simulate the LM35 and was changing the value while recording, and i could see that the value captured dropped after the conversion and before recording to the eeprom.

    this is the capture while increasing the variable resistor
    Code:
    111,3
    111,3
    111,8
    112,3
    112,3
    112,7
    112,7
    113,2
    113,7
    114,2
    114,7
    115,2
    115,7
    116,2
    117,6
    118,1
    118,6
    118,6
    118,6
    118,6
    119,1
    121
    121,5
    122
    122,5
    122,5
    122,5
    122,5
    0,4
    0,9
    0,4
    0,9
    0,4
    0,9
    0,4
    0,9
    0,4
    0,9
    now i'm lost

    .
    Last edited by ruijc; - 6th April 2008 at 13:37.

  16. #16
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,620


    Did you find this post helpful? Yes | No

    Default

    Hi, Ruicj

    Can you tell us how you get those values :

    ( 122.5 is NOT a PbP value ...)

    - Input value range ( volts ? ) / ref voltage
    - Math used ( in PbP )
    - Values you want to to output

    It's "not so clear" ...

    Alain

    PS : ANSEL doesn't match the ADCIN PORT !!! Check it !!!
    Last edited by Acetronics2; - 6th April 2008 at 13:51.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  17. #17


    Did you find this post helpful? Yes | No

    Default

    Hello Acetronics,

    these values i get from:

    Code:
    FOR ADDR=st TO ed
         
       		adcin temp,va
     
    tempe=(va*/5000 )>>2
    
            toggle red
            toggle green
            pause   418    ' calibration to get  1200  readings  ( 2 per second ) in 10 minutes   - 
            debug " recorded value: ", dec tempe," position  ", dec ADDR, 13,10
    the debug line gave these values after the adcin conversion.
    I'm colecting the voltage directly from the variable resistor which is simulating the voltage from a LM35 ( 0,2v - 1,5V )
    I'm not using any reference value, just VDD and VSS( i know...it's lame...but i'm not looking for the best resolution for now )

    .

  18. #18
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,620


    Did you find this post helpful? Yes | No

    Default

    seen it ???

    : ANSEL doesn't match the ADCIN PORT !!! Check it !!!

    ANSEL select A1 and A2
    ADCIN select A0 ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  19. #19


    Did you find this post helpful? Yes | No

    Default

    Acetronics,

    You are right !!! Thank you ( and the rest of the guys for the help )

    This was set when i was playing with several sensors

    But how can it be ?? If i have the ANSEL with a different channel, how can i get values on channel A0 ??

    This is why i didnt see it

  20. #20
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,620


    Did you find this post helpful? Yes | No

    Wink

    Capacitive coupling ... pins are side-by-side !!!
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

Similar Threads

  1. I2C Master/Slave 16F88/16F767 working code
    By DanPBP in forum Code Examples
    Replies: 2
    Last Post: - 23rd October 2012, 23:31
  2. HARDWARE I2C SAMPLE CODE question
    By Michael Wakileh in forum Code Examples
    Replies: 2
    Last Post: - 16th June 2009, 22:07
  3. Replies: 5
    Last Post: - 29th May 2008, 19:03
  4. PIC16F877 I2C programme
    By cooqo in forum mel PIC BASIC
    Replies: 3
    Last Post: - 21st April 2008, 11:02
  5. I2C Master Slave issues.
    By cpayne in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 29th March 2008, 20:33

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts