Topics

The Digital 49er and the Experiments Board

paul_hvidston
 

I have a couple Forty-9er boards on order and plan to make one QST VFO version but had some different ideas for the second one.

Anyone thought about using an Si5351, e.g. the Adafruit board instead of a DDS? I'm toying with that idea as well as using an AVR Butterfly (with its joystick button) in lieu of an Arduino + DDS + encoder + LCD. It would make a tiny, lower power consumption version of the VFO Forty-9er.

Back on topic, putting caps on the encoder lines is not the best way to debounce it. I wrote interrupt and non-interrtupt versions of an AVR encoder handler if anyone is interested.

72 de Paul/N6MGN

Nick Kennedy
 

Is the Si5351, like the Si570, a square wave output device?  If so, it would be a problem for PHSNA which wants a fairly clean sine wave signal source. I have the little Adafruit board but haven't played with it lately and don't remember what the output looks like.

The ATmel Bufferfly is a fun little board. I did a bunch of programming on one, starting with Steve Weber's code and adding more features for myself. Generally controlling the NJQRP DDS30 and/or DDS60, but it also had a nice keyer in the code as well.

73-

Nick, WA5BDU



On Sun, Mar 13, 2016 at 12:27 PM, prh@... [PHSNA] <PHSNA@...> wrote:
 

I have a couple Forty-9er boards on order and plan to make one QST VFO version but had some different ideas for the second one.

Anyone thought about using an Si5351, e.g. the Adafruit board instead of a DDS? I'm toying with that idea as well as using an AVR Butterfly (with its joystick button) in lieu of an Arduino + DDS + encoder + LCD. It would make a tiny, lower power consumption version of the VFO Forty-9er.

Back on topic, putting caps on the encoder lines is not the best way to debounce it. I wrote interrupt and non-interrtupt versions of an AVR encoder handler if anyone is interested.

72 de Paul/N6MGN


DuWayne Schmidlkofer
 

The 5351 is a square wave output, so will probably have issues with harmonics. One simple SNA using the si570 is the Sweeperino by Asher Farhan http://hfsignals.blogspot.in/p/sweeperino.html it can be used stand alone or has a PC interface program.
Another one one using the si5351 is the SNA/ Antenna analyzer by IW2NCH http://iw2ndh.com/
This one uses a mixing scheme with 2 clock outputs of the si5351 to eliminate the problems with harmonics.
Just did the layout for a simple version of the Sweeperino using a Adafruit si5351 board , so I can check some filters I am working on that are higher in frequency than my SNA Jr. will cover.
DuWayne
KV4QB.blogspot.com

On 3/13/2016 2:52 PM, Nick Kennedy kennnick@... [PHSNA] wrote:
Is the Si5351, like the Si570, a square wave output device? If so, it
would be a problem for PHSNA which wants a fairly clean sine wave signal
source. I have the little Adafruit board but haven't played with it
lately and don't remember what the output looks like.

The ATmel Bufferfly is a fun little board. I did a bunch of programming
on one, starting with Steve Weber's code and adding more features for
myself. Generally controlling the NJQRP DDS30 and/or DDS60, but it also
had a nice keyer in the code as well.

73-

Nick, WA5BDU



On Sun, Mar 13, 2016 at 12:27 PM, prh@...
<mailto:prh@...> [PHSNA] <PHSNA@...
<mailto:PHSNA@...>> wrote:

__

I have a couple Forty-9er boards on order and plan to make one QST
VFO version but had some different ideas for the second one.

Anyone thought about using an Si5351, e.g. the Adafruit board
instead of a DDS? I'm toying with that idea as well as using an AVR
Butterfly (with its joystick button) in lieu of an Arduino + DDS +
encoder + LCD. It would make a tiny, lower power consumption version
of the VFO Forty-9er.

Back on topic, putting caps on the encoder lines is not the best way
to debounce it. I wrote interrupt and non-interrtupt versions of an
AVR encoder handler if anyone is interested.

72 de Paul/N6MGN


paul_hvidston
 

RR the Si5351 output is a square wave, but that should be fine for both the mixer and the class C final since there's a pi low pass filter.

