2016-08-26 2 views
2

제 형제와 저는 지금 일하는 동안 노력하고 있으며, 우리가 뭘 잘못하고 있는지 알 수는 없지만, 실제로 도움이 될 수 있습니다. 부디!RPI에서 i2c 및 bcm2835를 사용하여 광 센서를 읽으려고 시도했습니다. - TSL2561

우리가하려는 것은 BCM2835 라이브러리를 사용하여 C로 작성된 자체 프로그램을 통해 RPI 확장 보드의 광 센서에서 데이터를 읽는 것입니다.

이것은 우리가 사용하고있는 광 센서이다 : TSL2561 https://cdn-shop.adafruit.com/datasheets/TSL2561.pdf

우리 (noobs에 사용)가 설치 Raspbian와 라즈베리 파이 B + 모델을 사용한다.

이것은 우리가 사용하는 C 라이브러리는 다음과 같습니다 http://www.airspayce.com/mikem/bcm2835/

내가 raspian 구성을 통해 I2C를 활성화.

및 i2ctools를 통해 광 센서가 감지되었으며 주소 0x29가 올바르게 표시됩니다.

읽음 값을 0으로 되돌리고 osciloscope를 사용하여 명령을 테스트했으며 ACK 명령에 쓰기 명령이있는 것으로 보입니다. 그는 단지 아무것도 돌려 보내지 않습니다. ...

누군가가 도와 줄 수 있습니까?

#include <bcm2835.h> 
#include <stdio.h> 

#include <stdlib.h> 
#include <string.h> 
#include <stdint.h> 

uint16_t clk_div = BCM2835_I2C_CLOCK_DIVIDER_148; 
uint8_t slave_address = 0x29; //0101001 - this is the sensor address 
uint64_t delay = 70000; 


int main(int argc, char **argv) 
{ 
    /* 
    DATA0LOW Ch 7:0 ADC channel 0 lower byte  
    DATA0HIGH Dh 7:0 ADC channel 0 upper byte 
    */ 



    char buffer[10]={0}; 
    char addr; 
    uint16_t data; 
    uint8_t data2; 
    int i =0; 

    char writeBuff[1] = {0x8C}; ////Address the Ch0 lower data register 
    char readBuff[10]; 
    char writeBuff2[2] = {0x8D}; ////Address the Ch0 upper data register 
    char readBuff2[10]; 


    char *wb_ptr,*r_ptr,*wb_ptr2,*r_ptr2; 
    wb_ptr = writeBuff; 
    wb_ptr2 = writeBuff2; 
    r_ptr = readBuff; 
    r_ptr2 = readBuff2; 

    printf("Running ... \n"); 

    bcm2835_init(): 
    bcm2835_i2c_begin(); 
    bcm2835_i2c_setSlaveAddress(slave_address); //0x29 

    printf("Clock divider set to: %d\n", clk_div); 
    printf("Slave address set to: %d or %X\n",slave_address,slave_address); 

    //needed according to datasheet to read although unsure if it needs to be sent in two writes or in one ? 0x83 instead of 0x80 + 0x03 ? 
    bcm2835_i2c_write(0x80, 1); //command register 
    bcm2835_i2c_write(0x03, 1); //command itself 
    bcm2835_delayMicroseconds(delay); 
    //-------------------------- 


    while (1) 
    { 

    printf("reading data from light sensor\n"); 

    bcm2835_i2c_write(wb_ptr, 1); // 0x8C 
    bcm2835_delayMicroseconds(delay); 
    data = bcm2835_i2c_read(readBuff,1); 
    bcm2835_delayMicroseconds(delay); 

    printf("Read Result 1 = %d\n", data); 

    bcm2835_i2c_write(wb_ptr2, 1); //0x8D 
    bcm2835_delayMicroseconds(delay); 
    data2 = bcm2835_i2c_read(readBuff2,1); 
    bcm2835_delayMicroseconds(delay); 

    printf("Read Result 2 = %d\n", data); 

    bcm2835_delay(1000); 

    } 
    bcm2835_i2c_end(); 
    bcm2835_close(); 
    printf("... done\n"); 
    return 0; 
} 

