0

I am trying to develop an Arduino sketch for ADS8320 ADC IC, which is 3-wire SPI. I need a 2.4MHz serial clock for the SPI interface. I tried the code below, but I don't know how to generate clock pulses at 2.4MHz clock speed.

#define CLK 22
#define DBIT 24 // so
#define CS 26

#include <SoftwareSerial.h>

int v = 0;
float Ctemp, Ftemp;

void setup()   {
  Serial.begin(9600);
  pinMode(CLK, OUTPUT);
  pinMode(DBIT, INPUT);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  digitalWrite(CLK, LOW);
}

void loop()   {
  v = spiRead();
  if (v == -1)   {
    Serial.print("No sensor \n");
  } else   {
    Serial.println(Ftemp);
  }
  delay(100);
}

int spiRead() {
  int value = 0;
  digitalWrite(CS, LOW);
  delay(2);
  digitalWrite(CS, HIGH);
  delay(220);
  /* Bring CS pin low to allow us to read the data from
    the conversion process */
  digitalWrite(CS, LOW);
  /* 1st 5 clock cycles  */
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  /*
    Read bits 16-0 from ads8320 for the adc. Loop for each bit reading
    the value and storing the final value in 'adc'
  */
  for (int i = 16; i >= 0; i--) {
    digitalWrite(CLK, HIGH);
    value += digitalRead(DBIT) << i;
    digitalWrite(CLK, LOW);
  }
  // check bit D2 if HIGH no sensor
  if ((value & 0x04) == 0x04) return -1;
  // shift right three places
  return value >> 3;
}

' i have added the code i tried with arduino spi library still i don't get any result

 // inslude the SPI library:
 #include <SPI.h>


 // set pin 10 as the slave select for the digital pot:
 const int slaveSelectPin = 10;

 void setup() {
 // set the slaveSelectPin as an output:
 pinMode(slaveSelectPin, OUTPUT);
 // initialize SPI:
 SPI.beginTransaction(SPISettings(2400000, MSBFIRST, SPI_MODE0))

 void loop() {
 while(1){
 spiread(slaveSelectPin);
 }
 }

 void spiread(int slaveSelectPin) {
 // take the SS pin low to select the chip:
 digitalWrite(slaveSelectPin, LOW);

 receivedVal = SPI.transfer(val);
// take the SS pin high to de-select the chip:
digitalWrite(slaveSelectPin, HIGH);
}
  • On an Arduino Mega and using the Arduino core the highest clock frequency by toggling a digital pin is approx. 70 kHz. The Arduino core is very slow. See GPIO library benchmark github.com/mikaelpatel/Arduino-GPIO/blob/master/examples/…. It is possible to generate up to 4 Mhz clock but you need core or library that is optimized for performance. Also the SPI clock is scaled 8, 4, 2, ..., etc MHz. 2.4 Mhz would force you to select 2 Mhz. – Mikael Patel Oct 1 '17 at 20:33
1

It's hardly possible to generate a stable and exact frequency with your method.
Imagine you have an interrupt routine interrupting your spiRead() or any function called inside: Your clock will be extended by the ISR runtime.
Apart from this:

  • I'm not sure if your LOW phase is long enough (there's no delay between setting CLK from LOW to HIGH. If 2.4 MHz is the max frequency for the chip, it should be at least 208ns.
    However:
    If you are sure that the runtime of digitalWrite is always longer than 208ns, you could remove your delay() at all. The resulting frequency is the maximum possible you can achieve with your method.
  • The smallest delay() is 1ms, which leads to a maximum of something < 1 kHz (or even 0.5kHz for a 50:50 signal).
    You should use delayMicroseconds() to get at least 500kHz.

But what I'm really wondering:
Why are you implementing bit banging instead of simply using the SPI library?

| improve this answer | |
  • i did not find 3 wire spi example for sensor interfacing. how to use arduino spi library here. can you let me know basic functions for 3 wire spi? which sets 2MHz clock at least – vassidefuk Jun 1 '17 at 10:27
  • @vassidefuk: For 3 wire SPI you could just leave MOSI unconnected. For the functions refer to the library documentation. What maybe is not so clear there: function "transfer" is byte oriented. As your sensor needs at least 22 bit for converting and sending one value, you would have to call "transfer" three times (24 bit; doesn't hurt) within CS = LOW – mic Jun 1 '17 at 11:34
  • i have put another question can you have a look and tell whats is wrong with the code? [arduino.stackexchange.com/questions/39047/… – vassidefuk Jun 1 '17 at 13:38
1

The Mega 2560 clock rate is 16 MHz. Your target SPI clock rate is 2.4 MHz. That leaves you with 16/2.4 = 6,67 clock cycles per SPI clock cycle, which means you have an available processing clearly insufficient for the task you intend. Your program will choke and will be unable to meet the hard time deadlines required. It will not work.

Instead, you should use another board with higher processing power, a slower SPI clock rate or a HW solution (instead of SW) for the SPI clock.

| improve this answer | |
0

The ADS8320 has to have a DCLOCK frequency of between 0.024MHz and 2.4MHz. Using primitive bit-banging with millisecond granularity delays is not going to get anywhere near even the lower end of that range (500Hz is all you could possibly get with a 1ms delay between each clock transition, also you're generating a pulse wave, not a square wave - nasty).

Even using smaller microsecond delays it's not going to give you good results.

Instead you should be using the hardware SPI port which generates a stable clock signal for defining the acquisition timing.

However you cannot get a 2.4MHz SPI clock on the Arduino. But, do you need a 2.4MHz SPI clock? That's the absolute top end of the sampling frequency. You can go much slower - all the way down to 0.024MHz (24kHz) and still be sampling.

On the Arduino SPI runs at a division of the system clock frequency. That is, 1/2, 1/4, 1/8, etc. So with a 16MHz system clock you can run SPI at 1/8 that speed and get a 2MHz clock.

You will also need to do a certain amount of bit shifting and unpacking to get the 16 bit data from the 24-bit stream (more bits than you have now) since SPI can only work in 8 bit chunks.

Minimum 22 clock cycles required for 16-bit conversion. Shown are 24 clock cycles. If CS remains LOW at the end of conversion, a new datastream with LSB-first is shifted out again.

-- Datasheet: Figure 29. ADS8320 Basic Timing Diagrams

So you can just ignore what you get in the last two bits of a 24-bit stream.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.