The code doesn't seem working for Arduino Due, following errors shown. And I am also confused about those SCK, SDO and CS connections with Arduino Due board.Which pins should I connect those into, and how to clarify them in the program. Appreciate any little help.
ADC_Uno_ino.ino: In function 'void setup()':
ADC_Uno_ino:26: error: 'PORTB' was not declared in this scope
ADC_Uno_ino:26: error: '_SFR_BYTE' was not declared in this scope
ADC_Uno_ino:26: error: '_BV' was not declared in this scope
ADC_Uno_ino:27: error: 'DDRB' was not declared in this scope
ADC_Uno_ino:34: error: 'SPCR' was not declared in this scope
ADC_Uno_ino:34: error: 'MSTR' was not declared in this scope
ADC_Uno_ino:35: error: 'SPR0' was not declared in this scope
ADC_Uno_ino:36: error: 'SPR1' was not declared in this scope
ADC_Uno_ino:37: error: 'SPE' was not declared in this scope
ADC_Uno_ino.ino: In function 'void loop()':
ADC_Uno_ino:54: error: 'PORTB' was not declared in this scope
ADC_Uno_ino:54: error: '_SFR_BYTE' was not declared in this scope
ADC_Uno_ino:54: error: '_BV' was not declared in this scope
ADC_Uno_ino:56: error: 'PINB' was not declared in this scope
ADC_Uno_ino:56: error: 'PORTB4' was not declared in this scope
ADC_Uno_ino.ino: In function 'byte SPI_read()':
ADC_Uno_ino:97: error: 'SPDR' was not declared in this scope
ADC_Uno_ino:98: error: 'SPSR' was not declared in this scope
ADC_Uno_ino:98: error: 'SPIF' was not declared in this scope
That sketch is written for an ATmega based Arduino. On a Due you cannot use the direct port manipulation commands of the ATmega platform, so you have to rewrite the sketch to use digitalWrite() instead of the port manipulations and the SPI library instead of the register manipulations in the sketch.
Appreciate your reply.
So, to use digitalWirte to set low or high for SCK and use digitalRead to read data from SDO? I am very new to Arduino, this gona be difficult for me to rewrite without similar examples.
And also I am not sure about how to connect those pins on ADC to SPI on Due since usually they are MISO, MOSI, SCK when using SPI. Do you have any thoughts on that?
It works! Thank you so much!
I only added one line to clarify which pin SS connect to.
const int SS = 4;
It is reading out the Vout from my pressure sensor now!
However, since both my SD card module (to log data) and this ADC need to use SPI on Due. I only know one SPI which is located in the middle of the board. Is ICSP another SPI or is there any solution so that I can use both these devices?
I realise that Due could communicate with more than one device through SPI. Each device could have its own SS which are pin 4, 10 and 52 for Due. But my question is I will need both these devices work (ADC do the converting and SD storage do the logging data) for the most of time. When I enable both of them, they will share SPI. Will it be alright?
Below is my code, I tried to enable both ADC and SD card module but couldn't get it work.
When they are separate, they both work fine.
Could anyone check it for me to see what did I write wrong or it's not the right way to use SPI for two device?
/*
#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>
const int SDCS = 4;
const int ADCCS = 10;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
pinMode(ADCCS, OUTPUT);
digitalWrite(ADCCS, HIGH);
SPI.begin();
lcd.begin(16, 2);
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(SDCS)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
float volt;
float v_ref=5.0; // Reference Voltage, 5.0 Volt for LT1021 or 3.0 for LP2950-3
long int ltw = 0; // ADC Data ling int
int cnt; // counter
byte b0; //
byte sig; // sign bit flag
char st1[20]; // float voltage text
void loop()
{
digitalWrite(ADCCS, LOW);
delayMicroseconds(1);
if (digitalRead(MISO) == LOW) { // ADC Converter ready ?
ltw=0;
sig=0;
b0 = SPI_read(); // read 4 bytes adc raw data with SPI
if ((b0 & 0x20) ==0) sig=1; // is input negative ?
b0 &=0x1F; // discard bit 25..31
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
delayMicroseconds(1);
digitalWrite(ADCCS, HIGH); // LTC2400 CS HIGH
delay(200);
if (sig) ltw |= 0xf0000000; // if input negative insert sign bit
ltw=ltw/16; // scale result down , last 4 bits have no information
volt = ltw * v_ref / 16777216; // max scale
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(volt);
lcd.print(volt);
// print to the serial port too:
Serial.print(cnt++);
Serial.print("; ");
Serial.print(volt,6);
dataFile.close();
lcd.clear();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
digitalWrite(ADCCS, HIGH); // LTC2400 CS hi
delay(20);
}
byte SPI_read()
{
return SPI.transfer(0x00);
}
The output is error opening datalog.txt, I am not quite sure about the reason.
But I was trying to set both low for the most of time. SD is low all the time, ADC is low when it's doing work.
I will need them both low to work at the same time. Is that possible?
But I was trying to set both low for the most of time. SD is low all the time, ADC is low when it's doing work.
I will need them both low to work at the same time. Is that possible?
A chip select signal is LOW active which means that the chip is activated on LOW and deactivated on HIGH. So you have to try to let the chip select lines be HIGH as often as possible.
Only one of them must be low at any given time because else you're sending commands to multiple devices which may even result in short circuits on the MISO line.
Thank you very much for your reply. It is working now.
I enable them alternatively within a loop. And it worked!
Below is my code, maybe someone else will be interested in someday.
/*
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 bit 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 pressureValue = 0;
LiquidCrystal lcd(12, 11, 6, 5, 3, 2);
void setup()
{
pinMode(ADCCS, OUTPUT);
pinMode(SDCS, OUTPUT);
digitalWrite(ADCCS, HIGH);
digitalWrite(SDCS, HIGH);
SPI.begin();
lcd.begin(16, 2);
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(SDCS)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
float volt;
float v_ref=5.0; // Reference Voltage, 5.0 Volt for LT1021 or 3.0 for LP2950-3
long int ltw = 0; // ADC Data ling int
int cnt; // counter
byte b0; //
byte sig; // sign bit flag
char st1[20]; // float voltage text
void loop()
{
digitalWrite(ADCCS, LOW);
delayMicroseconds(1);
lcd.print("Pressure Diff:");
lcd.setCursor(10, 1);
lcd.print("kPa");
lcd.setCursor(0, 1);
if (digitalRead(MISO) == LOW) { // ADC Converter ready ?
ltw=0;
sig=0;
b0 = SPI_read(); // read 4 bytes adc raw data with SPI
if ((b0 & 0x20) ==0) sig=1; // is input negative ?
b0 &=0x1F; // discard bit 25..31
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
delayMicroseconds(1);
digitalWrite(ADCCS, HIGH); // LTC2400 CS HIGH
delay(2);
if (sig) ltw |= 0xf0000000; // if input negative insert sign bit
ltw=ltw/16; // scale result down , last 4 bits have no information
volt = ltw * v_ref / 16777216; // max scale
pressureValue=(volt-0.2)/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(pressureValue);
lcd.print(pressureValue);
// print to the serial port too:
Serial.print(cnt++);
Serial.print("; ");
Serial.print(volt,6); // print voltage as floating number
Serial.print("; ");
Serial.print(pressureValue);
Serial.println(" ");
dataFile.close();
delay(200);
lcd.clear();
}
else {
Serial.println("error opening datalog.txt");
}
digitalWrite(SDCS, HIGH);
}
byte SPI_read()
{
return SPI.transfer(0x00);
}
Nice to see other work with the LTC2400. It is in my opinion a very good and cheap simple to use precision ADC.
And there are some resources to use. If anyone is interested, I have a thread with some links to things done before
about making a precision DVM of an LTC2400 and an Arduino in another forum.
It can be found by searching "Easy DIY 5.5 Digit DVM + Volt Ref./Cal. (LTC2400+LTC6655 / SPI uC / Arduino)"
from any web search engine.