72 de Paul/N6MGN

Nick Kennedy
 

Yes, I agree. I somehow jumped to the conclusion that you were suggesting it for the PHSNA system although the message was clear enough.

Sounds like a good way to go.

73-

Nick, WA5BDU

On Sun, Mar 13, 2016 at 5:14 PM, prh@... [PHSNA] <PHSNA@...> wrote:
 

RR the Si5351 output is a square wave, but that should be fine for both the mixer and the class C final since there's a pi low pass filter.

72 de Paul/N6MGN


Hans Summers
 


Hi Paul, all

> Anyone thought about using an Si5351, e.g. the Adafruit board instead of a DDS? 
> I'm toying with that idea as well as using an AVR Butterfly (with its joystick button) 
> in lieu of an Arduino + DDS + encoder + LCD. It would make a tiny, lower power 
> consumption version of the VFO Forty-9er.

Note, QRP Labs has an Si5351A "breakout board" kit, see http://qrp-labs.com/synth and also a VFO/Signal Generator kit that uses it. The VFO/Signal Generator http://qrp-labs.com/vfo is priced $33, that includes main PCB with processor, 16 x 2 blue backlit LCD, rotary encoder, and the SI5351A Synth kit. The code implements preset frequencies, IF offset, Multiplier, and some other features. New firmware versions coming soon will expand that. There are two outputs: one variable (rotary encoder tuned) and one fixed (configurable). The frequency range is 3.5kHz to 200MHz (it actually works fine up to around 300MHz despite the 200MHz datasheet spec). Additionally you can connect 1pps from a GPS receiver to calibrate and correct for drift (GPS discipline).

 

> Back on topic, putting caps on the encoder lines is not the best way 
> to debounce it. I wrote interrupt and non-interrtupt versions of an AVR 
> encoder handler if anyone is interested.

Yes I agree completely, and this was the second reason I wanted to make this post. MANY examples of Arduino and rotary encoder that I saw, either use resistors and capacitors to attempt to debounce, or timers in the software. BOTH are BAD ways of debouncing the encoder lines! I tried numerous examples and was satisfied with none of them. They miss rotation clicks or still suffer false outputs due to switch bounce. All too often, the quality of the rotary encoder itself is wrongly blamed, particularly if it came from eBay or China! Cheap ones are usually fine. The problem is not the cheap rotary encoder, the problem is the code!

The solution is elegant and simple. I wonder why it isn’t done this way more often! The microcontroller need only look for a phase transition between each of the 4 phases per "click". When it occurs, store it. The processor should then ignore any transition back and forth between those two phases, and only react to the adjacent phase transition, which will tell it which way the shaft has been rotated. For example suppose the processor sees the change between phase 1 and phase 2. It should then ignore any more changes 1->2 and 2->1 which could be due to switch bounce. When it sees 2->3 or 1->4, it will know whether the knob has been turned clockwise or anticlockwise. All with no switch bounce problems!

73 Hans G0UPL


DuWayne Schmidlkofer
 

Using a si5351 for the VFO in the 49er should work fine.  I built a si5351 based VFO for a Frog Sounds transceiver, which is very similar to the 49er.  I put provisions on the board I designed for an attenuator and Low-Pass filter before it went to the transceiver.  I have plans to use this same baord for other projects, and was easier to put the options in right away,
info at DuWayne's Place: "Canned Frog" finished  and several other posts prior to this one.

 

DuWayne
KV4QB

Tim
 

quadrature sampling.
Tim W4YN

Nick Kennedy
 

​On the subject of rotary encoder routines, I recently was programming an Arduino for the Si570 and using a library for the rotary encoder part. I wasn't very happy with the number of steps per rotation I got but blamed that on the inexpensive encoder.

But later I got a look at the explanation of the library code - the writer was highly focused on having no false reads and as a result, his code only produced one output "pulse" for each two (at best) or sometimes four stage changes from the encoder.

So I went back to the way I'd done it previously with various MCUs and got a much better "feel" to my VFO knob and still don't see any "false" or "wrong direction" events.

