Hi
I am using NRF5340dk with NCS version 1.5.0, I need to port the below library which was written for nrf51.
KIndly, Help me to resolve this
Thanks & Regards
Navin
Hi
I am using NRF5340dk with NCS version 1.5.0, I need to port the below library which was written for nrf51.
KIndly, Help me to resolve this
Thanks & Regards
Navin
Hi Oyvind
I have written some code like the same for nrf5340. I can't able to read any data
I will attach that code for your reference. Kindly guide me to get the output
/**
* @brief ADS1231.c
* @details 24-Bit Analog-to-Digital Converter for Bridge Sensors.
* Functions file.
*
*
* @return NA
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN
* @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
*/
#include <drivers/gpio.h>
#include <hal/nrf_gpio.h>
#include "ADS1231.h"
/**
* @brief ADS1231_Init ( uint32_t , uint32_t )
*
* @details It performs an internal reset.
*
* @param[in] myDOUT: Pin to be #DRDY/DOUT.
* @param[in] mySCLK: Pin to be SCLK.
*
* @param[out] NaN.
*
*
* @return The configured pins.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_pins_t ADS1231_Init ( uint32_t myDOUT, uint32_t mySCLK )
{
ADS1231_pins_t myPins;
// INPUT. #DRDY/DOUT PIN
nrf_gpio_cfg_input(myDOUT,NRF_GPIO_PIN_NOPULL);
// OUTPUT. SCLK PIN
nrf_gpio_cfg_output(mySCLK);
// Associate the pins
myPins.DOUT = myDOUT;
myPins.SCLK = mySCLK;
return myPins;
}
/**
* @brief ADS1231_Reset ( void )
*
* @details It performs an internal reset.
*
* @param[in] NaN.
*
* @param[out] NaN.
*
*
* @return Status of ADS1231_Reset.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre When SCLK pin changes from low to high and stays at high for
* longer than 26μs, ADS1231 enters power down mode.
*
* When SCLK returns to low, chip will reset and enter normal
* operation mode.
* @warning NaN.
*/
ADS1231_status_t ADS1231_Reset ( ADS1231_pins_t myPins )
{
nrf_gpio_pin_set( myPins.SCLK ); // SCLK HIGH
k_usleep ( 52 ); // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
nrf_gpio_pin_clear( myPins.SCLK ); // SCLK LOW
if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_PowerDown ( void )
*
* @details It puts the device in power-down mode.
*
* @param[in] NaN.
*
* @param[out] NaN.
*
*
* @return Status of ADS1231_PowerDown.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre When SCLK pin changes from low to high and stays at high for
* longer than 26μs, ADS1231 enters power down mode.
* @warning NaN.
*/
ADS1231_status_t ADS1231_PowerDown ( ADS1231_pins_t myPins )
{
// _SCLK = ADS1231_PIN_HIGH;
nrf_gpio_pin_set( myPins.SCLK );
k_usleep( 52 ); // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
if ( ( ( nrf_gpio_pin_read (myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_ReadRawData ( ADS1231_pins_t, Vector_count_t*, uint32_t )
*
* @details It reads the raw data from the device.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myAverage: How many measurement we have to get and deliver the average.
*
* @param[out] myNewRawData: The new value from the device.
*
*
* @return Status of ADS1231_ReadRawData.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning nrf_delay_us ( 1 ) does not seem to work well, the delay is about
* 5us instead of 1us.
*/
ADS1231_status_t ADS1231_ReadRawData ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
{
uint32_t i = 0; // Counter and timeout variable
uint32_t ii = 0; // Counter for average
uint32_t myAuxData = 0;
myNewRawData->myRawValue = 0; // Reset variable at the beginning
// Start collecting the new measurement as many as myAverage
for ( ii = 0; ii < myAverage; ii++ )
{
// Reset the value
myAuxData = 0;
// Wait until the device is ready or timeout
i = 23232323;
//_SCLK = ADS1231_PIN_LOW;
nrf_gpio_pin_clear( myPins.SCLK );
while ( ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH ) && ( --i ) );
// Check if something is wrong with the device because of the timeout
if ( i < 1 )
return ADS1231_FAILURE;
// Read the data
for ( i = 0; i < 24; i++ )
{
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
nrf_gpio_pin_set (myPins.SCLK );
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
myAuxData <<= 1;
nrf_gpio_pin_clear(myPins.SCLK );
// High or Low bit
if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
myAuxData++;
}
// Last bit to release the bus
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
nrf_gpio_pin_set ( myPins.SCLK );
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
nrf_gpio_pin_clear( myPins.SCLK );
// Update data to get the average
myAuxData ^= 0x800000;
myNewRawData->myRawValue += myAuxData;
}
myNewRawData->myRawValue /= ( float )myAverage;
if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_ReadData_WithCalibratedMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
*
* @details It reads data with a calibrated mass on the load cell.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myAverage: How many data to read.
*
* @param[out] myNewRawData: myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ).
*
*
* @return Status of ADS1231_ReadData_WithCalibratedMass.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_status_t ADS1231_ReadData_WithCalibratedMass ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
{
ADS1231_status_t aux;
// Perform a new bunch of readings
aux = ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
// Update the value with a calibrated mass
myNewRawData->myRawValue_WithCalibratedMass = myNewRawData->myRawValue;
if ( aux == ADS1231_SUCCESS )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_ReadData_WithoutMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
*
* @details It reads data without any mass on the load cell.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myAverage: How many data to read.
*
* @param[out] myNewRawData: myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ).
*
*
* @return Status of ADS1231_ReadData_WithoutMass.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_status_t ADS1231_ReadData_WithoutMass ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
{
ADS1231_status_t aux;
// Perform a new bunch of readings
aux = ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
// Update the value without any mass
myNewRawData->myRawValue_WithoutCalibratedMass = myNewRawData->myRawValue;
if ( aux == ADS1231_SUCCESS )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_CalculateMass ( Vector_count_t* , uint32_t , ADS1231_scale_t )
*
* @details It calculates the mass.
*
* @param[in] myNewRawData: It has myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ),
* myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ) and
* myRawValue ( the current data taken by the system ).
* @param[in] myCalibratedMass: A known value for the calibrated mass when myRawValue_WithCalibratedMass was
* calculated.
* @param[in] myScaleCalibratedMass: The range of the calibrated mass ( kg, g, mg or ug ).
*
* @param[out] NaN.
*
*
* @return The calculated mass.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
Vector_mass_t ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass )
{
// Terminology by Texas Instruments: sbau175a.pdf, p8 2.1.1 Calculation of Mass
float m, w_zs;
float c_zs, w_fs, c_fs, w_t;
float c = 0;
float myFactor = 1.0;
Vector_mass_t w;
// Adapt the scale ( kg as reference )
switch ( myScaleCalibratedMass )
{
default:
case ADS1231_SCALE_kg:
// myFactor = 1.0;
break;
case ADS1231_SCALE_g:
myFactor /= 1000.0;
break;
case ADS1231_SCALE_mg:
myFactor /= 1000000.0;
break;
case ADS1231_SCALE_ug:
myFactor /= 1000000000.0;
break;
}
// Calculate the Calibration Constant ( m )
w_fs = ( myCalibratedMass / myFactor ); // User-specified calibration mass
c_zs = myNewRawData->myRawValue_WithoutCalibratedMass; // ADC measurement taken with no load
c_fs = myNewRawData->myRawValue_WithCalibratedMass; // ADC code taken with the calibration mass applied
m = ( float )( w_fs / ( ( c_fs ) - c_zs ) ); // The Calibration Constant
// Calculate the zero-scale mass ( w_zs )
w_zs = - ( m * c_zs );
// Calculate the mass ( w )
w_t = myNewRawData->myRawValue_TareWeight; // ADC code taken without any mass after the system is calibrated;
c = myNewRawData->myRawValue; // The ADC code
w.myMass = ( m * c ) + w_zs - w_t; // The mass according to myScaleCalibratedMass
// Update Internal Parameters
//_ADS1231_USER_CALIBATED_MASS = myCalibratedMass;
//_ADS1231_SCALE = w;
return w;
}
/**
* @brief ADS1231_SetAutoTare ( ADS1231_pins_t, float , ADS1231_scale_t , Vector_count_t* , float )
*
* @details It reads data without any mass on the load cell after the system is calibrated to calculate the tare weight.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myCalibratedMass: A known value for the calibrated mass when myRawValue_WithCalibratedMass was
* calculated.
* @param[in] myScaleCalibratedMass: The range of the calibrated mass ( kg, g, mg or ug ).
* @param[in] myTime: How long the auto-set lasts.
*
* @param[out] myNewRawData: myRawValue_TareWeight ( ADC code taken without any mass ).
*
*
* @return Status of ADS1231_SetAutoTare.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_status_t ADS1231_SetAutoTare ( ADS1231_pins_t myPins, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime )
{
ADS1231_status_t aux;
Vector_mass_t myCalculatedMass;
float myAuxData = 0;
uint32_t i = 0;
// Perform a new bunch of readings every 1 second
for ( i = 0; i < myTime; i++ )
{
aux = ADS1231_ReadRawData ( myPins, myNewRawData, 10 );
myAuxData += myNewRawData->myRawValue;
k_msleep ( 1000 );
}
myNewRawData->myRawValue = ( float )( myAuxData / myTime );
// Turn it into mass
myCalculatedMass = ADS1231_CalculateMass ( myNewRawData, myCalibratedMass, myScaleCalibratedMass );
// Update the value without any mass
myNewRawData->myRawValue_TareWeight = myCalculatedMass.myMass;
// Update Internal Parameters
//_ADS1231_USER_CALIBATED_MASS = myCalibratedMass;
//_ADS1231_SCALE = myScaleCalibratedMass;
if (aux == ADS1231_SUCCESS )
{
return ADS1231_SUCCESS;
}
else
{
return ADS1231_FAILURE;
}
}
/**
* @brief ADS1231_SetManualTare ( float myTareWeight )
*
* @details It sets a tare weight manually.
*
* @param[in] myTareWeight: Tare weight.
*
* @param[out] NaN.
*
*
* @return myRawValue_TareWeight.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
Vector_count_t ADS1231_SetManualTare ( float myTareWeight )
{
Vector_count_t myNewTareWeight;
// Update the value defined by the user
myNewTareWeight.myRawValue_TareWeight = myTareWeight;
return myNewTareWeight;
}
/**
* @brief ADS1231_CalculateVoltage ( Vector_count_t* ,float )
*
* @details It calculates the mass.
*
* @param[in] myNewRawData: myRawValue ( the current data taken by the system ).
* @param[in] myVoltageReference: The voltage at the converter reference input.
*
* @param[out] NaN.
*
*
* @return The calculated voltage.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
Vector_voltage_t ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference )
{
// Terminology by Texas Instruments: sbau175a.pdf, p12 3.2 Measurement Modes Raw
float x, B, A;
Vector_voltage_t v;
x = myNewRawData->myRawValue;
B = ( 16777216.0 - 1.0 ); // 2^24 - 1
A = 128.0; // Gain
// Calculate the voltage ( v )
v.myVoltage = ( float )( ( x / B ) * ( myVoltageReference / A ) ); // The voltage
return v;
}
#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <stdio.h>
#include <hal/nrf_gpio.h>
#include "ADS1231.h"
#define PWDN 21
#define LED1 28
#define LED2 29
#define LED3 30
#define YES 1
#define NO 0
int main( void )
{
ADS1231_status_t aux;
ADS1231_pins_t myADS1231pins;
Vector_count_t myData;
Vector_mass_t myCalculatedMass;
Vector_voltage_t myCalculatedVoltage;
bool myNewMeasurement;
// conf_GPIO ();
//conf_TIMER0 ();
nrf_gpio_cfg_output(LED1);
nrf_gpio_cfg_output(LED2);
nrf_gpio_cfg_output(LED3);
// Configure the pins to handle the ADS1231 device ( P0.12: #DRDY/DOUT, P0.13: SCLK )
myADS1231pins = ADS1231_Init ( 19, 20 );
aux = ADS1231_PowerDown ( myADS1231pins );
aux = ADS1231_Reset ( myADS1231pins );
k_msleep( 1000 );
// CALIBRATION time start!
// 1. REMOVE THE MASS ON THE LOAD CELL ( ALL LEDs OFF ). Read data without any mass on the load cell
aux = ADS1231_ReadData_WithoutMass ( myADS1231pins, &myData, 4 );
nrf_gpio_pin_clear(LED1 );
k_msleep ( 3000 );
// 2. PUT A KNOWN MASS ON THE LOAD CELL ( JUST LED1 ON ). Read data with an user-specified calibration mass
aux = ADS1231_ReadData_WithCalibratedMass ( myADS1231pins, &myData, 4 );
// CALIBRATION time end!
// [ OPTIONAL ] REMOVE THE MASS ON THE LOAD CELL ( JUST LED2 ON ). Read the device without any mass to calculate the tare weight for 5 seconds
// NRF_GPIO->OUTSET = ( 1UL << LED1 );
//NRF_GPIO->OUTCLR = ( 1UL << LED2 );
//nrf_delay_ms ( 3000 );
// NRF_GPIO->OUTSET = ( 1UL << LED2 );
// Calculating the tare weight ( JUST LED3 ON )
nrf_gpio_pin_clear(LED3 );
aux = ADS1231_SetAutoTare ( myADS1231pins, 1.0, ADS1231_SCALE_kg, &myData, 5 );
nrf_gpio_pin_set(LED3 );
nrf_gpio_cfg_output(PWDN);
nrf_gpio_pin_clear(PWDN);
k_msleep ( 3000 );
nrf_gpio_pin_set(PWDN);
myNewMeasurement = YES ;
//NRF_TIMER0->TASKS_START = 1; // Start Timer0
while( 1 )
{
//NRF_POWER->SYSTEMOFF = 1;
/* NRF_POWER->TASKS_LOWPWR = 1; // Sub power mode: Low power.
// Enter System ON sleep mode
__WFE();
// Make sure any pending events are cleared
__SEV();
__WFE();*/
if ( myNewMeasurement == YES ){
aux = ADS1231_ReadRawData ( myADS1231pins, &myData, 4 );
myCalculatedMass = ADS1231_CalculateMass ( &myData, 1.0, ADS1231_SCALE_kg );
myCalculatedVoltage = ADS1231_CalculateVoltage ( &myData, 5.0 );
printf("Load in Kg: %f",myCalculatedMass);
myNewMeasurement = NO;
}
}
}
Thanks & regards
Navin
Hi Oyvind
I have written some code like the same for nrf5340. I can't able to read any data
I will attach that code for your reference. Kindly guide me to get the output
/**
* @brief ADS1231.c
* @details 24-Bit Analog-to-Digital Converter for Bridge Sensors.
* Functions file.
*
*
* @return NA
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN
* @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
*/
#include <drivers/gpio.h>
#include <hal/nrf_gpio.h>
#include "ADS1231.h"
/**
* @brief ADS1231_Init ( uint32_t , uint32_t )
*
* @details It performs an internal reset.
*
* @param[in] myDOUT: Pin to be #DRDY/DOUT.
* @param[in] mySCLK: Pin to be SCLK.
*
* @param[out] NaN.
*
*
* @return The configured pins.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_pins_t ADS1231_Init ( uint32_t myDOUT, uint32_t mySCLK )
{
ADS1231_pins_t myPins;
// INPUT. #DRDY/DOUT PIN
nrf_gpio_cfg_input(myDOUT,NRF_GPIO_PIN_NOPULL);
// OUTPUT. SCLK PIN
nrf_gpio_cfg_output(mySCLK);
// Associate the pins
myPins.DOUT = myDOUT;
myPins.SCLK = mySCLK;
return myPins;
}
/**
* @brief ADS1231_Reset ( void )
*
* @details It performs an internal reset.
*
* @param[in] NaN.
*
* @param[out] NaN.
*
*
* @return Status of ADS1231_Reset.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre When SCLK pin changes from low to high and stays at high for
* longer than 26μs, ADS1231 enters power down mode.
*
* When SCLK returns to low, chip will reset and enter normal
* operation mode.
* @warning NaN.
*/
ADS1231_status_t ADS1231_Reset ( ADS1231_pins_t myPins )
{
nrf_gpio_pin_set( myPins.SCLK ); // SCLK HIGH
k_usleep ( 52 ); // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
nrf_gpio_pin_clear( myPins.SCLK ); // SCLK LOW
if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_PowerDown ( void )
*
* @details It puts the device in power-down mode.
*
* @param[in] NaN.
*
* @param[out] NaN.
*
*
* @return Status of ADS1231_PowerDown.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre When SCLK pin changes from low to high and stays at high for
* longer than 26μs, ADS1231 enters power down mode.
* @warning NaN.
*/
ADS1231_status_t ADS1231_PowerDown ( ADS1231_pins_t myPins )
{
// _SCLK = ADS1231_PIN_HIGH;
nrf_gpio_pin_set( myPins.SCLK );
k_usleep( 52 ); // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
if ( ( ( nrf_gpio_pin_read (myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_ReadRawData ( ADS1231_pins_t, Vector_count_t*, uint32_t )
*
* @details It reads the raw data from the device.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myAverage: How many measurement we have to get and deliver the average.
*
* @param[out] myNewRawData: The new value from the device.
*
*
* @return Status of ADS1231_ReadRawData.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning nrf_delay_us ( 1 ) does not seem to work well, the delay is about
* 5us instead of 1us.
*/
ADS1231_status_t ADS1231_ReadRawData ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
{
uint32_t i = 0; // Counter and timeout variable
uint32_t ii = 0; // Counter for average
uint32_t myAuxData = 0;
myNewRawData->myRawValue = 0; // Reset variable at the beginning
// Start collecting the new measurement as many as myAverage
for ( ii = 0; ii < myAverage; ii++ )
{
// Reset the value
myAuxData = 0;
// Wait until the device is ready or timeout
i = 23232323;
//_SCLK = ADS1231_PIN_LOW;
nrf_gpio_pin_clear( myPins.SCLK );
while ( ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH ) && ( --i ) );
// Check if something is wrong with the device because of the timeout
if ( i < 1 )
return ADS1231_FAILURE;
// Read the data
for ( i = 0; i < 24; i++ )
{
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
nrf_gpio_pin_set (myPins.SCLK );
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
myAuxData <<= 1;
nrf_gpio_pin_clear(myPins.SCLK );
// High or Low bit
if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
myAuxData++;
}
// Last bit to release the bus
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
nrf_gpio_pin_set ( myPins.SCLK );
// nrf_delay_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns )
nrf_gpio_pin_clear( myPins.SCLK );
// Update data to get the average
myAuxData ^= 0x800000;
myNewRawData->myRawValue += myAuxData;
}
myNewRawData->myRawValue /= ( float )myAverage;
if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_ReadData_WithCalibratedMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
*
* @details It reads data with a calibrated mass on the load cell.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myAverage: How many data to read.
*
* @param[out] myNewRawData: myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ).
*
*
* @return Status of ADS1231_ReadData_WithCalibratedMass.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_status_t ADS1231_ReadData_WithCalibratedMass ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
{
ADS1231_status_t aux;
// Perform a new bunch of readings
aux = ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
// Update the value with a calibrated mass
myNewRawData->myRawValue_WithCalibratedMass = myNewRawData->myRawValue;
if ( aux == ADS1231_SUCCESS )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_ReadData_WithoutMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
*
* @details It reads data without any mass on the load cell.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myAverage: How many data to read.
*
* @param[out] myNewRawData: myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ).
*
*
* @return Status of ADS1231_ReadData_WithoutMass.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_status_t ADS1231_ReadData_WithoutMass ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
{
ADS1231_status_t aux;
// Perform a new bunch of readings
aux = ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
// Update the value without any mass
myNewRawData->myRawValue_WithoutCalibratedMass = myNewRawData->myRawValue;
if ( aux == ADS1231_SUCCESS )
return ADS1231_SUCCESS;
else
return ADS1231_FAILURE;
}
/**
* @brief ADS1231_CalculateMass ( Vector_count_t* , uint32_t , ADS1231_scale_t )
*
* @details It calculates the mass.
*
* @param[in] myNewRawData: It has myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ),
* myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ) and
* myRawValue ( the current data taken by the system ).
* @param[in] myCalibratedMass: A known value for the calibrated mass when myRawValue_WithCalibratedMass was
* calculated.
* @param[in] myScaleCalibratedMass: The range of the calibrated mass ( kg, g, mg or ug ).
*
* @param[out] NaN.
*
*
* @return The calculated mass.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
Vector_mass_t ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass )
{
// Terminology by Texas Instruments: sbau175a.pdf, p8 2.1.1 Calculation of Mass
float m, w_zs;
float c_zs, w_fs, c_fs, w_t;
float c = 0;
float myFactor = 1.0;
Vector_mass_t w;
// Adapt the scale ( kg as reference )
switch ( myScaleCalibratedMass )
{
default:
case ADS1231_SCALE_kg:
// myFactor = 1.0;
break;
case ADS1231_SCALE_g:
myFactor /= 1000.0;
break;
case ADS1231_SCALE_mg:
myFactor /= 1000000.0;
break;
case ADS1231_SCALE_ug:
myFactor /= 1000000000.0;
break;
}
// Calculate the Calibration Constant ( m )
w_fs = ( myCalibratedMass / myFactor ); // User-specified calibration mass
c_zs = myNewRawData->myRawValue_WithoutCalibratedMass; // ADC measurement taken with no load
c_fs = myNewRawData->myRawValue_WithCalibratedMass; // ADC code taken with the calibration mass applied
m = ( float )( w_fs / ( ( c_fs ) - c_zs ) ); // The Calibration Constant
// Calculate the zero-scale mass ( w_zs )
w_zs = - ( m * c_zs );
// Calculate the mass ( w )
w_t = myNewRawData->myRawValue_TareWeight; // ADC code taken without any mass after the system is calibrated;
c = myNewRawData->myRawValue; // The ADC code
w.myMass = ( m * c ) + w_zs - w_t; // The mass according to myScaleCalibratedMass
// Update Internal Parameters
//_ADS1231_USER_CALIBATED_MASS = myCalibratedMass;
//_ADS1231_SCALE = w;
return w;
}
/**
* @brief ADS1231_SetAutoTare ( ADS1231_pins_t, float , ADS1231_scale_t , Vector_count_t* , float )
*
* @details It reads data without any mass on the load cell after the system is calibrated to calculate the tare weight.
*
* @param[in] myPins: The pins to communicate with the device.
* @param[in] myCalibratedMass: A known value for the calibrated mass when myRawValue_WithCalibratedMass was
* calculated.
* @param[in] myScaleCalibratedMass: The range of the calibrated mass ( kg, g, mg or ug ).
* @param[in] myTime: How long the auto-set lasts.
*
* @param[out] myNewRawData: myRawValue_TareWeight ( ADC code taken without any mass ).
*
*
* @return Status of ADS1231_SetAutoTare.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
ADS1231_status_t ADS1231_SetAutoTare ( ADS1231_pins_t myPins, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime )
{
ADS1231_status_t aux;
Vector_mass_t myCalculatedMass;
float myAuxData = 0;
uint32_t i = 0;
// Perform a new bunch of readings every 1 second
for ( i = 0; i < myTime; i++ )
{
aux = ADS1231_ReadRawData ( myPins, myNewRawData, 10 );
myAuxData += myNewRawData->myRawValue;
k_msleep ( 1000 );
}
myNewRawData->myRawValue = ( float )( myAuxData / myTime );
// Turn it into mass
myCalculatedMass = ADS1231_CalculateMass ( myNewRawData, myCalibratedMass, myScaleCalibratedMass );
// Update the value without any mass
myNewRawData->myRawValue_TareWeight = myCalculatedMass.myMass;
// Update Internal Parameters
//_ADS1231_USER_CALIBATED_MASS = myCalibratedMass;
//_ADS1231_SCALE = myScaleCalibratedMass;
if (aux == ADS1231_SUCCESS )
{
return ADS1231_SUCCESS;
}
else
{
return ADS1231_FAILURE;
}
}
/**
* @brief ADS1231_SetManualTare ( float myTareWeight )
*
* @details It sets a tare weight manually.
*
* @param[in] myTareWeight: Tare weight.
*
* @param[out] NaN.
*
*
* @return myRawValue_TareWeight.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
Vector_count_t ADS1231_SetManualTare ( float myTareWeight )
{
Vector_count_t myNewTareWeight;
// Update the value defined by the user
myNewTareWeight.myRawValue_TareWeight = myTareWeight;
return myNewTareWeight;
}
/**
* @brief ADS1231_CalculateVoltage ( Vector_count_t* ,float )
*
* @details It calculates the mass.
*
* @param[in] myNewRawData: myRawValue ( the current data taken by the system ).
* @param[in] myVoltageReference: The voltage at the converter reference input.
*
* @param[out] NaN.
*
*
* @return The calculated voltage.
*
*
* @author Manuel Caballero
* @date 18/September/2017
* @version 18/September/2017 The ORIGIN
* @pre NaN.
* @warning NaN.
*/
Vector_voltage_t ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference )
{
// Terminology by Texas Instruments: sbau175a.pdf, p12 3.2 Measurement Modes Raw
float x, B, A;
Vector_voltage_t v;
x = myNewRawData->myRawValue;
B = ( 16777216.0 - 1.0 ); // 2^24 - 1
A = 128.0; // Gain
// Calculate the voltage ( v )
v.myVoltage = ( float )( ( x / B ) * ( myVoltageReference / A ) ); // The voltage
return v;
}
#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <stdio.h>
#include <hal/nrf_gpio.h>
#include "ADS1231.h"
#define PWDN 21
#define LED1 28
#define LED2 29
#define LED3 30
#define YES 1
#define NO 0
int main( void )
{
ADS1231_status_t aux;
ADS1231_pins_t myADS1231pins;
Vector_count_t myData;
Vector_mass_t myCalculatedMass;
Vector_voltage_t myCalculatedVoltage;
bool myNewMeasurement;
// conf_GPIO ();
//conf_TIMER0 ();
nrf_gpio_cfg_output(LED1);
nrf_gpio_cfg_output(LED2);
nrf_gpio_cfg_output(LED3);
// Configure the pins to handle the ADS1231 device ( P0.12: #DRDY/DOUT, P0.13: SCLK )
myADS1231pins = ADS1231_Init ( 19, 20 );
aux = ADS1231_PowerDown ( myADS1231pins );
aux = ADS1231_Reset ( myADS1231pins );
k_msleep( 1000 );
// CALIBRATION time start!
// 1. REMOVE THE MASS ON THE LOAD CELL ( ALL LEDs OFF ). Read data without any mass on the load cell
aux = ADS1231_ReadData_WithoutMass ( myADS1231pins, &myData, 4 );
nrf_gpio_pin_clear(LED1 );
k_msleep ( 3000 );
// 2. PUT A KNOWN MASS ON THE LOAD CELL ( JUST LED1 ON ). Read data with an user-specified calibration mass
aux = ADS1231_ReadData_WithCalibratedMass ( myADS1231pins, &myData, 4 );
// CALIBRATION time end!
// [ OPTIONAL ] REMOVE THE MASS ON THE LOAD CELL ( JUST LED2 ON ). Read the device without any mass to calculate the tare weight for 5 seconds
// NRF_GPIO->OUTSET = ( 1UL << LED1 );
//NRF_GPIO->OUTCLR = ( 1UL << LED2 );
//nrf_delay_ms ( 3000 );
// NRF_GPIO->OUTSET = ( 1UL << LED2 );
// Calculating the tare weight ( JUST LED3 ON )
nrf_gpio_pin_clear(LED3 );
aux = ADS1231_SetAutoTare ( myADS1231pins, 1.0, ADS1231_SCALE_kg, &myData, 5 );
nrf_gpio_pin_set(LED3 );
nrf_gpio_cfg_output(PWDN);
nrf_gpio_pin_clear(PWDN);
k_msleep ( 3000 );
nrf_gpio_pin_set(PWDN);
myNewMeasurement = YES ;
//NRF_TIMER0->TASKS_START = 1; // Start Timer0
while( 1 )
{
//NRF_POWER->SYSTEMOFF = 1;
/* NRF_POWER->TASKS_LOWPWR = 1; // Sub power mode: Low power.
// Enter System ON sleep mode
__WFE();
// Make sure any pending events are cleared
__SEV();
__WFE();*/
if ( myNewMeasurement == YES ){
aux = ADS1231_ReadRawData ( myADS1231pins, &myData, 4 );
myCalculatedMass = ADS1231_CalculateMass ( &myData, 1.0, ADS1231_SCALE_kg );
myCalculatedVoltage = ADS1231_CalculateVoltage ( &myData, 5.0 );
printf("Load in Kg: %f",myCalculatedMass);
myNewMeasurement = NO;
}
}
}
Thanks & regards
Navin