Ich habe diesse Libary hier verwendet:
https://github.com/watterott/VEML6070-Breakout/blob/master/software/VEML6070.ino
und lediglich den UV-Index hinzugefügt, sodass hieraus folgendes wurde:
Bis jetzt ist der Wire-Aufruf noch im Setup und funktioniert. Ich wollte aber noch beobachten, ob es nicht wie beim Luxsensor in den Loop wandert.
Ansonsten habe ich große Probleme mit meiner 0815 Raingauge. Funktioniert deine Davis problemlos? Ich bin am überlegen, ob ich noch einen Regensensor Regensensor verbaue, da ich sonst keine Scene bezüglich der Dachfenster und des Regens bauen kann.
#define DEBUG
#include <Wire.h>
#include <math.h>
#include "EEPROM.h"
#define EEPROM_ADDR 0x800 // EEPROM address
#define EEPROM_UPDATE_INTERVAL 120000 // Delayed EEPROM writing to minimize writting attempts
#include "ZUNO_BME280.h"
BME280 bme; //BME
#define Addr 0x4A //M44009
#define I2C_ADDR 0x38 //VEML6070
//Integration Time
#define IT_1_2 0x0 //1/2T
#define IT_1 0x1 //1T
#define IT_2 0x2 //2T
#define IT_4 0x3 //4T
#define wind2_factor 1.22 //m/s per pulse in 2 seconds
#define rain_factor 0.40894 //mm per pulse
ZUNO_SETUP_ISR_INT0(int0_handler);
ZUNO_SETUP_ISR_INT1(int1_handler);
ZUNO_SETUP_ISR_GPTIMER(gpt_handler); // 2" Timer (2" & 1 Minute measurements)
struct meter_data {
dword rain_total;
byte crc8;
};
meter_data my_meter_data;
struct sensor_data {
int temperature = 0;
unsigned int humidity = 0;
float pressure = 0;
unsigned int wind_speed = 0;
unsigned int wind_gust = 0;
unsigned int wind_direction = 0;
unsigned int rain_rate = 0;
dword light = 5000;
byte UVIndex;
};
sensor_data my_sensor;
long last_write_EEPROM_millis = 0;
unsigned int wind_pulses = 0;
unsigned int wind_pulses60 = 0;
unsigned int wind_boe60 = 0;
unsigned int rain_pulses = 0;
unsigned int rain_pulses300 = 0;
byte data_updated = FALSE;
byte GPT_2sec = 0;
byte count_2sec = 0;
byte minute_Count = 0;
byte hour_Count = 0;
byte RR[12];
ZUNO_SETUP_CHANNELS(// set up channels
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,
SENSOR_MULTILEVEL_SCALE_CELSIUS,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterTemperature),
ZUNO_SENSOR_MULTILEVEL_HUMIDITY(getterHumidity),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY,
SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterVelocity),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY,
SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterVelocityBoe),
ZUNO_SENSOR_MULTILEVEL_ANGLE_POSITION (getterDirection),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_RAIN_RATE,
SENSOR_MULTILEVEL_SCALE_MILLIMETERS_PER_HOUR,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL,
getterRainRate),
ZUNO_METER(ZUNO_METER_TYPE_WATER,
METER_RESET_ENABLE,
ZUNO_METER_WATER_SCALE_PULSECOUNT,
METER_SIZE_FOUR_BYTES,
METER_PRECISION_ONE_DECIMAL,
getterRain,
resetterRain),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_LUMINANCE,
SENSOR_MULTILEVEL_SCALE_LUX,
SENSOR_MULTILEVEL_SIZE_FOUR_BYTES,
SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS,
GetterLightLux),
ZUNO_SENSOR_MULTILEVEL_ANGLE_POSITION (getterCount),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_BAROMETRIC_PRESSURE,
SENSOR_MULTILEVEL_SCALE_KILOPASCAL,
SENSOR_MULTILEVEL_SIZE_FOUR_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterPressure),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_ULTRAVIOLET,
SENSOR_MULTILEVEL_SCALE_ULTRAVIOLET_INDEX,
SENSOR_MULTILEVEL_SIZE_ONE_BYTE,
SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS,
getterUV)
);
void setup() {
Serial.begin(9600);
zunoExtIntMode(ZUNO_EXT_INT0, RISING);
zunoExtIntMode(ZUNO_EXT_INT1, RISING);
zunoGPTInit(ZUNO_GPT_SCALE1024 | ZUNO_GPT_CYCLIC);
zunoGPTSet(62500); // 2 Sekunden Timer
zunoGPTEnable(1);
EEPROM.get(EEPROM_ADDR, &my_meter_data, sizeof(meter_data));
if (my_crc8((byte*)&my_meter_data, sizeof(meter_data) - 1) != my_meter_data.crc8) {
my_meter_data.rain_total = 0;
update_meter_data();
}
//VEML6070
Wire.begin();
Wire.beginTransmission(I2C_ADDR);
Wire.write((IT_1 << 2) | 0x02);
Wire.endTransmission();
delay(500);
}
void int0_handler() // PIN17-wind sensor interupt
{
wind_pulses++;
}
void int1_handler() // PIN18-rain sensor interupt
{
rain_pulses++;
}
void gpt_handler() // 2" Timer
{
GPT_2sec++;
}
byte ReadandDebugUVIndex() {
byte msb = 0, lsb = 0;
uint16_t uv;
int UV1 = 0;
Wire.requestFrom(I2C_ADDR + 1, 1); //MSB
delay(1);
if (Wire.available())
msb = Wire.read();
Wire.requestFrom(I2C_ADDR + 0, 1); //LSB
delay(1);
if (Wire.available())
lsb = Wire.read();
uv = (msb << 8) | lsb;
Serial.println("----------");
Serial.println("Sensor Type Max44009");
Serial.print("sensor voltage = ");
Serial.println(uv);
UV1 = uv;
if (UV1 < 50) return 0;
if (UV1 <= 227) return 1;
if (UV1 <= 318) return 2;
if (UV1 <= 408) return 3;
if (UV1 <= 503) return 4;
if (UV1 <= 606) return 5;
if (UV1 <= 696) return 6;
if (UV1 <= 795) return 7;
if (UV1 <= 881) return 8;
if (UV1 <= 976) return 9;
if (UV1 <= 1079) return 10;
return 11;
}
void readanddebugM44009() {
unsigned int dataL[2];
Wire.begin();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write(0x03);
// Stop I2C transmission
Wire.endTransmission();
// Request 2 bytes of data
Wire.requestFrom(Addr, 2);
// Read 2 bytes of data
// luminance msb, luminance lsb
if (Wire.available() == 2)
{
dataL[0] = Wire.read();
dataL[1] = Wire.read();
}
// Convert the data to lux
int exponent = (dataL[0] & 0xF0) >> 4;
int mantissa = ((dataL[0] & 0x0F) << 4) | (dataL[1] & 0x0F);
float lux = pow(2, exponent) * mantissa * 0.045 ;
my_sensor.light = lux;
delay(300);
#ifdef DEBUG
Serial.print("Helligkeit ");
Serial.print("\t");
Serial.print(my_sensor.light);
Serial.println(" Lux");
#endif
}
void readanddebugBME280() {
bme.begin();
bme.setOversampling(4);
char result = bme.startMeasurement();
my_sensor.temperature = (bme.getTemperature100());
my_sensor.humidity = (bme.getHum());
my_sensor.pressure = bme.getPressure100();
Serial.println("----------");
Serial.print("Sensor Type");
if (bme.chip_id == 96) Serial.println("BME 280");
else Serial.println("BMP 280");
Serial.print("Temperature ");
Serial.print(my_sensor.temperature / 100.00); Serial.println(" C");
Serial.print("Pressure ");
Serial.print(bme.getPressure100() / 100);
Serial.println(" hPa");
if (bme.chip_id == 96) {
Serial.print("Humidity ");
Serial.print(my_sensor.humidity); Serial.println(" %");
}
Serial.println("----------");
delay(5000);
}
void loop() {
if (count_2sec != GPT_2sec) {
count_2sec = GPT_2sec;
if (wind_pulses > wind_boe60) {
my_sensor.wind_direction = map(analogRead(A1), 0, 1024, 0, 100); //PIN4- wind direction 0-100 in 3.6° steps 100=N
Serial.print("Windrichtung2 ");
Serial.println(my_sensor.wind_direction);
wind_boe60 = wind_pulses ;
}
wind_pulses60 = (wind_pulses60 + wind_pulses);
wind_pulses = 0;
if (rain_pulses > 0) {
my_meter_data.rain_total = my_meter_data.rain_total + 1; //Debounce 2 would be 180-360mm/h
rain_pulses300 = rain_pulses300 + 1;
rain_pulses = 0;
data_updated = true;
}
if (count_2sec > 29) {
minute_Count++;
if (minute_Count > 4) {
minute_Count = 0;
hour_Count++;
if (hour_Count > 11) {
hour_Count = 0;
}
RR[hour_Count] = rain_pulses300;
rain_pulses300 = 0;
for (byte i = 0; i < 12; i++) {
rain_pulses300 = rain_pulses300 + RR[i] ;
}
my_sensor.rain_rate = rain_pulses300 ;
rain_pulses300 = 0;
}
my_sensor.wind_speed = wind_pulses60 * wind2_factor / 30 * 100; //Measurement in m/s
my_sensor.wind_gust = wind_boe60 * wind2_factor * 100; //Measurement in m/s
#ifdef DEBUG
Serial.print("Windspeed ");
Serial.print("\t");
Serial.println(my_sensor.wind_speed);
Serial.print("Regenrate(Clicks) ");
Serial.print("\t");
Serial.println(my_sensor.rain_rate);
Serial.println("----------");
#endif
wind_boe60 = 0;
wind_pulses60 = 0;
GPT_2sec = 0;
readSensor();
}
}
if (data_updated && (millis() - last_write_EEPROM_millis) > EEPROM_UPDATE_INTERVAL) { // To save EEPROM from a lot of r/w operation write it once in EEPROM_UPDATE_INTERVAL if data was updated
update_meter_data();
data_updated = false;
last_write_EEPROM_millis = millis();
}
delay(100);
/*
// TEST-SENSOREN-OHNE-1-MINUTE-WARTEZEIT
readSensor();
my_sensor.UVIndex = ReadandDebugUVIndex();
delay(1000);
#ifdef DEBUG
Serial.print("UV-INDEX = ");
Serial.print("\t");
Serial.println(my_sensor.UVIndex);
Serial.println("----------");
#endif
*/
}
void readSensor () {
readanddebugM44009();
readanddebugBME280();
my_sensor.UVIndex = ReadandDebugUVIndex();
delay(1000);
#ifdef DEBUG
Serial.print("UV-INDEX = ");
Serial.print("\t");
Serial.println(my_sensor.UVIndex);
Serial.println("----------");
#endif
zunoSendReport(1);
zunoSendReport(2);
zunoSendReport(3);
zunoSendReport(4);
zunoSendReport(5);
zunoSendReport(6);
zunoSendReport(7);
zunoSendReport(8);
zunoSendReport(9);
zunoSendReport(10);
zunoSendReport(11);
zunoSendReport(12);
}
byte my_crc8(byte * data, byte count) {
byte result = 0xDF;
while (count--) {
result ^= *data;
data++;
}
return result;
}
void update_meter_data() {
my_meter_data.crc8 = my_crc8((byte*)&my_meter_data, sizeof(meter_data) - 1);
EEPROM.put(EEPROM_ADDR, &my_meter_data, sizeof(meter_data));
}
word getterTemperature() {
return my_sensor.temperature;
}
word getterHumidity() {
return my_sensor.humidity;
}
word getterVelocity() {
return my_sensor.wind_speed;
}
word getterVelocityBoe() {
return my_sensor.wind_gust;
}
word getterDirection() {
return my_sensor.wind_direction;
}
word getterRainRate() {
return my_sensor.rain_rate * rain_factor * 10;
}
word getterCount() {
return minute_Count;
}
void resetterRain(byte v) {
my_meter_data.rain_total = 0;
update_meter_data();
}
dword getterRain(void) {
return my_meter_data.rain_total * rain_factor * 10;
}
dword GetterLightLux() {
return my_sensor.light;
}
dword getterPressure() {
return my_sensor.pressure;
}
byte getterUV() {
return my_sensor.UVIndex;
}