My code does this, which may be the same as Hans is describing:

First I see if either input has changed state, then-

The logic I use to detect the direction is this:

IF A changed and

               A<>B, then CW

               A=B, then CCW

IF B changed and

               A=B, then CW

               A<>B, then CCW

This logic detects changes for A or B going either high to low or low to high.  Some schemes only check one way and so get half as many steps per rotation.

Contact bounce time may be several ms or may be pretty small. A Bourns data sheet recommends a MC14490 debounce IC.  I haven’t tried it.  If I want to debounce, currently I’ll detect the change, wait a certain time delay, and read it again to see if it is the same, then proceed.

​73-

Nick, WA5BDU​



On Sun, Mar 13, 2016 at 6:14 PM, hans.summers@... [PHSNA] <PHSNA@...> wrote:
Yes I agree completely, and this was the second reason I wanted to make this post. MANY examples of Arduino and rotary encoder that I saw, either use resistors and capacitors to attempt to debounce, or timers in the software. BOTH are BAD ways of debouncing the encoder lines! I tried numerous examples and was satisfied with none of them. They miss rotation clicks or still suffer false outputs due to switch bounce. All too often, the quality of the rotary encoder itself is wrongly blamed, particularly if it came from eBay or China! Cheap ones are usually fine. The problem is not the cheap rotary encoder, the problem is the code!

The solution is elegant and simple. I wonder why it isn’t done this way more often! The microcontroller need only look for a phase transition between each of the 4 phases per "click". When it occurs, store it. The processor should then ignore any transition back and forth between those two phases, and only react to the adjacent phase transition, which will tell it which way the shaft has been rotated. For example suppose the processor sees the change between phase 1 and phase 2. It should then ignore any more changes 1->2 and 2->1 which could be due to switch bounce. When it sees 2->3 or 1->4, it will know whether the knob has been turned clockwise or anticlockwise. All with no switch bounce problems!

73 Hans G0UPL


paul_hvidston
 

No need for time delays,  low-pass filters etc., and with the cheap-o encoders with detent, the best resolution you can achieve is one step per detent. Pin change interrupt driven is the best, but I also have a polled version. Here's the code that gets executed upon pin change interrupt (sri abt loss of formatting):

void RotaryEncoder::encoderISR()
{
  uint8_t Cnd = ((digitalRead(inpA)==HIGH)?1<<1:0) + ((digitalRead(inpB)==HIGH)?1:0);
  uint8_t tableEntry = pgm_read_byte_near(encoder_table + CurSt + Cnd);
  CurSt = tableEntry & (0x7<<2);
  count += tableEntry & CNT_INC;
  if (tableEntry & CNT_DEC)
    count--;
}

count is just an 8-bit rolling (volatile) count of up/down encoder detent clicks. Your foreground routine keeps a snapshot of the last count value and the signed delta is the number of new steps, and the direction taken, i.e new steps = count - last_count.

Contact debbouncing is handled via state transition table "encoder_table" in ROM as follows:

#define CNT_INC (1<<0)
#define CNT_DEC (1<<1)
#define CNT_NONE 0
#define ST_0  (0<<2)
#define ST_U1 (1<<2)
#define ST_U2 (2<<2)
#define ST_U3 (3<<2)
#define ST_D1 (4<<2)
#define ST_D2 (5<<2)
#define ST_D3 (6<<2)

