PDA

View Full Version : Trouble with I2CREAD Command and Pressure Sensor



backlash550
- 9th July 2011, 18:38
Hi,

I have been struggling for the past few days trying to interface an I2C pressure sensor from SensorTechnics with the PIC16F1827. I successfully bit banged the sensor using a Basic Stamp II a few weeks ago so I know that the sensor is working properly. However, even when I convert the bit banging code to the PIC it still doesn't work, so I know I am doing something simple incorrectly.

I can see clock and data when I connect my oscilloscope to the I/O pins so I know their is activity on the ports, but the result is always filled 0's.

I2C DataSheet for Pressure Sensor (http://www.sensortechnics.com/download/appl_note_I2C_bus_e-155.pdf)

DataSheet for the PIC16F1827 chip (http://ww1.microchip.com/downloads/en/DeviceDoc/41391D.pdf)


When you use the I2CREAD command does it send a START condition?
Using this syntax
I2CRead sda,scl,$F1,[result1,result2] does the I2CREAD command send the device address? and an along with an Ack, Nak after the two bytes?


Do I need to use an I2CWRITE command to write the address to the I2C slave after manually generating a START condition myself?


DEFINE HSER_RCSTA 90h ' Define Receive Port
DEFINE HSER_TXSTA 24h ' Define Transmit Port

DEFINE HSER_BAUD 9600 ' Decalre 9600 Baud Rate for Serial Port
DEFINE OSC 20

scl VAR PORTB.4: TRISB.4 = 1 ' I2C clock input
sda VAR PORTB.1: TRISB.1 = 1 ' I2C data input

LED VAR PORTB.0 ' Assign name "LED" to PORTB.0
addr VAR Byte ' I2C Address Variable
result1 VAR BYTE ' I2C Result Variable
result2 VAR BYTE ' I2C Result Variable
result VAR WORD

ADDR = %11110001

'Reset Digi Xbee Module
LOW PORTB.3
HIGH PORTB.3

mainloop:

' *** Flash LED (HeartBeat)

High LED ' Turn on LED connected to PORTB.0
Pause 1000 ' Delay for .5 seconds

' *** Read I2C

Low LED ' Turn off LED connected to PORTB.0
Pause 1000 ' Delay for .5 seconds

TRISB.1 = 1
TRISb.4 = 1

HIGH SDA
HIGH SCL

LOW sda

I2CRead sda,scl,addr,[result1,result2], i2c_error

PAUSE 1000 ' Pause 1 Second for Read Operation to complete

HSEROUT ["Value:", BIN8 result1, BIN8 result2] ' Output Pressure reading through Serial Port

Goto mainloop ' Go back to loop and blink LED forever

End

' Trasnmit Error if Reading unable to occur
i2c_error:

HSEROUT ["Error"]

GOTO mainloop

Here is the bit banging code


DEFINE HSER_RCSTA 90h ' Define Receive Port
DEFINE HSER_TXSTA 24h ' Define Transmit Port
'DEFINE HSER_SPBRG 129
DEFINE OSC 20
DEFINE HSER_BAUD 9600 ' Declare 9600 Baud Rate for Serial Port

'Include Basic Stamp II Command Support
INCLUDE "modedefs.bas"


' ------------------------------------------------------------------------------ '
' I/O Definitions
' ------------------------------------------------------------------------------ '
SDA VAR PORTB.1 ' I2C serial data line
SCL VAR PORTB.4 ' I2C serial clock line

' ------------------------------------------------------------------------------ '
' Constants
' ------------------------------------------------------------------------------ '
Ack CON 0 ' acknowledge bit
Nak CON 1 ' no ack bit

slaveAddress CON %11110001 'SensorTechnics Slave Address

' ------------------------------------------------------------------------------ '
' Variables
' ------------------------------------------------------------------------------ '
i2cData VAR Word ' data to/from device
i2cWork VAR Byte ' work byte for TX routine
i2cAck VAR Bit ' Ack bit from device

' ------------------------------------------------------------------------------ '
' Initialization
'------------------------------------------------------------------------------ '
Init:
PAUSE 250

i2cACK = 0

' Reset XBee
LOW PORTB.3
HIGH PORTB.3

TRISB.1 = 0
TRISB.4 = 0

PAUSE 5000

' ------------------------------------------------------------------------------ '
' Program Code
' ------------------------------------------------------------------------------ '


Main:


GOSUB Read_Word

Hserout ["Current Pressure Reading (16 BITS): " , BIN16 i2cData]

PAUSE 1000

GOTO Main

END



' ------------------------------------------------------------------------------ '
' SensorTechnics Access Subroutines
' ------------------------------------------------------------------------------ '

' Read i2cData (16 bits) from Sensor

Read_Word:

GOSUB I2C_Start ' Send START Condition

i2cWork = slaveAddress ' Set Slave Address
GOSUB I2C_TX_Byte ' Send Slave Address

GOSUB I2C_RX_Byte
i2cData.HIGHBYTE = i2cWork ' Read high byte of data / send ack

GOSUB I2C_RX_Byte_Nak
i2cData.LOWBYTE = i2cWork ' Read low byte of data /send nack

GOSUB I2C_Stop ' Send STOP Command

RETURN

' ------------------------------------------------------------------------------ '
' Low Level I2C Subroutines
' ------------------------------------------------------------------------------ '
' --- Start ---
I2C_Start: ' I2C start bit sequence

TRISB.1 = 1
TRISB.4 = 1

'HIGH SDA ' Pull SDA High
'HIGH SCL ' Pull SCL High

LOW SDA ' SDA -> low while SCL high

Hserout ["Waiting for Clock"]

Clock_Hold:
IF (PORTB.4 = 0) THEN Clock_Hold ' device ready?

PAUSE 500

RETURN

' --- Transmit ---
I2C_TX_Byte:

SHIFTOUT SDA,SCL,MSBFIRST,[i2cWork\8] ' send byte to device
SHIFTIN SDA,SCL,MSBPRE,[i2cAck\1] ' get acknowledge bit

RETURN

' --- Receive ---
I2C_RX_Byte_Nak:
i2cAck = Nak ' no Ack = high
GOTO I2C_RX

I2C_RX_Byte:
i2cAck = Ack ' Ack = low

I2C_RX:

i2cWork = %00000000

SHIFTIN SDA,SCL,MSBPRE,[i2cWork\8] ' get byte from device
SHIFTOUT SDA,SCL,LSBFIRST,[i2cAck\1] ' send ack or nak

RETURN

' --- Stop ---
I2C_Stop: ' I2C stop bit sequence
LOW SDA

TRISB.1 = 1
TRISB.4 = 1

HIGH SCL
HIGH SDA ' SDA --> high while SCL high

RETURN


Any help would be appreciated, thanks in advance!

Ben

mackrackit
- 9th July 2011, 18:45
Maybe this will help answer some of your questions.
http://www.picbasic.co.uk/forum/content.php?r=165-Serial-EEPROM-Part-1

mackrackit
- 9th July 2011, 18:49
By the way, I moved this thread to the general section as it has nothing to do with USB.
I also deleted your duplicate thread in another section of the forum. One thread per topic.

backlash550
- 9th July 2011, 19:05
Sorry about the double post, I intended to post in the Serial forum. After I realized I had posted in the wrong one, I tried to delete my initial post but didn't see the option.

However, I read the first paragraph of the article you sent me and instantly realized what I had been doing wrong. I did not change the analog port to digital.

ANSELB = 0 ' Port B Digital

The sensor is working like a charm now.

Thanks so much for the help..

Ben