PDA

View Full Version : Second I2C address not responding



Amoque
- 16th October 2013, 13:29
Some time ago I bought several big, beautiful, single character LCDs. These things are 1.5" tall and just scream, "Look at me I'm cool!" I ordered up some backer-boards, populated them with PCF8574 port expanders and my gorgeous new chips, bread boarded several and had this really nice display all working. Oh, it was a thing of beauty! Then, the economy took a turn, job... etcetera.

Long story short(er)... Life is good again and my attention has returned.

I wrote a short, simple program because, well... I just wanted to see them work you know? I can't be the only one here that gets a little "goosebumpy" when intellect, dexterity, and technology all come together.

Alas... no joy.

I mean, technically, it works. Either digit works perfectly alone - in either position, but no amount of wishing will inspire the second address to respond. I am clearly missing something, but no amount of searching the forum, the internet, or the manual reveals an answer. I feel as though there needs to be something between the two writes - a stop, start, reset, a well enunciated "abracadabra"... something. I2CSTOP causes an error and no amount of pause resolves the issue. I've tried using a variable as the address, reversing the 2 statements... I don't know what else to try.

Please take a look and explain what I'm missing?




#CONFIG
__config _CONFIG1, _INTRC_IO & _WDT_OFF & _PWRTE_OFF & _MCLR_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_PROTECT_OFF & _DEBUG_OFF
__config _CONFIG2, _FCMEN_OFF & _IESO_OFF
#ENDCONFIG

OSCCON = %01110000 'SET OSC OPTIONS
DEFINE OSC 8
ANSEL = %00000011 'SET ANALOG TO DIGITAL
TRISA = %00000000 'SET PORTS OUTPUT
TRISB = %00000000

DEFINE DEBUG_REG PORTB 'SERIAL OUT
DEFINE DEBUG_BIT 5
DEFINE DEBUG_BAUD 2400
DEFINE DEBUG_MODE 0

SDA VAR PORTB.1
SCL VAR PORTB.4
OUTP VAR BYTE
LP VAR BYTE

mainloop:
FOR LP=0 TO 9
READ LP, OUTP
I2CWRITE SDA, SCL, $7C, OUTP 'WRITE 1's
I2CWRITE SDA, SCL, $70, OUTP 'WRITE 10's
PAUSE 250
NEXT LP
Goto mainloop 'VIRTUAL END

DATA 63, 6, 91, 79, 102, 109, 124, 7, 127, 103 'DEFINE DIGITS 0 - 9

End



I'm running it on a 16F88, internal 8M crystal, PBPX 3.0.4.4 and MCS 5.0.0.0

Art
- 16th October 2013, 13:52
Something like:


' test every location

bruteforce var byte
tencounter var byte
howeverlongittakestoseethedisplaywrittenlive var word

tencounter = 0
FOR bruteforce = $00 TO $FF

READ tencounter, OUTP
I2CWRITE SDA, SCL, bruteforce, OUTP

tencounter = tencounter + 1
IF tencounter > 9 THEN
tencounter = 0
ENDIF

PAUSE howeverlongittakestobeabletoseethedisplaywrittenli ve
NEXT bruteforce

Art
- 16th October 2013, 13:58
Except that I fell for your mistake, and that's not how I2CWRITE works:

I2CWRITE DataPin,ClockPin,Control,{Address,}[valvue{,Value...}]{,Label}

ie.


I2CWRITE PORTC.4,PORTC.3,$ao,0,[STR a\8]


I think you set the command to look for another I2C device on the bus rather than incremented the address index for the same device.

Art
- 16th October 2013, 14:14
PAUSE 10 for the first write to complete because you used two I2CWRITE commands.
(page 86).

Amoque
- 16th October 2013, 14:27
It may be that I have not been clear or perhaps I do not understand your comment. There are two devices, one address $70, one $7C (ones digit and tens digit) on the same bus. I have several of the modules and have tried several different addresses... always the first executes (and displays) perfectly; the other never. Do you suggest that there is some parameter missing from the I2CWRITE statement?

I tried adding ,[$00] in the case another tick was required to complete the "ACK", but no... error. In fact, everything I tried there failed. I thought I understood the syntax, but now I doubt.

Amoque
- 16th October 2013, 14:31
I added a PAUSE 250 between... and no. Still no joy.

