Detect amplifier keying line (PTT) with Arduino

Use an Arduino to detect transmit/receive state.

Using an Arduino Uno to detect the transmit state of a radio. The amplifier keying line (PTT) is grounded on transmit. The Arduino sees it as a switch being pulled low. The keying line is connected to digital input 2 (D2) and ground. The digital input uses the builtin pullup resistor. The sketch is the Arduino digital | input pullup example. Max polls the serial data from the Arduino and displays the state of the keying line.

Motorized potentiometers

And other ways to remotely control existing dials.

Suggestions from


Motorized potentiometers

from p3america:

Screen Shot 2015-05-11 at 1.38.41 PM


From Online Controls:

 Motorized faders

Sparkfun motorized fader (like the kind used in DAW control surfaces)


Servo control and sensing

from electronics stack exchange:



The Potentiometer Handbook by Carl David Todd:

Google search: servo to turn a knob

Shower temperature control from SmithyTech:

Arduino HVAC Servo Thermostat/Controller by tikka308:

What kind of motor would I need to turn this central heating valve? – observations about the difficulty of using robots to turn knobs

Sous vide cooker with feedback control:


Homemade Electric Telescope Focuser:


Use your Raspberry Pi to move parts of a robot or control anything that can rotate – by Rob Zwetsloot

Substituting components in parallel

Resistance and capacitance in an AM radio.

A first test to find out if its practical to ‘piggyback’ external controls on to an existing radio. The reason for doing this is to leave an original radio intact by clipping the remote components to the leads of the existing controls.

For example a varactor would be connected in parallel to the variable capacitor already in the circuit. The existing capacitor would be set low. The capacitance of the varactor would then be added to the total, using the formula for parallel capacitors.

For potentiometers, its not as easy because parallel resistors are divided:


Formula:  Rtotal = R1×R2/(R1+R2)

For example if R1 is 10K, R2 would need to be 100K to get a total resistance of 9K. To get 99% of the existing resistance, the piggyback resistor needs to be 100 times the value of the existing resistor. 1 MegOhm if matched with 10K.

Practical considerations

What happens when the radio is not being controlled remotely?

  • For capacitance, the remote capacitor (varactor) should be set to 0.
  • For resistance, the remote resistor should be set as high as possible.

Conversely, how should the physical controls on the radio be set when operating remotely?

  • Variable capacitors should be set as low as possible.
  • Potentiometers should be set as high as possible. For a volume control this actually means turning the volume all the way down.


SPST switches can be considered as a form of potentiometer with infinite resistance. A piggybacked switch will only work if the existing switch is in the ‘off’ position. And vice-versa.

Double-Throw and Rotary switches present more difficulties as multiple states are maintained by the same device.

I don’t think multiple throw switches can be piggybacked. Two possible solutions:

  • mechanical connection to manual control (servo)
  • internal relays – requiring modification of the radio, so that the existing control and the remote control operate the same relays
  • Hybrid approach: Operate the switches manually while operating other controls remotely.


I piggybacked a tuning capacitor from an AM radio onto the tuning capacitor of a vintage Radio Shack Globe Patrol (regenerative receiver).


Low resolution LED interface

Lots of information in a few pixels.

Computer displays have evolved to high resolutions. What about the other direction? This experiment  is a display interface using a grid of LED’s. Essentially, very large pixels.

information types
  • on/off 
  • small numbers (0-10)
  • large numbers (0-10,000,000)
  • clocks
  • level indicators
  • connections
  • map keys (i.e., explanations of symbols) 
communicating with LED’s

LED’s communicate information using

  • brightness
  • color
  • movement

With just a few LED’s its easy to display a clear message. A large matrix of LEDS can get confusing. Here are a few suggestions:

  • Use separate regions for each block of information.
  • Draw guide markers to help locate positions by giving frame of reference.
  • Animation catches the eye but also distracts, and confuses.


traffic lights

An effective but inefficient signaling method.

resistor codes:

Resistors use a numeric color code.

Find the value of any resistor by looking at the first four 4 color bands. Colors represent  base 10 exponential notation.


An abacus uses 5 or 10 beads for each digit. Faster than decoding a resistor and works with one color – but takes up more space.

level meters

Segmented level meters convey information using a line of pixels:

binary clock

Represents digits using binary coded decimal notation.

An LED grid in Max

This grid design was used for the visual interface of a shortwave radio:

And an etch-a-sketch:


folder: LED-display/rx-320/


  • rxpanel2.maxpat (main patch)
  • panel2.js (javascript)


There are 2 large toggles – one for etch-a-sketch, and another for the radio simulator. Try one, then toggle it off before trying another one. If you forget – just restart the patch.

The number box near the top can be used to expand or contract the display size (while it is active) The default size is 17.

how it works

