-
1 Attachment(s)
I2C CONFUSION, Help needed please
I am trying to communicate with an I2C device. I have done almost everything I could think of but it is not working. The manual mentions stuff but not exactly matching with the datasheet of the device. The device datasheet mentions something about ACK/NACK which the pbp manual does not mention even once. On top my lack of understanding of I2C has left me with no other option to ask here about what I am doing wrong.
What I have done:
I have tried the following commands:
Value var byte
I2CREAD SDA,SCL,%000110100,0,[Value] ' Tried this
I2CREAD SDA,SCL,$1B0,0,[Value] ' Tried this
I2CREAD SDA,SCL,$1B,0,0,[Value] ' Tried this
Then When I do this:
debug HEX Value ' I am expecting '2E' on my screen. But I am not getting it.
(Location Zero will read 2E in the device)
I attach the section explaining the I2C from the datasheet. The device address is $1B.
Many thanks in advance
(Using 16F688 @ 4 MHz)
-
Re: I2C CONFUSION, Help needed please
Did you put the two pull-up 4.7k resistors in the SDA and SCL lines?
Robert
-
Re: I2C CONFUSION, Help needed please
Also, you don't need to worry about anything that you highlighted in red. The I2CREAD and I2CWRITE commands take care of that for you.
Robert
-
Re: I2C CONFUSION, Help needed please
Quote:
Originally Posted by
rsocor01
Did you put the two pull-up 4.7k resistors in the SDA and SCL lines?
Robert
Yes, pull ups are there @ 3.2k.
I tried the statement : I2CREAD SDA,SCL,$1B,0,[VALUE] (is it correct? because I don't had any luck)
-
1 Attachment(s)
Re: I2C CONFUSION, Help needed please
My Code is this:
Quote:
Include "modedefs.bas"
DEFINE OSC 4
#CONFIG
ifdef PM_USED
device pic16F688, intrc_osc_noclkout, wdt_on, mclr_on, protect_off
else
__config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _CP_ON & _CPD_ON & _BOD_ON & _IESO_ON & _FCMEN_ON
endif
#ENDCONFIG
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 3
DEFINE DEBUG_BAUD 2400
DEFINE DEBUG_MODE 1
DEFINE I2C_SLOW 1
'DEFINE I2C_HOLD 1
'-----------------------------------------------------
PORTA=0
PORTC=0
TRISA = %000100
TRISC = %110000
CMCON0 = 7
ANSEL = 0
OPTION_REG = 128
INTCON=128
'-----------------------------------------------------
Value Var word
'------------------------------------------------------------
SCL Var PortC.5
SDA Var PortC.4
Change Var PortA.2
LED Var PortC.0
'---------------------------------------------------------
Pause 500
DEBUG "Start......",13,10
value=0
Main:
High Led : Pause 1000: Low Led : PAUSE 1000
I2CREAD SDA,SCL,$1B,0,[VALUE],Fail
PAUSE 25
DEBUG HEX Value,13,10
PAUSE 250
DEBUG "Done....",13,10
Goto Main
Fail:
toggle portc.2
goto main
PortC.2 keeps toggling along with normal LED.
I have also attached the device datasheet. I really appreciate the help in this.
-
Re: I2C CONFUSION, Help needed please
From PBP manual about I2CREAD:
"Constants should not be used for address..."
Don't know if this can help.
Robert
-
Re: I2C CONFUSION, Help needed please
Quote:
Originally Posted by
Demon
From PBP manual about I2CREAD:
"Constants should not be used for address..."
Don't know if this can help.
Robert
I added two bytes - Addr & Loc
Addr=$1B
Loc=0
Sent - I2CREAD SDA,SCL,Addr,Loc,[Value],Fail
No Luck :(
'-----------
What is also confusing me is the control byte in the manual, the device datasheet does not mention any control byte.
I have an address $1B which I am sending as control and location in the device is being sent as Address according to the manual.
-
Re: I2C CONFUSION, Help needed please
The device you are using is a fast mode device (400 khz) so you have to remove the "DEFINE I2C_SLOW 1" and very likely you have to increase your clock speed (4 MHz could be too slow). Also change the variable into byte (you are using word).
Good luck
Al.
-
Re: I2C CONFUSION, Help needed please
I thought I saw 9 bits used from control in the datasheet you linked.
Maybe you're supposed to use a word and ignore the other 7 bits? Or that could be handled by PBP for I2C?
Do you get only a byte back, word, multiple bytes?
Your circuit does make address 0 right?
(just throwing ideas at you)
Robert
-
Re: I2C CONFUSION, Help needed please
Steps Taken:
1) Configuration changed: _INTRC_OSC_NOCLKOUT
2) Made 16f688 run at 8MHz : OSCCON=%01110001
3) Commented DEFINE I2CSLOW 1
4) Value changed to BYte (then to word again)
I get a byte back from the device (from what I have understood). Yes there is an address 0 in the device. I should get back chip ID i.e-'2E' as per the datasheet.
Still no Luck.
-
1 Attachment(s)
Re: I2C CONFUSION, Help needed please
I couldn't find detailed info on the Write/Read bit of the device address. But I will guess it is bit 7.
You need to Write to the device first using the address with the "Write" bit set.
$1B or %00011011 becomes $9B or $10011011
Without confirming the proper syntax of the commands, here's something off the top of my noodle:
This will cover steps 1~4 of Section 4.3.2 of the datasheet
Code:
I2CWRITE SDA,SCL,[Addr,Loc,] ' Addr plus Write bit = $9B
This will cover steps 5~7 of Section 4.3.2 of the datasheet
Code:
I2CREAD SDA,SCL,[Addr,Loc] ' Addr plus Read bit = $1B
Putting it together should get you moving in the right direction.
Code:
I2CWRITE SDA,SCL,[Addr,Loc,] ' Addr plus Write bit = $9B
I2CREAD SDA,SCL,[Addr,Loc] ' Addr plus Read bit = $1B
Here's a note to myself that might come in handy too:
-
Re: I2C CONFUSION, Help needed please
Tried this:
Code:
Pause 500
DEBUG "Start......",13,10
Value=0
Addr=$9B
Loc=0
Main:
High Led : Pause 500: Low Led : PAUSE 500
I2CWRITE SDA,SCL,ADDR,LOC
Addr=$1B : PAUSE 50
I2CREAD SDA,SCL,ADDR,LOC,[VALUE],Fail
PAUSE 25
DEBUG HEX Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail:
toggle portc.2
goto main
Didn't worked. (Value/Addr/Loc = Byte size)
'=======
Can I not the Micro at 4MHz? The Datasheet says MAX speed is 400KHz, so I assume lower speeds are supported. Am I right?
-
Re: I2C CONFUSION, Help needed please
Remove the PAUSE 50 after I2CWRITE because the device starts sending immediately if its happy.
Then try bit 6 then 5 instead for the Write bit if the Write bit position was a wrong guess.
Bit 6 = $5B
Bit 5 = $3B
-
Re: I2C CONFUSION, Help needed please
Yeah, 400kHz is the max speed so at 4MHz it will run closer to 100kHz
-
Re: I2C CONFUSION, Help needed please
OSCCON changed to set 4MHz, internal oscillator.
I2CSLOW 1 stays commented
I2CHOLD 1 stays commented
Code:
LED Var PortC.0
Value Var Byte
Addr Var Byte
Loc Var Byte
'---------------------------------------------------------
Pause 500
DEBUG "Start......",13,10
Value=0
Addr=$9B 'Tried $3B,$5B
Loc=0
Main:
High Led : Pause 500: Low Led : PAUSE 500
I2CWRITE SDA,SCL,ADDR,LOC
Addr=$1B
I2CREAD SDA,SCL,ADDR,LOC,[VALUE],Fail
PAUSE 25
DEBUG HEX Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail:
toggle portc.2
goto main
No Luck :(
> It is bit 7 for R/W (Slave address + write bit)
-
Re: I2C CONFUSION, Help needed please
> It is bit 7 for R/W (Slave address + write bit)
How did you find that?
-
Re: I2C CONFUSION, Help needed please
Picked up from the datasheet of the device. That is what I understood, am I wrong?
Though I did tried $3B & $5B.
-
Re: I2C CONFUSION, Help needed please
Not sure if you're wrong or not. I'm still trying to decipher that part in the datasheet because they don't make it easy. I've found that some information has to be gleaned from other devices of the same manufacturer to put the whole story together, kinda sucks!
I also noticed the address stays at $1B after the first loop in your test program and if it works you might miss it.
Note: I just found one of my programs on another I2C device that has bit 1=0 as the Write bit.
$1B = $00011011 used for Read
$1A = $00011010 used for Write
-
1 Attachment(s)
Re: I2C CONFUSION, Help needed please
I read it again to confirm this, the attachment is my source. It also mentions 9 bits long address. Not sure who sends an ack. I see that in read statement the device send ack, so why add it to the address PIC is sending. Very confusing.
-
Re: I2C CONFUSION, Help needed please
Ahhhh... okay
Let's use this info then. Looks like the address is using bits 1~7 and the Read/Write control bit is 0.
If control bit is set (=1) then Read, if bit cleared (=0) then Write
So:
%00110111 = $37 ' Read function
%00110110 = $36 ' Write function
Try that.
By the way, the device sends the ACK, or acknowledges, by holding the Data line LOW on the 9th clock cycle. The PIC will see this and continue to send data.
-
Re: I2C CONFUSION, Help needed please
Quote:
Originally Posted by
LinkMTech
By the way, the device sends the ACK, or acknowledges, by holding the Data line LOW on the 9th clock cycle. The PIC will see this and continue to send data.
How do I implement this, like this below?
Code:
Main:
High Led : Pause 500: Low Led : PAUSE 500
Addr=$36
I2CWRITE SDA,SCL,ADDR,LOC
Addr=$37 : pause 10 ' OR If SDA=1 then main
I2CREAD SDA,SCL,loc,[VALUE],Fail
PAUSE 25
DEBUG HEX Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail:
toggle portc.2
goto main
-
Re: I2C CONFUSION, Help needed please
Just notice the address missing on the Read function.
Moved the Fail label after Write to test this part first. This will let you know if the Write address was recognized so the Pause 10 is not needed.
Code:
Main:
High Led : Pause 500: Low Led : PAUSE 500
Addr=$36
I2CWRITE SDA,SCL,ADDR,LOC, Fail ' Test here first
Addr=$37 ': pause 10 ' OR If SDA=1 then main
I2CREAD SDA,SCL,ADDR,loc,[VALUE] ',Fail
PAUSE 25
DEBUG HEX Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail:
toggle portc.2
goto main
-
Re: I2C CONFUSION, Help needed please
Checked it. It fails on the first write statement.
-
Re: I2C CONFUSION, Help needed please
Fails on the second statement if I swap the values of Addr. i.e. First $37, second Addr $36. First one goes fine.
-
Re: I2C CONFUSION, Help needed please
Quote:
Checked it. It fails on the first write statement.
Okay let's fix that first.
Put brackets around the Loc as shown in the PBP manual to see if that helps.
Code:
Main:
High Led : Pause 500: Low Led : PAUSE 500
Addr=$36
I2CWRITE SDA,SCL,ADDR,[LOC],Fail ' Test here first
Addr=$37 ': pause 10 ' OR If SDA=1 then main
I2CREAD SDA,SCL,ADDR,[LOC,VALUE] ',Fail
PAUSE 25
DEBUG HEX Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail:
toggle portc.2
goto main
-
Reaching there
I did exactly the same as above and the sequence completed fine. BUT the values are not consistent with the datasheet, I should get '$2E' from location 0, but WHATEVER location I try to read, I am getting '$FF'
-
1 Attachment(s)
Update
Have a look at my real term serial monitor. I am actually getting a lot of unexpected data which I don't understand how is getting stored in just one byte. Though among all this, I can see '2E' (but it is swapped around so 'E2'). Note sure if I am trying to convince myself or the data is rubbish.
-
1 Attachment(s)
Re: Update
Better in nibble setting. I can see '2E' repeated a few times.
-
Re: Update
My bad, change the Read statement:
Code:
I2CREAD SDA,SCL,ADDR,[VALUE] ',Fail
-
1 Attachment(s)
Re: I2C CONFUSION, Help needed please
Still getting the same with the following code:
Code:
Value Var BYTE
Addr Var byte
Loc Var Byte
'---------------------------------------------------------
Pause 500
DEBUG "Start......",13,10
Value=0
Loc=0
Main:
High Led : Pause 500: Low Led : PAUSE 500
Addr=$36
I2CWRITE SDA,SCL,ADDR,[LOC],Fail1
Addr=$37 : pause 10 ' Sometimes it is failing, leaving pause 10 makes it better.
I2CREAD SDA,SCL,ADDR,[VALUE] ,Fail2
PAUSE 25
DEBUG Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail1:
while 1: toggle portc.2 : pause 50 : wend
goto main
Fail2:
WHILE 1
High Portc.2 : Pause 250 : Low PortC.2 : Pause 250
WEND
-
Re: I2C CONFUSION, Help needed please
What if you assign the Read/Write addresses before hand?
Code:
Value Var BYTE
Addr Var byte
Loc Var Byte
'---------------------------------------------------------
Pause 500
DEBUG "Start......",13,10
Value=0
Loc=0
WR_Add CON $36
RD_Add CON $37
Main:
High Led : Pause 500: Low Led : PAUSE 500
'Addr=$36
I2CWRITE SDA,SCL,WR_Add,[LOC],Fail1
'Addr=$37 : pause 10 ' Sometimes it is failing, leaving pause 10 makes it better.
I2CREAD SDA,SCL,RD_Add,[VALUE] ,Fail2
PAUSE 25
DEBUG Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail1:
while 1: toggle portc.2 : pause 50 : wend
goto main
Fail2:
WHILE 1
High Portc.2 : Pause 250 : Low PortC.2 : Pause 250
WEND
Question: Where is the "1" monitored at in these statements? Never seen it done this way before.
-
Re: I2C CONFUSION, Help needed please
The manual says do not use constants for address.
Though I tried the above but the result is the same.
While 1 : Wend - I just put this just like that to halt the code.
-
Re: I2C CONFUSION, Help needed please
Oh yeah, no Constants.
Then give it to him straight!
Have you tried clearing the LOC and Value variables at the beginning of each loop just in case? Start with a clean slate every time.
Code:
Main:
Loc=0
Value=0
High Led : Pause 500: Low Led : PAUSE 500
I2CWRITE SDA,SCL,$36,[LOC],Fail1
I2CREAD SDA,SCL,$37,[VALUE] ,Fail2
PAUSE 25
DEBUG Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail1:
while 1: toggle portc.2 : pause 50 : wend
goto main
Fail2:
WHILE 1
High Portc.2 : Pause 250 : Low PortC.2 : Pause 250
WEND
You're so close, I can smell it!
Or was that someone in the room?
-
1 Attachment(s)
Re: I2C CONFUSION, Help needed please
Did the above, no luck.
Doesn't like it straight, giving it $37/$36 direct sends it to Fail1 routine. So write statement fails.
Funny thing is that when it goes to Fail1, though there should be no output of data, IT does output some of the data. This looks like half the data compared to when cycle runs normally.
The code only run once and then I reset the PIC to run it again, so though it won't make any effect resetting the values in the main loop, I still tried with no luck. I am losing hairs on my head because of this now.
-
Re: I2C CONFUSION, Help needed please
Still Debugging after failing is strange. There is something else being introduced corrupting your instructions.
Use the Addr variables and see what happens when it free runs:
Code:
x VAR BYTE
RD_Addr = $37
WR_Addr = $36
Main:
High Led : Pause 500: Low Led : PAUSE 500
I2CWRITE SDA,SCL,WR_Addr,[LOC],Fail1
I2CREAD SDA,SCL,RD_Addr,[VALUE] ,Fail2
PAUSE 25
DEBUG Value,13,10
PAUSE 250
DEBUG "Done....",13,10
WHILE 1 : WEND
Goto Main
Fail1:
FOR x = 0 TO 10
toggle portc.2 : pause 50
NEXT x
goto main
Fail2:
FOR x = 0 TO 10
High Portc.2 : Pause 250 : Low PortC.2 : Pause 250
NEXT x
GOTO Main
Going to church now, BBL
-
Re: I2C CONFUSION, Help needed please
Is that Write only an initialisation?
Shouldn't it be outside the Main loop?
Robert
-
Re: I2C CONFUSION, Help needed please
This is a Touch IC. So shouldn't you check the device ID once, then check at another address within the loop to detect a touch? (not sure of trigger yet)
I'm dense, won't WHILE 1: WEND loop endlessly?
Robert
Edit: I see it now; 1 to 7 keys max for I2C, triggers lines out.
Also, looking in datasheet if it says 400kHz max. I think you might have to run fast.
4.1.1 max 400kHz, so you should be able to run slower.
-
Re: I2C CONFUSION, Help needed please
Quote:
Originally Posted by
LinkMTech
...
%00110111 = $37 ' Read function
%00110110 = $36 ' Write function
..
I would have thought:
%00000001 = $37 ' Read function
%00000000 = $36 ' Write function
I don't see in this datasheet where you get the rest.
Robert
-
Soooooo Close
I just discovered, that the I am actually receiving only 1 byte as expected. Rest are just "Start......"13,10 and "Done",13,10. Yesterday got too exhausted and missed this mistake of mine.
Here is the current code with
Code:
Start:
Loc=0
Start_Again:
I2CWRITE SDA,SCL,$36,[LOC],Fail1
Main:
Value=0
High Led : Pause 500: Low Led : PAUSE 500
I2CREAD SDA,SCL,$37,[VALUE] ,Fail2
PAUSE 250
DEBUG Value
Loc=Loc+1
If Loc<4 then Start_Again ' Read first 4 locations
x=0
WHILE !Change ' Stay here if Change Stays High
Pause 500 : x=x+1
If x =10 then
LOC=3 : Goto Main ' Do another read
Endif
WEND
while Change : pause 100 : wend ' Stay here if change is Low
Goto Start
Fail1: ' Try Write again
For x=0 to 50
High Portc.2 : Pause 50 : Low PortC.2 : Pause 50
Next x
Goto Start_again
Fail2: ' Try read again
For x=0 to 5
High Portc.2 : Pause 250 : Low PortC.2 : Pause 250
Next x
Goto Main
Every time Change line goes low (detected something), I try to read first 4 memory locations. The communication fails a lot of times (both write and read (write more than read) )in this attempt but I do get the data on the screen finally. Secondly, the data which comes is wrong. For example, memory locations 0 does not read 2E for a start.
-
Re: Soooooo Close
Success but with one question.
Finally, I put 20MHz clock. It started working with absolutely no problems.
This leaves me with one MAJOR question - Is there any way, I can run the whole show at 4MHz, any settings I missed or anything I can do. I have got no extra pins on my PIC to put an external oscillator, I want to confirm the answer to this question before I start again and choose another suitable PIC. My task will get much much easier if there is a way to run it at 4 Sweet Megahertz.
Many many many thanks to you guys for trying to helping me out on this. This forum is the best.