I have spent the day trying to port the Adafruit UV Sensor Library (Link) from Arduino to Python and SMBUS and am definitely making progress. The data sheet is a bit vague on detail compared to the HDC1008 sensor about how to read but am hoping that someone with a better understanding of C++ and SMBUS/i2c might be able to double check my assumptions and explain why I'm getting slightly different values than those seen on the Arduino.
Current outputs are Pi Vs Arduino:
- Vis:350 Vs 266
- IR: 941 Vs 304
- UV: 0.46 Vs 0.05
The whole class is a bit long so I am linking to it here - bad I know. The two functions I'm most unsure of are when the UV sensor is enabled (C++ lines are commented):
"""uint8_t Adafruit_SI1145::writeParam(uint8_t p, uint8_t v) {"""
def writeParam(self,p,v):
#Serial.print("Param 0x"); Serial.print(p, HEX);
#print("Param 0x",p,"HEX")
#Serial.print(" = 0x"); Serial.println(v, HEX);
#print("= 0x",v,"HEX")
#write8(SI1145_REG_PARAMWR, v);
self.bus.write_byte_data(self.SI1145_ADDR, self.SI1145_REG_PARAMWR, v)
#write8(SI1145_REG_COMMAND, p | SI1145_PARAM_SET);
self.bus.write_byte_data(self.SI1145_ADDR, self.SI1145_REG_COMMAND, p | self.SI1145_PARAM_SET)
#return read8(SI1145_REG_PARAMRD);
return self.bus.read_byte_data(self.SI1145_ADDR, self.SI1145_REG_PARAMRD)
and reading 16 bits for each of the different light types (I thought it was only 7!) e.g
"""returns the UV index * 100 (divide by 100 to get the index)"""
"""uint16_t Adafruit_SI1145::readUV(void) {"""
def readUV(self):
#return read16(0x2C);
raw = float(self.read16(0x2C)) / 100.00
return raw
Here is the method:
"""Read method used to read 16 bits"""
"""uint16_t Adafruit_SI1145::read16(uint8_t a) {"""
def read16(self,reg):
#Wire.beginTransmission(_addr); // start transmission to device
#Wire.write(a); // sends register address to read from
#Wire.endTransmission(); // end transmission
self.bus.write_byte(self.SI1145_ADDR, reg)
time.sleep(0.015)
#Wire.requestFrom(_addr, (uint8_t)2);// send data n-bytes read
#ret = Wire.read(); // receive DATA
ret = self.bus.read_byte(self.SI1145_ADDR)
#ret |= (uint16_t)Wire.read() << 8; // receive DATA
ret |= self.bus.read_byte(self.SI1145_ADDR) << 8
return ret