Art
- 16th October 2013, 14:42
I didn't understand you were talking to two different devices.
I thought it was supposed to be writing the least significant digit to the right of the display,
and then the tens digit in the position to the left, on the same display.

The I2CWRITE still looks incomplete:


I2CWRITE SDA,SDL,I2CDEVICESELECT,ADDRESSONDEVICE,DATA

aratti
- 16th October 2013, 15:10
You should post the data sheet for your single character LCDs. Very likely you need to set the new address on each LCD (one at the time) before using them on a I2C bus.

Cheers

Al.

Amoque
- 16th October 2013, 15:54
Al, thanks for the reply. The LCDs are dumb; I'm using a PCF8574 port expander to control the segments. I did look again at that datasheet and all seems well in that the I2C seems to be a very standard implimentation.

At this pint I'm exploring Art's assertion that its in the I2CWrite syntax - I think he's right; I just don't understand the "control byte" thing well enough to fix it. Lining up the commas...

I2CWRITE SDA, SCL, $70, ,OUTP <- my code
I2CWRITE SDA, SDL, I2CDEVICESELECT, ADDRESSONDEVICE, DATA <- Art's

Shows I've missed something. Art calls it the ADDRESSONDEVICE, but since I have no clue what the control byte would be on the chip I'm using (I read and understand the examples given for memory chips), I'm pretty sure thats where the problem lies.

Off, armed with a hint, in search of an answer.

Archangel
- 16th October 2013, 17:46
If you are using NXP data sheet it's hard to understand address, the T I data sheet is more clear the link below to that data sheet
See page 6
http://www.google.com/url?q=http://www.ti.com/product/pcf8574&sa=U&ei=6b1eUtavEoPW2gX_noGQBw&ved=0CCYQFjAB&usg=AFQjCNEBNsP4KKw5J4lm0Ee8TD_UJQnvOw

LinkMTech
- 16th October 2013, 19:11
I'm confused how the 1st I2C address is even responding.

Your device address range, dependent on which address bits are tied HI, is between $40 and $4E according the data sheet.

7103



01000000 = $40 ' With A2, A1, A0 all set to 0 : (bit 0 set to Write)
01001110 = $4E ' With A2, A1, A0 all set to 1 : (bit 0 set to Write)


Verify which of your PCF8574 address select pins are pulled High and correct them on your current code because other than that it looks right.

Art, the 10ms PAUSE in the manual is referring to writing to an EEPROM that needs that Write delay because it's slow getting out of bed like me. :wink:

Amoque
- 16th October 2013, 20:03
The data sheet link passed on by Archangel is much appreciated! Way easier to read... thanks again.

LinkMTech- I have to be honest, the chips may be tha "A" version. I sandwiched the chip between the board and the LCD, so no way to tell, but I also marked each board with a correct address as I verified their function while building. I didn't think to mention the discrepancy because they work individually and it never occurred to me that the addresses could be part of the problem. It does make sense to check this out though as, of course, until the problem is found it may be anywhere.

I am at work presently and have no access to try any of these solutions for some hours, but I will give each every effort and report back soonest.

Amoque

These things are worth the time spent, they are beautiful when lit. Two are very nearly (I mean micro-smidgens different) the same size as the 128X64 GLCDS available in matching background and display color. Already I imagine a modular weather station (like a group of framed pictures) hanging on my den wall with groups of these providing clear visibility from anywhere in the room. Might even throw in a GLCD or two for graph functions. Gold foil touch sensors under glass... I tell ya boys, that's class, and I'm gonna get me some.

Amoque
- 16th October 2013, 23:11
I was so impatient to try the suggestions made that I took the rest of the day off.

Below is the modified code. I added another digit in hopes that the change might reveal the problem...




#CONFIG
__config _CONFIG1, _INTRC_IO & _WDT_OFF & _PWRTE_OFF & _MCLR_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_PROTECT_OFF & _DEBUG_OFF
__config _CONFIG2, _FCMEN_OFF & _IESO_OFF
#ENDCONFIG

OSCCON = %01110000 'SET OSC OPTIONS
DEFINE OSC 8
ANSEL = %00000011 'SET ANALOG TO DIGITAL
TRISA = %00000000 'SET PORTS OUTPUT
TRISB = %00000000

