Go Down

Topic: NilRTOS - A Fast Tiny Preemptive RTOS (Read 17 times) previous topic - next topic

pito

#45
Feb 01, 2013, 08:38 pm Last Edit: Feb 01, 2013, 09:06 pm by pito Reason: 1
With the latest:
6ADC channels, 1000usec period:
Code: [Select]
Done!
Max Write Latency: 47624 usec
Unused Stack: 53 5354
FIFO record count: 833
Minimum free count: 724

Is it faster or am I doing something wrong? :)
Yea, I did - almost all ADC data were "0" so the print to file was fast enough..

fat16lib

#46
Feb 01, 2013, 09:44 pm Last Edit: Feb 01, 2013, 09:53 pm by fat16lib Reason: 1
pito,

Here is a simple Arduino sketch that logs ADCs as fast as possible with no regard for overruns.
Code: [Select]

//Dummy Arduino Logger
#include <SdFat.h>
SdFat sd;

SdFile file;

const uint16_t NREC = 4000;
const uint8_t NADC = 2;
const uint8_t sdChipSelect = SS;
//------------------------------------------------------------------------------
void setup() {

 Serial.begin(9600);
 Serial.println(F("type any character to begin"));
 while (Serial.read() < 0);
 
 // Initialize SD and create or open and truncate the data file.
 if (!sd.begin(sdChipSelect)
   || !file.open("DATA.CSV", O_CREAT | O_WRITE | O_TRUNC)) {
   Serial.println(F("SD problem"));
   sd.errorHalt();
 }

 uint32_t t = micros();
 
 for (uint16_t r = 0; r < NREC; r++) {
   for (int i = 0; i < NADC; i++) {
     file.print(analogRead(i));
     file.print(',');
   }
   // Fake overrun field.
   file.println(0);
 }
 t = micros() - t;
 file.close();
 Serial.print("NADC: ");
 Serial.println(NADC);
 Serial.print("Average interval: ");
 Serial.print(t/NREC);
 Serial.println(" usec");

}
void loop() {}

Here is the output for two ADC channels.
Quote

type any character to begin
NADC: 2
Average interval: 1219 usec

It ignores overruns but can't log two ADC channels at 1024 usec per record.  Of course the rate is dependent on the ADC values and I tied channel zero to 5V.

With nilSdLogger and four channels at 1000 usec:
Quote

type any character to begin
type any character to end
Done!
Max Write Latency: 60940 usec
Unused Stack: 53 108
FIFO record count: 118
Minimum free count: 56

fat16lib

pito,

I can log the six Uno analog pins at 1000 Hz.  I wrote a printHexField() function that runs much faster than the decimal version.

You can't go faster than this because of the ADC conversion time.  Also the amount of buffering on Uno is marginal for six ADCs.

I may try a faster ADC clock on a Mega.

Here is the finish message:
Quote

Done!
Max Write Latency: 47748 usec
Unused Stack: 53 110
FIFO record count: 79
Minimum free count: 30


Here is the Hex data file:
Quote

PERIOD_USEC,1000
ADC0,ADC1,ADC2,ADC3,ADC4,ADC5,Overruns
3FF,2DA,238,208,3FF,3FF,0
3FF,30E,2AC,267,3FF,3FF,0
3FF,31B,2E6,2AB,3FF,3FF,0
3FF,32F,30D,2DE,3FF,3FF,0
3FF,369,342,314,3FF,3FF,0
3FF,3A6,37C,34B,3FE,3FF,0
3FF,3D6,3B1,381,3FF,3FF,0
3FF,3FF,3F0,3BB,3FF,3FF,0
3FF,3FF,3FF,3E0,3FF,3FF,0
3FF,3FF,3FF,3F3,3FF,3FF,0
3FF,3FF,3FF,3FC,3FF,3FF,0
3FF,3FF,3FF,3FF,3FF,3FF,0

Pin zero is tied to 5V, pins 1,2,3 are floating and pins 4,5 are connected to a DS1307 with pull ups.

pito

You may use a simple data compression - do record changes per channel only, when no change "0" will be written..  :) :)

fat16lib

I don't think compression would help.  The problem is CPU for formatting, not data size, so simple is better.

The printHexField() is six times faster than Arduino Print.  1.51 seconds vs 9.63 seconds for the same data.  The Hex file is a little smaller but that is not a big factor.

Quote

Test of println(uint16_t)
Time 9.63 sec
File size 128.89 KB
Write 13.38 KB/sec
Maximum latency: 47552 usec, Minimum Latency: 176 usec, Avg Latency: 474 usec

Test of printHexField(uint16_t, char)
Time 1.51 sec
File size 115.63 KB
Write 76.63 KB/sec
Maximum latency: 24132 usec, Minimum Latency: 44 usec, Avg Latency: 68 usec


A real speedup would happen with a properly designed binary logger.  That would require a fast external ADC.

I have a really fast library for MCP300x and MCP320x ADCs.  Conversion happens in parallel with readout. It takes about 10 microseconds to read a 12 bit ADC value with my fast bit-bang driver.

Go Up