Stips
Posts: 6
Joined: Mon Jul 20, 2015 4:03 pm

WiringPi bh1750

Tue Jul 05, 2016 10:48 am

Hi guys I am beginner in doing rpi stuff, so I go stucked at reading ls bh1750 light sensor data, I worote some code but its not working well and I dont know why so I was woundering if you experts could help me.

Code: Select all

#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <unistd.h>

#define bh1750 0x23

int main (int argc, char *argv[])
{
        int fd;
	
		double data1 = 0;
		
		
        wiringPiSetup () ;
        fd=wiringPiI2CSetup (bh1750) ;  /*Use i2cdetect command to find your respective device address*/
        if(fd==-1)
        {
                printf("Can't setup the I2C device\n");
                return -1;
        }
        else
        {
                while (1)
                {
			sleep(1);
                        
				data1=wiringPiI2CReadReg16(fd,0x1b00);
                               //data2=wiringPiI2CRead(fd);  //this part returns 0 down know why
                       if(data1==-1)
                        {
                                printf("No data\n");
                                return -1;
                        }
                        else
                        {      
			printf("data=%f\n", data1);
			}
                }
        }
        return 0;
}
I checked adress of sensor with i2cdetect -y 1 it returned 23 so I guess that part is ok.
With this code I can get some data but I dont understand it , i tried to devide those values I get with coeficient to get right value and It works light increases to certant value than It gives wrong values ,for example i get data of 3072 and right value is 10lx , If i but If i divide value by 307.2 i get ok values for smaller sizes up to around <40 lux but when i light sensor with around 10k I get value of 8lux with my code, guys what to do.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2588
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: WiringPi bh1750

Wed Jul 06, 2016 8:16 am

You need to read the datasheet for the light sensor: http://rohmfs.rohm.com/en/products/data ... 0fvi-e.pdf

Notice on page 7 how the data is returned in big endian format. 3072 is 0x0c00 but if that has been misinterpreted as little-endian then the original byte stream might have been 00 0c, making the result 12.

I also suggest you don't use floating point numbers (double, float) to store integer values - you could potentially end up with rounding problems.

Stips
Posts: 6
Joined: Mon Jul 20, 2015 4:03 pm

Re: WiringPi bh1750

Wed Jul 06, 2016 10:09 pm

Mate so If I understood well I basicly need to read twice for 8bits, but when i tried same function for read except its for 8 bit reg read It returned 0 as data, and how should I get adress of other register, sry for noobish questions I am beginner

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2588
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: WiringPi bh1750

Thu Jul 07, 2016 8:18 am

This is what you need to do:

1) Read 16-bits of data into an integer - a short would be best because it is 16 bits on a Pi.

2) That number contains all the right data but in the wrong order - what you've read is 0xcdab, and what you want is 0xabcd.
You have two options:
a) You can assume that your Pi is always going to be little endian (it is) and always swap the two halves. You can do this using boolean operations to separate the two halves (0xcdab -> 0xcd00 & 0xab), then shifts or multiplies and divides to realign them (0xcd & 0xab00), then add or "or" them together again (0xabcd)
b) You can treat that integer as an array of bytes (0xcdab = [ 0xab, 0xcd ]). Then you use a shift or multiply to push the first byte up to the high position (0xab -> 0xab00), then combine them as above (0xabcd).
I prefer method b) because it works regardless of the processor endianness. All it requires is a C cast to reinterpret the short as an array of bytes:

Code: Select all

short data1=wiringPiI2CReadReg16(fd,0x1b00);
unsigned char *bytes = (unsigned char *)&data1;
unsigned int msb = bytes[0]; /* the first byte is the most significant - 0xab */
unsigned int lsb = bytes[0]; /* the second byte is the least significant - 0xcd */
msb = (msb << 8); /* shift the msb upwards - 0xab00. You could multiply by 256 (0x100) if you prefer. */
data1 = msb + lsb; /* You could use a boolean or ("|") here if you prefer - the result is the same */
or just:

Code: Select all

short data1=wiringPiI2CReadReg16(fd,0x1b00);
unsigned char *bytes = (unsigned char *)&data1;
data1 = (bytes[0] << 8) | bytes[1];

Stips
Posts: 6
Joined: Mon Jul 20, 2015 4:03 pm

Re: WiringPi bh1750

Thu Jul 07, 2016 9:37 am

Tnx mate you really helped alot :D

Return to “C/C++”