I have written a little project, it works so far as it should but the for loop is only iterated once, then the result is displayed on the LCD.
#include <LiquidCrystal.h>
#include <stdlib.h>
const int Contrast=20;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int led = A5;
const int button = A3;
void setup() {
Serial.begin(9600);
analogWrite(6,Contrast);
lcd.begin(16, 2);
pinMode(led, OUTPUT);
digitalWrite(led,LOW);
pinMode(button, INPUT_PULLUP);
}
void loop() {
unsigned long mittelwert = 0;
for(int i=0; i<10; i++){
unsigned long r = random(1,5000);
unsigned long now = millis();
digitalWrite(led,HIGH);
while (digitalRead(button) == HIGH){
lcd.setCursor(0,0);
lcd.print("druecken");
}
mittelwert = mittelwert + millis() - now;
digitalWrite(led, LOW); //LED aus
}
lcd.clear();
lcd.setCursor(0,0); //setze Cursor auf 1.Stelle in der 1. Zeile
lcd.print(mittelwert/1000);
lcd.setCursor(0,1);
lcd.print("Sekunden");
delay(5000);
lcd.clear();
}
2 Answers 2
It does iterate 10 times, it's just really fast. You probably want to wait some time to debounce the button, and then wait for the button to be released again.
I don't know why you have to keep printing to the LCD during the loop. Wouldn't printing it once before the loop be enough?
There's something wrong with your math as well. To get an average value, you add up all values, and divide by the number of values. Your variable name mittelwert
is confusing, totalTime
would be more appropriate.
averageTime/1000
is an integer division, so it floors the result. For example, if the average time is 999 ms, ⌊999 / 1000⌋ == 0.
Use a floating point division if you want a decimal number.
In your setup, you don't have to use digitalWrite(led, LOW);
because it is already initialized to LOW
when you start the program.
const int led = LED_BUILTIN;
const int button = A3;
const int numberOfTests = 10; // repeat 10 times
void setup() {
Serial.begin(115200);
pinMode(led, OUTPUT);
pinMode(button, INPUT_PULLUP);
}
void loop() {
unsigned long totalTime = 0;
for (int i = 0; i < numberOfTests; i++) { // repeat 10 times
int r = random(1, 5000);
delay(r); // wait a random number of milliseconds (between 0.001 s and 5 s)
digitalWrite(led, HIGH); // turn LED on
unsigned long startTime = millis();
Serial.println("Press button");
while (digitalRead(button) == HIGH); // wait for the button to be pressed
totalTime += millis() - startTime;
digitalWrite(led, LOW); // turn LED off
delay(25); // button debounce
while (digitalRead(button) == LOW); // wait for the button to be released
}
unsigned long averageTime = totalTime / numberOfTests;
Serial.print(averageTime);
Serial.println(" milliseconds");
Serial.print((float)averageTime / 1000.0, 3); // print the result of the floating point division with 3 digits after the decimal point
Serial.println(" seconds");
delay(10000); // Wait 10 seconds before repeating
}
Your button is configured as an input with a pullup. Therefore, except when the button is depressed to ground that input, this nested loop
while (digitalRead(button) == HIGH){
lcd.setCursor(0,0);
lcd.print("druecken");
}
will endlessly repeat, preventing execution from advancing.
Given that your question fails to state what you are hoping to accomplish it's not possible to make any corrective recommendations. If you do want to make use of the button, you should probably first search and read the existing questions here having to do with debouncing.