Просмотр исходного кода

fix: usage,description and Implementation errors

Jaxon 2 лет назад
Родитель
Сommit
ac38792058
3 измененных файлов с 109 добавлено и 49 удалено
  1. 78 39
      Si115X.cpp
  2. 17 2
      Si115X.h
  3. 14 8
      examples/Si1151/Si1151.ino

+ 78 - 39
Si115X.cpp

@@ -17,9 +17,33 @@ void Si115X::config_channel(uint8_t index, uint8_t *conf){
 
     int inc = index * len;
     
+    // ADCCONFIGx: 
+    // - bits[7] - Reserved
+    // - bits[6:5] - A/D conversion rate
+    // - bits[4:0] - ADC MUX select (see below)
+    //      00000 - Small IR   00001 - Medium IR   00010 - Large IR
+    //      01011 - Visible    01101 - Large Visible
     param_set(Si115X::ADCCONFIG_0 + inc, conf[0]);
+
+    // ADCSENSx:
+    // - bits[7] - ADC high signal range enable
+    // - bits[6:4] - an internal accumulation of samples
+    // - bits[3:0] - Measurement time for 512 decimation rate
     param_set(Si115X::ADCSENS_0 + inc, conf[1]);
+
+    // ADCPOSTx:
+    // - bits[7] - Reserved
+    // - bits[6] - HOSTOUTx size(0 = 16 bits, 1 = 24 bits)
+    // - bits[5:3] - Number of bits to shift right of the output
+    // - bits[2] - Threshold polarity
+    // - bits[1:0] - Threshold enable
     param_set(Si115X::ADCPOST_0 + inc, conf[2]);
+
+    // MEASCONFIGx:
+    // - bits[7:6] - MEASCOUNTx select
+    // - bits[5:4] - Reserved
+    // - bits[3] - LEDx_A or LEDx_B BANK select
+    // - bits[2:0] - LEDx enable
     param_set(Si115X::MEASCONFIG_0 + inc, conf[3]);   
 }
 
