ATTiny Cooling System (programming) - Page 1
Forum section: electronics / projects

author: Saitama
author_rank: Contributor
timestamp: July 07, 2019, 11:37:33 pm
content: Hello!I need to make a cooling system for a project and to do that I wrote a small code for an ATtiny 25. What I want to do is to measure temperature using LM35 and send out a PWM signal to the base of a transistor, which is going to drive the fan.The code:int out = 0; //pin 5 on the chipfloat sens_pin = A1; //pin 7 on the chipint output;int out_value;void setup() {pinMode(out, OUTPUT);}void loop() {output = analogRead(sens_pin);if(output > 72){out_value = map(output, 0, 160, 0, 255);analogWrite(out, out_value);delay(1);}}I want the cooling system to start when the temperature gets over ~35C.Is this code good enough?P.S Sorry for bad English, I'm not a native speaker.

author: sokoloff
author_rank: Super Contributor
timestamp: July 07, 2019, 11:46:04 pm
content: At a minimum:move the delay(1); call out of the if statement and into the main body of the loop() function.You want a delay each time through the loop, not only when it's hot.Make an initial assignment of out_value = 0; in the loop function before the if statement.Move the analogWrite(out, out_value); outside the if statement as well.The combination of these two will allow the fan to turn off when the temperature falls. Without this, once the fan turns on, it will never turn off (only speed up and slow down, but never turn off).Can't comment on the temp threshold specifically.PS: Your English was quite good; if you hadn't said anything, I'd have never thought twice about it!

author: ledtester
author_rank: Super Contributor
timestamp: July 08, 2019, 12:27:03 am
content: A slightly better way to write the loop function which allows you to do other things:Code:void loop() {// update fan speed about once a secondif ((millis() % 1024) == 0) {// fan control code goes here - no need to call delay()}// still can do other stuff here}I choose% 1024with the idea that gcc will strength reduce it to a more efficient bit operation.

author: floobydust
author_rank: Super Contributor
timestamp: July 08, 2019, 01:23:45 am
content: I think sense_pin should not be a float, it is an int.The A/D default output is 0-1023. Are you thinking it is an 8-bit value? Then you need to first callanalogReadResolution(Or change the map numbers.A option is to put a potentiometer on two other A/D channels and use those to get your fan settings:One A/D channel for setting the temperature to start the fan i.e. "72", and another A/D channel for speed increase "170" (slope) setting. Instead of hard-coding the values.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 08, 2019, 03:29:11 pm
content: I'd suggest adding some kind of hysteresis, otherwise the behavior of the fan may get really annoying when close to a temperature threshold.As I got it, you have a table of control values for the fan depending on the measured temperature? Make this a dual table - one for when the temperature is crossing thresholds upwards, and one when it's crossing thresholds downwards, and make the corresponding thresholds overlap a bit (if I'm clear...)

author: sokoloff
author_rank: Super Contributor
timestamp: July 08, 2019, 03:46:34 pm
content: Another way to implement SiliconWizard's suggestion is to do a strong low-pass filter on cooling and a weaker low-pass filter on heating.Code:const int FAN_PIN = 0; //pin 5 on the chipconst int TEMP_SENSE_PIN = A1; //pin 7 on the chipconst int FAN_OFF_TEMP_THRESHOLD = 72;const int FAN_OFF_SPEED_THRESHOLD = 64;int out_value;void setup() {pinMode(FAN_PIN, OUTPUT);}void loop() {int out_value_target;int output = analogRead(TEMP_SENSE_PIN);out_value_target = map(output, 0, 1023, 0, 255);if (output <= FAN_OFF_TEMP_THRESHOLD) {out_value_target = 0;}if (out_value_target > out_value) {// Fan being commanded to speed upout_value = (15 * out_value + out_value_target) / 16;} else {// Fan being allowed to slow downout_value = (63 * out_value + out_value_target) / 64;if (out_value <= FAN_OFF_SPEED_THRESHOLD)out_value = 0; // Give a sharp cutoff once the fan command slows below a threshold}analogWrite(FAN_PIN, out_value);delay(1);}(Code is hand written, not even checked to see if it compiles and surely not checked for functionality.)