As I'm learning more about programming the Teensy, I am also developing a keener appreciation for clear code.
So I have rewritten the sketch from my last post to do pretty much the same thing as before, but to be a bit cleaner.
Code:
int CO2_ReadPin = 38; // initialize pin 38 for analog voltage in
int PWM_WritePin = 14; // initialize pin 14 for PWM
int CO2_Value;
int PWM_Value;
int DutyCycle;
int ppm;
void setup() { // BEGIN SETUP
pinMode(PWM_WritePin, OUTPUT); // Make PWM_pin (AKA: pin 14) an output pin
int CO2_Value = 0; // variable set to zero
int PWM_Value = 0; // variable set to zero
int DutyCycle = 0; // variable set to zero
int ppm = 0; // variable set to zero
Serial.begin(38400); // Initialize Serial Monitor
} // END SETUP
void loop()
{ // BEGIN LOOP
CO2_Value = analogRead(CO2_ReadPin); // read Teensy input pin 38
unsigned int ppm = ((unsigned long)analogRead(CO2_ReadPin) * 2500)/1024; // calc ppm
Serial.print("CO2 level = "); // print ppm to serial monitor
Serial.print(ppm);
Serial.println(" ppm");
PWM_Value = CO2_Value/4; // Scale CO2_Value (range = 1024) to PWM_Value (range = 256)
analogWrite(PWM_WritePin, PWM_Value); // Write PWM_Value to PWM_WritePin
Serial.print("PWM_Value is = "); // print val to serial monitor
Serial.println(PWM_Value);
DutyCycle = (100 * PWM_Value / 256); // Calculate DutyCycle
Serial.print("PWM DutyCycle = "); // Print DutyCycle to serial monitor
Serial.print(DutyCycle);
Serial.println("%");
Serial.println(); // print null line to serial monitor
delay(1000); // delay 1 second before repeating loop
} // END LOOP
...which has this more readable output:
I am also realizing that there are some refinements that are needed:
- Stalled Fan Prevention
- Pulse Width Modulation Noise
- Use the Proper Power FET
Stalled Fan Prevention
The stalled fan issue comes about when the CO2 level is so low that the resulting duty cycle of the pulse stream is too low to overcome the 'magnetic friction' of the fans, and although the fans are receiving pulses of power, the pulses are insufficient to initiate motion, thus energy is expended, but no work is being done... not good economy.
I anticipate that the stalled fan characteristic will be different for different fans but they will each have their individual stall points.
I wrote a simple program that counted down and printed duty cycle values to the serial monitor, while it sent pulses to the fan of incrementally decreasing duty cycles. I watched the fan gradually slow down until it came to a stop. The fan stops when the duty cycle reaches 28%, which corresponds to a pulse width value of 73.
I then altered the program so that it counted up, with the fan initially being in a stopped state. The fan starts when the duty cycle reaches 36%, which corresponds to a pulse width value of 92.
The amount of air that was moved by a 36% duty cycle is pretty low, so I decided that I need to make my fan turn-on and turn-off points a bit higher than 36%, which corresponds to a PWM value of 92 (out of 256).
Pulse Width Modulation Noise
The fans I am using are extremely quiet, but the the pulses that are sent to the fan are within the range of hearing... so even when the fan is changing speed, the high-pitched whine of the pulse stream remains the same. I played too much rock & roll in the previous decades, and I can't hear the problem at all. My girlfriend however, has very good hearing and is quite uncomfortable with the high-pitched whine of the fan.
The fans will be inside a box, which should reduce the sound, but I think the problem can be entirely eliminated by increasing the frequency to some super-audible level.
The Arduino Integrated Development Environment (AKA: IDE) makes many simplifications in order to lower the threshold for entry into this interesting world. The unfortunate result of that decision is that the user does not have direct control of all the variables that might be available to someone programming in C for instance. The Arduino IDE does not give me direct access to the frequency of the PWM stream, but C does.
So it looks like I'll be headed back to the next DorkBotPDX meeting to learn a little C.
Use the Proper Power FET
This problem was a piece of cake. The new FETS came in from Sparkfun, and installing was a simple matter of pulling out the amplifying transistor plus associated parts and of course the old power FET. Then I installed the new power FET that has a lower turn-on threshold. Then, the output of the Teensy PWM pin goes straight into the gate of the new device.
Here is the before picture...
...and here's the after picture...
Much simplified!
The LEDs and their associated resistors are in the circuit just for testing purposes, so the final version will get even simpler...
Best,
-AC