@@ -132,62 +156,77 @@ int Si115X::get_int_from_bytes(uint8_t *data, size_t len){
 
 
 
-bool Si115X::Begin(void){
+bool Si115X::Begin(bool mode){
+    is_autonomous = mode;
     Wire.begin();
     // Wire.setClock(400000);
+    // send_command(RESET_SW);
     if (ReadByte(0x00) != 0x51) {
         return false;
     }
 
-    Si115X::param_set(Si115X::CHAN_LIST, 0B001010); // enable channel 1 and 3
-
-    Si115X::param_set(Si115X::MEASRATE_H, 0);
-    Si115X::param_set(Si115X::MEASRATE_L, 1);  // 1 for a base period of 800 us
-    Si115X::param_set(Si115X::MEASCOUNT_0, 5); 
-    Si115X::param_set(Si115X::MEASCOUNT_1, 10);
-    Si115X::param_set(Si115X::MEASCOUNT_2, 10);
-    Si115X::param_set(Si115X::THRESHOLD0_L, 200);
-    Si115X::param_set(Si115X::THRESHOLD0_H, 0);
-
-    Wire.beginTransmission(Si115X::DEVICE_ADDRESS);
-    Wire.write(Si115X::IRQ_ENABLE);
-    Wire.write(0B001010); // enable channel 1 and 3
-    Wire.endTransmission();
-
-    uint8_t conf[4]; // ADCCONFIGx, ADCSENSx, ADCPOSTx, MEASCONFIGx
-
-    conf[0] = 0B00000000; // 1x Small IR
-    conf[1] = 0B00000010; // 48.8us Nominal Measurement time for 512 decimation rate
-    conf[2] = 0B00000001; // 16-bits output, Interrupt when the measurement is larger than THRESHOLD0
-    conf[3] = 0B11000001; // enable LED1, the time between measurements is 800*MEASRATE*MEASCOUNT2 us
-    Si115X::config_channel(1, conf);
-
-    conf[0] = 0B00000000;
-    conf[1] = 0B00000010; 
-    conf[2] = 0B00000001;
-    conf[3] = 0B11000001;
-    Si115X::config_channel(3, conf);
-
-    Si115X::send_command(Si115X::START);
+    // Enable 2 channels for proximity measurement
+    param_set(CHAN_LIST, 0B000011);
+    // Enable Interrupt
+    write_register(DEVICE_ADDRESS, IRQ_ENABLE, 0B000011);
+    // Initialize LED current
+    param_set(LED1_A, 0x3F);
+    param_set(LED1_B, 0x3F);
+
+    // Configure ADC and enable LED drive
+    if (is_autonomous) {
+        param_set(MEASRATE_H, 0);
+        param_set(MEASRATE_L, 1);  // 1 for a base period of 800 us
+        param_set(MEASCOUNT_0, 1); 
+        param_set(MEASCOUNT_1, 1);
+        param_set(THRESHOLD0_L, 0);
+        param_set(THRESHOLD0_H, 0);
+        uint8_t conf[4]; // ADCCONFIGx, ADCSENSx, ADCPOSTx, MEASCONFIGx
+        conf[0] = 0B01100000; // 1x Small IR
+        conf[1] = 0B00000010; // 48.8us Nominal Measurement time for 512 decimation rate
+        conf[2] = 0B00000001; // 16-bits output, Interrupt when the measurement is larger than THRESHOLD0
+        conf[3] = 0B01000001; // enable LED1A, the time between measurements is 800*MEASRATE*MEASCOUNT0 us
+        config_channel(0, conf);
+        conf[0] = 0B01101101; // 1x Visible
+        conf[1] = 0B00000010; // 48.8us Nominal Measurement time for 512 decimation rate
+        conf[2] = 0B00000001; // 16-bits output, Interrupt when the measurement is larger than THRESHOLD0
+        conf[3] = 0B10001001; // enable LED1B, the time between measurements is 800*MEASRATE*MEASCOUNT1 us
+        config_channel(1, conf);
+        send_command(START);
+    }
+    else {
+        param_set(ADCCONFIG_0, 0B01100000);
+        param_set(MEASCONFIG_0, 0x00);
+        param_set(ADCPOST_0, 0x00);
+        param_set(ADCCONFIG_1, 0B01101101);
+        param_set(MEASCONFIG_1, 0x00);
+        param_set(ADCPOST_1, 0x00);
+    }
 
     return true;
 
 }
 
-uint16_t Si115X::ReadAmbientLight(void) {
-    Si115X::send_command(Si115X::FORCE);
+uint16_t Si115X::ReadIR(void) {
+    if (!is_autonomous) send_command(FORCE);
     uint8_t data[2];
-    data[1] = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::HOSTOUT_0, 1);
-    data[2] = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::HOSTOUT_1, 1);
-
-    return data[0] << 8 | data[1];
+    data[0] = read_register(DEVICE_ADDRESS, HOSTOUT_0);
+    data[1] = read_register(DEVICE_ADDRESS, HOSTOUT_1);
+    return (data[0] << 8) + data[1];
 }
 
+uint16_t Si115X::ReadVisible(void) {
+    if (!is_autonomous) send_command(FORCE);
+    uint8_t data[2];
+    data[0] = read_register(DEVICE_ADDRESS, HOSTOUT_2);
+    data[1] = read_register(DEVICE_ADDRESS, HOSTOUT_3);
+    return (data[0] << 8) + data[1];
+}
 
 uint8_t Si115X::ReadByte(uint8_t Reg) {
-    Wire.beginTransmission(Si115X::DEVICE_ADDRESS);
+    Wire.beginTransmission(DEVICE_ADDRESS);
     Wire.write(Reg);
     Wire.endTransmission();
-    Wire.requestFrom(Si115X::DEVICE_ADDRESS, 1);
+    Wire.requestFrom(DEVICE_ADDRESS, 1);
     return Wire.read();
 }

+ 17 - 2
Si115X.h

@@ -124,14 +124,29 @@ class Si115X
 		void config_channel(uint8_t index, uint8_t *conf);
 		void write_data(uint8_t addr, uint8_t *data, size_t len);
 		int read_register(uint8_t addr, uint8_t reg, int bytesOfData);
+		uint8_t read_register(uint8_t addr, uint8_t reg) {
+			return read_register(addr, reg, 1);
+		}
+		void write_register(uint8_t addr, uint8_t reg, uint8_t val) {
+			uint8_t data[2] = {reg, val};
+			write_data(addr, data, 2);
+		}
+
 		void param_set(uint8_t loc, uint8_t val);
 		int param_query(uint8_t loc);
 		void send_command(uint8_t code);
 		int get_int_from_bytes(uint8_t *data, size_t len);
 
-		bool Begin(void);
-		uint16_t ReadAmbientLight(void);
+		bool Begin(bool mode);
+		bool Begin(void) {
+			return Begin(false);
+		}
+		uint16_t ReadIR(void);
+		uint16_t ReadVisible(void);
 		uint8_t ReadByte(uint8_t Reg);
+
+	private:
+		bool is_autonomous;
 };
 
 #endif

+ 14 - 8
examples/Si1151/Si1151.ino

@@ -7,15 +7,18 @@ Si115X si1151;
  */
 void setup()
 {
-    uint8_t conf[4];
-
     Wire.begin();
     Serial.begin(115200);
-    if (!si1151.Begin())
+    if (!si1151.Begin()) {
         Serial.println("Si1151 is not ready!");
-    else
+        while (1) {
+            delay(1000);
+            Serial.print(".");
+        };
+    }
+    else {
         Serial.println("Si1151 is ready!");
-
+    }
 }
 
 /**
@@ -23,7 +26,10 @@ void setup()
  */
 void loop()
 {
-    Serial.print("Ambient Light: ");
-    Serial.println(si1151.ReadHalfWord());
-    delay(100);
+    Serial.print("IR: ");
+    Serial.println(si1151.ReadIR());
+    Serial.print("Visible: ");
+    Serial.println(si1151.ReadVisible());
+
+    delay(500);
 }