Bladeren bron

Add Si1151 sunlight sensor

0hotpotman0 4 jaren geleden
bovenliggende
commit
c616ffc95e
3 gewijzigde bestanden met toevoegingen van 355 en 0 verwijderingen
  1. 191 0
      Si115X.cpp
  2. 136 0
      Si115X.h
  3. 28 0
      examples/Si1151/Si1151.ino

+ 191 - 0
Si115X.cpp

@@ -0,0 +1,191 @@
+#include <Arduino.h>
+#include "Si115X.h"
+
+// Si115X::Si115X() {
+// 	//empty constructor
+// }
+
+/**
+ * Configures a channel at a given index
+ */
+void Si115X::config_channel(uint8_t index, uint8_t *conf){
+    int len = sizeof(conf);
+  
+    if(len != 4 || index < 0 || index > 5)
+      return;
+
+    int inc = index * len;
+    
+    param_set(Si115X::ADCCONFIG_0 + inc, conf[0]);
+    param_set(Si115X::ADCSENS_0 + inc, conf[1]);
+    param_set(Si115X::ADCPOST_0 + inc, conf[2]);
+    param_set(Si115X::MEASCONFIG_0 + inc, conf[3]);   
+}
+
+/**
+ * Writes data over i2c
+ */
+void Si115X::write_data(uint8_t addr, uint8_t *data, size_t len){
+    Wire.beginTransmission(addr);
+    Wire.write(data, len);
+    Wire.endTransmission();
+}
+
+/**
+ * Reads data from a register over i2c
+ */
+int Si115X::read_register(uint8_t addr, uint8_t reg, int bytesOfData){
+    int val = -1;
+  
+    Si115X::write_data(addr, &reg, sizeof(reg));
+    Wire.requestFrom(addr, bytesOfData);
+  
+    if(Wire.available())
+      val = Wire.read();
+	
+    return val;
+}
+
+/**
+ * param set as shown in the datasheet
+ */
+void Si115X::param_set(uint8_t loc, uint8_t val){
+    uint8_t packet[2];
+    int r;
+    int cmmnd_ctr;
+
+    do {
+        cmmnd_ctr = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
+      
+        packet[0] = Si115X::HOSTIN_0;
+        packet[1] = val;
+        Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
+      
+        packet[0] = Si115X::COMMAND;
+        packet[1] = loc | (0B10 << 6);
+        Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
+      
+        r = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);	    
+    } while(r > cmmnd_ctr); 
+}
+
+/**
+ * param query as shown in the datasheet
+ */
+int Si115X::param_query(uint8_t loc){
+    int result = -1;
+    uint8_t packet[2];
+    int r;
+    int cmmnd_ctr;
+
+    do {
+        cmmnd_ctr = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
+	    
+        packet[0] = Si115X::COMMAND;
+        packet[1] = loc | (0B01 << 6);
+	    
+        Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
+	    
+        r = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
+    } while(r > cmmnd_ctr);
+	
+    result = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_1, 1);
+	
+    return result;
+}
+
+/**
+ * Sends command to the command register
+ */
+void Si115X::send_command(uint8_t code){
+    uint8_t packet[2];
+    int r;
+    int cmmnd_ctr;
+    do {
+        cmmnd_ctr = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
+	    
+        packet[0] = Si115X::COMMAND;
+        packet[1] = code;
+	    
+        Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
+	    
+        r = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1); 
+    } while(r > cmmnd_ctr);
+}
+
+/**
+ * Returns int given a byte array
+ */
+int Si115X::get_int_from_bytes(uint8_t *data, size_t len){
+    int result = 0;
+    int shift = 8 * len;
+	
+    for(int i = 0; i < len; i++){
+        shift -= 8;
+        result |= ((data[i] << shift) & (0xFF << shift));
+    }
+	
+    return result;
+}
+
+
+
+
+bool Si115X::Begin(void){
+    Wire.begin();
+    if (ReadByte(0x00) != 0x51) {
+        return false;
+    }
+    Si115X::send_command(Si115X::START);
+
+    Si115X::param_set(Si115X::CHAN_LIST, 0B000010);
+
+    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(0B000010);
+    Wire.endTransmission();
+
+    uint8_t conf[4];
+
+    conf[0] = 0B00000000;
+    conf[1] = 0B00000010, 
+    conf[2] = 0B00000001;
+    conf[3] = 0B11000001;
+    Si115X::config_channel(1, conf);
+
+    conf[0] = 0B00000000;
+    conf[1] = 0B00000010, 
+    conf[2] = 0B00000001;
+    conf[3] = 0B11000001;
+    Si115X::config_channel(3, conf);
+    return true;
+
+}
+
+uint16_t Si115X::ReadHalfWord(void) {
+    Si115X::send_command(Si115X::FORCE);
+    uint8_t data[3];
+    data[0] = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::HOSTOUT_0, 1);
+    data[1] = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::HOSTOUT_1, 1);
+    // Si115X::send_command(Si115X::PAUSE);
+    // data[3] = data[0] * 256 + data[1];
+    return data[0] * 256 + data[1]; //* 256 + data[1];
+}
+
+
+uint8_t Si115X::ReadByte(uint8_t Reg) {
+    Wire.beginTransmission(Si115X::DEVICE_ADDRESS);
+    Wire.write(Reg);
+    Wire.endTransmission();
+    Wire.requestFrom(Si115X::DEVICE_ADDRESS, 1);
+    return Wire.read();
+}
+