SDA VAR PORTB.1
SCL VAR PORTB.4
OUTP VAR BYTE
LP VAR BYTE
CHP100 VAR BYTE
CHP010 VAR BYTE
CHP001 VAR BYTE
CHP100 = $74
CHP010 = $72
CHP001 = $78
mainloop:
FOR LP = 0 TO 9
READ LP, OUTP
I2CWRITE SDA, SCL, CHP001, CHP001, OUTP 'WRITE 1's
PAUSE 250
I2CWRITE SDA, SCL, CHP010, CHP010, OUTP 'WRITE 10's
PAUSE 250
I2CWRITE SDA, SCL, CHP100, CHP100, OUTP 'WRITE 100's
PAUSE 250
NEXT LP
Goto mainloop 'LOGICAL END

DATA 63, 6, 91, 79, 102, 109, 124, 7, 127, 103
End




I think there is some progress in that now, at least, each digit will work independently. Applying power with all three modules plugged in, one (random) will work. Pulling the functioning digit, one of the others begins to cycle. Regardless of which digit I remove, one will always work; the others do not. It doesn't matter which spot they occupy - as long as they have a valid address.

In addition, I tried changing the value of the I2C resistors: 3K3, 4K7, 10K0 - no change in function. The circuit is run from adequate supply and is well filtered...

I still don't understand the "control" byte well, but RTFM indicates the class should match the fixed part of the address (MSBs) and the LSB should be zero; the addresses satisfy those requirements and beyond that I don't understand well enough to make an intelligent correction.

Amoque
- 16th October 2013, 23:13
Sorry... double post

aratti
- 16th October 2013, 23:50
Do you have pullup resistors on each module? If so you should remove them otherwise you parallel them, and if the pullup value on the I2C bus become too low hardy it will work. A recommended value for bus pullup is 4.7K to 10K.

Cheers

Al.

Amoque
- 16th October 2013, 23:59
Currently have 4K7s only. Doubled checked to be sure.

LinkMTech
- 17th October 2013, 01:51
Okay, try inserting brackets around your OUTP variable this way:



mainloop:
FOR LP = 0 TO 9
READ LP, OUTP
I2CWRITE SDA, SCL, CHP001, [OUTP] 'WRITE 1's
PAUSE 250
I2CWRITE SDA, SCL, CHP010, [OUTP] 'WRITE 10's
PAUSE 250
I2CWRITE SDA, SCL, CHP100, [OUTP] 'WRITE 100's
PAUSE 250
NEXT LP
Goto mainloop 'LOGICAL END


I just tried removing the brackets on a short test program I've been playing with and it didn't work right anymore until I put them back.

Amoque
- 17th October 2013, 02:47
Wow... How dumb do I feel? It works perfectly now! I've been sitting here scratching a bald spot behind my right ear as I review every comma, wire, and word on the manual page - all the while looking right past the missing brackets.

Thanks, Louie. I guess I just don't know how to say it more plainly than that. I really appreciate the help.

I just did a little more extensive testing... moved the digits around and fiddled with the timing some... it is rock solid now, every digit works in every position - fast - without skipping or cogging. Very nice! Thank you ALL again for your attention, time, and effort.

Art
- 17th October 2013, 03:36
Congrats :)


I'm confused how the 1st I2C address is even responding.

I'm also still stuck on this, and thought I still must be misunderstanding something.
It shouldn't have worked at all as far as I can tell.

Pictures of display device?

LinkMTech
- 17th October 2013, 16:30
Cool! You're welcome Amoque, glad you can continue on your quest.

I'm with Art, still confused with the addresses that are working. It must be an early version not mentioned in the data sheet I was looking.

Amoque
- 18th October 2013, 01:58
Haha! A question I can answer for you! The part number is PCF8574A - the "A" differing only by its upper address nibble, 0111xxx. If I include the write bit (I do because no read is ever done from the completed modules), the address range is $70 - $7F. With both the '74 and '74A, I can put 16 modules on a bus and make my own "Wheel of Fortune"! Did I not say I bought quite a number of these? :)

A picture so that you can envy my good fortune...

7107

The small item is a standard dot-matrix LED for comparison.

--All the best,
Amoque

Art
- 18th October 2013, 06:27
I was hoping they were matrix displays :)
They do look like a good way to make a project flexible.
I wouldn't want to be making the front panel for them though! :D