Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add changed library for STM32 tested with STM32 BluePill STM32F103C8t6 #13

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions VEML6075_stm32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* VEML6075.cpp
*
* Arduino library for the Vishay VEML6075 UVA/UVB i2c sensor.
*
* Author: Sean Caulfield <[email protected]>
*
* License: GPLv2.0
*
*/

#include "VEML6075.h"

VEML6075::VEML6075(I2C_HandleTypeDef &hi2c) : i2c(hi2c){

// Despite the datasheet saying this isn't the default on startup, it appears
// like it is. So tell the thing to actually start gathering data.


config = 0;
config |= VEML6075_CONF_SD_OFF;

// App note only provided math for this one...
config |= VEML6075_CONF_IT_100MS;
}

bool VEML6075::begin() {


if (getDevID() != VEML6075_DEVID) {
return false;
}

// Write config to make sure device is enabled
write16(VEML6075_REG_CONF, config);

return true;
}

// Poll sensor for latest values and cache them
void VEML6075::poll() {
raw_uva = read16(VEML6075_REG_UVA);
raw_uvb = read16(VEML6075_REG_UVB);
raw_dark = read16(VEML6075_REG_DUMMY);
raw_vis = read16(VEML6075_REG_UVCOMP1);
raw_ir = read16(VEML6075_REG_UVCOMP2);
}

uint16_t VEML6075::getRawUVA() {
return raw_uva;
}

uint16_t VEML6075::getRawUVB() {
return raw_uvb;
}

uint16_t VEML6075::getRawDark() {
return raw_dark;
}

uint16_t VEML6075::getRawVisComp() {
return raw_vis;
}

uint16_t VEML6075::getRawIRComp() {
return raw_ir;
}


uint16_t VEML6075::getDevID() {
return read16(VEML6075_REG_DEVID);
}

float VEML6075::getUVA() {
//float comp_vis = raw_vis - raw_dark;
//float comp_ir = raw_ir - raw_dark;
//float comp_uva = raw_uva - raw_dark;
float comp_vis;
float comp_ir;
float comp_uva;

// Constrain compensation channels to positive values
comp_ir = max(raw_ir - raw_dark, 0.0);
comp_vis = max(raw_vis - raw_dark, 0.0);
comp_uva = max(raw_uva - raw_dark, 0.0);

// Scale by coeffs from datasheet
comp_vis *= VEML6075_UVI_UVA_VIS_COEFF;
comp_ir *= VEML6075_UVI_UVA_IR_COEFF;

// Subtract out visible and IR components
comp_uva = max(comp_uva - comp_ir, 0.0);
comp_uva = max(comp_uva - comp_vis, 0.0);

return comp_uva;
}

float VEML6075::getUVB() {
//float comp_vis = raw_vis - raw_dark;
//float comp_ir = raw_ir - raw_dark;
//float comp_uvb = raw_uvb - raw_dark;
float comp_vis;
float comp_ir;
float comp_uvb;

// Constrain compensation channels to positive values
comp_ir = max(raw_ir - raw_dark, 0.0);
comp_vis = max(raw_vis - raw_dark, 0.0);
comp_uvb = max(raw_uvb - raw_dark, 0.0);

// Scale by coeffs from datasheet
comp_vis *= VEML6075_UVI_UVB_VIS_COEFF;
comp_ir *= VEML6075_UVI_UVB_IR_COEFF;

// Subtract out visible and IR components
comp_uvb = max(comp_uvb - comp_ir, 0.0);
comp_uvb = max(comp_uvb - comp_vis, 0.0);

return comp_uvb;
}

float VEML6075::getUVIndex() {
float uva_weighted = getUVA() * VEML6075_UVI_UVA_RESPONSE;
float uvb_weighted = getUVB() * VEML6075_UVI_UVB_RESPONSE;
return (uva_weighted + uvb_weighted) / 2.0;
}

uint16_t VEML6075::read16(uint8_t reg) {
uint8_t data[2];

HAL_I2C_Mem_Read(&i2c, VEML6075_ADDR, reg, I2C_MEMADD_SIZE_8BIT, data , 2, 100);

return (data[1] << 8) | data[0];
}

void VEML6075::write16(uint8_t reg, uint16_t data) {

uint8_t lsb = (uint8_t)(0xFF & (data >> 0));
uint8_t msb = (uint8_t)(0xFF & (data >> 8));

uint8_t buffer[2] = {lsb,msb};

HAL_I2C_Mem_Write(&i2c, VEML6075_ADDR, reg, I2C_MEMADD_SIZE_8BIT, buffer, 2, 100);
}

