Lab_interaccio/2016/Monitor_Bateria/SCKAmbient.ino
2025-02-25 21:29:42 +01:00

544 lines
15 KiB
C++

//Valores por defecto de la resistencia en vacio de los MICS
float RoCO = 750000;
float RoNO2 = 2200;
#if ((decouplerComp)&&(F_CPU > 8000000 ))
#include "TemperatureDecoupler.h"
TemperatureDecoupler decoupler; //use this object to compensate for charger generated heat affecting temp values
#endif
float RsCO = 0;
float RsNO2 = 0;
#define RES 256 //Resolucion de los potenciometros digitales
#if F_CPU == 8000000
#define R1 12 //Kohm
#else
#define R1 82 //Kohm
#endif
#define P1 100 //Kohm
float k= (RES*(float)R1/100)/1000; //Constante de conversion a tension de los reguladores
float kr= ((float)P1*1000)/RES; //Constante de conversion a resistencia de potenciometrosen ohmios
#if F_CPU == 8000000
uint16_t lastHumidity;
uint16_t lastTemperature;
int accel_x=0;
int accel_y=0;
int accel_z=0;
#else
int lastHumidity;
int lastTemperature;
#endif
void sckWriteVH(byte device, long voltage ) {
int data=0;
#if F_CPU == 8000000
int temp = (int)(((voltage/0.41)-1000)*k);
#else
int temp = (int)(((voltage/1.2)-1000)*k);
#endif
if (temp>RES) data = RES;
else if (temp<0) data=0;
else data = temp;
#if F_CPU == 8000000
sckWriteMCP(MCP1, device, data);
#else
sckWriteMCP(MCP2, device, data);
#endif
}
float sckReadVH(byte device) {
int data;
#if F_CPU == 8000000
data=sckReadMCP(MCP1, device);
float voltage = (data/k + 1000)*0.41;
#else
data=sckReadMCP(MCP2, device);
float voltage = (data/k + 1000)*1.2;
#endif
return(voltage);
}
void sckWriteRL(byte device, long resistor) {
int data=0x00;
data = (int)(resistor/kr);
#if F_CPU == 8000000
sckWriteMCP(MCP1, device + 6, data);
#else
sckWriteMCP(MCP1, device, data);
#endif
}
float sckReadRL(byte device)
{
#if F_CPU == 8000000
return (kr*sckReadMCP(MCP1, device + 6)); //Devuelve en Ohms
#else
return (kr*sckReadMCP(MCP1, device)); //Devuelve en Ohms
#endif
}
void sckWriteRGAIN(byte device, long resistor) {
int data=0x00;
data = (int)(resistor/kr);
sckWriteMCP(MCP2, device, data);
}
float sckReadRGAIN(byte device)
{
return (kr*sckReadMCP(MCP2, device)); //Devuelve en Ohms
}
void sckWriteGAIN(long value)
{
if (value == 100)
{
sckWriteRGAIN(0x00, 10000);
sckWriteRGAIN(0x01, 10000);
}
else if (value == 1000)
{
sckWriteRGAIN(0x00, 10000);
sckWriteRGAIN(0x01, 100000);
}
else if (value == 10000)
{
sckWriteRGAIN(0x00, 100000);
sckWriteRGAIN(0x01, 100000);
}
delay(100);
}
float sckReadGAIN()
{
return (sckReadRGAIN(0x00)/1000)*(sckReadRGAIN(0x01)/1000);
}
void sckGetVcc()
{
float temp = average(S3);
analogReference(INTERNAL);
delay(100);
Vcc = (float)(average(S3)/temp)*reference;
analogReference(DEFAULT);
delay(100);
}
void sckHeat(byte device, int current)
{
float Rc=Rc0;
byte Sensor = S2;
if (device == MICS_2710) { Rc=Rc1; Sensor = S3;}
float Vc = (float)average(Sensor)*Vcc/1023; //mV
float current_measure = Vc/Rc; //mA
float Rh = (sckReadVH(device)- Vc)/current_measure;
float Vh = (Rh + Rc)*current;
sckWriteVH(device, Vh);
#if debuggSCK
if (device == MICS_2710) Serial.print("MICS2710 corriente: ");
else Serial.print("MICS5525 corriente: ");
Serial.print(current_measure);
Serial.println(" mA");
if (device == MICS_2710) Serial.print("MICS2710 correccion VH: ");
else Serial.print("MICS5525 correccion VH: ");
Serial.print(sckReadVH(device));
Serial.println(" mV");
Vc = (float)average(Sensor)*Vcc/1023; //mV
current_measure = Vc/Rc; //mA
if (device == MICS_2710) Serial.print("MICS2710 corriente corregida: ");
else Serial.print("MICS5525 corriente corregida: ");
Serial.print(current_measure);
Serial.println(" mA");
Serial.println("Heating...");
#endif
}
float sckReadRs(byte device)
{
byte Sensor = S0;
float VMICS = VMIC0;
if (device == MICS_2710) {Sensor = S1; VMICS = VMIC1;}
float RL = sckReadRL(device); //Ohm
float VL = ((float)average(Sensor)*Vcc)/1023; //mV
if (VL > VMICS) VL = VMICS;
float Rs = ((VMICS-VL)/VL)*RL; //Ohm
#if debuggSCK
if (device == MICS_5525) Serial.print("MICS5525 Rs: ");
else Serial.print("MICS2710 Rs: ");
Serial.print(VL);
Serial.print(" mV, ");
Serial.print(Rs);
Serial.println(" Ohm");
#endif;
return Rs;
}
float sckReadMICS(byte device)
{
float Rs = sckReadRs(device);
float RL = sckReadRL(device); //Ohm
/*Correccion de impedancia de carga*/
if ((Rs <= (RL - 1000))||(Rs >= (RL + 1000)))
{
if (Rs < 2000) sckWriteRL(device, 2000);
else sckWriteRL(device, Rs);
delay(100);
Rs = sckReadRs(device);
}
return Rs;
}
void sckGetMICS(){
/*Correccion de la tension del Heather*/
sckHeat(MICS_5525, 32); //Corriente en mA
sckHeat(MICS_2710, 26); //Corriente en mA
RsCO = sckReadMICS(MICS_5525);
RsNO2 = sckReadMICS(MICS_2710);
}
#if F_CPU == 8000000
uint16_t sckReadSHT21(uint8_t type){
uint16_t DATA = 0;
Wire.beginTransmission(Temperature);
Wire.write(type);
Wire.endTransmission();
Wire.requestFrom(Temperature,2);
unsigned long time = millis();
while (!Wire.available()) if ((millis() - time)>500) return 0x00;
DATA = Wire.read()<<8;
while (!Wire.available());
DATA = (DATA|Wire.read());
DATA &= ~0x0003;
return DATA;
}
void sckGetSHT21()
{
#if DataRaw
lastTemperature = sckReadSHT21(0xE3); // Datos en RAW para conversion por plataforma
lastHumidity = sckReadSHT21(0xE5); // Datos en RAW para conversion por plataforma
#else
//T = -53 + 175.72 / 65536.0 * ( Traw * 10 )
lastTemperature = (-50 + 175.72 / 65536.0 * ( sckReadSHT21(0xE3))) * 10 ;
//H = 7 + 125.0 / 65536.0 * ( Hraw * 10 )
lastHumidity = (4 + 125.0 / 65536.0 * ( sckReadSHT21(0xE5))) * 10 ;
#endif
#if debuggSCK
Serial.print("SHT21: ");
Serial.print("Temperatura: ");
Serial.print(lastTemperature/10.);
Serial.print(" C, Humedad: ");
Serial.print(lastHumidity/10.);
Serial.println(" %");
#endif
}
void sckWriteADXL(byte address, byte val) {
Wire.beginTransmission(ADXL); //start transmission to device
Wire.write(address); // write register address
Wire.write(val); // write value to write
Wire.endTransmission(); //end transmission
}
//reads num bytes starting from address register on device in to buff array
void sckrReadADXL(byte address, int num, byte buff[]) {
Wire.beginTransmission(ADXL); //start transmission to device
Wire.write(address); //writes address to read from
Wire.endTransmission(); //end transmission
Wire.beginTransmission(ADXL); //start transmission to device
Wire.requestFrom(ADXL, num); // request 6 bytes from device
int i = 0;
unsigned long time = millis();
while (!Wire.available())
{
if ((millis() - time)>500)
{
for(int i=0; i<num; i++) buff[i]=0x00;
break;
}
}
while(Wire.available()) //device may write less than requested (abnormal)
{
buff[i] = Wire.read(); // read a byte
i++;
}
Wire.endTransmission(); //end transmission
}
void sckAverageADXL()
{
#define lim 512
int temp_x=0;
int temp_y=0;
int temp_z=0;
int lecturas=10;
byte buffADXL[6] ; //6 bytes buffer for saving data read from the device
accel_x=0;
accel_y=0;
accel_z=0;
for(int i=0; i<lecturas; i++)
{
sckrReadADXL(0x32, 6, buffADXL); //read the acceleration data from the ADXL345
temp_x = (((int)buffADXL[1]) << 8) | buffADXL[0];
temp_x = map(temp_x,-lim,lim,0,1023);
temp_y = (((int)buffADXL[3])<< 8) | buffADXL[2];
temp_y = map(temp_y,-lim,lim,0,1023);
temp_z = (((int)buffADXL[5]) << 8) | buffADXL[4];
temp_z = map(temp_z,-lim,lim,0,1023);
accel_x = (int)(temp_x + accel_x);
accel_y = (int)(temp_y + accel_y);
accel_z = (int)(temp_z + accel_z);
}
accel_x = (int)(accel_x / lecturas);
accel_y = (int)(accel_y / lecturas);
accel_z = (int)(accel_z / lecturas);
#if debuggSCK
Serial.print("eje_x= ");
Serial.print(accel_x);
Serial.print(", ");
Serial.print("eje_y= ");
Serial.print(accel_y);
Serial.print(", ");
Serial.print("eje_z= ");
Serial.println(accel_z);
#endif
}
#else
uint8_t bits[5]; // buffer to receive data
#define TIMEOUT 10000
boolean sckDHT22(uint8_t pin)
{
// READ VALUES
int rv = sckDhtRead(pin);
if (rv != true)
{
lastHumidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
lastTemperature = DHTLIB_INVALID_VALUE; // invalid value
return rv;
}
// CONVERT AND STORE
lastHumidity = word(bits[0], bits[1]);
if (bits[2] & 0x80) // negative temperature
{
lastTemperature = word(bits[2]&0x7F, bits[3]);
lastTemperature *= -1.0;
}
else
{
lastTemperature = word(bits[2], bits[3]);
}
// TEST CHECKSUM
uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
if (bits[4] != sum) return false;
if ((lastTemperature == 0)&&(lastHumidity == 0))return false;
return true;
}
boolean sckDhtRead(uint8_t pin)
{
// INIT BUFFERVAR TO RECEIVE DATA
uint8_t cnt = 7;
uint8_t idx = 0;
// EMPTY BUFFER
for (int i=0; i< 5; i++) bits[i] = 0;
// REQUEST SAMPLE
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delay(20);
digitalWrite(pin, HIGH);
delayMicroseconds(40);
pinMode(pin, INPUT);
// GET ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = TIMEOUT;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return false;
loopCnt = TIMEOUT;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return false;
// READ THE OUTPUT - 40 BITS => 5 BYTES
for (int i=0; i<40; i++)
{
loopCnt = TIMEOUT;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return false;
unsigned long t = micros();
loopCnt = TIMEOUT;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return false;
if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
if (cnt == 0) // next byte?
{
cnt = 7;
idx++;
}
else cnt--;
}
return true;
}
#endif
uint16_t sckGetLight(){
#if F_CPU == 8000000
uint8_t TIME0 = 0xDA;
uint8_t GAIN0 = 0x00;
uint8_t DATA [8] = {0x03, TIME0, 0x00 ,0x00, 0x00, 0xFF, 0xFF ,GAIN0} ;
uint16_t DATA0 = 0;
uint16_t DATA1 = 0;
Wire.beginTransmission(bh1730);
Wire.write(0x80|0x00);
for(int i= 0; i<8; i++) Wire.write(DATA[i]);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(bh1730);
Wire.write(0x94);
Wire.endTransmission();
Wire.requestFrom(bh1730, 4);
DATA0 = Wire.read();
DATA0=DATA0|(Wire.read()<<8);
DATA1 = Wire.read();
DATA1=DATA1|(Wire.read()<<8);
uint8_t Gain = 0x00;
if (GAIN0 == 0x00) Gain = 1;
else if (GAIN0 == 0x01) Gain = 2;
else if (GAIN0 == 0x02) Gain = 64;
else if (GAIN0 == 0x03) Gain = 128;
float ITIME = (256- TIME0)*2.7;
float Lx = 0;
float cons = (Gain * 100) / ITIME;
float comp = (float)DATA1/DATA0;
if (comp<0.26) Lx = ( 1.290*DATA0 - 2.733*DATA1 ) / cons;
else if (comp < 0.55) Lx = ( 0.795*DATA0 - 0.859*DATA1 ) / cons;
else if (comp < 1.09) Lx = ( 0.510*DATA0 - 0.345*DATA1 ) / cons;
else if (comp < 2.13) Lx = ( 0.276*DATA0 - 0.130*DATA1 ) / cons;
else Lx=0;
#if debuggSCK
Serial.print("BH1730: ");
Serial.print(Lx);
Serial.println(" Lx");
#endif
return Lx*10;
#else
int temp = map(average(S5), 0, 1023, 0, 1000);
if (temp>1000) temp=1000;
if (temp<0) temp=0;
return temp;
#endif
}
unsigned int sckGetNoise() {
#if F_CPU == 8000000
#define GAIN 10000
sckWriteGAIN(GAIN);
delay(100);
#endif
float mVRaw = (float)((average(S4))/1023.)*Vcc;
float dB = 0;
#if F_CPU == 8000000
#if DataRaw==false
//dB = 0.0222*mVRaw + 58.006;
//aplicar aqui conversion
if(mVRaw<=5){
dB = (5+44*mVRaw)/5;
}else if(mVRaw<=15){
dB = (195 + 8*mVRaw)/5;
}else if(mVRaw<=40){
dB = (1220 + 4*mVRaw)/20;
}else if(mVRaw <= 300){
//y=69.242283950617+0.038618827160494x
dB = (69.242283950617 + 0.038618827160494*mVRaw);
}else if(mVRaw <= 950){
//y=76.744423542059+0.013363343187315x
dB = (76.744423542059+0.013363343187315*mVRaw);
} else {
//y=80.167357356927+0.0085240259833374x
dB = (80.167357356927+0.0085240259833374*mVRaw);
}
#endif
#else
#if DataRaw==false
dB = 9.7*log( (mVRaw*200)/1000. ) + 40; // calibracion para ruido rosa // energia constante por octava
if (dB<50) dB = 50; // minimo con la resolucion actual!
#endif
#endif
#if debuggSCK
Serial.print("nOISE = ");
Serial.print(mVRaw);
#if DataRaw==false
Serial.print(" mV nOISE = ");
Serial.print(dB);
Serial.print(" dB, GAIN = ");
#else
Serial.print(" mV GAIN = ");
#endif
Serial.println(GAIN);
#endif
#if DataRaw
return mVRaw;
#else
return dB*100;
#endif
}
unsigned long sckGetCO()
{
return RsCO;
}
unsigned long sckGetNO2()
{
return RsNO2;
}