I want to receive the x and y values measured by the inclination sensor using two channels of the LTC1865AHMS.
But I can't know the byte value of 2 channels. Does anyone know how to find out? (Communication uses SPI.)
there is an example code avaialble here.
It's not for arduino per say but assuming you have some experience of coding within the arduino IDE, it's pretty staightforward to 'translate' the code there ![]()
hope that helps....
Thank you for answer.
I checked the code well, but I'm not sure how to change it to Arduino style. And it is difficult to find this content with the code written as 'spi.~~' in the code. Could you please give me some help on this matter?
something like this maybe:
(Compiles, NOT tested!)
/***************************************************************************************/
/* */
/* Program: LTC1865_ADC_Example(adapted for arduino) */
/* Original Author: Chris Mabey */
/* Date: November 2016 */
/* Target Platform:Arduino */
/* Description: External LTC1865 16-bit ADC example */
/* Version: 1v0 */
/* */
/* LTC1865 Datasheet: http://cds.linear.com/docs/en/datasheet/18645fb.pdf */
/* */
/***************************************************************************************/
#include<SPI.h>
/* The LTC1864 ADC has two input channels */
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 1
/*SPI Pin definitions*/
#define SPI_CS 10 /* Assuming Arduino UNO*/
/* The LTC1864 conversion cycle begins with the rising edge of CONV. */
/* After a period equal to tCONV, the conversion is finished. */
/* The maximum conversion time is 3.2uS, so wait for 4uS */
/* accepts an integer value. */
#define ADC_CONVERSION_TIME 4
/***********************************************************/
/* */
/* Read_External_ADC / SendCommand */
/* */
/* Function: Read the latest value from the specified */
/* channel of the external LTC1865 ADC. */
/* */
/* Input Parameters: */
/* unsigned char: the ADC channel */
/* */
/* Output Parameters: */
/* unsigned int: the ADC value (range 0 to 65535) */
/* */
/***********************************************************/
uint16_t Read_External_ADC(uint8_t channel)
{
/* Holds the last ADC conversion channel */
static uint8_t previousADCchannel = ADC_CHANNEL_0;
/* If changing channel a dummy read is required as the */
/* two bits of the input word (SDI) assign the MUX */
/* configuration for the next requested conversion. */
if (channel != previousADCchannel)
{
SendCommand(channel);
/* Save the new ADC channel */
previousADCchannel = channel;
}
return SendCommand(channel); /* Return the 16-bit ADC value */
}
uint16_t SendCommand(uint8_t channel)
{
uint16_t adcVal, transmitVal;
/* The LTC1865 conversion cycle begins with the rising edge of CONV */
digitalWrite(SPI_CS, HIGH);
/* Wait for the conversion to complete */
delayMicroseconds(ADC_CONVERSION_TIME);
/* Enable the Serial Data Out to allow the data to be shifted out by taking CONV low */
digitalWrite(SPI_CS, LOW);
/* Send command and read previous selected ADC channel value, whilst */
/* telling the ADC the next conversion is for the new channel */
transmitVal = (0x8000 | (((unsigned int)channel) << 14)); /* Transmit the Mode (Single-ended MUX Mode), */
uint16_t temp = (transmitVal >> 8);
adcVal = SPI.transfer((byte)temp);
adcVal <<= 8;
adcVal |= SPI.transfer((byte)transmitVal);
/* the channel and receive the sixteen bit result */
return (adcVal); /* Return the 16-bit ADC value */
}
void setup() {
Serial.begin(115200);
//Define SPI Chip Select pin
pinMode(SPI_CS, OUTPUT);
digitalWrite(SPI_CS, LOW); /* Deselect the ADC by setting chip select low */
//Initialise SPI interface
//SPI clock speed:10MHz, Data Shift:MSB First, Data Clock Idle: SPI_MODE1
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE1));
/* Perform a dummy read to initialise the ADC conversion channel to ADC_CHANNEL_0 */
Read_External_ADC(ADC_CHANNEL_0);
Serial.println("LTC1865 External ADC Example");
}
void loop() {
Serial.print("Channel 0 = ");
Serial.println(Read_External_ADC(ADC_CHANNEL_0));
delay(500); /* 0.5s arbitrary wait*/
Serial.print("Channel 1 = ");
Serial.println(Read_External_ADC(ADC_CHANNEL_1));
delay(500); /* 0.5s arbitrary wait*/
}
hope that helps...
Thank you for kindly uploading the code. I wrote a code to output the gradient value using that code, but only 'nan value' is output. Could you please take a look at the code and see what the problem is?
The inclinometer sensor I used is SCA100T-D01. The board is Arduino Uno.
#include<SPI.h>
/* The LTC1864 ADC has two input channels */
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 1
/*SPI Pin definitions*/
#define SPI_CS 10 /* Assuming Arduino UNO*/
/* The LTC1864 conversion cycle begins with the rising edge of CONV. */
/* After a period equal to tCONV, the conversion is finished. */
/* The maximum conversion time is 3.2uS, so wait for 4uS */
/* accepts an integer value. */
#define ADC_CONVERSION_TIME 10
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO
#define SPICLOCK 13//Clock
/***********************************************************/
/* */
/* Read_External_ADC / SendCommand */
/* */
/* Function: Read the latest value from the specified */
/* channel of the external LTC1865 ADC. */
/* */
/* Input Parameters: */
/* unsigned char: the ADC channel */
/* */
/* Output Parameters: */
/* unsigned int: the ADC value (range 0 to 65535) */
/* */
/***********************************************************/
uint16_t Read_External_ADC(uint8_t channel)
{
/* Holds the last ADC conversion channel */
static uint8_t previousADCchannel = ADC_CHANNEL_0;
/* If changing channel a dummy read is required as the */
/* two bits of the input word (SDI) assign the MUX */
/* configuration for the next requested conversion. */
if (channel != previousADCchannel)
{
SendCommand(channel);
/* Save the new ADC channel */
previousADCchannel = channel;
}
return SendCommand(channel); /* Return the 16-bit ADC value */
}
uint16_t SendCommand(uint8_t channel)
{
uint16_t adcVal, transmitVal;
/* The LTC1865 conversion cycle begins with the rising edge of CONV */
digitalWrite(SPI_CS, HIGH);
/* Wait for the conversion to complete */
delayMicroseconds(ADC_CONVERSION_TIME);
/* Enable the Serial Data Out to allow the data to be shifted out by taking CONV low */
digitalWrite(SPI_CS, LOW);
/* Send command and read previous selected ADC channel value, whilst */
/* telling the ADC the next conversion is for the new channel */
transmitVal = (0x8000 | (((unsigned int)channel) << 14)); /* Transmit the Mode (Single-ended MUX Mode), */
uint16_t temp = (transmitVal >> 8);
adcVal = SPI.transfer((byte)temp);
adcVal <<= 8;
adcVal |= SPI.transfer((byte)transmitVal);
/* the channel and receive the sixteen bit result */
return (adcVal); /* Return the 16-bit ADC value */
}
float angle(int axisdata)
{
float Angle = asin(((float)axisdata-1024.0)/1638.0);
return Angle;
}
void setup() {
Serial.begin(9600);
//Define SPI Chip Select pin
pinMode(SPI_CS, OUTPUT);
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK, OUTPUT);
digitalWrite(SPI_CS, LOW); /* Deselect the ADC by setting chip select low */
//Initialise SPI interface
//SPI clock speed:10MHz, Data Shift:MSB First, Data Clock Idle: SPI_MODE1
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE1));
/* Perform a dummy read to initialise the ADC conversion channel to ADC_CHANNEL_0 */
Read_External_ADC(ADC_CHANNEL_0);
Serial.println("LTC1865 External ADC Example");
}
void loop() {
int xAxisData = Read_External_ADC(ADC_CHANNEL_0);
float xAngle = angle(xAxisData);
Serial.print("X : ");
Serial.println(xAngle);
//!!!assigns integer to store Y axis value
int yAxisData = Read_External_ADC(ADC_CHANNEL_1);
float yAngle = angle(yAxisData);
Serial.print("Y : ");
Serial.println(yAngle);
Serial.print("\n");
delay(500);
}
I'm confused.... are you using
a. LTC1865AHMS
b. SCA100T-D01
those are not the same chip and likely not use the same commands! so what you got is no surprise to me!
The LTC1865AHMS receives the analog x and y output values from the SCA100T-D01 sensor through two channels and receives the converted digital value through the Arduino to output the slope value.
Ok. its clearer now. thank you.
Just to confirm, did you try the code proposed in reply #4?
Did you get any 'sensible' values then?
ie the readings with that code, assuming it is working correctly, should change as you tilt the sensor around.
Yes. Before applying the code for calculating the slope value, first, I checked the value obtained by compiling only the code of #4. It was confirmed that the value changes whenever the sensor is tilted.
OK, then assuming the values a good, this might be the issue then:
if I'm not mistaken it return NaN if asin argument is not in the range [-1, +1].
The LTC1865 is a 16-bit A/D converter i.e the of axisdata range would be 0 - 65,535. So it's very possible that the above formula will have argument outside of the range [-1, +1].
I would suggest you try print out (float)axisdata and ((float)axisdata-1024.0)/1638.0) to see if that is the case.
hope that helps...
As you said, a value out of the range [-1,+1] appears. If so, I don't think I can use the formula to find the slope shown in the datasheet of SCA100T-D01. How can I make it output the correct slope value??
The number below is the result of applying only the formula ((float)axisdata-1024.0)/1638.0) without asin.
X : 7.37
Y : 8.30
X : 7.37
Y : 8.40
X : 7.50
Y : 8.21
X : 7.36
Y : 8.37
do you know what those constants are? probably they will need some conversion factor to account for the use of the LTC1865 ADC and to be able to get that you need to understand what those constants mean.
hope that helps...

