trainning_template

Dependencies:   mbed

sensors.cpp

Committer:
xmwmx
Date:
2018-10-18
Revision:
4:fe1e9f9c7b33
Parent:
3:31aec950f7dc
Child:
5:7534fc9248a8

File content as of revision 4:fe1e9f9c7b33:

#include "sensors.h"
#include "mbed.h"

extern Serial usb2pc;  
extern DigitalOut myled;
//============================================================SR501
void sr501::triggered()                                     //触发中断!!
{
    usb2pc.printf("sr501 Triggered!\r\n");
    status = true;
}
//--------
sr501::sr501(PinName pSignal)                               //启动热释电!!!
    : status(false), signal(pSignal)
{
    signal.rise(this, &sr501::triggered);
    usb2pc.printf("sr501 start!\r\n");
}
//-------
bool sr501::operator==(const bool &target)
{
    if(status == target)
    {
        return true;
    }
    else
    {
        return false;
    }
}
//-------
void sr501::reset()
{
    status = false;
}
//-------
int sr501::read()
{
    return signal.read();
}
//==========================================                //BH1750
BH1750::BH1750(PinName sda,PinName scl)                     //启动光强!!!!!(默认设置)
    :link(sda,scl)                   
{
    status = true;
    char mode[1]={BH1750_CONTINUOUS_HIGH_RES_MODE};
    //usb2pc.printf("modifying\r\n");
    while(status)
    {
        status = link.write(BH1750_I2CADDR, mode, sizeof(mode), false);
        wait_ms(10);
    }
    usb2pc.printf("BH1750 start with default mode!\r\n");
}
//--------
BH1750::BH1750(PinName sda,PinName scl,char mode[])           //启动光强!!!!!(自定义设置)
    :link(sda,scl)         
{
    status = true;
    while(status)
    {
        status = link.write(BH1750_I2CADDR, mode, sizeof(mode), false);
        wait_ms(10);
    }
    usb2pc.printf("BH1750 start with customize mode!\r\n");    
}
//--------
float BH1750::getlightdata()                                //读取光强(lux)
{
    status = true;
    status = link.read(BH1750_I2CADDR, rawdata, 2, false);
    if(!status)
    {
        float result = ((rawdata[0]<<8)|rawdata[1])/1.2;
        return result;
    }
    else
    {
        usb2pc.printf("BH1750 read fail!\r\n");
        return -1;
    }
}
//==============================================MQ-2
mq::mq(PinName dio)
    : status(false), signal(dio),signallevel(PC_13)
{
    signal.fall(this, &mq::triggered);
    usb2pc.printf("mq start!\r\n");
}
//--------
mq::mq(PinName dio,PinName aio)
    : status(false), signal(dio),signallevel(aio)
{
    signal.fall(this, &mq::triggered);
    usb2pc.printf("mq start!\r\n");
}
//--------
void mq::triggered()                                     //触发中断!!
{
    usb2pc.printf("mq Triggered!\r\n");
    status = true;
}
//--------
bool mq::operator==(const bool &target)
{
    if(status == target)
    {
        return true;
    }
    else
    {
        return false;
    }
}
//--------
float mq::getairdata()
{
    return signallevel.read();
}  
//-----------
void mq::reset()
{
    status = false;
}
int mq::read()
{
    return signal.read();
}
//===========================================DHT11
dht11::dht11(PinName pin)
    :datapin(pin)
{
    starttime.start();
    usb2pc.printf("dht11 start!\r\n");
}
//----------
int dht11::getdata()
{
    int timeout=10000;
    uint8_t data[5];
    uint8_t bit=7;
    uint8_t count=0;
        
    for(int i=0;i<5;i++)
    {
        data[i]=0;
    }
    if(starttime.read_ms()<1500){while(starttime.read_ms()<1500){}starttime.stop();}
        
    datapin.output();
    datapin=0;
    wait_ms(19);
    datapin=1;
    wait_us(30);
    datapin.input();
        
    while(!datapin)
    {
        if(timeout--==0){usb2pc.printf("timeout!no reset\r\n");return 0;}
    }
    timeout=10000;
    while(datapin)
    {
        if(timeout--==0){usb2pc.printf("timeout!no respanse\r\n");return 0;}
    }
    timeout=10000;
    for(int i=0;i<40;i++)
    {
        while(!datapin)
        {
            if(timeout--==0){usb2pc.printf("timeout!\r\n");return 0;}
        }
        timer.start();
        timeout=10000;
        while(datapin)
        {
            if(timeout--==0){usb2pc.printf("timeout!n\r\n");return 0;}
        }
        timeout=10000;
        long t=timer.read_us();
        timer.stop();
        timer.reset();
            
        if(bit==0)
        {
            if(t>40){data[count]|=(1<<bit);}
            bit=7;
            count++;
        }
        else
        {
            if(t>40)
            {
                data[count]|=(1<<bit);
            }
            bit--;
        }
    }
    datapin=1;
    if(data[4]==data[0]+data[1]+data[2]+data[3])
    {
        //usb2pc.printf("Humidity (%):%f\r\n",(float)data[0]);
        //usb2pc.printf("Temperature (oC): %f\r\n",(float)data[2]);
        H=data[0]+data[1]/10.0;
        T=data[2]+data[3]/10.0;
        return 1;
    }
    else{usb2pc.printf("error!\r\ndata0:%d\tdata1:%d\r\ndata2:%d\tdata3:%d\r\ndata4:%d\r\n",(int)data[0],(int)data[1],(int)data[2],(int)data[3],(int)data[4]);return 0;}
}  
//-------
float dht11::gethumidity()
{
    return H;
}
//-------
float dht11::gettemperature()
{
    return T;
}
//============================================DS18B20
DS18B20::DS18B20(PinName pin)
    :datapin(pin)
{
        if(start()){usb2pc.printf("DS18B20 started\r\n");}
}
//-----------
int DS18B20::start()
{
    //usb2pc.printf("starting\r\n");
    datapin.output();
    datapin=0;
    wait_us(600);
    datapin.input();
    datapin.mode(PullUp);
    wait_us(70);
    while(datapin.read()){return 0;}
    //usb2pc.printf("started\r\n");
    wait_us(250);
    return 1;
}
//----------
void DS18B20::writebyte(uint8_t send)
{
    datapin.output();
    datapin=1; 
    wait_us(20);
    for(int i=0;i<8;i++)
    {
        datapin.output();
        datapin=0;           //产生读写时序的起始信号  
        wait_us(2);        //要求至少1us的延时  
        datapin=send & 0x01; //对总线赋值,从最低位开始写起  
        wait_us(70);//延时70us,写0在60~120us之间释放,写1的话大于60us均可释放  
        datapin=1;          //释放总线,为下一次mcu送数据做准备,         
        send>>=1;     //有效数据移动到最低位,2次写数据间隙至少需1us  
    }
    datapin.output();
    datapin=1; 
    wait_us(70);
}
//-----------
uint8_t DS18B20::readByte()    //mcu读一个字节  
{  
    uint8_t i,value=0;
    for(i=0;i<8;i++)  
    {  
        datapin.output();
        datapin=0;                  //起始信号                     
        wait_us(2); 
        datapin.input();                 //mcu释放总线  
        datapin.mode(PullUp);
        if(datapin)            
        {  
            value=value|0x80;//保存高电平数据,低电平的话不用保存,移位后默认是0  
        }   
        value>>=1;
        wait_us(30); //延时40us    
    }  
    return value;  
}  
//------------
float DS18B20::transfer(uint8_t h,uint8_t l)
{
    //h=0x01;
    //l=0x01;
    int flag=(h&0x01)>>7; 
    if(!flag)
    {
        float i=(h*256+l)*0.25;
        //usb2pc.printf("flag:%d\th:%d\tl:%d\r\n",flag,h,l);
        return i;
    }
    else
    {
        float i=((~h)*256+(~l))*0.25*-1;
        //usb2pc.printf("flag:%d\th:%d\tl:%d\r\n",flag,h,l);
        return i;
    }
}
//----------
int DS18B20::getdata()
{
    T=5000;
    start();
    writebyte(0xcc);
    writebyte(0x44);
    wait(2);
    
    start();
    writebyte(0xcc);
    writebyte(0xbe);
    uint8_t a=readByte();//l
    uint8_t b=readByte();//h
    T=transfer(b,a);
    
    if(T==5000){return 0;}
    else{return 1;}
}
//----------
float DS18B20::gettemperature()
{
    if(getdata()){return T;}
    else{usb2pc.printf("get temperature fail!\r\n");return 0;}
}
//==============================================YL-38
YL::YL(PinName dio)
    : status(false), signal(dio),signallevel(PC_13)
{
    signal.fall(this, &YL::triggered);
    usb2pc.printf("YL start!\r\n");
}
//--------
YL::YL(PinName dio,PinName aio)
    : status(false), signal(dio),signallevel(aio)
{
    signal.fall(this, &YL::triggered);
    usb2pc.printf("YL start!\r\n");
}
//--------
void YL::triggered()                                     //触发中断!!
{
    usb2pc.printf("YL Triggered!\r\n");
    status = true;
}
//--------
bool YL::operator==(const bool &target)
{
    if(status == target)
    {
        return true;
    }
    else
    {
        return false;
    }
}
//--------
float YL::getairdata()
{
    return signallevel.read();
}  
//-----------
void YL::reset()
{
    status = false;
}
int YL::read()
{
    return signal.read();
}
//=============================================
BMP180::BMP180(PinName sda,PinName scl)  
    :i2c(sda,scl)  
{
    OSS=OSS_3;
    uint8_t c = readByte(BMP180_ADDRESS, BMP180_WHO_AM_I);   
    if(c == 0x55) {
 
    usb2pc.printf("BMP-180 is 0x%x\r\n", c);
    usb2pc.printf("BMP-180 should be 0x55\r\n");
    usb2pc.printf("BMP-180 online...\r\n");
   
    BMP180Calibration();
    usb2pc.printf("BMP-180 calibration complete...\r\n");
   }
   else 
   {
    usb2pc.printf("BMP-180 is 0x%x\r\n", c);
    usb2pc.printf("BMP-180 should be 0x55\r\n");
    while(1); // idle here forever
   }
}
void BMP180::writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
   char data_write[2];
   data_write[0] = subAddress;
   data_write[1] = data;
   i2c.write(address, data_write, 2, 0);
}

