|
|
View previous topic :: View next topic |
Author |
Message |
engrgyrl
Joined: 28 Nov 2017 Posts: 2
|
PIC 16F1947 and i2c with Adafruit TCS34725 |
Posted: Thu Mar 08, 2018 10:45 am |
|
|
Hi all,
I've been working to add a color sensor to a test fixture, and I'm having issues reading a 16 bit register with i2c. I can read all the 8 bit registers and see the results I expect to see, but I have no luck with actually reading the sensor. There is lots of arduino code examples but nothing in C. I don't write code too often some I'm kind of rusty.
Code: |
#include <16F1947.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal Clock oscillator with no clockout
#FUSES NOPUT //Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES PROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //brownout reset
#FUSES NOWRT //Program memory not write protected
#FUSES NOVCAP
#FUSES PLL
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP // low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=32000000)
#use rs232(baud=115200,xmit=PIN_C6,rcv=PIN_C7,parity=N, UART1,stream = SER1,DISABLE_INTS,RECEIVE_BUFFER=32,LONG_DATA, ERRORS)
#use spi(force_hw)
#use I2C(master, sda=PIN_C4, scl=PIN_C3, NOFLOAT_HIGH, FORCE_HW )
//#use fixed_io(c_inputs=PIN_C4, PIN_C3)
//#use I2C(master,I2C1, NOFLOAT_HIGH, FORCE_HW)
void initColorSense(sLED)
{
output_high(sLED);
delay_ms(50);
i2c_start();
i2c_write(sensor_Write_address);
i2c_write(LS_ENABLE|0x80);
i2c_write(0x13);//0x0b
i2c_stop();
i2c_start();
i2c_write(sensor_Write_address);
i2c_write(ATIME_address|0x80);
i2c_write(0xFF);//0X00 2.4ms - 1 cycle - Max Count: 1024
i2c_stop();
// printf("Step 2\r\n");
i2c_start();
i2c_write(sensor_Write_address);
i2c_write(0X0D|0x80);//Enable wlong
i2c_write(0x00);//0xAB
i2c_stop();
// printf("Step 3\r\n");
i2c_start();
i2c_write(sensor_Write_address);
i2c_write(LS_WTIME|0x80);
i2c_write(0x00);//0xAB
i2c_stop();
// printf("Step 4\r\n");
i2c_start();
i2c_write(sensor_Write_address);
i2c_write(0x0F|0x80);
i2c_write(0x03);
i2c_stop();
//! delay_ms(40);
printf("Step 5\r\n");
}
//**************************** FUNCTIONS *************************************
void colorSenseWrite(int8 address, int8 data)
{
i2c_start();
i2c_write(0x52);
i2c_write(address);
i2c_write(data);
i2c_stop();
}
//**************************** FUNCTIONS *************************************
void colorSenseRead(sLED,lsbDET,msbDET)
{
i2c_start();
i2c_write(sensor_Write_address);
i2c_write(0x12|0xA0);
i2c_start();
i2c_write(sensor_Read_address);
msb = i2c_read(1);
lsb = i2c_read(1);
LSB1 = i2c_read(1);
LSB2 = i2c_read(1);
i2c_stop();
delay_ms(40);
printf("lsbDet = %x\r\n",lsbDET);
printf("msb = %x\r\n",msb);
printf("lsb = %x\r\n",lsb);
printf("LSB1 = %x\r\n",LSB1);
printf("LSB2 = %x\r\n",LSB2);
color = make16(msb,lsb);
printf("Color = %Lu\r\n",color);
output_low(sLED);
} |
Thanks in advance for any help! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Mar 08, 2018 10:59 am |
|
|
1st program you need to use is PCM Ps 'I2C Scanner' in the code library. It will confirm IF the PIC can actually communicate with any I2C device. The one 'tricky' aspect is the real address. CCS follows the 8 bit style and 'others' may use 7 bit. So run the scanner and see what comes up.
Also be sure to use the proper I2C bus pullups. They 'may' be on the sensor PCB...best to check it's datasheet and/or schematic.
And... check the VDD for the sensor. 'most' sensors these days are 3 volt devices, PICs can be 5 or 3 or both....again, check the datasheets !
It's not fun to see 3V stuff go POOF when 5 is applied....
Jay |
|
|
engrgyrl
Joined: 28 Nov 2017 Posts: 2
|
|
Posted: Thu Mar 08, 2018 11:19 am |
|
|
I am getting a response for the registers that are 8 bit and I've confirmed that is what I expect, so I know the PIC is communicating. My frustration is that every time I read the sensor it just returns 0x00. The data sheet mentions a two byte read but the LSB and the MSB are in two registers. That are part of one 16 bit value. Is this common to do with I2C?
Also I did confirm that it is a 2.7v min on the sensor. Thanks for the heads up! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Mar 08, 2018 12:45 pm |
|
|
OK... I can't see where you declare what 'sensor_Write_address' is in your program...whicj according to the datasheet is 0x29 ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Mar 08, 2018 1:21 pm |
|
|
Reading two (or more) bytes is common with I2C, SPI etc. etc..
One glaring thing is wrong. The master is meant to NACK the last byte read. This is vital when doing multi-byte reads. So:
Code: |
i2c_write(sensor_Read_address);
msb = i2c_read();
lsb = i2c_read();
LSB1 = i2c_read();
LSB2 = i2c_read(0);
i2c_stop();
|
If you don't NACK the last byte of a multi byte read can cause problems with many devices.
Generally, in some places you have the device address 'hard coded' (0x52), and in others you are using a variable or define, but you don't show this. Should be:
Code: |
#define sensor_Write_address (0x52)
#define sensor_Read_address (0x53)
|
0x29 * 2 = 0x52. This is because the PIC uses 8bit address form, rather than just the high seven bits used in a lot of Arduino code. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|