Test firmware for the Supermote hardware.

Dependencies:   K30_I2C libxDot-mbed5

Fork of K30_I2C_Program by Hux Connect

HPM/hpm.cpp

Committer:
bjenkins
Date:
2018-09-07
Revision:
2:680fc2690d10
Child:
3:2ab969b31f6b

File content as of revision 2:680fc2690d10:

#include "mbed.h"
#include "hpm.h"

    
HPM::HPM(Serial* device, Serial* debug): _device(device), _debug(debug)
{
   _device->baud(9600);
   wait(0.1);
}

bool HPM::init(void)
{
    // Stop autosend
    if (!this->stop_autosend())
    {
        _debug->printf("Stop autosend failed\r\n");
        return 0;
    }
    
    // Start fan
    if (!this->start_measurement())
    {
        _debug->printf("Start measurement failed\r\n");
        return 0;
    }
    
    return 1;
}
    
bool HPM::start_measurement(void)
{
    // First, we send the command
    unsigned char start_measurement[] = {0x68, 0x01, 0x01, 0x96 };
    for (int i=0; i<sizeof(start_measurement); i++)
    {
        _device->putc(start_measurement[i]);  
    }
  
  //Then we wait for the response
  while (!_device->readable()) {} // wait until chars arrive
  char read1 = _device->getc();
  char read2 = _device->getc();
  
  // Test the response
  if ((read1 == 0xA5) && (read2 == 0xA5)){
    return 1;   // ACK
  }
  else if ((read1 == 0x96) && (read2 == 0x96))
  {
    _debug->printf ("NACK\r\n");
    return 0;   // NACK
  }
  else return 0;
}

bool HPM::stop_measurement(void)
{
    // First, we send the command
    unsigned char stop_measurement[] = {0x68, 0x01, 0x01, 0x95 };
    for (int i=0; i<sizeof(stop_measurement); i++)
    {
        _device->putc(stop_measurement[i]); 
    }
  
  
  //Then we wait for the response
  while (!_device->readable()) {} // wait until chars arrive
  char read1 = _device->getc();
  char read2 = _device->getc();
  
  // Test the response
  if ((read1 == 0xA5) && (read2 == 0xA5)){
    return 1;   // ACK
  }
  else if ((read1 == 0x96) && (read2 == 0x96))
  {
    _debug->printf ("NACK\r\n");
    return 0;   // NACK
  }
  else return 0;
}

bool HPM::read_measurement (long int &PM25, long int &PM10)
{
    // Send the command 0x68 0x01 0x04 0x93
    unsigned char read_particle[] = {0x68, 0x01, 0x04, 0x93 };
    for (int i=0; i<sizeof(read_particle); i++)
    {
        _device->putc(read_particle[i]);   
    }
  
    // A measurement can return 0X9696 for NACK
    // Or can return eight bytes if successful
    // We wait for the first two bytes
    while(!_device->readable());
    unsigned char HEAD = _device->getc();
    
    while(!_device->readable());
    unsigned char LEN = _device->getc();
  
    // Test the response
    if ((HEAD == 0x96) && (LEN == 0x96))
    {
        _debug->printf("NACK");
        return 0;
    }
    else if ((HEAD == 0x40) && (LEN == 0x05))
    {
        // The measuremet is valid, read the rest of the data 
        // wait for the next byte
        while(!_device->readable());
        unsigned char COMD = _device->getc();
        
        while(!_device->readable());
        unsigned char DF1 = _device->getc();
        
        while(!_device->readable());
        unsigned char DF2 = _device->getc();
             
        while(!_device->readable());
        unsigned char DF3 = _device->getc();
           
        while(!_device->readable());
        unsigned char DF4 = _device->getc();
         
        while(!_device->readable());
        unsigned char CS = _device->getc();
          
        // Now we shall verify the checksum
        unsigned int cs_calc = 65536;
        cs_calc -= HEAD - LEN - COMD - DF1 - DF2 - DF3 - DF4;
        cs_calc %= 256;
        
        if (((0x10000 - HEAD - LEN - COMD - DF1 - DF2 - DF3 - DF4) % 0XFF) != CS)
        {
            _debug->printf("Checksum fail\r\n");
            _debug->printf ("HEAD=%02x LEN=%02x COMD=%02x DF1=%02x DF2=%02x DF3=%02x DF4=%02x CS=%02x, cs_calc=%02x\r\n", HEAD, LEN, COMD, DF1, DF2, DF3, DF4, CS, cs_calc);
            return 0;
        }
        else
        {
            // Checksum OK, we compute PM2.5 and PM10 values
            PM25 = DF1 * 256 + DF2;
            PM10 = DF3 * 256 + DF4;
            return 1;
        }
    }
    return 0;
}

bool HPM::stop_autosend(void)
{
    // Stop auto send
    unsigned char stop_autosend[] = {0x68, 0x01, 0x20, 0x77 };
    for (int i=0; i<sizeof(stop_autosend); i++)
    {
        _device->putc(stop_autosend[i]); 
    }
  
  //Then we wait for the response
  while(!_device->readable());
  char read1 = _device->getc();
  char read2 = _device->getc();
  
  // Test the response
  if ((read1 == 0xA5) && (read2 == 0xA5)){
    // ACK
    return 1;
  }
  else if ((read1 == 0x96) && (read2 == 0x96))
  {
    // NACK
    _debug->printf ("NACK\r\n");
    return 0;
  }
  else return 0;
}

bool HPM::start_autosend(void)
{
    // Start auto send
    unsigned char start_autosend[] = {0x68, 0x01, 0x40, 0x57 };
    for (int i=0; i<sizeof(start_autosend); i++)
    {
        _device->putc(start_autosend[i]); 
    }  

  //Then we wait for the response
  while(!_device->readable());
  char read1 = _device->getc();
  char read2 = _device->getc();
  // Test the response
  if ((read1 == 0xA5) && (read2 == 0xA5)){
    // ACK
    return 1;
  }
  else if ((read1 == 0x96) && (read2 == 0x96))
  {
    // NACK
    _debug->printf ("NACK\r\n");
    return 0;
    
  }
  else return 0;
}