Skip to main content
Removed erroneous division by INTERVAL_LENGTH_US.
Source Link
Edgar Bonet
  • 45.2k
  • 4
  • 42
  • 81
#define INTERVAL_LENGTH_US 1000UL

unsigned long previousMicros;

void loop()
{
    unsigned long currentMicros = micros() / INTERVAL_LENGTH_US;;
    
    if (((currentMicros - previousMicros) />= INTERVAL_LENGTH_US) > 0)
    {
        previousMicros += INTERVAL_LENGTH_US;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMicros) / 1000000UL, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

NOTE: The millis() function is replaced by micros() / INTERVAL_LENGTH_US according to Edgar's and Nick's comments.

#define INTERVAL_LENGTH_US 1000UL

unsigned long previousMicros;

void loop()
{
    unsigned long currentMicros = micros() / INTERVAL_LENGTH_US;
    
    if (((currentMicros - previousMicros) / INTERVAL_LENGTH_US) > 0)
    {
        previousMicros += INTERVAL_LENGTH_US;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMicros) / 1000000UL, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

NOTE: The millis() function is replaced by micros() / INTERVAL_LENGTH_US according to Edgar's and Nick's comments.

#define INTERVAL_LENGTH_US 1000UL

unsigned long previousMicros;

void loop()
{
    unsigned long currentMicros = micros();
    
    if ((currentMicros - previousMicros) >= INTERVAL_LENGTH_US)
    {
        previousMicros += INTERVAL_LENGTH_US;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMicros) / 1000000UL, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

NOTE: The millis() function is replaced by micros() according to Edgar's and Nick's comments.

Corrected according to Edgar's remarks
Source Link
frarugi87
  • 2.7k
  • 12
  • 19
#define SAMPLE_EVERY_MSINTERVAL_LENGTH_US 11000UL

unsigned long previousMillis;previousMicros;

void loop()
{
    unsigned long currentMilliscurrentMicros = millismicros(); / INTERVAL_LENGTH_US;
    
    if ((currentMillis(currentMicros - previousMillispreviousMicros) >=/ SAMPLE_EVERY_MSINTERVAL_LENGTH_US) > 0)
    {
        previousMillispreviousMicros += SAMPLE_EVERY_MS;INTERVAL_LENGTH_US;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMilliscurrentMicros) / 10001000000UL, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

NOTE: The millis() function is replaced by micros() / INTERVAL_LENGTH_US according to Edgar's and Nick's comments.

Change just the define to reducechange the sample time. Now its set to 1000us (i.e. 1ms, so 1kHz), but don't go much higher otherwise you will have to check accurately the sampling time and the transfer speed. The t variable is not needed anymore.

If you need a faster sample rate you should use another timer to get the correct timing, but again avoid delays.If you need a faster sample rate you should use another timer to get the correct timing, but again avoid delays. Not needed anymore

#define SAMPLE_EVERY_MS 1

unsigned long previousMillis;

void loop()
{
    unsigned long currentMillis = millis();
    
    if ((currentMillis - previousMillis) >= SAMPLE_EVERY_MS)
    {
        previousMillis += SAMPLE_EVERY_MS;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMillis) / 1000, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

Change just the define to reduce the sample time. The t variable is not needed anymore.

If you need a faster sample rate you should use another timer to get the correct timing, but again avoid delays.

#define INTERVAL_LENGTH_US 1000UL

unsigned long previousMicros;

void loop()
{
    unsigned long currentMicros = micros() / INTERVAL_LENGTH_US;
    
    if (((currentMicros - previousMicros) / INTERVAL_LENGTH_US) > 0)
    {
        previousMicros += INTERVAL_LENGTH_US;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMicros) / 1000000UL, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

NOTE: The millis() function is replaced by micros() / INTERVAL_LENGTH_US according to Edgar's and Nick's comments.

Change just the define to change the sample time. Now its set to 1000us (i.e. 1ms, so 1kHz), but don't go much higher otherwise you will have to check accurately the sampling time and the transfer speed. The t variable is not needed anymore.

If you need a faster sample rate you should use another timer to get the correct timing, but again avoid delays. Not needed anymore

Source Link
frarugi87
  • 2.7k
  • 12
  • 19

At first I thought that the main problem was not that you too slow at sampling, but that you were too slow at transmitting the data. As Edgar already stated, at 9600 b/s you need 22.88ms to send a line, so the maximum frequency is less than 50Hz.

However as you experienced, the speed you are getting is 200Hz. This is because that calculation is right in the case of a real serial interface. Arduino Leonardo, on the other hand, emulates the serial interface. But.. There is no such thing as baud rate. If you look at the CDC emulation source code you will see that the baud rate you pass to the begin function is ignored.

So... Why is it still slow? Because you are using the delay function! You are waiting for 1ms every time you perform an acquisition, and then you still have to perform all the sending. This has two errors embedded: 1) using the delay function breaks the timing - better use a timer - and 2) you are too slow.

Now, if you want a 1kHz sampling (or any delay multiple of 1ms) you already have a timer running (so you can just use that):

#define SAMPLE_EVERY_MS 1

unsigned long previousMillis;

void loop()
{
    unsigned long currentMillis = millis();
    
    if ((currentMillis - previousMillis) >= SAMPLE_EVERY_MS)
    {
        previousMillis += SAMPLE_EVERY_MS;
        
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);
        
        Serial.print(((double)currentMillis) / 1000, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}

Change just the define to reduce the sample time. The t variable is not needed anymore.

Just a side note: this will also fix the bug in your code that prevents the program to display the current timing (instead of printing 2.5 it prints 2.0).

If you need a faster sample rate you should use another timer to get the correct timing, but again avoid delays.