Searching \ for '[PIC] I2C dropping data in PIC slave' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/i2cs.htm?key=i2c
Search entire site for: 'I2C dropping data in PIC slave'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] I2C dropping data in PIC slave'
2007\01\17@092644 by alan smith

picon face
Well, down to one last issue on a project, and its I2C.  Setup is this....a master board with a couple other I2C devices on it, and existing formware running fine sending out commands to the other devices on that board.  Using some GPIO expanders.  Essentially it sends out the address, a command word and the data word.  I've looked at it with a analyzer and all looks good as expected since its working and has been working.  Now, I've taken that board and added another board with about 3' of cable to talk to a 18F8310 device, simple slave, it never sends anything back (short of the ACK of course) to the master, simply listens.  I have 2K pullups on that boards I2C interface as well, and eventually will be adding two more boards on that same I2C interface, and assume that each will need a pullup as well.  But thats after I get this one slave to work correctly.
 
 What is happening is the 3 byte transfer (address, data1,data2) isnt always getting into the correct registers...meaning.....when the I2C transfer occurs, I log that transfer to a buffer so I can go into the debugger and see what came over, given that I know what the master is sending at least.   I've coded it up two different ways, one using interupts, the other not..just polling for the start bit.  Since I know that when it starts, it always will consist of address, data1,data2 I can be reasonably assured I can remain in a loop looking for that sequence.
 
 So the interesting part is, using the polling method, its much more reliable..ie.....the slave PIC turns on a sequence of LEDs that shows if the 8 bits was correctly recieved.  As I watch, most the time it cycles correctly but now and then it either halts or skips LEDs. If I look in the buffer I can see where the data pattern was lost.  Sometimes I get the address showing up where data should be...ie.....address = 0x80 and the buffer shows 0x80,0x50,0x30 correctly but other times its 0x80,0x80,0x50..... etc
 
 So here is the code snippits for the polling method, that is working much better (maybe only by luck?)
 
 --------------------------------------------------------------------------------------------------------------------------
 INIT_I2C
       bsf         TRISC,3   ;initialize MSSP module
       bsf         TRISC,4
         movlw     0x80    ; initialize slave address
       movwf     SSPADD    ; and load to the address register
       bsf         SSPSTAT,SMP
       movlw     b'00110110'
       movwf     SSPCON1
       bcf         SSPCON1,SSPOV
         return

 
 
 
 MAIN
           btfss     SSPSTAT,S         ; check status
           goto      MAIN                   ;   no valid address decoded, keep looping
           call        GET_I2C             ;    go capture
           call        SHOW_DATA     ;       and show the updated data
           goto       MAIN
 
 GET_I2C
 
 wait4validAddr
         btfsc   SSPSTAT,P
         goto   _I2Cexit
         btfss   SSPSTAT,BF            ; buffer full?
         goto    wait4validAddr
         movff   SSPBUF,scratch        ; just the address, ignore
         call     MoveScratch              ; store to a buffer
wait4validData_1
         btfsc    SSPSTAT,P
         goto    _I2Cexit
         btfss   SSPSTAT,BF            ; buffer full?
         goto    wait4validData_1
         movff   SSPBUF,Data_1
           movff   SSPBUF,scratch        ; put Data_1 into scratch register
         call     MoveScratch              ; store to a buffer
wait4validData_2
         btfsc    SSPSTAT,P
         goto    _I2Cexit
         btfss   SSPSTAT,BF            ; buffer full?
         goto    wait4validData_2
         movff   SSPBUF,Data_2
           movff   SSPBUF,scratch        ; put Data_1 into scratch register
         call     MoveScratch              ; store to a buffer
wait4stop
         btfss   SSPSTAT,P
         goto    wait4stop
          bcf  SSPCON1,SSPOV       ; clear any overflow
          bcf  PIR1,SSPIF                  ; clear the interupt flag (not used)
          return
