1#![no_std]
2extern crate embedded_hal;
3
4use embedded_hal::blocking::delay;
5use embedded_hal::blocking::i2c;
6
7#[derive(Debug, Copy, Clone)]
8#[allow(non_camel_case_types)]
9pub enum Address {
10 ADDR_H = 0b101_1100, ADDR_L = 0b010_0011, }
13
14#[derive(Debug, Copy, Clone)]
15#[allow(non_camel_case_types)]
16enum Instruction {
17 POWER_DOWN = 0b0000_0000,
18 POWER_ON = 0b0000_0001,
19 RESET = 0b0000_0111,
20}
21
22#[allow(non_camel_case_types)]
23pub enum OneTimeMeasurement {
24 HIHGT_RES = 0b0010_0000, HIHGT_RES2 = 0b0010_0001, LOW_RES = 0b0010_0011, }
28
29#[allow(non_camel_case_types)]
30pub enum ContinuesMeasurement {
31 HIHGT_RES = 0b0001_0000, HIHGT_RES2 = 0b0001_0001, LOW_RES = 0b0001_0011, }
35pub struct BH1750<I2C, DELAY> {
36 com: I2C,
37 delay: DELAY,
38 address: Address,
39}
40
41impl<I2C, DELAY, E> BH1750<I2C, DELAY>
42where
43 I2C: i2c::WriteRead<Error = E>,
44 DELAY: delay::DelayMs<u32>,
45{
46 pub fn new(i2c: I2C, delay: DELAY, address: Address) -> Result<Self, E> {
48 let chip = BH1750 {
49 com: i2c,
50 delay,
51 address,
52 };
53 Ok(chip)
54 }
55
56 pub fn light_one_shot(&mut self, mode: OneTimeMeasurement) -> u32 {
57 let delay = match mode {
58 OneTimeMeasurement::HIHGT_RES => 140,
59 OneTimeMeasurement::HIHGT_RES2 => 160,
60 OneTimeMeasurement::LOW_RES => 18,
61 };
62 let command = mode as u8;
63 self.send_instruction(command);
64 self.delay.delay_ms(delay);
65 raw_to_lx(self.resive_answer(command))
66 }
67
68 pub fn start_measurement(&mut self, mode: ContinuesMeasurement) {
69 let command = mode as u8;
70 self.send_instruction(command);
71 }
72
73 pub fn reset(&mut self) {
74 self.send_instruction(Instruction::RESET as u8);
75 }
76
77 pub fn power_down(&mut self) {
78 self.send_instruction(Instruction::POWER_DOWN as u8);
79 }
80
81 pub fn power_on(&mut self) {
82 self.send_instruction(Instruction::POWER_ON as u8);
83 }
84
85 pub fn get_measurement(&mut self, mode: ContinuesMeasurement) -> u32 {
86 let delay = match mode {
87 ContinuesMeasurement::HIHGT_RES => 120,
88 ContinuesMeasurement::HIHGT_RES2 => 120,
89 ContinuesMeasurement::LOW_RES => 16,
90 };
91 let command = mode as u8;
92 self.delay.delay_ms(delay);
93 raw_to_lx(self.resive_answer(command))
94 }
95
96 fn send_instruction(&mut self, instr: u8) {
97 let mut buffer = [0];
98 let _ = self
99 .com
100 .write_read(self.address as u8, &[instr], &mut buffer);
101 }
102
103 fn resive_answer(&mut self, instr: u8) -> u16 {
104 let mut data: [u8; 2] = [0; 2];
105 let _ = self.com.write_read(self.address as u8, &[instr], &mut data);
106 let raw_answer: u16 = ((data[0] as u16) << 8) | data[1] as u16;
107 raw_answer
108 }
109}
110
111fn raw_to_lx(raw: u16) -> u32 {
112 (raw as u32) * 12 / 10
113}