Let's say you want to read up to 100 values, do this:
1. Poor technique (uses blocking code with delay()
)
//let's say you want to read up to 100 values
const unsigned int numReadings = 100;
unsigned int analogVals[numReadings];
unsigned int i = 0;
void setup()
{
}
void loop()
{
analogVals[i] = analogRead(A0);
i++;
if (i>=numReadings)
{
i=0; //reset to beginning of array, so you don't try to save readings outside of the bounds of the array
}
delay(1000); //wait 1 sec
}
Note: you cannot make the number in brackets too large. Ex: analogVals[2000]
will not work because it takes up too much RAM.
Note: the above type approach is also covered in Arduino's basic tutorials on the website. Please reference here: https://www.arduino.cc/reference/en/ --> click on "array" under "Data Types" --> at the bottom of this page it takes you to, click "How to Use Arrays example.
There are a lot of other really useful "Built-in Examples" here: https://docs.arduino.cc/built-in-examples/.
2. Alternate method (also a poor technique, since it uses blocking code with delay()
)
//let's say you want to read up to 100 values
const unsigned int numReadings = 100;
unsigned int analogVals[numReadings];
void setup()
{
}
void loop()
{
//take numReadings # of readings and store into array
for (unsigned int i=0; i<numReadings; i++)
{
analogVals[i] = analogRead(A0);
delay(1000); //wait 1 sec
}
}
3. Better technique (non-blocking method--no delay
!)
//let's say you want to read up to 100 values
const unsigned int numReadings = 100;
unsigned int analogVals[numReadings];
unsigned int i = 0;
void setup()
{
Serial.begin(115200);
}
void loop()
{
static uint32_t tStart = millis(); // ms; start time
const uint32_t DESIRED_PERIOD = 1000; // ms
uint32_t tNow = millis(); // ms; time now
if (tNow - tStart >= DESIRED_PERIOD)
{
tStart += DESIRED_PERIOD; // update start time to ensure consistent and near-exact period
Serial.println("taking sample");
analogVals[i] = analogRead(A0);
i++;
if (i>=numReadings)
{
i = 0; //reset to beginning of array, so you don't try to save readings outside of the bounds of the array
}
}
}
4. Professional-type approach (non-blocking method, avoids global variables by passing around pointers instead, uses C stdint types, and uses static variables to store local, persistent data)
// Function prototypes
// - specify default values here
bool takeAnalogReadings(uint16_t* p_numReadings = nullptr, uint16_t** p_analogVals = nullptr);
void setup()
{
Serial.begin(115200);
Serial.println("\nBegin\n");
}
void loop()
{
// This is one way to just take readings
// takeAnalogReadings();
// This is a way to both take readings *and* read out the values when the buffer is full
uint16_t numReadings;
uint16_t* analogVals;
bool readingsDone = takeAnalogReadings(&numReadings, &analogVals);
if (readingsDone)
{
// Let's print them all out!
Serial.print("numReadings = "); Serial.println(numReadings);
Serial.print("analogVals = [");
for (uint16_t i=0; i<numReadings; i++)
{
if (i!=0)
{
Serial.print(", ");
}
Serial.print(analogVals[i]);
}
Serial.println("]");
}
}
// Function definitions:
//---------------------------------------------------------------------------------------------------------------------
// Take analog readings to fill up a buffer.
// Once the buffer is full, return true so that the caller can read out the data.
// Optionally pass in a pointer to get access to the internal buffer in order to read out the data from outside
// this function.
//---------------------------------------------------------------------------------------------------------------------
bool takeAnalogReadings(uint16_t* p_numReadings, uint16_t** p_analogVals)
{
static const uint16_t NUM_READINGS = 10;
static uint16_t i = 0; // index
static uint16_t analogVals[NUM_READINGS];
const uint32_t SAMPLE_PD = 1000; // ms; sample period (how often to take a new sample)
static uint32_t tStart = millis(); // ms; start time
bool bufferIsFull = false; // set to true each time NUM_READINGS have been taken
// Only take a reading once per SAMPLE_PD
uint32_t tNow = millis(); // ms; time now
if (tNow - tStart >= SAMPLE_PD)
{
Serial.print("taking sample num "); Serial.println(i + 1);
tStart += SAMPLE_PD; // reset start time to take next sample at exactly the correct pd
analogVals[i] = analogRead(A0);
i++;
if (i >= NUM_READINGS)
{
bufferIsFull = true;
i = 0; // reset to beginning of array, so you don't try to save readings outside of the bounds of the array
}
}
// Assign the user-passed-in pointers so that the user can retrieve the data if they so desire to do it this way
if (p_numReadings != nullptr)
{
*p_numReadings = NUM_READINGS;
}
if (p_analogVals != nullptr)
{
*p_analogVals = analogVals;
}
return bufferIsFull;
}
Sample Serial Monitor output from the last code just above:
Begin
taking sample num 1
taking sample num 2
taking sample num 3
taking sample num 4
taking sample num 5
taking sample num 6
taking sample num 7
taking sample num 8
taking sample num 9
taking sample num 10
numReadings = 10
analogVals = [1023, 1023, 1023, 1023, 1023, 687, 0, 0, 0, 0]
taking sample num 1
taking sample num 2
taking sample num 3
taking sample num 4
taking sample num 5
taking sample num 6
taking sample num 7
taking sample num 8
taking sample num 9
taking sample num 10
numReadings = 10
analogVals = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
More reading/study:
- My thorough answer on How to do high-resolution, timestamp-based, non-blocking, single-threaded cooperative multi-tasking
- Arduino's very basic but extremely useful "Blink Without Delay" tutorial: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
- Other "Build-in Examples" from Arduino: https://docs.arduino.cc/built-in-examples/