/*
 encoder table accessed by current_state + EncA<<1 + EncB
                      0  1  2  3  0
 Increment sequence: AB aB ab Ab AB
 Decrement sequence: AB Ab ab aB AB
 (where capitol letters are 1 and lower case are 0)
 Contents of ROM: next state + DEC,INC
*/
static const PROGMEM uint8_t encoder_table[7 * 4] = {
// idle state
//ST0 AB
ST_0  + CNT_NONE, // ST_0  ab=00
ST_U1 + CNT_NONE, // ST_0  aB=01
ST_D1 + CNT_NONE, // ST_0  Ab=10
ST_0  + CNT_NONE, // ST_0  AB=11
// clockwise
//ST_U1 aB
ST_U2 + CNT_NONE, // ST_U1 ab
ST_U1 + CNT_NONE, // ST_U1 aB
ST_0  + CNT_NONE, // ST_U1 Ab
ST_0  + CNT_NONE, // ST_U1 AB
//ST_U2 ab
ST_U2 + CNT_NONE, // ST_U2 ab
ST_0  + CNT_NONE, // ST_U2 aB
ST_U3 + CNT_NONE, // ST_U2 Ab
ST_0  + CNT_NONE, // ST_U2 AB
//ST_U3 Ab
ST_U2 + CNT_NONE, // ST_U3 ab
ST_0  + CNT_NONE, // ST_U3 aB
ST_U3 + CNT_NONE, // ST_U3 Ab
ST_0  + CNT_INC,  // ST_U3 AB increment count

// counter-clockwise
//ST_D1 Ab
ST_D2 + CNT_NONE, // ST_D1 ab
ST_0  + CNT_NONE, // ST_D1 aB
ST_D1 + CNT_NONE, // ST_D1 Ab
ST_0  + CNT_NONE, // ST_D1 AB
//ST_D2 ab
ST_D2 + CNT_NONE, // ST_D2 ab
ST_D3 + CNT_NONE, // ST_D2 aB
ST_D1 + CNT_NONE, // ST_D2 Ab
ST_0  + CNT_NONE, // ST_D2 AB
//ST_D3 aB
ST_D2 + CNT_NONE, // ST_D3 ab
ST_D3 + CNT_NONE, // ST_D3 aB
ST_0  + CNT_NONE, // ST_D3 Ab
ST_0  + CNT_DEC   // ST_D3 AB
};


Interestingly enough, debouncing the pushbutton w/o time delays (sleeping) takes more code space than the encoder, but we're taking advantage of the quadrature output of the encoder for much of the heavy lifting.

73 de Paul/N6MGN

Alfredo Mendiola Loyola
 

I read about a gray code to prevent encoder debouncing.
 
Regards.
Alfredo Mendiola Loyola

paul_hvidston
 

RR, Alfredo, Gray Code is exactly what's at play here. Only one signal changes between states. So even if one signal is bouncing, we are at most bouncing between the two bounding states. The interesting part is keeping track that you have incremented/decremented the count once and only once as you transition to the detent. This is why you must track all four states as well as the direction you are traveling.

73 de Paul/N6MGN

P.S. I don't think this is getting too far off-topic since we use encoders in our analyzers.

Bob V
 

Re: Rotary Encoder Voodoo

I too, have been plagued by the rotary encoder blues.  I initially softwared the problem to death, but the result was overly complex I used port manipulation as can be seen here: https://hifiduino.wordpress.com/2010/10/20/rotaryencoder-hw-sw-no-debounce/.  Ultimately I found that a an RC circuit (in the same reference: https://hifiduino.wordpress.com/2010/10/20/rotaryencoder-hw-sw-no-debounce/  ) which much easier to implement.  The attached circuit has a time constant of .1 mS.  I used a 0.1 uF capacitor to get about 1 ms time constant.  It worked every time.

-Bob
WA2i

paul_hvidston
 

It doesn't have to be Voodoo. The Arduino encoder library and many implementations on the web are simply work-arounds, as are the Arduino libraries for momentary pushbuttons. Software delays are a band-aid, and additional hardware components are unnecessary. Simply using the AVR input pin internal pullup is the only hardware required.

It is ill-advised to connect capacitors directly to the encoder (or other) switches. It tends to wear the plating off the contact faster due to the discharge when the contact closes. The linked article does at least show one schematic with a series current-limiting resistor on each encoder switch, but it's all unnecessary. Especially unnecessary when you end up adding a software delay in addition to it!

Who wants extra delay in their firmware when it could be doing something useful? At the very least, poll for an event, and keep track of time or number of passes through the polling function to validate a stable state. This is how one must handle a SPST pushbutton. In earlier times we would use  a SPDT pushbutton and an R-S flipflop to properly debounce in hardware. Today that's wasteful when a bit of firmware can do the job FB.

73 de Paul/N6MGN

George Thomas
 

