Thursday, July 14, 2016

$5.00 tuning knob for SDRuno


Here it is. The complete plans and parts to make your very own tuning knob for SDRuno. You can edit the code to make it work with other frontends but since I do a lot of testing and work for SDRplay I will only release SDRuno devices from now own. The parts are very inexpensive. The video below was taken on my cell phone only to show the proof of concept. You can make use of the rotary encoder button but I decide to keep in very basic. I deleted 2 byte codes in the source code. I would like you to explore and learn about how these micro controllers work. It's really not that hard. Have fun. The 2 byte codes needed are at the bottom. remove the // and enter the needed codes in the FIND ME section (source code lines 97 & 102). Have fun.


1a Digispark ATTINY85 $1.59
2a Keyes-040 Rotary Encoder $1.59

If you would like more background information about the 2 boards here are 2 links with really good information.
Rotary Encoder
Digispark

The connections are as follows.
Keyes-040 Gnd to ATTINY85 Gnd
Keyes-040 + to ATTINY8 5v
Keyes-040 SW=No Connection
Keyes-040 DT to ATTINY8 Pin 0
Keyes-040 CLK to ATTINY8 Pin 2

You will need 4 pieces of software

1a The ATTINY85 Drivers
2a The Arduino IDE
3a The Adafruit Trinket Drivers
4a My source code (posted below)



1a Before you plug in the ATTINY85 you will need to install the drivers.If your on a 64bit flavor of windows double click DPinst64.exe If your on a 32bit system double click DPinst.exe. After the drivers install. Reboot and plug in the Digispark.

2a Install the Arduino IDE from the link above. Follow the directions in this link to add the Digispark boards to the Arduino IDE. Make sure after you finish all 4 steps and your ready to upload the code you need to select Digispark default-16.5Mhz under tools/board when uploading my sketch in the Arduino IDE.

3a Download the master.zip from github. move the folder called TrinketHidCombo from Adafruit-Trinket-USB-master to Documents\Arduino\libraries.

4a Don't forget. Lines 97 & 102 are missing byte codes. You will need to explore a little bit and find the missing codes :) I can't force you to like electronics or micro controllers but it really is a lot of fun when you can prototype any idea you might have.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
#include "TrinketHidCombo.h"
 
#define PIN_ENCODER_A 0
#define PIN_ENCODER_B 2
#define TRINKET_PINx  PINB
 
static uint8_t enc_prev_pos = 0;
static uint8_t enc_flags    = 0;
 
void setup()
{
  // set pins as input with internal pull-up resistors enabled
  pinMode(PIN_ENCODER_A, INPUT);
  pinMode(PIN_ENCODER_B, INPUT);
  digitalWrite(PIN_ENCODER_A, HIGH);
  digitalWrite(PIN_ENCODER_B, HIGH);
 
  TrinketHidCombo.begin(); // start the USB device engine and enumerate
 
  // get an initial reading on the encoder pins
  if (digitalRead(PIN_ENCODER_A) == LOW) {
    enc_prev_pos |= (1 << 0);
  }
  if (digitalRead(PIN_ENCODER_B) == LOW) {
    enc_prev_pos |= (1 << 1);
  }
}
 
void loop()
{
  int8_t enc_action = 0; // 1 or -1 if moved, sign is direction
 
  // note: for better performance, the code will now use
  // direct port access techniques
  // http://www.arduino.cc/en/Reference/PortManipulation
  uint8_t enc_cur_pos = 0;
  // read in the encoder state first
  if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_A)) {
    enc_cur_pos |= (1 << 0);
  }
  if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_B)) {
    enc_cur_pos |= (1 << 1);
  }
 
  // if any rotation at all
  if (enc_cur_pos != enc_prev_pos)
  {
    if (enc_prev_pos == 0x00)
    {
      // this is the first edge
      if (enc_cur_pos == 0x01) {
        enc_flags |= (1 << 0);
      }
      else if (enc_cur_pos == 0x02) {
        enc_flags |= (1 << 1);
      }
    }
 
    if (enc_cur_pos == 0x03)
    {
      // this is when the encoder is in the middle of a "step"
      enc_flags |= (1 << 4);
    }
    else if (enc_cur_pos == 0x00)
    {
      // this is the final edge
      if (enc_prev_pos == 0x02) {
        enc_flags |= (1 << 2);
      }
      else if (enc_prev_pos == 0x01) {
        enc_flags |= (1 << 3);
      }
 
      // check the first and last edge
      // or maybe one edge is missing, if missing then require the middle state
      // this will reject bounces and false movements
      if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4))) {
        enc_action = 1;
      }
      else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4))) {
        enc_action = 1;
      }
      else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4))) {
        enc_action = -1;
      }
      else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4))) {
        enc_action = -1;
      }
 
      enc_flags = 0; // reset for next time
    }
  }
 
  enc_prev_pos = enc_cur_pos;
 
  if (enc_action > 0) {
     //TrinketHidCombo.pressKey(0x00,FIND ME);
    TrinketHidCombo.pressKey(0,0);
    delay(10);
  }
  else if (enc_action < 0) {
     //TrinketHidCombo.pressKey(0x00,FIND ME);
    TrinketHidCombo.pressKey(0,0);
    delay(10);
    }
  else {
    TrinketHidCombo.poll(); // do nothing, check if USB needs anything done
  }
}


If you found this step by step useful throw a buck in the jar.
Click the button below. It's a fixed amount of $1.00
 

No comments:

Post a Comment

Thank you for adding your input to the discussion.