02-10-13, 05:21 PM | #31 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Project Progress...
I was successfully able to run the Teensy "Blink Both" hex examples.
I was also able to make the Arduino "Blink" example run. I tried different pins, changing code for each different pin, to get the feel of that. So, I want to be able to get the Teensy to be able to print information out from the Serial Monitor. I found a dead simple Teensy example on the Teensy site that is called "Tutorial 3: Serial Monitor & Input" So from that page I cut the code... Code:
void setup() { Serial.begin(38400); } void loop() { Serial.println("Hello World"); delay(1000); } But compiling and running running the code did not result in my being able to see the Teensy output anything... So after trying everything I could think of, even burning a candle to the saints (which did calm my nerves), but nothing more. So, out of despiration, I posted a message to the Teensy Forum and quicker than I could say, "this thing will never work", I had an answer... Turns out that I needed to change a default on the Serial menu... ... and once that was done, the Teensy was more than happy to talk to me. Road block removed... progress continues. Best, -AC_Hacker
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... Last edited by AC_Hacker; 02-10-13 at 05:26 PM.. |
02-10-13, 11:27 PM | #32 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Teensy Reads Voltage on Analog pin...
More good progress to report...
My goal now is to get the Teensy to read an analog voltage and write it to the screen. When the Teensy reads an analog signal, it has 1024 incremental steps it can express a voltage in. A value of 0 would correspond to 0 volts and a value of 1024 would correspond to 5 volts. I combined a couple of pieces of code I found on the web... The first was the piece of code that prints to the screen FOUND HERE and shown in the previous post Code:
void setup() { Serial.begin(38400); } void loop() { Serial.println("Hello World"); delay(1000); } Code:
int analogPin = 3; // potentiometer wiper (middle terminal) connected to analog pin 3 // outside leads to ground and +5V int val = 0; // variable to store the value read void setup() { Serial.begin(9600); // setup serial } void loop() { val = analogRead(analogPin); // read the input pin Serial.println(val); // debug value } Code:
int analogPin = 38; // initialize Teensy pin 38 for input of analog voltage // int val = 0; // variable to store the value read set to zero void setup() { Serial.begin(38400); } void loop() //BEGIN LOOP { val = analogRead(analogPin); // read the Teensy input pin 38 Serial.println(val); // print val to serial monitor delay(1000); // delay 1 second before repeating loop } // END LOOP Here's a close up... And when I compiled and ran code, this is what I got. The voltage is just stray voltage, and when I got my hand close, the reading increased. Next I hooked up the CO2 sensor's power and ground to the proto board, and ran the analog out wire from the sensor to the analog in pin on the Teensy. So I ran the code and this is what I got... There was a delay of several seconds after I exhaled, until the values rose on the serial monitor. I have made no attempt to relate the values I am seeing to CO2 ppm. But so far, it is a go! Best, -AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... |
02-11-13, 01:27 PM | #33 |
Steve Hull
Join Date: Dec 2012
Location: hilly, tree covered Arcadia, OK USA
Posts: 826
Thanks: 241
Thanked 165 Times in 123 Posts
|
AC,
A quick calibration can be the CO2 content of your breath at the end of expiration ~ 7%.
__________________
consulting on geothermal heating/cooling & rational energy use since 1990 |
The Following User Says Thank You to stevehull For This Useful Post: | AC_Hacker (02-12-13) |
02-12-13, 10:13 AM | #34 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Exploring Pulse Width Modulation (AKA: PWM)
To make the Teensy control the speed of a fan, I will use the built-in PWM feature of the Teensy/Arduino.
The PWM pin can send out a stream of pulses, hi = 5V, lo = 0V. The duty cycle of the PWM, the percent of time the voltage is high, can be changed in 256 steps (0 to 255) from 0% to 100%, respectively. NOTE: My Analog read pin can read in steps of 1024, so I will need to divide my analog read values by 4 before I direct them to the PWM output. So I located the simplest Arduino program I could find and stripped out everything I didn't need. I ended up with this endless loop PWM program: Code:
//PWM test; PWM Value = 0 to 255 const int Brightness = 14; //This sets up Teensy pin 14 and names it Brightness void setup() { pinMode(Brightness, OUTPUT); //This makes Brightness (AKA: pin 14) an output pin } void loop() //This sets up a loop { //BEGIN LOOP analogWrite(FanSpeed, 255); //This sends a value of 255 to Brightness delay(500); //Delay one half second } //REPEAT LOOP LED comes on full bright. Next I changed the 255 value to 128 and re-ran. LED came on less bright. Ditto 64 (dimmer) Ditto 32 (dimmer) Ditto 16 (etc.) . . . Ditto 0 (LED off) Everything worked as I had expected! On to the next test. Best, -AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... |
02-13-13, 11:36 PM | #35 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Video of CO2 Controller for HRV!
More progress to report...
Trying to send analog voltage from Telair to Teensy PWM pin. Scaled the 1024 step analog read to 256 step PWM write. Code:
int CO2_Read = 38; // initialize pin 38 for input of analog voltage int PWM_feed = 14; // initialize Teensy pin 14 for PWM void setup() { // BEGIN SETUP pinMode(PWM_feed, OUTPUT); // Make Brightness (AKA: pin 14) an output pin int CO2_Read = 0; // variable set to zero int PWM_feed = 0; // variable set to zero Serial.begin(38400); } // END SETUP int CO2_volt = 0; void loop() { // BEGIN LOOP CO2_volt = analogRead(CO2_Read); // read the Teensy input pin 38 PWM_feed = (CO2_volt/4); // PWM out takes the value of CO2 volt divided Serial.print("PWM_feed is = "); // print val to serial monitor Serial.println(PWM_feed); delay(1000); // delay 1 second before repeating loop } // END LOOP Then I was really interested in using setup to actually power a fan, to get some idea if this was actually feasible. I knew that the output from the Teensy pins was pretty puny, but trying to attach ANYTHING more than an LED led to disappointment. So I learned about various Power MOSFET transistors, as the solution. I discovered that the choices of MOSFETS that can directly interface with Teensy is fairly limited, because most MOSFETs need at least a 10v pulse to turn on the transistor, but the Teensy only has 5 volts. I did find out that these will work:
I also found out that you can build a single transistor amplifier to kick the 5 volt output up to 10 volt(+) levels, which I did until the real thing arrives. I also discovered that the single transistor amp inverts the signal, so I wrote a line of code that inverted the pulse, and I'm in business. Code:
int CO2_Read = 38; // initialize pin 38 for analog voltage in int PWM_pin = 14; // initialize pin 14 for PWM void setup() { // BEGIN SETUP pinMode(PWM_pin, OUTPUT); // Make PWM_pin (AKA: pin 14) an output pin int CO2_Read = 0; // variable set to zero int PWM_pin = 0; // variable set to zero //Serial.begin(38400); } // END SETUP int CO2_volt = 0; int PWM_feed = 0; int DutyCycle = 0; int PWM_invert = 0; void loop() { // BEGIN LOOP CO2_volt = analogRead(CO2_Read); // read the Teensy input pin 38 PWM_feed = CO2_volt/4; // Scale CO2_volts (1024) to PWM (256) PWM_invert = 256 - PWM_feed; // Invert PWM_feed //analogWrite(PWM_pin, PWM_feed); analogWrite(PWM_pin, PWM_invert); Serial.print("PWM_feed is = "); // print val to serial monitor Serial.print(PWM_feed); //DutyCycle = PWM_feed/256; DutyCycle = CO2_volt/10 ; Serial.print(" and duty cycle = "); Serial.print(DutyCycle); Serial.println("%"); delay(1000); // delay 1 second before repeating loop } // END LOOP Many thanks to the very helpful dorks at DorkbotPDX, you guys helped me a bunch! Best, -AC_Hacker
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... Last edited by AC_Hacker; 02-16-13 at 11:36 AM.. |
02-14-13, 08:56 AM | #36 |
Steve Hull
Join Date: Dec 2012
Location: hilly, tree covered Arcadia, OK USA
Posts: 826
Thanks: 241
Thanked 165 Times in 123 Posts
|
This is GREAT news and you have done well by hacking a control transistor to drive an output pulse.
Digital controls have incredible precision, but the analog world often is much faster. Chips like I suggested have built in hysteresis - but still need drivers like the one you just showed. VERY nice to have the audio (aka card on bicycle wheel) to audibly demonstrate the CO2 control. Keep going Steve
__________________
consulting on geothermal heating/cooling & rational energy use since 1990 |
02-14-13, 08:44 PM | #37 | |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Quote:
Don't forget to explain everything clearly and include lots of photos. Starting a project thread is very easy, just PRESS HERE and you're on your way... Best, -AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... |
|
02-18-13, 11:23 AM | #38 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Code Sanitization & Refinements & the Right Power FET
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 I am also realizing that there are some refinements that are needed:
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
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... Last edited by AC_Hacker; 02-18-13 at 11:33 AM.. |
02-18-13, 05:52 PM | #39 |
Master EcoRenovator
Join Date: Aug 2012
Location: Toronto
Posts: 958
Thanks: 40
Thanked 158 Times in 150 Posts
|
So, if you don't have control over the frequency, how do you control the PWM with the arduino or can you have it do a 0-10vdc (or 0-5vdc) equivalant
|
02-18-13, 07:54 PM | #40 | |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Quote:
The above picture is a representation of a PWM wave. If you assume that the rising edge is the beginning of each pulse, the percentage of time the wave is high during each wave is called the duty cycle. In this picture, it looks like the wave is high for about one third of the duration on the wave, so the duty cycle would be 33%. If it was only high a quarter of the time, the duty cycle would be 25%. So, without varying the frequency of the wave you can vary how long the wave is high. With the Arduino, you can send a PWM pin a value between 0 and 256, to control the percentage of time that the wave is high. In the case of the first example, you would send the Arduino PWM pin a value of 256 divided by 3, so you would send it a value of 85. In the second example you would send a value of 256/4 or 64. If you wanted the duty cycle to be 80%, you would send a value of about 204. I'm using the Arduino in integer mode to conserve memory, so there are some math errors but they are not so important. There's a good entry in Wikipedia that goes over this pretty well. Does this help? Best, -AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... Last edited by AC_Hacker; 02-22-13 at 11:39 AM.. |
|
|
|