alternative solutions to the "for" statement

Hi everyone :slight_smile: , I'm new in the Arduino and programming world and this is my first topic so be patient please :confused: .
I'm in trouble with my code and I don't know how to answer to my question.
I'm projecting a control unit for a cold cuts seasoning cell, to control the humidity and temperature inside the cell itself.
The values are printed in a OLED screen and with 3 buttons I can change the thresholds of humidity and temperature in the hysteresis.
I'd like to get a read of T° and H every second and then calculate the median every 5 seconds. Probably I could use an array for the two "macro-variables" but I'm afraid if I use a "for" cycle the code out of the "for" statement is executed every 5 seconds, losing the readiness to read a button pressed.
Every help is appreciated !!
Thanks a lot
Piero

What is a “macro variable”?

If you don’t want to use a for loop, don’t.
Just control your indexing in your top-secret code explicitly.

Hello Piero,
Welcome.

I'm projecting a control unit for a cold cuts seasoning cell

Please explain what that means, I can't speak for anyone else but I have never heard of such a thing.

The values are printed in a OLED screen and with 3 buttons I can change the thresholds of humidity and temperature in the hysteresis.

I infer from that that you have some code already, please post it in code tags as per the instructions you were directed to before your first post.

Please also post your best attempt at doing this yourself and explain where you got stuck.

The alternative to a for loop is to let loop() do the looping, there are examples in the tutorials on this site, such at the excellent demonstration for doing several things at once.

I'd suggest structuring your code like this (pseudo code):

void loop()
{
  if ( 1 second has elapsed )
  {
    take_reading();
    if ( 5 seconds have elapsed )
      calculate_median();
  }
  ... do any other stuff ...
}

And then the only for loop will be in the function calculate_median. The standard way to
determine whether a certain amount of time has elapsed uses a static/global auxialary variable like this:

#define ELAPSED_MS 1000   // 1 second elapsed in milliseconds

void loop()
{
  static unsigned long last_time = 0 ;  // static variable has global extent
  if (millis() - last_time >= ELAPSED_MS)
  {
    last_time += ELAPSED_MS; // set up for next time
    .... do stuff ....
  }
}

You need one such variable and test for each time test. The subtraction before comparison is
vital for correct operation when millis() wraps round.

Spaccalunotti:
Hi everyone :slight_smile: , I'm new in the Arduino and programming world and this is my first topic so be patient please :confused: .
I'm in trouble with my code and I don't know how to answer to my question.
I'm projecting a control unit for a cold cuts seasoning cell, to control the humidity and temperature inside the cell itself.
The values are printed in a OLED screen and with 3 buttons I can change the thresholds of humidity and temperature in the hysteresis.
I'd like to get a read of T° and H every second and then calculate the median every 5 seconds. Probably I could use an array for the two "macro-variables" but I'm afraid if I use a "for" cycle the code out of the "for" statement is executed every 5 seconds, losing the readiness to read a button pressed.
Every help is appreciated !!
Thanks a lot
Piero

You say you're new to Arduino and programming but what you are doing is non-trivial so you'll likely get suggestions that you may not recognize or understand.

I would structure this with separate finite state machines for temperature and humidity control and separate methods for updating the display, sampling the user interface etc.

You want to be doing a number of things "at once"; control of temperature and humidity and interfacing with the user will suffer if at any point you stop doing everything else to service another task exclusively.

Can you post your code for reference?

Which sensors?

Thank you all for the support. I’ve used a DHT 11 sensor to read the H and T. I posted the code so that you can see better the situation. For now the code works fine but the sensor readings are highly unstable, especially in the temperature readings (even ±0.5 °C from a second to another one). I thought I median of some values can get a more stable values, but I’d like to keep the readiness of the code to read a button pressed.
To be clear, I connected the DHT 11 to pin 2. Pins 5 and 9 are connected to two relays that turn on and off a fridge and a air dryer when the T and H go out of the thresholds setted.

Thanks for the help !!

OLED_cella_stagionatura.ino (8.78 KB)

I'd like to get a read of T° and H every second and then calculate the median every 5 seconds. Probably I could use an array for the two "macro-variables" but I'm afraid if I use a "for" cycle the code out of the "for" statement is executed every 5 seconds, losing the readiness to read a button pressed.

There is a very simple technique for a modified moving average which is a form of exponential moving average that can be patched into your code very easily and may give you the stability you need.

Declare two new variables for the moving average t and h values. You will use the average value instead of the individual values later in the code when you act on the t and h values.

float t = 0.0;
float h = 0.0;

float mma_t = 0.0;
float mma_h = 0.0;

Then if you want to use 5 values in your reading and smoothing routine

if(dt >= INTERVALLO) {
  
      t0 = millis();
      t = dht.readTemperature();            // variabili di tipo "float" possono contenere valori con la virgola. Conterranno le letture
      h = dht.readHumidity();               // di temperatura e umidità eseguite ogni volta che si entra nell'if.                                               
      mma_t = (mma_t*4.0 + t)/5.0;
      mma_h = (mma_h*4.0 + h)/5.0; 

}

median every 5 seconds

Do you really want the median? How about the Average? (Mean)

-jim lee

Given the limited accuracy of the sensor, why bother averaging? Why does it have to be “smooth”?

This is how you get signal out of noise. Averaging a bunch of readings. Without this, you'd never be able to see an electron scanning microscope image. Each image is just snow until you average about 1,000 of them together.

-jim lee

jimLee:
This is how you get signal out of noise. Averaging a bunch of readings. Without this, you’d never be able to see an electron scanning microscope image. Each image is just snow until you average about 1,000 of them together.

-jim lee

Yes, I understand the principle but you can’t get “something for nothing”. After you eliminate all the noise, you will still have a reading that is only accurate to +/- 1.0 degree C. I suspect the variation due to “noise” is not much more than that.

Precision vs Accuracy

Capture.JPG

Capture.JPG

You could try computing a “rolling” average ever reading, using the last N samples (in this case, 16).

OLED_cella_stagionatura.ino (12.5 KB)

Blackfin:
You could try computing a "rolling" average ever reading, using the last N samples (in this case, 16).

Well yeah, I have a library that does exactly that.

-jim lee