이 내가 그것을 해결하기 위해 관리하는 빠른 편집

#include <bcm2835.h> 
#include <stdio.h> 

#include <stdlib.h> 
#include <string.h> 
#include <stdint.h> 

uint16_t clk_div = BCM2835_I2C_CLOCK_DIVIDER_148; 
uint8_t slave_address = 0x29; //0101001 - this is the sensor address 
uint64_t delay = 70000; 


int main(int argc, char **argv) 
{ 
    /* 
    DATA0LOW Ch 7:0 ADC channel 0 lower byte  
    DATA0HIGH Dh 7:0 ADC channel 0 upper byte 
    */ 

    /* 
    enum bcm2835I2CReasonCodes { BCM2835_I2C_REASON_OK = 0x00, BCM2835_I2C_REASON_ERROR_NACK = 0x01, BCM2835_I2C_REASON_ERROR_CLKT = 0x02, BCM2835_I2C_REASON_ERROR_DATA = 0x04 } 
    */ 


    char buffer[10]={0}; 
    char addr; 
    uint16_t data; 
    uint8_t data2; 
    uint8_t error = 0xff; 
    int i =0; 

    char writeBuff[1] = {0x8C}; ////Address the Ch0 lower data register 
    char readBuff[10]; 
    char writeBuff2[2] = {0x8D}; ////Address the Ch0 upper data register 
    char readBuff2[10]; 
    char writeBuff3[2] = {0x80}; 
    char writeBuff4[2] = {0x03}; 


    char *wb_ptr,*r_ptr,*wb_ptr2,*r_ptr2,*r_ptr3,*r_ptr4; 
    wb_ptr = writeBuff; 
    wb_ptr2 = writeBuff2; 
    r_ptr = readBuff; 
    r_ptr2 = readBuff2; 
    r_ptr3 = writeBuff3; 
    r_ptr4 = writeBuff4; 

    printf("Running ... \n"); 

    bcm2835_init(); 
    bcm2835_i2c_begin(); 
    bcm2835_i2c_setSlaveAddress(slave_address); //0x29 

    printf("Clock divider set to: %d\n", clk_div); 
    printf("Slave address set to: %d or %X\n",slave_address,slave_address); 

    //needed according to datasheet to read although unsure if it needs to be sent in two writes or in one ? 0x83 instead of 0x80 + 0x03 ? 
    bcm2835_i2c_write(r_ptr3, sizeof(r_ptr3)); //command register 
    bcm2835_i2c_write(r_ptr4, sizeof(r_ptr4)); //command itself 
    bcm2835_delayMicroseconds(delay); 
    //-------------------------- 


    // Blink 
    while (1) 
    { 

    printf("reading data from light sensor\n"); 

    error = bcm2835_i2c_write(wb_ptr, sizeof(wb_ptr)); // 0x8C 
    bcm2835_delayMicroseconds(delay); 
    data = bcm2835_i2c_read(readBuff,sizeof(readBuff)); 
    bcm2835_delayMicroseconds(delay); 

    printf("readbuff1 = 0x%02X \n",readBuff); 
    printf("error result = 0x%02X\n", error); 
    printf("Read Result 1 = 0x%02X\n", data); 

    error = bcm2835_i2c_write(wb_ptr2, sizeof(wb_ptr2)); //0x8D 
    bcm2835_delayMicroseconds(delay); 
    data2 = bcm2835_i2c_read(readBuff2,sizeof(readBuff2)); 
    bcm2835_delayMicroseconds(delay); 

    printf("readbuff2 = 0x%02X \n",readBuff2); 
    printf("error result = 0x%02X\n", error); 
    printf("Read Result 2 = 0x%02X\n", data2); 

    bcm2835_delay(1000); 

    } 
    bcm2835_i2c_end(); 
    bcm2835_close(); 
    printf("... done\n"); 
    return 0; 
} 
+0

