Computing > Embedded Computing

Arduino question: unstable signal

(1/6) > >>

billbyrd1945:
I have built the circuit shown in the attached diagram. An if statement tells the LED to come on when the ADC number drops below a certain number. It works. The LED will eventually be replaced with relays controlling a network of fans and Peltier cooling elements for a wine cooler. My problem is that the LED (or relay) flashes off and on when approaching the desired number, then it finally becomes completely on or completely off. I've read about some complicated methods for using 3.3v, but they involve inner workings that I simply don't understand yet. I am using the smoothing method, but seems of very little help if any. Is there a simpler way? I was hoping maybe a well placed cap or something like that might work. Any help will be appreciated.

PS: Using Uno V3

WildMOSFET:
Add a ten microfarad electrolytic capacitor in parallel with the resistance.
And take an average of the readings.
For example, take ten readings with a for cycle, add them all up and divide them by 10.
For each reading, you need to add a small delay, for example 10 milliseconds.

I have an example code, it is in Italian but I believe that the logic is understood the same.

--- Code: ---float LetturaMediaTensione(int n_letture)
{
unsigned int valore = 0;
float tensione = 0;

for(int i=0; i<n_letture; i++)
{
delay(10);
}
tensione = (valore/n_letture)*(300.0/1024.0);

return tensione;
}

--- End code ---

djacobow:
Averaging, as described by another poster will help, but in theory even with averaging, the value will hover around your switch point. If you have a control loop, then it *will* hover around your switch point, and you will get a lot of annoying transitions.

The normal way to deal with this is to add some hysteresis to your control, so that there is a bit of a dead band. You do this by making the turn on value a bit lower than the turn off value.

Something like:

--- Code: ---
const uint16_t switch_point = 1234;
const uint16_t half_dead_band  = 5;

bool getOutputState(uint16_t input) {
static bool curent_state = false;
if (input < (switch_point - half_dead_band)) current_state = true;
else if (input > (switch_point + half_dead_band)) current_state = false;
return current_state;
}

--- End code ---

I didn't test this, but you get the idea.

WildMOSFET:

--- Quote from: djacobow on March 17, 2019, 04:40:35 pm ---Averaging, as described by another poster will help, but in theory even with averaging, the value will hover around your switch point. If you have a control loop, then it *will* hover around your switch point, and you will get a lot of annoying transitions.

The normal way to deal with this is to add some hysteresis to your control, so that there is a bit of a dead band. You do this by making the turn on value a bit lower than the turn off value.

I didn't test this, but you get the idea.

--- End quote ---

You made the idea right.
Hysteresis is also important, otherwise the wine cooler would almost always be in operation, with short breaks.

billbyrd1945:
Thanks guys! Over time, I will explore averaging and hysteresis as I want to learn everything. But-- lucky me: I found another solution that seems to be dead-nuts perfect. I abandoned the thermistor and voltage divider, and the need for some kind of stabilization for a TMP36 temp sensor. It will mean pulling the two-conductor wires out of the cooler and letting a three-conductor be pulled in behind them. But that's a small price to pay for excellent performance. Thanks again!