Check out this fellow's blog:


It's an interrupt driven, state machine that absolutely eliminates debounce w/o any hardware mods.  I can personally attest to its capabilities and swear by it.  I've used his code in an Arduino based function generator I built using a rotary encoder, LCD display and DDS9850 module.  No matter how fast I spin the encoder it does not miss a beat.

 



vasilyivanenko@...
 

Thanks for posting --  That is "normal code" for the task. Simple state machines have been around forever and proper coding techniques for such were taught to us in 1st year computer science back in the early 1980s.

Caveat emptor regarding free Internet code fixes for problems . Although well meaning amateurs inspire me to bits, lots of bad schematics (hardware) and code (software) circulate for "old" problems. Seek out good code and discern wisely.

...e.g.

The DEC LA36 printer had a DC motor that moved the print head back and forth.  The motor had a thin metal disc on the back.  The disc had 100 thin slots cut in it.  There were two optical sensors mounted such that one was 90 degrees out of phase with the other ( pi /2 ) .  The two sensors produced the 4 state pattern of the rotary encoder and could tell the position and direction and accurately count the slots as they went by.  I've got the schematic somewhere....

 

This was in 1974! The DEC LA36 DECwriter II Terminal

 

Nick Kennedy
 

It was the Buxtronic code that I was using until I discovered that it only gave an output for every four (or possibly) two state changes. I admire his programming sophistication, but don't want to throw away any events.

Possibly with an encoder with detents it doesn't make any difference? I don't like encoders with detents. When I think of a smooth VFO feel, the ratcheting of detents is not what I have in mind.

73 & happy programming,

Nick, WA5BDU

On Tue, Mar 15, 2016 at 4:48 PM, georgejane@... [PHSNA] <PHSNA@...> wrote:
 

Check out this fellow's blog:



It's an interrupt driven, state machine that absolutely eliminates debounce w/o any hardware mods.  I can personally attest to its capabilities and swear by it.  I've used his code in an Arduino based function generator I built using a rotary encoder, LCD display and DDS9850 module.  No matter how fast I spin the encoder it does not miss a beat.

Buxtronix: Rotary encoders, done properly
Rotary encoders, in the most recognisable form, are mechanical devices that look a bit like potentiometers, and are often used in their place.
Preview by Yahoo

 




DuWayne Schmidlkofer
 

I have modified several of the inexpensive rotary encoders by removing the detent ball. There are several Youtube videos about this. Gives a much nicer feel. Also if you have room in your project there are several fairly inexpensive < $20.00 optical encoders available. These usually have around 400 pulses per revolution. About 1" square or diamaeter depending on style. Since they are optical, no problems with debounce. Just divide the pulse count to get the tuning ratio you want.
DuWayne
KV4QB

On 3/17/2016 9:34 AM, Nick Kennedy kennnick@... [PHSNA] wrote:
It was the Buxtronic code that I was using until I discovered that it
only gave an output for every four (or possibly) two state changes. I
admire his programming sophistication, but don't want to throw away any
events.

Possibly with an encoder with detents it doesn't make any difference? I
don't like encoders with detents. When I think of a smooth VFO feel, the
ratcheting of detents is not what I have in mind.

73 & happy programming,

Nick, WA5BDU

On Tue, Mar 15, 2016 at 4:48 PM, georgejane@...
<mailto:georgejane@...> [PHSNA] <PHSNA@...
<mailto:PHSNA@...>> wrote:

__

Check out this fellow's blog:


Buxtronix: Rotary encoders, done properly
<http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html>

It's an interrupt driven, state machine that absolutely eliminates
debounce w/o any hardware mods. I can personally attest to its
capabilities and swear by it. I've used his code in an Arduino
based function generator I built using a rotary encoder, LCD display
and DDS9850 module. No matter how fast I spin the encoder it does
not miss a beat.


image
<http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html>


Buxtronix: Rotary encoders, done properly
<http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html>
Rotary encoders, in the most recognisable form, are mechanical
devices that look a bit like potentiometers, and are often used in
their place.

View on www.buxtronix.net
<http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html>

Preview by Yahoo