_I2Cexit
           bcf  PIR1,SSPIF
           bcf  SSPCON1,SSPOV
           return
 
 MoveScratch

           lfsr      FSR2, AD_BUFFER_START   ;Load FSR2 with the start  
           movff   RXoutOffset, FSR2L               ; load the offset.
           movff   scratch,INDF2                       ; and put data into the buffer.
           incf      RXoutOffset, f                            ; incrment RXoutOffset.
           return

 -------------------------------------------------------------------------------------------------------------------------------------
 
 and for the interupt driven solution, that appears to lose even more data.  This is inside the
 ISR, and the ISR is doing nothing else but triggering on either TMR0 interupt or this
 
 
         btfss      PIR1,SSPIF
       goto      _ExitISR
       bcf        PIR1,SSPIF
         movf     SSPSTAT,W       ; Get the value of SSPSTAT
       andlw    b'00101101'         ; Mask out unimportant bits in SSPSTAT.
       movwf    Temp                 ; for comparision checking.
 ADDRESS  
       movlw    b'00001001'         ; address, buffer is full.
       xorwf     Temp,W  ;
       btfss     STATUS,Z            ; looking for the address?
       goto      DATA                 ; No, must be data.....
       movff     SSPBUF,scratch  ; just the address, ignore
       call       MoveScratch
       clrf        byteCount

 DATA
       movlw    b'00101001' ; buffer is full.
       xorwf     Temp,W
       btfss      STATUS,Z      ; data available?
         goto       _ExitISR
       btfss      SSPSTAT,BF
       goto      DATA
       movff     SSPBUF,scratch
       call       MoveScratch
       incf       byteCount,f
 
_ExitISR
 
 ;----------------------------------------------------------------------------------------------------------------------------------
 
 So in either case, the PIC is really acting like a big GPIO expander since short if adding in I2C repeaters, etc you can't have that many devices on the I2C bus.  And since its not doing
 anything else, a short tight loop should work fine.
 
 I am thinking there is just something fundamentally wrong, but looking at your own creation its sometimes hard to spot.  I am going to try this same code on another demo board and see if its a hardware issue or just in the firmware (hoping for the latter of course).   This should be simple...but something is just wrong.  I2C shouldnt be prone to losing data like this?
 
 For the interutp driven, I thought I read that for every I2C (address or data) the interupt is generated?  I thought it just was generated when the start bit was detected?
 
 Thanks for anyone taking the time to look at this....I'm just going a bit crazy over this, when it should just simply work.
 
 -Al
 
 
 
 


---------------------------------
TV dinner still cooling?
Check out "Tonight's Picks" on Yahoo! TV.

2007\01\17@102614 by Alan B. Pearce

face picon face
>So the interesting part is, using the polling method, its much more
>reliable..ie.....the slave PIC turns on a sequence of LEDs that shows
>if the 8 bits was correctly recieved.  As I watch, most the time it
>cycles correctly but now and then it either halts or skips LEDs. If
>I look in the buffer I can see where the data pattern was lost.  
>Sometimes I get the address showing up where data should be...
>ie.....address = 0x80 and the buffer shows 0x80,0x50,0x30 correctly
>but other times its 0x80,0x80,0x50..... etc
>  
>So here is the code snippits for the polling method, that is working
>much better (maybe only by luck?)

I doubt that it is a code problem, but rather a noise problem.

How is your cable configured? If it is ribbon cable it needs to be

1 - gnd
2 - SDA
3 - gnd
4 - SCL
5 - gnd

and may need to be shielded on top of that.

Personally I would use a twin twisted pair, or STP cable.

then go looking for software problems.

2007\01\17@110239 by David Novak

picon face
1.) What is your clock rate? Have you tried slowing it to see if the
situation improves?

2.) Are you pulling the I2C lines to 5V? If so, 2K seems too stiff. Check
the iOL specs. for the IC's on the bus. I would recomment pullups only at
the master. Remember, additional pullups will be in series with existing
pullups.

3.) You may want to try a series resistor to dampen the noise.

If the interface works without the 3' cable, then the software is likely ok
and you should concentrate on the hardware.

Good luck,
David

=============================
David Novak
Dajac Inc.
17152 Shadoan Way
Wesfield, IN  46074

Email: spam_OUTnovakdTakeThisOuTspamdajac.com
Phone: 317-258-0223
Fax: 317-867-1888

http://www.dajac.com

Hardware/Software Consulting
Headlamp Alignment Equipment
=============================