char BMP180::readByte(uint8_t address, uint8_t subAddress)
{
    char data[1]; // `data` will store the register data     
    char data_write[1];
    data_write[0] = subAddress;
    i2c.write(address, data_write, 1, 1); // no stop
    i2c.read(address, data, 1, 0); 
    return data[0]; 
}

void BMP180::readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{     
    char data[14];
    char data_write[1];
    data_write[0] = subAddress;
    i2c.write(address, data_write, 1, 1); // no stop
    i2c.read(address, data, count, 0); 
    for(int ii = 0; ii < count; ii++) {
     dest[ii] = data[ii];
    }
} 
 

// Stores all of the BMP180's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
// These BMP-180 functions were adapted from Jim Lindblom of SparkFun Electronics
void BMP180::BMP180Calibration()
{
  ac1 = readByte(BMP180_ADDRESS, 0xAA) << 8 | readByte(BMP180_ADDRESS, 0xAB);
  ac2 = readByte(BMP180_ADDRESS, 0xAC) << 8 | readByte(BMP180_ADDRESS, 0xAD);
  ac3 = readByte(BMP180_ADDRESS, 0xAE) << 8 | readByte(BMP180_ADDRESS, 0xAF);
  ac4 = readByte(BMP180_ADDRESS, 0xB0) << 8 | readByte(BMP180_ADDRESS, 0xB1);
  ac5 = readByte(BMP180_ADDRESS, 0xB2) << 8 | readByte(BMP180_ADDRESS, 0xB3);
  ac6 = readByte(BMP180_ADDRESS, 0xB4) << 8 | readByte(BMP180_ADDRESS, 0xB5);
  b1  = readByte(BMP180_ADDRESS, 0xB6) << 8 | readByte(BMP180_ADDRESS, 0xB7);
  b2  = readByte(BMP180_ADDRESS, 0xB8) << 8 | readByte(BMP180_ADDRESS, 0xB9);
  mb  = readByte(BMP180_ADDRESS, 0xBA) << 8 | readByte(BMP180_ADDRESS, 0xBB);
  mc  = readByte(BMP180_ADDRESS, 0xBC) << 8 | readByte(BMP180_ADDRESS, 0xBD);
  md  = readByte(BMP180_ADDRESS, 0xBE) << 8 | readByte(BMP180_ADDRESS, 0xBF);
}

