Each channel has 8 bits input control register and 24 bits output data register. (Shutdown, RST, etc..)
In total, sampling instant control register will be 32 bits and data register will be 96 bits.
My questions are:
How to send 32 bits control register through SPI? As SPI.transfer can only transfer 8 bits, right? Should I do SPI.transfer four times?
What's a proper way to select the three bytes from total 12 bytes?
What I am having with my code is 2.4999 which is not the input value for my channel 0.
Below is how I am doing currently for this device: the relative part
void setup()
{
byte command1 = B00100000;
byte command2 = B10000000;
digitalWrite(ADCCS, LOW);
SPI.transfer(command1);
SPI.transfer(command2);
SPI.transfer(command2);
SPI.transfer(command2);
digitalWrite(ADCCS, HIGH);
}
long int ltw = 0;
byte b0;
void loop()
{
if (digitalRead(MISO) == LOW) {
ltw=0;
b0 = SPI_read(); // read 3 bytes for channel 0,
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
b0 = SPI_read(); //reads the rest three three bytes but not going to use it.
b0 = SPI_read();
b0 = SPI_read();
b0 = SPI_read();
b0 = SPI_read();
b0 = SPI_read();
b0 = SPI_read();
b0 = SPI_read();
b0 = SPI_read();
delayMicroseconds(1);
digitalWrite(ADCCS, HIGH); //
delay(2);
volt = ltw * v_ref / 16777216; // max scale
}
}
Below is my current code; the output are basically 1 for all the bits for the four channels: 16777215 as it is 24 bits. But once in ten, the channel 0 will output another output which is 196608.
Does anyone know what the problem is based on this?
Is it the code problem or pin connections?
digitalWrite(ADCCS, LOW);
SPI.transfer(1100000); //configuration Address
SPI.transfer(B00110000);
digitalWrite(ADCCS, HIGH);
digitalWrite(ADCCS, LOW);
SPI.transfer(1110000); //Read Data Register address
b0=SPI.transfer(0); // Get the fourth channel's output as the device is LSB
ltw3 |= b0;
b0=SPI.transfer(0);
b0<<=8;
ltw3 |= b0;
b0=SPI.transfer(0);
b0<<=16;
ltw3 |= b0;
b0=SPI.transfer(0); //Get the third channel's output
ltw2 |= b0;
b0=SPI.transfer(0);
b0<<=8;
ltw2 |= b0;
b0=SPI.transfer(0);
b0<<=16;
ltw2 |= b0;
b0=SPI.transfer(0); //Get the second channel's output
ltw1 |= b0;
b0=SPI.transfer(0);
b0<<=8;
ltw1 |= b0;
b0=SPI.transfer(0);
b0<<=16;
ltw1 |= b0;
b0=SPI.transfer(0); //Get the first channel's output
ltw0 |= b0;
b0=SPI.transfer(0);
b0<<=8;
ltw0 |= b0;
b0=SPI.transfer(0);
b0<<=16;
ltw0 |= b0;
digitalWrite(ADCCS, HIGH);
Thank you so much for your reply. I didn't notice that, yes, I meant binary.
I have just changed both of the addresses into B1100000 and tested. Unfortunately, it's still not working.
It outputs 1 for 96 bits.
The first channel is outputting proper values now, but the rest channels can only provide proper data once after press reset button. For the rest of time, they are not output correct values.
ydy023:
The first channel is outputting proper values now, but the rest channels can only provide proper data once after press reset button. For the rest of time, they are not output correct values.
You must have changed something to get it to work that well. If you share your code maybe someone can figure out what is wrong with the other three channels.
Saying "they are not output correct values" doesn't help with determining the problem. If you say what incorrect values you get, what correct value you expected, and why you expect that value, it will help us figure out what is wrong. This is particularly important when you are using hardware that few other people have handy.
Thank you very much for your reply and advise how should I clarify my problem.
What I have changed with the code is SPI.transfer(B11110000), it's a 8 bits address and the MSB bit standing for read/write was missing. And I also add B in front. And that's all I changed, the rest stay the same.
So I having four channels measuring voltage output from four sensors, the initial reading of each sensor should be around 0.2V. As you can see from below, I have four reading outputs which stands for channel 0, 1, 2 and 3. Although channel 0's output isn't perfect, but it is proper. The rest three channels only provide relative readings for the first line. From the second line, channel 0 is still working, but the rest three's output are messy.
If I totally get the output format or pin connection wrong, I would expect channel 1,2 and 3 give messy output all the time.
That's where confused me.
Thank you? I cannot believe I forgot to clear ltw1,2,3 before new action. I didn't notice this!
They are all working now. Thank you so much for your help.
Here is my final code using now.
Although all four channels are working now, but they have 0.04 V variation which is around 152520 out of 16777216 variation going on.
Regardless of sensors, even placing both AIN- and AIN+ with ground, the noise still existing. I have use decoupling capacitors and also a 2.5 voltage regulator as signal reference.
I know this is more about the entire circuit and device problem, but if anyone have any idea about what might cause this would be appreciate.
Here is the datasheet for this device ADC max11040k. http://datasheets.maximintegrated.com/en/ds/MAX11040K-MAX11060.pdf
/*
Pressure sensor system
This system shows how to log data from a analog sensor and log
data into an SD card using the SD library.Also use an external
24 bits ADC
created 20 June 2013
by Danny
*/
#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>
const int SDCS = 4;
const int ADCCS = 10;
double pressureValue0 = 0;
double pressureValue1 = 0;
double pressureValue2 = 0;
double pressureValue3 = 0;
const int fs=3;
LiquidCrystal lcd(12, 11, 6, 5, 3, 2);
byte command1 = B00110100;
byte command2 = B10000000;
void setup()
{
pinMode(ADCCS, OUTPUT);
pinMode(SDCS, OUTPUT);
digitalWrite(ADCCS, HIGH);
digitalWrite(SDCS, HIGH);
SPI.begin();
lcd.begin(16, 2);
SPI.setBitOrder(MSBFIRST);
digitalWrite(ADCCS, LOW);
SPI.transfer(B01100000); //address
SPI.transfer(command1);
digitalWrite(ADCCS, HIGH);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
if (!SD.begin(SDCS)) {
Serial.println("Card failed, or not present");
return;
}
Serial.println("card initialized.");
}
float volt0;
float volt1;
float volt2;
float volt3;
float v_ref=2.48; // Reference Voltage, 5.0 Volt for LT1021 or 3.0 for LP2950-3
long int ltw0 = 0; // ADC Data ling int
long int ltw1 = 0;
long int ltw2 = 0;
long int ltw3 = 0;
int cnt; // counter
byte b0; //
char st1[20]; // float voltage text
void loop()
{
lcd.print("0:");
lcd.setCursor(9, 0);
lcd.print("1:");
lcd.setCursor(0, 1);
lcd.print("2:");
lcd.setCursor(9, 1);
lcd.print("3:");
digitalWrite(ADCCS, LOW);
if (digitalRead(MISO) == LOW) { // ADC Converter ready ?
ltw0=0;
ltw1=0;
ltw2=0;
ltw3=0;
SPI.transfer(B11110000);
b0=SPI.transfer(0);
ltw0 |= b0;
ltw0 <<= 8;
b0=SPI.transfer(0);
ltw0 |= b0;
ltw0 <<= 8;
b0=SPI.transfer(0);
ltw0 |= b0;
b0=SPI.transfer(0);
ltw1 |= b0;
ltw1 <<= 8;
b0=SPI.transfer(0);
ltw1 |= b0;
ltw1 <<= 8;
b0=SPI.transfer(0);
ltw1 |= b0;
b0=SPI.transfer(0);
ltw2 |= b0;
ltw2 <<= 8;
b0=SPI.transfer(0);
ltw2 |= b0;
ltw2 <<= 8;
b0=SPI.transfer(0);
ltw2 |= b0;
b0=SPI.transfer(0);
ltw3 |= b0;
ltw3 <<= 8;
b0=SPI.transfer(0);
ltw3 |= b0;
ltw3 <<= 8;
b0=SPI.transfer(0);
ltw3 |= b0;
delayMicroseconds(1);
digitalWrite(ADCCS, HIGH);
delayMicroseconds(1);
volt0 = ltw0 * v_ref *0.88*2/ 16777216;
volt1 = ltw1 * v_ref*0.88*2 / 16777216;
volt2 = ltw2 * v_ref*0.88*2 / 16777216;
volt3 = ltw3 * v_ref*0.88*2/ 16777216;
pressureValue0=(volt0-0.205)/0.01845;
pressureValue1=(volt1-0.205)/0.01845;
pressureValue2=(volt2-0.205)/0.01845;
pressureValue3=(volt3-0.205)/0.01845;
}
digitalWrite(ADCCS, HIGH);
digitalWrite(SDCS, LOW);
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(pressureValue0);
lcd.setCursor(2, 0);
lcd.print(pressureValue0);
lcd.setCursor(11, 0);
lcd.print(pressureValue1);
lcd.setCursor(2, 1);
lcd.print(pressureValue2);
lcd.setCursor(11, 1);
lcd.print(pressureValue3);
// print to the serial port too:
Serial.print(cnt++);
Serial.print("; ");
Serial.print(volt0,6); // print voltage as floating number
Serial.print("; ");
Serial.print(volt1,6);
Serial.print("; ");
Serial.print(volt2,6);
Serial.print("; ");
Serial.print(volt3,6);
Serial.print("; ");
// Serial.print(ltw0);
// Serial.print("; ");
//Serial.print(pressureValue);
Serial.println(" ");
dataFile.close();
delay(1000/fs);
lcd.clear();
}
else {
Serial.println("error opening datalog.txt");
}
digitalWrite(SDCS, HIGH);
}
byte SPI_read()
{
return SPI.transfer(0x00);
}