Library for working with the HYCON HY3116/8 24-bit weigh-scales ADC series.

HY3116.cpp

Committer:
seajayshore
Date:
2016-07-26
Revision:
8:530aad60c490
Parent:
7:c9a0ce000a18

File content as of revision 8:530aad60c490:

#include "HY3116.h"

/**
 * Default Constructor.
 * Sets default I2C pins with default frequency
 */
HY3116::HY3116() : 
    i2c(p22, p21)
{
    
    // Set the I2C clock frequency
    i2c.frequency(250000);
} // End constructor

/**
 * Constructor #2
 * Sets I2C pins with default frequency
 */
HY3116::HY3116(PinName sda,
               PinName scl) : 
    i2c(sda, scl)
{
    
    // Set the I2C clock frequency
    i2c.frequency(250000);
} // End constructor

/**
 * Constructor #3
 * Sets I2C pins and non-default frequency
 */
HY3116::HY3116(PinName sda,
               PinName scl,
               int freq   ) : 
    i2c(sda, scl)
{
    
    // Set the I2C clock frequency
    i2c.frequency(freq);
} // End constructor

/**
 * Destructor.
 */
HY3116::~HY3116()
{

}

/**
 * Helper function to write correct data to HY3116 registers
 */
int HY3116::writeRegister(uint8_t regAddress, uint8_t writeData)
{
    int retval = 1;
    char writeBuffer[2];
    writeBuffer[0]=regAddress;
    writeBuffer[1]=writeData;
    retval = i2c.write(HY3116_ADDRESS,writeBuffer,sizeof(writeBuffer),0);
    if (retval != 0) {
        return retval;
    }
    return 0;
}

/**
 * Helper function to write correct data to HY3116 registers
 */
int HY3116::readRegister(uint8_t regAddress, uint8_t byteNum, uint8_t* dest)
{
    int retval = 1;
    if (byteNum > sizeof(dest)) {
        return retval;
    }
    char writeBuffer[1];
    writeBuffer[0] = regAddress;
    char readBuffer[byteNum];
    retval = i2c.write(HY3116_ADDRESS,writeBuffer,sizeof(writeBuffer),1);
    if (retval != 0) {
        return retval;
    }
    retval = i2c.read(HY3116_ADDRESS,readBuffer,sizeof(readBuffer),0);
    if (retval != 0) {
        return retval;
    }
    for(int i=0; i<byteNum; i++) {
        dest[i]=readBuffer[i];
    }
    return 0;
}

// Function to send the reset command
int HY3116::resetChip()
{
    int retval = 0;
    char writeBuffer[1];
    writeBuffer[0] = RESET;
    retval = i2c.write(RESET_ADDRESS,writeBuffer,sizeof(writeBuffer),0);
    if (retval != 0) {
        return 1;
    }
    return  0;
}

// Dedicated ADC-output read, check & format function
uint8_t HY3116::readAdc(int32_t *_adcReading)
{
    // Initialise function variables
    uint8_t rawData[3];
    bool newReading = 0;
    int32_t adcReading = 0;
    uint8_t adc_error = 0;
    uint8_t returnError = 0;
    
    // Read in the raw ADO bytes
    adc_error = readRegister(ADO, 3, &rawData[0]);
    if (adc_error != 0) {
            returnError = 2;
            return returnError;
    }
    
    // Test if there is new data (polling mode)
    if (rawData[2] & 0b00000001) {
        
        // Set the newReading flag
        returnError = 0;
        
        // Shift the raw bytes into the 32-bit variable
        adcReading += rawData[0] << 15;
        adcReading += rawData[1] << 7;
        adcReading += rawData[2] >> 1;
        
        // Account for twos complement polarity
        if (rawData[0] & 0b10000000) {
            adcReading ^= 0xFF800000;
        }
    }
    else {
        
        // Set the newReading flag
        returnError = 1;
    }
    
    *_adcReading = adcReading;
    
    return returnError;
}

// Initialise the HY3116 with the following config.:
//
bool HY3116::init()
{
    int adc_error = 0;
    
    // Reset the chip
    adc_error = resetChip();
    if (adc_error != 0) {
            return 0;
    }
    wait_ms(1);
    
    // Set-up the SYS register
    adc_error = writeRegister(SYS, 0b00011100); // Enable the ADC & LDO
    if (adc_error != 0) {
            return 0;
    }
    wait_ms(1); // wait 100 ms to stabilize 
        
    // Set-up the ADC1 register
    adc_error = writeRegister(ADC1, 0b00001000); // Set inputs to AIN1 & AIN2
    if (adc_error != 0) {
            return 0;
    }
    wait_ms(1); // wait 100 ms to stabilize
    
    // Set-up the ADC2 register
    adc_error = writeRegister(ADC2, 0b01010000); // Set pos. ref. voltage to VDDA, neg. ref. to VSSA, DC offset to 0VRef
    if (adc_error != 0) {
            return 0;
    }
    wait_ms(1); // wait 100 ms to stabilize
    
    // Set-up the ADC3 register
    adc_error = writeRegister(ADC3, 0b00111111); // Set to int. osc. 327kHz, full ref. range, PGA to 32x, pre-amp to 2x
    if (adc_error != 0) {
            return 0;
    }
    wait_ms(1); // wait 100 ms to stabilize
    
    // Set-up the ADC4 register
    // [0:1] = LDO voltage select, 01 = 3.0V
    // [2] = REFO voltage, 0 = 1.2V
    // [3] = HS conversion rate, 0 = slow (327kHz)
    // [4:6] = OSR ADC output rate, 110 = 40SPS (when HS = 0)
    // [7] = N/A
    adc_error = writeRegister(ADC4, 0b01001100);
    if (adc_error != 0) {
            return 0;
    }
    wait_ms(1); // Wait to stabilise
    
    return 1;
}