+ 136 - 0
Si115X.h

@@ -0,0 +1,136 @@
+#ifndef SI115X_H
+#define SI115X_H
+
+#include <Arduino.h>
+#include <Wire.h>
+
+class Si115X
+{
+	public:
+		typedef enum {
+			DEVICE_ADDRESS = 0x53			
+		} UnitAddress;
+
+		typedef enum {
+			RESET_CMD_CTR = 0x00,
+			RESET_SW = 0x01,
+			FORCE = 0x11,
+			PAUSE = 0x12,
+			START = 0x13
+		} CommandCodes;
+		
+		typedef enum {	
+			PART_ID = 0x00,
+			REV_ID = 0x01,
+			MFR_ID = 0x02,
+			INFO_0 = 0x03,
+			INFO_1 = 0x04,
+			HOSTIN_3 = 0x07,
+			HOSTIN_2 = 0x08,
+	
+			HOSTIN_0 = 0x0A,
+			COMMAND = 0x0B,
+			IRQ_ENABLE = 0x0F,
+			RESPONSE_0 = 0x11,
+			RESPONSE_1 = 0x10,
+			
+			IRQ_STATUS = 0x12,
+			HOSTOUT_0 = 0x13,
+			HOSTOUT_1 = 0x14,
+			HOSTOUT_2 = 0x15,
+			HOSTOUT_3 = 0x16,
+			HOSTOUT_4 = 0x17,
+			HOSTOUT_5 = 0x18,
+			HOSTOUT_6 = 0x19,
+			HOSTOUT_7 = 0x1A,
+			HOSTOUT_8 = 0x1B,
+			HOSTOUT_9 = 0x1C,
+			HOSTOUT_10 = 0x1D,
+			HOSTOUT_11 = 0x1E,
+			HOSTOUT_12 = 0x1F,
+			HOSTOUT_13 = 0x20,
+			HOSTOUT_14 = 0x21,
+			HOSTOUT_15 = 0x22,
+			HOSTOUT_16 = 0x23,
+			HOSTOUT_17 = 0x24,
+			HOSTOUT_18 = 0x25,
+			HOSTOUT_19 = 0x26,
+			HOSTOUT_20 = 0x27,
+			HOSTOUT_21 = 0x28,
+			HOSTOUT_22 = 0x29,
+			HOSTOUT_23 = 0x2A,
+			HOSTOUT_24 = 0x2B,
+			HOSTOUT_25 = 0x2C	
+		} RegisterAddress;
+
+		typedef enum {		
+			I2C_ADDR = 0x00,
+			CHAN_LIST = 0x01,
+
+			ADCCONFIG_0 = 0x02,
+			ADCSENS_0 = 0x03,
+			ADCPOST_0 = 0x04,
+			MEASCONFIG_0 = 0x05,
+			
+			ADCCONFIG_1 = 0x06,
+			ADCPOST_1 = 0x08,
+			ADCSENS_1 = 0x07,
+			MEASCONFIG_1 = 0x09,
+
+			ADCCONFIG_2 = 0x0A,
+			ADCSENS_2 = 0x0B,
+			ADCPOST_2 = 0x0C,
+			MEASCONFIG_2 = 0x0D,
+
+			ADCCONFIG_3 = 0x0E,
+			ADCSENS_3 = 0x0F,
+			ADCPOST_3 = 0x10,
+			MEASCONFIG_3 = 0x11,
+
+			ADCCONFIG_4 = 0x12,
+			ADCSENS_4 = 0x13,
+			ADCPOST_4 = 0x14,
+			MEASCONFIG_4 = 0x15,
+
+			ADCCONFIG_5 = 0x16,
+			ADCSENS_5 = 0x17,
+			ADCPOST_5 = 0x18,
+			MEASCONFIG_5 = 0x19,
+			
+			MEASRATE_H = 0x1A,
+			MEASRATE_L = 0x1B,
+			MEASCOUNT_0 = 0x1C,
+			MEASCOUNT_1 = 0x1D,
+			MEASCOUNT_2 = 0x1E,
+			
+			LED1_A = 0x1F,
+			LED1_B = 0x20,
+			LED2_A = 0x21,
+			LED2_B = 0x22,
+			LED3_A = 0x23,
+			LED3_B = 0x24,
+
+			THRESHOLD0_H = 0x25,
+			THRESHOLD0_L = 0x26,
+			THRESHOLD1_H = 0x27,
+			THRESHOLD1_L = 0x28,
+			THRESHOLD2_H = 0x29,
+			THRESHOLD2_L = 0x2A,
+
+			BURST = 0x2B			
+		} ParameterAddress;
+		
+		// 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);
+		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 ReadHalfWord(void);
+		uint8_t ReadByte(uint8_t Reg);
+};
+
+#endif

+ 28 - 0
examples/Si1151/Si1151.ino

@@ -0,0 +1,28 @@
+#include "Si115X.h"
+
+Si115X si1151;
+
+/**
+ * Setup for configuration
+ */
+void setup()
+{
+    uint8_t conf[4];
+
+    Wire.begin();
+    Serial.begin(115200);
+    if (!si1151.Begin())
+        Serial.println("Si1151 is not ready!");
+    else
+        Serial.println("Si1151 is ready!");
+
+}
+
+/**
+ * Loops and reads data from registers
+ */
+void loop()
+{
+    Serial.println(si1151.ReadHalfWord());
+    delay(100);
+}