Friday, February 28, 2014

More ideas for Space Heater Thermostat


After studying up on quadrature encoders, I bought one from Sparkfun!

Rotary Encoder
COM-09117


While I was at it, I got the Mayhew Labs blue LED encoder ring board upon which to mount my encoder.

Rotary Encoder LED Ring Breakout Board - Blue
COM-10407


And a black plastic knob.

Originally, I wanted to use this quad encoder as a general purpose manual input adjuster. As it relates to my Space Heater project, I want a manual setpoint adjusting knob to control the level of heat being produced.

Later on I hope to have a better control system for my Space Heater to make it more useful as the "climate control" for my tabletop greenhouse.

I want a temperature sensor, a control knob, a thermostat,  and an LCD display of both setpoint (demand) and the output of the heater. Above and beyond that, the ability to monitor and control it from say, my Android tablet via WiFi. Yeah, pimp that puppy!!!

I control the heater with Pulse Width Modulation,  using a loaned TI MSP430G2 microcontroller board (thanks again Gus). I'm not sure if it will be up to doing all that, but if it can't, no problem.  I can use the Arduino.

I want to point out that I've gotten the LED display to respond to program inputs, but the quadrature encoder itself has never seemed to work.

After much digging and double checking I have convinced myself the encoder is functional, and that I've wired it up correctly to the proper pins on my Arduino Mega2560.  My friend Gus showed me how simple
it is to function check one of these encoders with an ohmmeter or two LEDs each with current limiting resistors in series, and a DC power source.

Oleg has written an elegant Tutorial & Example Sketch he makes available at the  Circuits@Home website's blog.  Oleg's function  uses a lookup table and some binary bit manipulation to implement a "state machine".

As I understand it this provides a sanity check by first reading the A and B pins simultaneously, and weeding out "illegal state changes". In other words, the function must return -1, 0, or +1 to indicate one incremental move either clockwise or counterclockwise, of the encoder shaft. the function is called many many times a second. This ensures a sampling rate that is sure to "catch" those twin-but-out-of-phase series of switch closures and openings.

This particular encoder has 12 "clicks" in one complete revolution of the encoder shaft, fortunately making it inexpensive for hobbyist and learning purposes.   These clicks are points where the encoders A and B terminals connect to momentarily to its ground or common pin using a mechanical switch.

Higher quality/price rotary quadrature encoders may have as many as 1024 points in on full revolution, and as a result provide far more resolution (and cost more!). Many of them are also employ optical switches...no "clicks"! They turn smoothly and avoid the problems associated with "bounce" prone mechanical switches.

The illegal (theoretically impossible or just plain meaningless) state changes, which could be due to electrical interference, bouncing switch contacts, broken wires, or bad timing,  are trapped and reported as 0, indicating no movement.

The heart of this function encoder_read() involves taking a snapshot of the logic levels of all the pins that belong to one "group" at the same time, which is important because you are monitoring two inputs, the encoder's A terminal and B terminal, in relation to time.

These A and B terminals make momentary contacts 90 degrees out of phase with each other, hence the term "quadrature". They are connected to digital input pins on the Arduino.

Setup involves enabling  the internal pullup resistors.  The digital input pins are set in the 1 state using digitalWrite().  When the encoder shaft turns, the switch contacts of the A and B terminals on the encoder pull their respective Digital Input pins on the Arduino low momentarily.

Oleg's example is written for an Arduino Pro, which has different pin numbers, names and PORT groupings than does my Mega2560. I've done a lot of digging to learn this much. Needless to say, when "it doesn't work" you end up learning far more about it than you expected to.


It is based on Mayhew Lab's example sketch, (which also uses Oleg's encoder_read() function) made freely available at their web site

I've been using debugging statements liberally sprinkled throughout this sketch to monitor what's going on, and it seems that when Oleg's encoder_read() function gets to the part about actually reading PINB, what it sees is that PB7, Pin 13 on my Arduino, is always high.

PINB = 10000000 prints out every time the loop calls the encoder_read function. I think that's pretty conclusive evidence...but of what I 'm not sure. This tells me PB7 is always HIGH and PB6 - PB0 are always LOW no matter how I twist that encoder knob.

Each of the 8 bits, 0-7 correspond to physical pins on the headers that form a PORTx group In this case, PORTB.

In my case I have my encoder hooked up to PINB, which includes PWM pins 6-13.

The Reference materials at Arduino.cc caution that pins 6 ( PB0 ) and 7 (PB1) , are not usable being connected to the crystal pins. So I guess we don't care about those two.

I believe we only care about the changes that occur on PWM Pins 8, 9, and 10 (PB2, PB3, and PB4).

But they never change. Still trying to understand why.

That's the latest.
.


No comments:

Post a Comment