{Original Message removed}

2007\01\17@111846 by Robert Rolf

picon face
David Novak wrote:

> 1.) What is your clock rate? Have you tried slowing it to see if the
> situation improves?
>
> 2.) Are you pulling the I2C lines to 5V? If so, 2K seems too stiff. Check
> the iOL specs. for the IC's on the bus. I would recomment pullups only at
> the master. Remember, additional pullups will be in series with existing
> pullups.

Uhhh, "PARALLEL with existing pullups".

I recommend splitting the pullup value between the master and the farthest slave.
I cuts down on ringing. e.g. 4.7K local and 4.7K distant giving 2.4K effective value.
You'll want the low value (2.2K effective) if you are using high speed (400kHz).
10K is typical for low speed (100kHz).

You should look at the signals with a scope to see if there is ground bounce,
ringing, or high frequency noise on the lines that could be corrupting the data.
The rising edges should be, at most, 20% of the bit time. If worse, you have too
much cable capacitance.

> 3.) You may want to try a series resistor to dampen the noise.

A small value like 100R works well on long cables.

Robert

2007\01\17@112035 by John Temples

flavicon
face
There's an errata that affects the SSP some PICs when they are slaves
on a bus that has other slave devices: BF and SSPOV can be falsely set
when a data byte matching the slave's address is seen on the bus.
This makes it appear you're losing data even though you're not.  I've
found this errata in PICs that don't have it documented.

On Wed, 17 Jan 2007, alan smith wrote:

{Quote hidden}

> --

2007\01\17@130147 by David Novak

picon face
>> Uhhh, "PARALLEL with existing pullups".

Oops! I was thinking parallel and typed series. Sorry for the confusion.

David


{Original Message removed}

2007\01\17@140104 by alan smith

picon face
Thanks for all the tips.  I am going to hook up a very short cable to another board and see if that makes a difference, while building up a shielded cable for the real design.  As far as pull-ups, since the master has pullups, think they are 4.7K to +5, maybe there isnt a need for them to be on the slave side then, for some reason I always thought they needed to be associated with each slave.

---------------------------------
Never Miss an Email
Stay connected with Yahoo! Mail on your mobile. Get started!

2007\01\17@160933 by Bob Axtell

face picon face
All was well until I noticed the 3' cable length and the second PCB.

i2c is not famous for distance, 3' is longer than anything I ever did,
and i2c was designed for single-board TV designs- nothing outside of the
same PCB.
So I think you have a noise problem, caused by poor GND, long cable, and
probably the multiple 2K pullups (much too heavy, 3.3K works for me, near
the master).

--Bob

alan smith wrote:
{Quote hidden}

2007\01\17@163604 by PAUL James

picon face
The main reason this is probably failing is the capacitance of the cable
is out of the spec if I2C.

{Original Message removed}

2007\01\17@183457 by David Novak

picon face
4.7K to +5 is very reasonable (I typically use 5.1K). With your scheme of
adding additional slaves, I think your best choice is to include the pullups
only at the master.

David


> {Original Message removed}

2007\01\17@184815 by Dario Greggio

face picon face
Bob Axtell wrote:

> i2c is not famous for distance, 3' is longer than anything I ever did,
> and i2c was designed for single-board TV designs- nothing outside of the
> same PCB.

Hi, I can say that I've been using up to some 8meters of UTP cable on
I2c (TC74 sensors). I reduced the pull-ups down to 470ohm circa.
Also, reduced the frequency to 15KHz or so.
Others have reached the same distances.

So, I guess that either you have big capacitance on your wires, or the
problem lies somewhere else.

--
Ciao, Dario
--
ADPM Synthesis sas - Torino

2007\01\17@192046 by David Novak

picon face
> i2c is not famous for distance, 3' is longer than anything I
> ever did,
> and i2c was designed for single-board TV designs- nothing
> outside of the
> same PCB.

I have worked with an I2C bus containing approximately 18 slaves and close
to 3' after spanning 4 seperate boards...in a TV! Keeping the clock rate
slow was a very wise decision. We used 50KHz, but 100KHz is not out of the
question for a long bus.