You can see the numbers in the photos posted together. (Pictures are the formula for calculating the slope value from the datasheet of SCA100T-D01 and the symbols used in the formula. You can think of RDAX and RDAY as x and y values read from the sensor, respectively.)
I've been looking at the datasheet of the sensor and this formula IMHO is for the DIGITAL output. for the analog output (which is what I believe is what you are using the ADC to read) the formula is this:
So determine the X and Y 'Offset' by reading the corresponding ADC value for a 0deg inclination.
As for the Sensitivity, assuming the ADC ref is 5V, then the ADC value for a sensitivity of 4V/g would be
(4*65536)/5 = 52,429
hope that helps....
I'm sorry, but I don't understand the (465536)/5 = 52,429 expression you wrote at all... And I also don't understand the definition of offset and sensitivity described in the datasheet. Could you please explain it in an easy to understand way?
[/quote]
I have not experience with this sensor so it would be difficult for me to do so.
I have only quoted what IMHO should be the formula to use from the datasheet and how I would adjust it to account for the ADC you are using to read the analog sensor output.
as explained in reply #14
-
you should be able to determine the 'Offset' value to use by placing the sensor at 0deg inclination and record the corresponding ADC output readings for X and Y (using the code in reply #4 should allow you to do that
).
If you cannot check for the ACTUAL Offset value, it does say that the nominal value is 2.5V (the 16bit ADC value for this would be 32,768). I guess you can always take that value. -
the datasheet specifies that for your sensor, the sensitivity value to use is 4V/g.
Since you are using a 16bit ADC the ADC value that equates to 4V is 52,429
16bit -> 2^16 = 65536
assuming 5V ADC ref, then 5V = 65536.
therefore
4V = (4*65536)/5 = 52,429
2.5V = 32,768
this would be the conversion I would do for the angle calculation since Vout here would be the 16bit ADC output
hopethat helps...
I understood that 52,429 is the value corresponding to the sensitivity in the above expression, is that correct??
correct
I understood that the offset is the output value of ch0 and ch1 when it is 0 degrees, is this correct?
correct! ![]()