uint16_t VEML6075::max(uint16_t a, uint16_t b){
if(a <= b){
return b;
}else{
return a;
}
}
121 changes: 121 additions & 0 deletions VEML6075_stm32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* VEML6075.h
*
* Arduino library for the Vishay VEML6075 UVA/UVB i2c sensor.
*
* Author: Sean Caulfield <[email protected]>
* License: GPLv2.0
*
*/

#ifndef _VEML6075_H
#define _VEML6075_H

#include "main.h"
#include "i2c.h"

#define VEML6075_ADDR 0x20
#define VEML6075_DEVID 0x26

// Reading the application note on calculation of UV index, the "dummy" channel
// value is actually not a dummy value at all, but the dark current count.
// NAMES ARE IMPORTANT PEOPLE.

#define VEML6075_REG_CONF (0x00) // Configuration register (options below)
#define VEML6075_REG_UVA (0x07) // UVA register
#define VEML6075_REG_DUMMY (0x08) // Dark current register (NOT DUMMY)
#define VEML6075_REG_UVB (0x09) // UVB register
#define VEML6075_REG_UVCOMP1 (0x0A) // Visible compensation register
#define VEML6075_REG_UVCOMP2 (0x0B) // IR compensation register
#define VEML6075_REG_DEVID (0x0C) // Device ID register

#define VEML6075_CONF_IT_50MS (0x00) // Integration time = 50ms (default)
#define VEML6075_CONF_IT_100MS (0x10) // Integration time = 100ms
#define VEML6075_CONF_IT_200MS (0x20) // Integration time = 200ms
#define VEML6075_CONF_IT_400MS (0x30) // Integration time = 400ms
#define VEML6075_CONF_IT_800MS (0x40) // Integration time = 800ms
#define VEML6075_CONF_IT_MASK (0x8F) // Mask off other config bits

#define VEML6075_CONF_HD_NORM (0x00) // Normal dynamic seetting (default)
#define VEML6075_CONF_HD_HIGH (0x08) // High dynamic seetting

#define VEML6075_CONF_TRIG (0x04) // Trigger measurement, clears by itself

#define VEML6075_CONF_AF_OFF (0x00) // Active force mode disabled (default)
#define VEML6075_CONF_AF_ON (0x02) // Active force mode enabled (?)

#define VEML6075_CONF_SD_OFF (0x00) // Power up
#define VEML6075_CONF_SD_ON (0x01) // Power down

// To calculate the UV Index, a bunch of empirical/magical coefficients need to
// be applied to UVA and UVB readings to get a proper composite index value.
// Seems pretty hand wavey, though not nearly as annoying as the dark current
// not being subtracted out by default.

#define VEML6075_UVI_UVA_VIS_COEFF (2.22) // aka coeff "A"
#define VEML6075_UVI_UVA_IR_COEFF (1.33) // aka coeff "B"
#define VEML6075_UVI_UVB_VIS_COEFF (2.95) // aka coeff "C"
#define VEML6075_UVI_UVB_IR_COEFF (1.74) // aka coeff "D"

// Once the above offsets and crunching is done, there's a last weighting
// function to convert the ADC counts into the UV index values. This handles
// both the conversion into irradiance (W/m^2) and the skin erythema weighting
// by wavelength--UVB is way more dangerous than UVA, due to shorter
// wavelengths and thus more energy per photon. These values convert the
// compensated values.
//
// NB These are the "open air" values given in the application note for the
// VEML6075.

#define VEML6075_UVI_UVA_RESPONSE (0.001461)
#define VEML6075_UVI_UVB_RESPONSE (0.002591)

enum veml6075_int_time {
VEML6075_IT_50MS,
VEML6075_IT_100MS,
VEML6075_IT_200MS,
VEML6075_IT_400MS,
VEML6075_IT_800MS
};
typedef enum veml6075_int_time veml6075_int_time_t;

class VEML6075 {

public:

VEML6075(I2C_HandleTypeDef &hi2c);
bool begin();
I2C_HandleTypeDef &i2c;

void poll();
float getUVA();
float getUVB();
float getUVIndex();
uint16_t getDevID();

uint16_t getRawUVA();
uint16_t getRawUVB();
uint16_t getRawDark();
uint16_t getRawVisComp();
uint16_t getRawIRComp();

void setIntegrationTime(veml6075_int_time_t it);

private:

uint16_t max(uint16_t,uint16_t b);

uint8_t config;

uint16_t raw_uva;
uint16_t raw_uvb;
uint16_t raw_dark;
uint16_t raw_vis;
uint16_t raw_ir;

uint16_t read16(uint8_t reg);
void write16(uint8_t reg, uint16_t data);

};

#endif