I'm trying to run two "Blink"-esque functions simultaneously.
I've found some code elsewhere that lets me do that and modified it! Great.
However, what I am trying to do is have one LED turn on and off every 1000ms as per usual, but have the other blink in an odd pattern, like ON for 3000ms, OFF for 100ms, ON for 100ms, OFF for 200ms then loop back.
To make this happen I tried adding a random function to the code I found but I don't like how it looks. It looks like a blinking LED with interference or something, like on a radio transmitter or whatever. I'm trying to replicate an old flickering lightbulb, meaning it always has to be ON for longer than it is off, Essentially it needs to be ON/HIGH for a "longer" period of time and then interrupted by several short flashes of ON and OFF
So I'm looking for help in how I can orchestrate the 2nd LED to turn on and off in a more specific series of flickers.
Here's the code I'm using so far:
/* Blink Multiple LEDs without Delay
*
* Turns on and off several light emitting diode(LED) connected to a digital
* pin, without using the delay() function. This means that other code
* can run at the same time without being interrupted by the LED code.
*/
int led1 = 13; // LED connected to digital pin 13
int led2 = 12;
int value1 = LOW; // previous value of the LED
int value2 = HIGH; // previous value of the LED
long time1 = millis();
long time2 = millis();
long interval1 = 1000; // interval at which to blink (milliseconds)
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));
pinMode(led1, OUTPUT); // sets the digital pin as output
pinMode(led2, OUTPUT);
}
void loop()
{
unsigned long m = millis();
if (m - time1 > interval1){
time1 = m;
if (value1 == LOW)
value1 = HIGH;
else
value1 = LOW;
digitalWrite(led1, value1);
}
long interval2 = random(100,1500);
if (m - time2 > interval2){
time2 = m;
if (value2 == LOW)
value2 = HIGH;
else
value2 = LOW;
digitalWrite(led2, value2);
}
Serial.println(interval2);
}
This will always take less than a second to run so you can get back to your main loop and ensure that you don't miss the 1 second on/off for the other LED:
void flicker(){
boolean state = false;
int r = random(20, 175);
for(int i = 0; i < 5; i++){
digitalWrite(led2, state);
state = !state;
delay(r);
r = random(20, 175);
}
digitalWrite(led2, HIGH);
}
Btw. I'm replacing this toggle code:
if (value2 == LOW)
value2 = HIGH;
else
value2 = LOW;
digitalWrite(led2, value2);
with this:
state = !state;
digitalWrite(led2, state);
Now, call flicker() at random intervals; maybe every 15-45 seconds or whatever you find appropriate/realistic.
Try something like this:
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));
pinMode(led1, OUTPUT); // sets the digital pin as output
pinMode(led2, OUTPUT);
}
long interval2 = random(100,1500);
void loop()
{
unsigned long m = millis();
if (m - time1 > interval1){
time1 = m;
if (value1 == LOW)
value1 = HIGH;
else
value1 = LOW;
digitalWrite(led1, value1);
}
if (m - time2 > interval2){
time2 = m;
if (value2 == LOW) {
value2 = HIGH;
interval2 = random(100, 1500);
} else {
value2 = LOW;
interval2 = random(100, 200);
}
digitalWrite(led2, value2);
}
Related
I'm currently working on a mini project to have my pushbutton toggle a blinking LED, meaning: when I press the button, I want the LED to keep blinking until I press the button again.
I managed to toggle the LED without blinking (when I press the button, the LED lights up, and when I press the button again, the LED switches off, but no blinking).
I've appended my code below, and my logic is based on tracking the current button state and the previous button state, which I think is the correct logic (but if I'm wrong please criticise/correct me!!) to cause a change in LED output state, so I'm not sure what's wrong with my thinking/code. The problem I have now is that the LED will only blink twice (according to the line of code I've written in void loop) but it does not keep blinking forever until I want it to stop (what can I do to execute this?)
const int ledPin = 8;
const int buttonPin = 7;
int buttonState;
int ledState = HIGH;
int lastbuttonState = LOW;
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState != lastbuttonState) {
if (ledState == HIGH) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
} else {
digitalWrite(ledPin, LOW);
}
}
lastbuttonState = buttonState;
}
Will be extremely grateful if anyone can point out any mistakes!! Thank you!
The most important idea here is use the button to toggle blinkState. When the state indicate the LED should be blinking, use millis() get the current time and calculate when ledState should be toggled. When enough time has passed, calculate the next time, toggle ledState, and loop back.
Note I am using the bounce2 library to debounce the button. You could do button debouncing with timer as well.
#include <Bounce2.h>
#define LED_PIN 13
#define BUTTON_PIN 2
#define DEBOUNCE_DELAY 100
#define BLINK_DELAY 200
uint32_t nextMillis = 0;
bool blinkState = 0, ledState = 0, previousLedState = 0;
Bounce b = Bounce();
void setup() {
Serial.begin(9600);
delay(1000);
pinMode(LED_PIN, OUTPUT);
b.attach(BUTTON_PIN, INPUT_PULLUP);
b.interval(DEBOUNCE_DELAY);
}
void loop() {
b.update();
if(b.fell()){
blinkState = !blinkState;
}
if (blinkState){
if (millis() > nextMillis){
nextMillis = millis() + BLINK_DELAY;
ledState = !ledState;
}
} else {
ledState = 0;
}
//only write to pin if ledState changed
if (ledState != previousLedState){
digitalWrite(LED_PIN, ledState);
previousLedState = ledState;
}
}
This part
(buttonState != lastbuttonState)
is logically incorrect as the state of the push button will immediately become false when you press the push button once and release it. The last state of the push button would be FALSE as per the logic that you have written.
Another way could be to implement would be to increment an counter variable on pressing the push button once and start blinking when the counter value is odd and stop blinking when the counter value is even.
const int ledPin = 8;
const int buttonPin = 7;
int buttonState=HIGH,reading;
int ledState = LOW;
int lastbuttonState = HIGH,icounter;
unsigned long latchMillis,lastDebounceTime;
void setup()
{
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
}
void loop()
{
unsigned long blinkdelay = 1000,debounceDelay=1;
/***Debounce logic for the input ***/
reading = digitalRead(buttonPin); //Check for the change in PB
if (reading != lastbuttonState)
{
lastDebounceTime = millis(); // reset the debouncing timer
}
lastbuttonState = reading; //Update previous button state
if ((millis()-lastDebounceTime) > debounceDelay) //If debounce has elapsed then accept the input
{
if (buttonState != lastbuttonState)
{
if (buttonState == LOW)
{
icounter = icounter +1; //Increment counter on every rising edge of PB
latchMillis = millis(); //Latch the current millis
}
buttonState = lastbuttonState;
}
}
if ((icounter%2)!= 0)
{
if ((millis() - latchMillis) > blinkdelay)
{
ledState = !ledState;
latchMillis = millis();
digitalWrite(ledPin,ledState);
}
}
else
{
digitalWrite(ledPin, LOW);
}
}
`
I am building a program that measure the voltage of a component (photoswitch). When the potential is under 5 V, the lamp will turn on.
But my problem is, I want the Arduino to turn on the lamp, if the voltage has been under 5 V for 10 seconds or more. For example, if the voltage level is under 5 V for 8 seconds and then it changes to over 5 V again, the lamp should not turn on.
Here is my code so far:
int Pin = 2;
const float baselineVoltage = 5.0;
void setup() {
Serial.begin(9600);
pinMode(Pin,OUTPUT);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.println(voltage);
if(voltage < baselineVoltage){
digitalWrite(2,HIGH);
}
delay(10);
}
I believe something like this addresses your 10 second delay issue. If you want the same 10 second delay to turn it off, you will need to do something similar.
int Pin = 2;
const float baselineVoltage = 5.0;
int belowBaselineVoltage = false;
unsigned long turnOnAt;
const unsigned long turnOnDelay = 10 * 1000;
void setup() {
Serial.begin(9600);
pinMode(Pin, OUTPUT);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.println(voltage);
if (voltage < baselineVoltage)
{
if (belowBaselineVoltage == true)
{
if (millis() >= turnOnAt)
{
digitalWrite(2, HIGH);
}
}
else
{
belowBaselineVoltage = true;
turnOnAt = millis() + turnOnDelay;
}
}
else
{
belowBaselineVoltage = false;
}
}
I am measuring light, temperature and humidity on a arduino uno, and have programmed the loop to run every minute. Monitoring the values on the serial monitor.
However, what i would like is the code to run once to get the values, then wait, or pause, until one of the values change, and then output this on the serial monitor.
I want to get informed of changes in the sensors immediately, not wait for a minute for the loop to run. Is there a way to do this?
Thanks.
So I would need to add an if/else function to the following code?
int lightPin = A5;
int lightok = 9;
int lighthigh = 10;
void setup()
{
Serial.begin(9600);
pinMode(lightok,OUTPUT);
pinMode(lighthigh,OUTPUT);
}
void loop()
{
delay(600000);
int lightlevel = analogRead(lightPin);
lightlevel = map(lightlevel, 0, 1023, 0, 255);
lightlevel = constrain(lightlevel, 0, 255);
Serial.print("Lightlevel: ");
Serial.println(lightlevel);
//led control for light levels
if (lightlevel < 15 || lightlevel > 125) {
digitalWrite(lighthigh, HIGH);
digitalWrite(lightok, LOW);
} else {
digitalWrite(lighthigh, LOW);
digitalWrite(lightok, HIGH);
}
}
You have to ways of doing this:
you can run your loop faster, say every second or half-second and only output a value to serial if the value is different from the previous one or if the difference is bigger than a specific value
you can setup interrupts run code only when something happens. But I need to know the sensor you are using to be more specific on this one.
Hope this helps! :)
EDIT
Okay, I'd do something like that :
int lightSensorPin = A5;
int lightOkPin = 9;
int lightHighPin = 10;
int currentLightLevel = 0;
int previousLightLevel = 0;
int delta = 0;
int deltaValue = 10; // needs to be changed to suit your needs
void setup() {
Serial.begin(9600);
pinMode(lightOkPin, OUTPUT);
pinMode(lightHighPin, OUTPUT);
}
void loop() {
currentLightLevel = analogRead(lightSensorPin); //read the sensor
currentLightLevel = map(currentLightLevel, 0, 1023, 0, 255); // map the value
currentLightLevel = constrain(currentLightLevel, 0, 255); // not sure this is useful
delta = abs(previousLightLevel - currentLightLevel); // calculate the absolute value of the difference btw privous and current light value
if (delta >= deltaValue) { // if the difference is higher than a threshold
Serial.print("currentLightLevel: ");
Serial.println(currentLightLevel);
//led control for light levels
if (currentLightLevel < 15 || currentLightLevel > 125) {
digitalWrite(lightHighPin, HIGH);
digitalWrite(lightOkPin, LOW);
}
else {
digitalWrite(lightHighPin, LOW);
digitalWrite(lightOkPin, HIGH);
}
}
previousLightLevel = currentLightLevel;
delay(1000);
}
I'm doing project like this http://grathio.com/2013/11/new-old-project-secret-knock-drawer-lock/ The project only process time interval between knock, and I try to add amplitude as input, if I just use the code from the link above it works fine but I want to add amplitude (loud and soft knock) as input too. But my code still have problem, it can't recognise knock and the LED acting weird. I need to recognise knock time interval and knock amplitude. Comment 'This is what I add' is the code that I add myself, but the code doesn't work. Could anyone tell me what is wrong with my code?
Below is the code:
#include <EEPROM.h>
const byte eepromValid = 123; // If the first byte in eeprom is this then the data is valid.
/*Pin definitions*/
const int programButton = 0; // Record A New Knock button.
const int ledPin = 1; // The built in LED
const int knockSensor = 1; // (Analog 1) for using the piezo as an input device. (aka knock sensor)
const int audioOut = 2; // (Digial 2) for using the peizo as an output device. (Thing that goes beep.)
const int lockPin = 3; // The pin that activates the solenoid lock.
/*Tuning constants. Changing the values below changes the behavior of the device.*/
int threshold = 3; // Minimum signal from the piezo to register as a knock. Higher = less sensitive. Typical values 1 - 10
const int rejectValue = 25; // If an individual knock is off by this percentage of a knock we don't unlock. Typical values 10-30
const int averageRejectValue = 15; // If the average timing of all the knocks is off by this percent we don't unlock. Typical values 5-20
const int knockFadeTime = 150; // Milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)
const int lockOperateTime = 2500; // Milliseconds that we operate the lock solenoid latch before releasing it.
const int maximumKnocks = 20; // Maximum number of knocks to listen for.
const int maximumAmp = 20; // This is what i add
const int ampLoud = 10; // This is what i add
const int ampSoft = 20; // This is what i add
const int knockComplete = 1200; // Longest time to wait for a knock before we assume that it's finished. (milliseconds)
byte secretCode[maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initial setup: "Shave and a Hair Cut, two bits."
byte secretAmp[maximumAmp] = {10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // This is what i add
int knockReadings[maximumKnocks]; // When someone knocks this array fills with the delays between knocks.
int ampReadings[maximumAmp]; // This is what i add
int knockSensorValue = 0; // Last reading of the knock sensor.
int amp = 0; // This is what i add
boolean programModeActive = false; // True if we're trying to program a new knock.
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(lockPin, OUTPUT);
readSecretKnock(); // Load the secret knock (if any) from EEPROM.
doorUnlock(500); // Unlock the door for a bit when we power up. For system check and to allow a way in if the key is forgotten.
delay(500); // This delay is here because the solenoid lock returning to place can otherwise trigger and inadvertent knock.
}
void loop() {
// Listen for any knock at all.
knockSensorValue = analogRead(knockSensor);
if (digitalRead(programButton) == HIGH){ // is the program button pressed?
delay(100); // Cheap debounce.
if (digitalRead(programButton) == HIGH){
if (programModeActive == false){ // If we're not in programming mode, turn it on.
programModeActive = true; // Remember we're in programming mode.
digitalWrite(ledPin, HIGH); // Turn on the red light too so the user knows we're programming.
chirp(500, 1500); // And play a tone in case the user can't see the LED.
chirp(500, 1000);
} else { // If we are in programing mode, turn it off.
programModeActive = false;
digitalWrite(ledPin, LOW);
chirp(500, 1000); // Turn off the programming LED and play a sad note.
chirp(500, 1500);
delay(500);
}
while (digitalRead(programButton) == HIGH){
delay(10); // Hang around until the button is released.
}
}
delay(250); // Another cheap debounce. Longer because releasing the button can sometimes be sensed as a knock.
}
if (knockSensorValue >= threshold){
if (programModeActive == true){ // Blink the LED when we sense a knock.
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
knockDelay();
if (programModeActive == true){ // Un-blink the LED.
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
listenToSecretKnock(); // We have our first knock. Go and see what other knocks are in store...
}
}
// Records the timing of knocks.
void listenToSecretKnock(){
int i = 0;
int j = 0;
// First reset the listening array.
for (i=0; i < maximumKnocks; i++){
knockReadings[i] = 0;
}
for (j=0; j < maximumAmp; j++){ // This is what i add
ampReadings[j] = 0;
}
int currentKnockNumber = 0; // Position counter for the array.
int currentAmpNumber = 0;
int startTime = millis(); // Reference for when this knock started.
int now = millis();
do { // Listen for the next knock or wait for it to timeout.
knockSensorValue = analogRead(knockSensor);
//===========================================================================================================
if(knockSensorValue >=3 && knockSensorValue <=75){ // This is what i add
amp = ampSoft; // This is what i add
}
if(knockSensorValue >=76){ // This is what i add
amp = ampLoud; // This is what i add
}
ampReadings[currentAmpNumber] = amp; // This is what i add
currentAmpNumber++; // This is what i add
//===========================================================================================================
if (knockSensorValue >= threshold){ // Here's another knock. Save the time between knocks.
now=millis();
knockReadings[currentKnockNumber] = now - startTime;
currentKnockNumber ++;
startTime = now;
if (programModeActive==true){ // Blink the LED when we sense a knock.
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
knockDelay();
if (programModeActive == true){ // Un-blink the LED.
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}
now = millis();
// Stop listening if there are too many knocks or there is too much time between knocks.
} while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
//we've got our knock recorded, lets see if it's valid
if (programModeActive == false){ // Only do this if we're not recording a new knock.
if (validateKnock() == true){
doorUnlock(lockOperateTime);
} else {
// knock is invalid. Blink the LED as a warning to others.
for (i=0; i < 4; i++){
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
} else { // If we're in programming mode we still validate the lock because it makes some numbers we need, we just don't do anything with the return.
validateKnock();
}
}
// Unlocks the door.
void doorUnlock(int delayTime){
digitalWrite(ledPin, HIGH);
digitalWrite(lockPin, HIGH);
delay(delayTime);
digitalWrite(lockPin, LOW);
digitalWrite(ledPin, LOW);
delay(500); // This delay is here because releasing the latch can cause a vibration that will be sensed as a knock.
}
// Checks to see if our knock matches the secret.
// Returns true if it's a good knock, false if it's not.
boolean validateKnock(){
int i = 0;
int currentKnockCount = 0;
int secretKnockCount = 0;
int currentAmpCount = 0; // This is what i add
int secretAmpCount = 0; // This is what i add
int maxKnockInterval = 0; // We use this later to normalize the times.
for (i=0;i<maximumKnocks;i++){
if (knockReadings[i] > 0){
currentKnockCount++;
}
if (secretCode[i] > 0){
secretKnockCount++;
}
if (ampReadings[i] > 0){ // This is what i add
currentAmpCount++; // This is what i add
}
if (secretAmp[i] > 0){ // This is what i add
secretAmpCount++; // This is what i add
}
if (knockReadings[i] > maxKnockInterval){ // Collect normalization data while we're looping.
maxKnockInterval = knockReadings[i];
}
}
// If we're recording a new knock, save the info and get out of here.
if (programModeActive == true){
for (i=0; i < maximumKnocks; i++){ // Normalize the time between knocks. (the longest time = 100)
secretCode[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
}
for (int j = 0; j < maximumAmp; j++){
secretAmp[j] = ampReadings[j];
}
saveSecretKnock(); // save the result to EEPROM
programModeActive = false;
playbackKnock(maxKnockInterval);
return false;
}
if (currentKnockCount != secretKnockCount && currentAmpCount != secretAmpCount){ // Easiest check first. If the number of knocks is wrong, don't unlock. // This is what i add
return false;
}
/* Now we compare the relative intervals of our knocks, not the absolute time between them.
(ie: if you do the same pattern slow or fast it should still open the door.)
This makes it less picky, which while making it less secure can also make it
less of a pain to use if you're tempo is a little slow or fast.
*/
int totaltimeDifferences = 0;
int timeDiff = 0;
for (i=0; i < maximumKnocks; i++){ // Normalize the times
knockReadings[i]= map(knockReadings[i], 0, maxKnockInterval, 0, 100);
timeDiff = abs(knockReadings[i] - secretCode[i]);
if (timeDiff > rejectValue){ // Individual value too far out of whack. No access for this knock!
return false;
}
totaltimeDifferences += timeDiff;
}
// It can also fail if the whole thing is too inaccurate.
if (totaltimeDifferences / secretKnockCount > averageRejectValue){
return false;
}
return true;
}
// reads the secret knock from EEPROM. (if any.)
void readSecretKnock(){
byte reading;
int i;
int j;
reading = EEPROM.read(0);
if (reading == eepromValid){ // only read EEPROM if the signature byte is correct.
for (int i=0; i < maximumKnocks ;i++){
secretCode[i] = EEPROM.read(i+1);
}
for (int j=0; j < maximumAmp ;j++){ // This is what i add
secretAmp[j] = EEPROM.read(j+1); // This is what i add
}
}
}
//saves a new pattern too eeprom
void saveSecretKnock(){
EEPROM.write(0, 0); // clear out the signature. That way we know if we didn't finish the write successfully.
for (int i=0; i < maximumKnocks; i++){
EEPROM.write(i+1, secretCode[i]);
EEPROM.write(i+1, secretAmp[i]); // This is what i add
}
EEPROM.write(0, eepromValid); // all good. Write the signature so we'll know it's all good.
}
// Plays back the pattern of the knock in blinks and beeps
void playbackKnock(int maxKnockInterval){
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
chirp(200, 1800);
for (int i = 0; i < maximumKnocks ; i++){
digitalWrite(ledPin, LOW);
// only turn it on if there's a delay
if (secretCode[i] > 0){
delay(map(secretCode[i], 0, 100, 0, maxKnockInterval)); // Expand the time back out to what it was. Roughly.
digitalWrite(ledPin, HIGH);
chirp(200, 1800);
}
}
digitalWrite(ledPin, LOW);
}
// Deals with the knock delay thingy.
void knockDelay(){
int itterations = (knockFadeTime / 20); // Wait for the peak to dissipate before listening to next one.
for (int i=0; i < itterations; i++){
delay(10);
analogRead(knockSensor); // This is done in an attempt to defuse the analog sensor's capacitor that will give false readings on high impedance sensors.
delay(10);
}
}
// Plays a non-musical tone on the piezo.
// playTime = milliseconds to play the tone
// delayTime = time in microseconds between ticks. (smaller=higher pitch tone.)
void chirp(int playTime, int delayTime){
long loopTime = (playTime * 1000L) / delayTime;
pinMode(audioOut, OUTPUT);
for(int i=0; i < loopTime; i++){
digitalWrite(audioOut, HIGH);
delayMicroseconds(delayTime);
digitalWrite(audioOut, LOW);
}
pinMode(audioOut, INPUT);
}
I'm guessing that you are wanting to record the knock pattern and knock volume at the same time. So that a similar pattern with softer or louder knocks will not activate the lock. If this is the case, I would suggest that you make the array mySecretKnock a 2 dimensional array.
Then use two variables to record the analog and digital inputs.
Capture them one after the other in the same control structure.
i.e. If the value of one is high enough to trigger the if statement just record the value of the other one on the next line of code.
Keep in mind that the analog input will be lower if processed after the digital one, so you may have to adjust your threshold numbers
I want to run my Arduino for a specific amount of time (say 60 seconds) and collect
data from the analog pin with a specific sampling rate (say four samples a second).
I got the code working in matlab... but I want to use the arduino environment.
Please help me convert it.
a_pin = 0;
fs = 4; % sampling frequency (samplings per second)
mt = 20; % time for measurements
ind = 1;
nind = 1;
last_beep = 0;
tic;
while toc < mt
time(ind) = toc;
v(ind) = a.analogRead(a_pin);
% wait for appropriate time for next measurement
while( nind == ind )
nind = floor(toc*fs) + 1;
end
ind = nind;
end
Ok this is what i have so far in my sketch. Would this measure for 10 seconds taking
readings every 5?
int sensePin = 0;
unsigned long starttime = 0;
unsigned long endtime = 0;
int i = 0;
int n;
const int sizeofv = 50;
int v[sizeofv];
void setup(){
pinMode(sensePin, INPUT);
Serial.begin(9600);
}
void loop() {
starttime = millis();
endtime = starttime;
while ((endtime - starttime) <= 10000) // do this loop for up to 1000mS
{
i = i + 1;
v[i] = analogRead(sensePin);
endtime = millis();
delay(5000);
}
for(n=0; n < sizeofv; n++)
{
Serial.print(v[n]);
Serial.print('\n');
}
while(1) { }
}
I recommend using SimpleTimer library, it does all the work for you and is road proven.
There's one bug in your code, you're incrementing i prior to assigning the first value. So when you'll loop over the v[] array, you'll end up printing v[0] which will have an undefined value, and you'll never print the last recorded value of v (if you did not end up overflow the buffer and write outside its boundaries).
There's one glitch with your code, it's that you make a condition that you need to end it at 10000, and you make two delays of 5000. Theoretically it looks ok, but in practice, you may get a surprise having only one value. That's because code takes time to execute, and an analogRead() is particularly slow.
I think using loops within the loop() function make things more complicated, and add close to no flexibility. So here you have another take you could try, to use the loop() only by tracking states of the loop, based on some simple calculations:
#define TIME_WINDOW 10000
#define NB_STEPS 2
void setup() {
// ...
endtime = millis();
}
bool over = false;
void loop() {
if (!over) {
curtime = endtime - millis();
// get in this block for up to 1000mS
if (curtime <= TIME_WINDOW) {
v[i] = analogRead(sensePin);
// increments only once when 5000 has been reached.
if ((curtime / (TIME_WINDOW/NB_STEPS)) != i)
i = (curtime / (TIME_WINDOW/NB_STEPS));
} else {
for(n=0; n < NB_STEPS; n++)
Serial.println(v[n]);
over = true;
}
}
}
I did not test my code, so it may fail or have typos, but the idea is the following:
we define the time window and the number of measure steps
while the time window is not over:
store the measurement in the current array at current index
if integer division of spent time over time_window is different from current index
store the new value into the current index
e.g.: i = 4000/(10000/2) <=> i = 4000/5000 <=> i = 0 and i = 6000/(10000/2) <=> i = 1
when the time window is over:
print out each result
set over to true thus we're not entering the loop again
But a simpler (non flexible) solution for you would be:
void setup() {
int value1, value2, value3, value4;
value1 = analogRead(sensePin);
delay(2500);
value2 = analogRead(sensePin);
delay(2500);
value3 = analogRead(sensePin);
delay(2500);
value4 = analogRead(sensePin);
Serial.println("first value: %d", value1);
Serial.println("second value: %d", value2);
Serial.println("third value: %d", value3);
Serial.println("fourth value: %d", value4);
}
and there you got your solution!
HTH