모든 함수 호출에 대해 API 반환 코드를 확인하고 오류 메시지를 표시하지 않는 이유는 무엇입니까? 귀하의 코드는 모든 것이 작동한다고 가정합니다. – Mick

+0

처음 추가하는 방법을 이해하지 못했지만 알아 냈으므로 (적어도 생각한 것 같아요) 0x00은 모든 것이 좋습니다. 내가 잘못된 변수를 내가 다시 얻는 데이터로 읽었는지 궁금 해서요. 그래서 지금은 readbuff와 readbuff2를 콘솔에 출력하고 readbuff = 0xBEEFA6C8 그리고 readbuff2 = 0xBEEFAB8이됩니다. –

답변

1

, 난, 그것은 0xa0을 할 내가 명령을 보낼 수있는 잘못된 ADRESS을 adressing 것을이었다 중 하나 몇 가지 문제를 가지고 있었다 0x80 대신.

#include <bcm2835.h> 
#include <stdio.h> 



int main(void) 
{ 
    /* 
    DATA0LOW Ch 7:0 ADC channel 0 lower byte  
    DATA0HIGH Dh 7:0 ADC channel 0 upper byte 
    */ 

    /* 
    enum bcm2835I2CReasonCodes { BCM2835_I2C_REASON_OK = 0x00, BCM2835_I2C_REASON_ERROR_NACK = 0x01, BCM2835_I2C_REASON_ERROR_CLKT = 0x02, BCM2835_I2C_REASON_ERROR_DATA = 0x04 } 
    */ 

     if (!bcm2835_init()) 
    return 1; 
    char uitgelezenTempWaarde[1];   
    int totalTemp[2]; 
    int error =0; 


    bcm2835_i2c_begin();     // start i2c 
    bcm2835_i2c_setSlaveAddress(0x29);  // slave address 
    bcm2835_i2c_set_baudrate(1000);   // default 

    //----------- turn channels on for measurement ------ 

    uitgelezenTempWaarde[0] = 0xa0;    
    error = bcm2835_i2c_write(uitgelezenTempWaarde,1); 
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 

    uitgelezenTempWaarde[0] = 0x03;    
    error = bcm2835_i2c_write(uitgelezenTempWaarde,1); 
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 

    bcm2835_delay(500); 
    error = bcm2835_i2c_read(uitgelezenTempWaarde,1); 
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 

    //----------- read data ------ 

     uitgelezenTempWaarde[0] = 0xac;    //DATA0LOW Ch 7:0 ADC channel 0 lower byte 
    error = bcm2835_i2c_write(uitgelezenTempWaarde,1);  
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 
    error = bcm2835_i2c_read(uitgelezenTempWaarde,1); 
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 

     totalTemp[1]= (int)uitgelezenTempWaarde[0]; 

     uitgelezenTempWaarde[0] = 0xad;    //DATA0HIGH Dh 7:0 ADC channel 0 upper byte 
    error = bcm2835_i2c_write(uitgelezenTempWaarde,1); 
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 
    error = bcm2835_i2c_read(uitgelezenTempWaarde,1); 
    if(error != 0x00) 
    { 
     printf("i2c error! : 0x%02X \n",error); 
    } 

     totalTemp[0] = (int)uitgelezenTempWaarde[0]; // 

     totalTemp[0] *= 256; //hex conversion for the highest byte so it is seen as a high number (16 bits) 
     printf("The light value is :%d\n",totalTemp[0]+totalTemp[1]); 


    bcm2835_i2c_end(); 
    bcm2835_close(); 

    return 0; 
} 
+0

잘 했어요! 코드 공유에 감사드립니다. 투표 수 옆에있는 짙은 녹색 진드기 (체크 표시라고도 함)를 선택하면 정답으로 * 받아 들일 수 * 있어야합니다. –