Designers tend to worry a great deal about the rise time, but I have seen
I2C work flawlessly with as large as 5us rise times. It helps that most IC's
have some amount of glitch rejection on SCL. Actually, for a long bus, the
fast fall times may cause more grief than the slow rise times due to
transmission line effects.


David


> {Original Message removed}

2007\01\18@041719 by Alan B. Pearce

face picon face
>i2c is not famous for distance, 3' is longer than anything I
>ever did, and i2c was designed for single-board TV designs-
>nothing outside of the same PCB.

Although there are many TVs where the IR receiver and tuner are on a
different PCB on the front panel with a flying cable for the I2C to the main
PCB. I wouldn't consider 3' an excessive length provided good care is taken
with shielding.

Also on the Philips page link I posted, there is a link to pages about hubs
and bus extenders for I2C.

2007\01\18@041850 by Alan B. Pearce

face picon face
>The main reason this is probably failing is the capacitance
>of the cable is out of the spec if I2C.

The solution to that is to run the clock slower. I have had I2C clocked at
10kHz to get around problems in an opto-isolated bus I used.

2007\01\18@085620 by alan smith

picon face
OK, problem is solved I think...
 
 Made up a very short cable to go from my existing master board to a PicDem2 board, and just hard wired it in.  I ended up shutting off interupts (which is OK for this application) and running it in a polled fashion (again, for this app its fine) and cleaned up the code and then started to get the address/data1/data2 correctly.  I had the master just send down a sequential count and then I logged it to the buffer so I could review it every 100 transactions and not a single dropped transaction.
 
 So, made up a shorter cable...its still about 28"  and pushed the same code to that device..same results.
 
 Couple of notes.  First, on the picdem board, I had no pullups.  I left the pullups on the target board.  Didnt seem to make a difference, in that I wasn't losing data, but not sure about the signal integrity, didnt pull out the scope to look since it appears to be working.  I believe the master is running at 100KHz but I need to go verify that, just for my own information.  Second, when I rebuilt the cable, I am quite sure the ground was broken, so that in itself may have been the root cause (grrrrr).
 
 
 
 So, thanks for listening, advising and commenting.
 
 -Al
 

Dario Greggio <.....adpm.toKILLspamspam@spam@inwind.it> wrote:
 Bob Axtell wrote:

> i2c is not famous for distance, 3' is longer than anything I ever did,
> and i2c was designed for single-board TV designs- nothing outside of the
> same PCB.

Hi, I can say that I've been using up to some 8meters of UTP cable on
I2c (TC74 sensors). I reduced the pull-ups down to 470ohm circa.
Also, reduced the frequency to 15KHz or so.
Others have reached the same distances.

So, I guess that either you have big capacitance on your wires, or the
problem lies somewhere else.

--
Ciao, Dario
--
ADPM Synthesis sas - Torino

2007\01\18@114256 by Herbert Graf

flavicon
face
On Thu, 2007-01-18 at 09:18 +0000, Alan B. Pearce wrote:
> >The main reason this is probably failing is the capacitance
> >of the cable is out of the spec if I2C.
>
> The solution to that is to run the clock slower. I have had I2C clocked at
> 10kHz to get around problems in an opto-isolated bus I used.

Absolutely. I once had an I2C bus running about 15 meters. Clocked it at
about 1kHz. It wasn't perfect but it did work well enough for my
purposes.

TTYL

2007\01\22@182214 by alan smith

picon face
Just wanted to thank everyone that suggested solutions to this problem.  It appeared to be just a bad cable, as I had the client build a cable for his hardware setup, and the code ran fine, and then HIS client....was sent another set of hardware, complete with a 'good' cable and its running fine.  The cable is about 35" long, just individual wires (18AWG) and then daisy chained to 3 other boards, about 6" long on each run.  I did suggest they use something like CAT5 for the final installation.  But all is well...short of some other code bugs but the I2C is running like it should...
 
 Again, thanks to everyone that did take some time to respond and suggest.

 
---------------------------------
Looking for earth-friendly autos?
Browse Top Cars by "Green Rating" at Yahoo! Autos' Green Center.  

More... (looser matching)
- Last day of these posts
- In 2007 , 2008 only
- Today
- New search...