The same patch generated both video examples above. It uses javascript to make a two dimensional array of Max led objects. Each object is addressable by its position in the array. Here’s the code to make the objects:

// makecells - create matrix of led objects
function makecells( x, y, color )

var p;		// this patcher
var tmpstr;
var objname;

	post( "makecells: ", x, y, color );
	post( );

	p = this.patcher;

// make cells

	for( i = 0; i < x; i++ )
		for(j = 0; j < y; j++ )
			cell[i][j] = p.newdefault(xorigin + (i * cellspace), yorigin + (j * cellspace), "led" );    // create leds
			if(color != 9 )
				cell[i][j].hidden = 0;
				cell[i][j].message( "pict", color );
				cell[i][j].hidden = 1;

			cell[i][j].varname = "led" + i + "x" +  j;							//  assigns name for future use	




Although each LED in a grid is addressable, its easier to group sections of the grid into blobs. Each blob is a unit that displays data, like a number for example. There are several types of blobs:

Here are the properties of a blob:

//  blob data structure
//   x, y upper left
//   lengthx, lengthy, 
//   orientation: 0 = horizontal, 1 = vertical
//   step  1 = downward or rightward,  -1 = upward or leftward  (this defines the corner of origin too)
//   data lorange, hirange
//   scale: 0 = no, 1 = yes
//   blobtype: 0 = generic decimal,  1 = spare,  2 = pushbutton flash,  3 = radiobutton, 
//   color code 0-9
//   contrast color 0-9
//   signed ( 0 = no, 1 = yes)		// booooooooooooooolean  
//   colorshift ( 0 = normal , 1 = use different colors every 3 digits, like comma separators (frequency display)
//   blink  (milliseconds duration for pushbutton flash type only (led blinktime )
//   radio number
//   name
//   value


Blob data examples

Lets look at examples of various ways to display data – as used in the shortwave radio video above.

Here are 3 blobs that represent numbers in three different ways.

The far left column and the bottom row are key graphics. They give a frame of reference for the data.


Moving from left to right…

The LED’s far left column, are a graphic key, starting with red on the bottom, represent the numbers 1-9

The next blue column is just a divider

The 3rd column of white dots is the signal strength data ranging from the 0-9. The current value is ‘4’, represented by a column of 4 dots.

The next nine columns (4-12) represent the frequency in Hz. ranging from 0-999,999,999. The data is in groups of three (as you can see by looking at the graphical key in the bottom row). The number currently displayed is: 4,999,991.

Negative frequencies are displayed by shifting the colors to values that don’t match the key graphic.

The last column is a radio button with 4 possible values and is currently set to ‘3’


The bottom row is a key graphic, showing a different color, or group of colors for each data item. So for example, there is one white dot under the signal strength data in column 3. There are 3 groups of 3 dots (yellow, green, yellow) in columns 4-12 representing the frequency data in the format: 999,999,999.

The 2nd blue row from the bottom is a divider.

The next shows which data items are being controlled by modulators. The 3 white LED’s show modulation of frequency data in the million’s, 100’s, and ten’s  places.

Modulator units

There are 5 modulator units in the display. Data is represented using a color code..

  1.  red
  2. green
  3. blue
  4. yellow
  5. white

Gray LED’s represent ‘momentary’ controls in the off state. When a momentary button is pressed, it will blink white.

Here is an example of a modulator unit

The blue LED’s are just dividers (background space)


The first column of data on the left is the on/off indicator and the modulator’s ID number.

The top LED of the column is the on/off toggle. It is blank, which means off.

The next two red LED’s together represent the ID number of the modulator: red = 1

For the remaining columns, the top row indicates whether the input gate is open allowing other modulators to control the parameter. Grey indicates the gate is closed, A white LED means the input gate is open.

The second and third columns of data are the clock speed and wave type. The 2 LEDS in each column are grouped together and are using the color code above. The clock speed is 5 (white). The wave type is 4 (yellow)

The fourth and fifth columns of data are the low and high range. Low range value is 5 (white) and high range value is 2 (green) – which doesn’t make sense, but this is simulator data.

The last column is the modulator destination activity indicator: grey if zero (not assigned) or white if any non-zero value.

modulator data structure:
// modulator data structure
// these are fixed structures 8x2, with specific color rules
// ulx, uly
// mod id number 1-n 
// on	: 0 = off, 1 = on
// modin :  modulation source index 0-4
// clockspeed  :  0-4
// wavetype : 0-4
// lorange : 0-4
// hirange : 0-4
// ingate : 0 - 4  (tells which control is being modulated)
// spare
// destination : 0-127 destination index  // this is displayed elsewhere


hardware interface

Adafruit 32×32 RGB LED panel

local file notes:

files are also in tkzic/new max radio project/

There is a newer version adapted for the Max radio project – basically same code, but file names are

  • rxpanel3.maxpat
  • panel3.js