Data gets from Arduino to the PC so slowly

Hi!

I have an LTC1859 IC, which is an AD converter circuit at 16 bit and with 120kS/sec. It communicates with the Arduino using SPI.
Everything works -almost - perfectly: the data gets to the Arduino, and then to the PC. The only problem is: I am unable to get higher transmission speed than 4000 data/sec (that means cca 70 kbit/s, becouse of 16 data bit and the control bits on serial port). The evidence is that, when I drive the ADC with a 4kHz square signal, the values on the serial terminal changing very slow (a lot of the level change is missing). If I decrease the frequency to 3,5 kHz the data begin to change in the right way.
The sketch is very simple (Baud rate, config_data is set up in the setup section):

void loop ()
{
delayMicroseconds(1);
LTC1859_read(config_data1, config_data2, &adc_code);
Serial.write(adc_code);
}

The baud rate of COM port is 230400.
I was able to realise cca. 50,000 sampling per secundum, if I did not use serial port (just counting the samples without to send them to the PC).
So I think that the communication is the bottleneck. Am I right? What should I do? Is there anybody who could make faster communication between Arduino and PC than I did? (I am shure about that, but can't find anything similar project)

Thanks, if you can help me!

You can probably push the baud rate up to 1,000,000

How many bytes of data per second are you trying to send?

What is the 1usec delay for?

You may find the throughput is better if you take several readings (up to 64 bytes) and send them all at once.

The new version 1.5.7 of the IDE seems to have much a improved USB transmission system. If you really want high speed use it with a Leonardo because the Leonardo doesn't bother with the baud rate.

...R

Hi Robin!
Thanks for the reply!

  • I'll try the higher baud rate.

  • The goal is to send at least 10kByte/s (5000 word), but I would be happy if all the 50000 data could be send.

  • I read somewhere that some delay should be used due to AD converter.

  • I tried to fill an array with 10 data, and then send like this: seral.write(buffer,buffersize), but the compiler says:

error: no matching function for call to 'HardwareSerial::write(uint16_t [10], int)

buffer is declared as an array with 10 element of uint16_t

I'll install the new Arduino, and give a try.

Best regards!

katonacs:

  • The goal is to send at least 10kByte/s (5000 word), but I would be happy if all the 50000 data could be send.

At 230400 baud the data rate should be around 23k byte/sec - say 20k to allow for overhead. From my own tests these rates are easily achieved with IDE 1.5.6 and 1.0.5

  • I read somewhere that some delay should be used due to AD converter.

That sounds as useful as needing some sugar in your coffee

error: no matching function for call to 'HardwareSerial::write(uint16_t [10], int)

buffer is declared as an array with 10 element of uint16_t

Serial.write only woks with bytes or uint8_t
If the data from your ADC provide 16bit values (or values > 8 bits that need to be treated as INTs) you need to separate them into their high and low bytes so you have an array of 20 (rather than 10) of them.

The software at the receiving end won't know the difference PROVIDED you send the correct byte of each pair first.

One convenient way to treat an array of INTs as an array of BYTEs is through the use of a Union. A Union is a C/C++ concept in which the same piece of memory is treated as two different variables.

...R

  • downloaded and installed the 1.0.5.
  • deleted the delay, but nothing has changed
  • modified the code in the loop section just for testing like this:
    for (int i=0;i<10;i++)
      {
      myarray[2*i] = 48;  //highbyte
      myarray[2*i+1] = 48; //lowbyte
    }
    Serial.write(myarray,20);

I thought on the serial terminal I will see a lot of '1' ( Char(48) ). But instead: '...XLLL,&&&...' (kind of garbage)
What did I wrong?

What did I wrong?

You posted only a snippet of your code.

katonacs:

  • downloaded and installed the 1.0.5.

What has this got to do with anything?

I thought on the serial terminal I will see a lot of '1' ( Char(48) ). But instead: '...XLLL,&&&...' (kind of garbage)
What did I wrong?

Apart from the fact that 48 is the code for 0 - it workes fine on my Uno - I get 20 0s.

How have you declared myarray[] - as @PaulS says, don't post snippets.

...R

  • Sorry about the Chr(48) :slight_smile:

  • I tried with the baud rate 230400, and the code worked well

  • but the transmission speed doesnot get better with the writebuffer method :frowning:

katonacs:

  • but the transmission speed doesnot get better with the writebuffer method :frowning:

What throughput are you getting at 230400 baud?

Post the code you are using to measure that so that I can try to replicate your results.

...R

you might find this interesting - Experiment - split up analog read in 3 steps - Libraries - Arduino Forum -

still the bottleneck is the ADC is the ADC convertor.

If you can live with 8bit samples you should know you can configure the ADC to do this.
increasing its speed .

check this excellent blog - http://www.microsmart.co.za/technical/2014/03/01/advanced-arduino-adc/ -
how to get up to 50K samples.

exporting them over Serial needs a baud rate of 1000000 or so..

Here is the code, but...
I made a last check and realised that I am the bottleneck :disappointed_relieved: : when I capture the serail data the speed became 23 kByte/sec.

So I have to find/write a program for the PC which can handle the huge amount of serial data.

#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "LTC1859.h"
#include <SPI.h>
#include <Wire.h>

// Global variables

uint8_t adc_tomb[200];  
uint16_t adc_code;  

// Constants
const uint8_t COMMAND_SINGLE_ENDED[8] = {LTC1859_CH0, LTC1859_CH1, LTC1859_CH2, LTC1859_CH3,
    LTC1859_CH4, LTC1859_CH5, LTC1859_CH6, LTC1859_CH7}; //!< Builds the command for single-ended mode, input with respect to GND

//! Initialize Linduino
void setup()
{
  byte Cfg;
  uint16_t adc_code;  
  quikeval_I2C_init();           // Configure the EEPROM I2C port for 100kHz
  quikeval_SPI_init();           // Configure the spi port for 4MHz SCK
  quikeval_SPI_connect();        // Connect SPI to main data port
  Serial.begin(230400);          // Initialize the serial port to the PC
  adc_command = LTC1859_build_command(COMMAND_SINGLE_ENDED[0], uni_bipolar, range_low_high);
  LTC1859_read(LTC1859_CS, COMMAND_SINGLE_ENDED[0], &adc_code); // Wakes up ADC if it was in sleep mode
}

void loop()
{
    for (int i=0;i<100;i++)
      {
      LTC1859_read(LTC1859_CS, 12, &adc_code);
      adc_tomb[2*i] = ((adc_code>>8)&0xFF);
      adc_tomb[2*i+1] = (adc_code & 0xFF);      
    }
    Serial.write(adc_tomb,200);      
}

robtillaart:
still the bottleneck is the ADC is the ADC convertor.

Thanks, but I use different ADC than the built-in. I have a free sample ADC made by Linear Technology: LTC1859. It is a 8 channel 16 bit delta-sigma ADC, and it's conversion speed is 180,000 sample/sec.

Thank you very much for the links, because I want to use in an other project the ADC-s of the AVR.

katonacs:
Thanks, but I use different ADC than the built-in. I have a free sample ADC made by Linear Technology: LTC1859. It is a 8 channel 16 bit delta-sigma ADC, and it's conversion speed is 180,000 sample/sec.

Thank you very much for the links, because I want to use in an other project the ADC-s of the AVR.

Can you have a link to its datasheet & library?

katonacs:
I made a last check and realised that I am the bottleneck :disappointed_relieved: : when I capture the serail data the speed became 23 kByte/sec.

Sorry, but I have no idea what you are trying to say with this sentence - I'm not even going to guess because there seem to be several possibilities.

You have so many specialized bits in your code that I can't test it.

...R

I captured the serial data into a file on the PC with the Realterm program. During the 10 seconds of capturing 230,000 byte got into the file, so the transmission speed is 23 kB/s, and that is enough for me. So it seems I was unobservant.

I made a program that displays the serial data on a chart. It looks like this program unable to handle the data in the right speed. But this is not a problem with Arduino.

Thanks very much for your kind help, Robin2!

Robtillaart!

Here is the link:

I was wrong: the sampling speed is "only" 100 kS/s, but this is also quite high, isn't it?