// Temperature returned will be in units of 0.1 deg C
long BMP180::BMP180GetTemperature()
{
  long ut = 0;
  uint8_t rawData[2] = {0, 0};
  
  writeByte(BMP180_ADDRESS, 0xF4, 0x2E); // start temperature measurement
  wait_ms(5);
  readBytes(BMP180_ADDRESS, 0xF6, 2, &rawData[0]); // read raw temperature measurement
  ut = rawData[0]*256+ rawData[1];
 
  long x1, x2;
  
  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;

  return  ((b5 + 8)>>4)/10.0;  
}

// Calculate pressure read calibration values  
// b5 is also required so BMP180GetTemperature() must be called first.
// Value returned will be pressure in units of Pa.
long BMP180::BMP180GetPressure()
{
  long up = 0;
  writeByte(BMP180_ADDRESS, 0xF4, 0x34 | OSS << 6); // Configure pressure measurement for highest resolution
  wait_ms(5+8*OSS); // delay 5 ms at lowest resolution, 29 ms at highest
  uint8_t rawData[3] = {0, 0, 0};
  readBytes(BMP180_ADDRESS, 0xF6, 3, &rawData[0]); // read raw pressure measurement of 19 bits
  up = (((long) rawData[0] << 16) | ((long)rawData[1] << 8) | rawData[2]) >> (8 - OSS);

  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;
  
  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
  
  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  
  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;
    
  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;
  
  return p;
}      
//===============================
GP2Y1010::GP2Y1010(PinName led,PinName measure)
    :measurePin(measure),ledPower(led)
{
    samplingTime = 280;
    deltaTime = 40;
    sleepTime = 9680;
 
    voMeasured = 0;
    calcVoltage = 0;
    dustDensity = 0;
}

float GP2Y1010::getairdata()
{
      ledPower=1;
  
  wait_us(samplingTime);
 
  voMeasured = measurePin.read();
 
  wait_us(deltaTime);
   ledPower=0;
  wait_us(sleepTime);
 
  calcVoltage = voMeasured*5.0;
  dustDensity = 0.17*calcVoltage-0.1;
 
  if ( dustDensity < 0)
  {
    dustDensity = 0.00;
  }
 return dustDensity ;
}