News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

BH1750 Lux Sensor

Started by shantanu@india, Mar 05, 2025, 10:26 AM

Previous topic - Next topic

shantanu@india

Hi,
Anyone got a working code?
The following does not seem to work:

Symbol LuxAddr 0x23    'Target BH1750 with address pin LOW 
Symbol HiRes   0x20    'One time high resolution mode

Declare SDA_Pin PORTA.6
Declare SCL_Pin PORTC.0

Dim lux         As Word

lux = BusIn LuxAddr,HiRes
Regards
Shantanu

flosigud

Yes, her is my suggestion:

'   ---------------------------------------------

'   Name    : BH1750.BAS                                     
'   Author  : Flosi Guðmundsson                                 
'   Notice  : Copyright (c) 2015 Flosi Guðmundsson             
'           : All Rights Reserved                               
'   Date    : 11.11.2015 - 30.10.2020                                       
'   Version : 1.0                                               
'   Notes   :                                                   
'           :                                                   
'   ---------------------------------------------
'   Include "..\..\33fj128GP802.inc"
   Include "..\..\33FJ12MC202.inc"
'   Include "..\..\33FJ32MC302.inc"

       
'   BH1750 constants
'   ---------------------------------------------

    Symbol  BH1750Write         0x46
    Symbol  BH1750Read          0x47
             
    Symbol  PowerDown           0x00
    Symbol  PowerUp             0x01
    Symbol  Reset               0x07
    Symbol  ContHiRes1          0x10
    Symbol  ContHiRes2          0x11
    Symbol  ContLoRes           0x13
    Symbol  OneTimeHiRes1       0x20
    Symbol  OneTimeHiRes2       0x21
    Symbol  OneTimeLoRes        0x23
   
    Dim LuxValue As Word
    Dim Mode As Byte 


                                           
$define BH1750init                       '
    HBusOut BH1750Write,[PowerDown]
   


Proc BH1750getLux(pMode As Byte),Byte
    HBusOut BH1750Write,[PowerUp]
    HBusOut BH1750Write,[pMode]                     
    DelayMS 125
    Result = HBusIn BH1750Read                     
    DelayMS 125
    HBusOut BH1750Write,[PowerDown]
    Result = Result*10/12
EndProc
     



                                 
    BH1750init
    Do                     
        LuxValue = BH1750getLux(ContHiRes2)
        HRSOut Dec LuxValue,13
        DelayMS 500
    Loop   

shantanu@india

Thanks Flosigud.
The following code worked:
        Symbol LuxRead 0x47        'Target BH1750 with LSB high
        Symbol LuxWrite 0x46        ' Target BH1750 with LSB low
        Symbol HiRes   0x20        'One time high resolution mode
        Symbol LoRes   0x23        'one time low resolution
        .............
        BStart
        BusOut LuxWrite
        BusOut HiRes
        BStop
        BStart
        BusOut LuxRead
        BusIn lux.HighByte
        BusAck
        BusIn lux.LowByte
        BusAck       
        BStop         
        lux=lux/12
        lux=lux*10
Regards
Shantanu

Pepe

To avoid losing resolution, first multiply by 10 and then divide by 12
lux=(lux*10)/12

shantanu@india

Quote from: Pepe on Mar 05, 2025, 12:08 PMTo avoid losing resolution, first multiply by 10 and then divide by 12
lux=(lux*10)/12
Thank you so much Pepe....I was really losing resolution!!
Regards
Shantanu

John Drew

#5
Something to think about:
Pepe's comment is important but it is necessary to check the dimension of the variables involved.
For example a sensor provides 0-4095 and is input into a Word.
If the correction was 17/12 you would need to use a dWord for the result as the Word will overflow. When using this strategy I always check for possible overflows.

In any case it's always better to reduce the calculation to lowest terms if possible so X×10/12 should be calculated as X×5/6 reducing the chance of overflow.

Just some thoughts.
John

shantanu@india

Very true John. The lux sensor is giving a reading around 100 sitting on my table but there is a chance of overflow under a very intense light source.
BTW what is the lux at the surface of the Sun??
Regards
Shantanu

ken_k


david

Quote from: John Drew on Mar 09, 2025, 10:56 PMSomething to think about:

In any case it's always better to reduce the calculation to lowest terms if possible so X×10/12 should be calculated as X×5/6 reducing the chance of overflow.

Just some thoughts.
John

Some more thoughts John - what about calculating as X-X/6?  Even less chance of overflow.

trastikata

Why talking about chances...

Take the maximum possible output value from the sensor, multiply it by the desired factor and if it doesn't exceed 2^16 - 1 then it will fit in a 16b variable.

Otherwise decide depending on application conditions whether to use a 32b variable or not and how to scale up or down and you can verify the worst case scenario step by step if the value will overflow or not.

In any case it should never be a guess.

John Drew

Agreed Trastikata, you said it more clearly than me. It should never be a matter of chance.

David, your option is a good one for the reason you explained. I'll try your solution next time although, like Trastikata, I always check loops for overflow potential.
There are often interesting alternatives in calculations choosing safety, speed or accuracy.

We're in the middle of an intense thunder/lightning storm. Some of the flashes and thunder are scaringly close together.
The lights have gone out for a second or so several times and the modem has reset each time. I'm not game to disconnect the antennas in my ham shack in case I become part of a lightning rod.
John

david

Yes indeed - we should always check that any calculation doesn't roll over the end of a variable.
I quite often refer to this website to check if a decimal calculation may have a simple integer fraction equivalent.
 https://www.gigacalculator.com/converters/convert-decimal-to-fraction.php
As an example - converting knots to km/h requires multiplying by 1.852 but 37/20 gives 1.850 which may be close enough for most people.

Cheers,
David

John Lawton

Thanks David for posting that link, I'd forgotten about it.

Using fractional arithmetic is often very useful when scaling results accurately and quickly.

John

shantanu@india

Quote from: ken_k on Mar 10, 2025, 05:21 AMHi Shantanu
Not what you asked for but very interesting.

Light intensity on other planets.
https://www.skymarvels.com/freebies/reference/Intensity%20of%20Sunlight%20at%20the%20Planets.pdf

Find your Pluto Time.
https://science.nasa.gov/dwarf-planets/pluto/plutotime/




Nice information Ken. So people living in Pluto always greet you by "Good Evening !!". They might say "Good Morning !" only if there is a supernova explosion.
Regards
Shantanu

ken_k

Quote from: shantanu@india on Mar 11, 2025, 11:39 AMNice information Ken. So people living in Pluto always greet you by "Good Evening !!". They might say "Good Morning !" only if there is a supernova explosion.
I have been outside to test "Pluto time". I have also used a light meter as the sun sets to experience the equivalent light levels on all the planets. The sad life of a retiree.
BTW one could use a BH1750 to make a light meter that displayed LUX and a comment like midday light level on Mars.