Easily adds stepped IR volume control to any audio project.



Volume +mute receiver with remote
$179.00 (matte black) Bourns 100k
$199.00 (natural aluminum) Bourns 100k
$229.00 (matte black) ALPS 10k


New features for 2025, 3 user selectable modes of operation.
1 – ultra fine: 18 steps push and release, 100 steps push and hold. This is the default for all new devices.
2 – fine: 18 steps push and release, 70 steps push and hold.
3 – continuous: 50 steps push and release, push and hold for continuous.
Shown above in volume / mute configuration with pre-programmed remote and dc power supply.
Uses codes: Power , Volume Up , Volume Down , Volume Mute .
All quality parts including gold jacks, silver plated FR4 board, Mircochip PIC16F18323 micro-controller, Vishay TSOP IR receiver, Texas Instruments SN754410 motor driver and Bourns 100k motorized pot.
Completely passive audio path with non shorting mute circuit.
Dry contact outputs follow power status. Ideal for triggering external devices/amps. Contacts rated .5a @ 12Vdc.
Precise 2 speed motor control step rate. Click – Hold – Release will increment / decrement volume in small steps (60 steps). Rapidly clicking and releasing will increment / decrement volume at a high rate (11 steps).
Intelligent features include instruction received feedback via power led and return to low volume on shutdown.
Long range reliability of +30ft.
Compatible with any remote that supports Sony codes.
Also available as volume only.
Schematic and code for full version shown below.




Simple SONY IR receiver V3.1 :
'EULA:
'Copyright (2024) PJL Electronics LLC
'Licenced under Creative Commons
'https://creativecommons.org/licenses/by-nc/4.0/
'You are free to:
'Share — copy and redistribute the material in any medium or 'format
'Adapt — remix, transform, and build upon the material
'The licensor cannot revoke these freedoms as long as you follow 'the license terms.
'Under the following terms:
'Attribution — You must give appropriate credit , provide a link 'to the license, and indicate if changes were made . You may do so in 'any reasonable manner, but not in any way that suggests the licensor 'endorses you or your use.
'NonCommercial — You may not use the material for commercial 'purposes .
'No additional restrictions — You may not apply legal terms or 'technological measures that legally restrict others from doing 'anything the license permits.
'Notices:
'You do not have to comply with the license for elements of the 'material in the public domain or where your use is permitted by an 'applicable exception or limitation .
'No warranties are given. The license may not give you all of the 'permissions necessary for your intended use. For example, other 'rights such as publicity, privacy, or moral rights may limit how you 'use the material.
'Simple IR receiver for the PIC16F18323: ' V3.1
' PICBASIC PRO
DEFINE OSCCON_1K 1
define OSC 32
low portc
low porta
' SETUP I/O
TRISA = %00001001
TRISC = %00100000
'''''''''''''''''''''''''''''''''''The inits
initIR:
define PULSEIN_MAX 2800
pwrswc var porta.0
pwrled var porta.1
source3 var porta.2
IR_Sense var porta.3
pwrrly var porta.4
murly var porta.5
source2 var portc.0
source0 var portc.1
source1 var portc.2
mtrA var portc.3
mtrB var portc.4
srcswc var portc.5
st var word
IRWord var word
bits var byte
ID var word
power var bit
mute var bit
temp var byte
temp1 var byte
source var byte
salt var byte
direction var byte
button1 var byte
button2 var byte
button3 var byte
button4 var byte
button5 var byte
button6 var byte
ircount var byte
salt =125
read 0, source
if source > 4 then source = 1
low source0
low source1
low source2
low source3
mute = 1
gosub volmute
power = 1
gosub powerset
mute = 0
gosub volmute
toggle pwrled
''''''''''''''''''''''''''''''''''''''Main Program
direction = 10
gosub stpmtr
top:
if pwrswc = 0 then gosub hardpwr
if mute = 1 and power = 1 then toggle pwrled
gosub scanir
if button1 > 1 then gosub powerset
if power = 0 then goto top
if button6 > 1 then gosub volmute
if mute = 1 then goto top
if button4 > 1 then gosub volup
if button5 > 1 then gosub voldown
if button2 > 1 then gosub sourceup
if button3 > 1 then gosub sourcedown
if direction = 1 or direction = 2 then direction = 11
if direction > 10 then direction = direction + 1
if power = 1 and mute = 0 then high pwrled
if srcswc = 0 then gosub hardsrc
if direction = 25 then gosub stpmtr
goto top
volup:
toggle pwrled
gosub resetbuttons
low mtrB
high mtrA
pause 50
gosub debounce
direction = 1
return
voldown:
toggle pwrled
gosub resetbuttons
low mtrA
high mtrB
pause 50
gosub debounce
direction = 2
return
hardpwr:
gosub stpmtr
gosub powerset
debounceloop:
pause 10
if pwrswc = 0 then goto debounceloop
pause 500
return
hardsrc:
if mute = 1 and power = 1 then return
source = source + 1
if source = 5 then source = 1
gosub setsource
debouncesrc:
pause 10
if srcswc = 0 then goto debouncesrc
pause 100
return
powerset:
gosub resetbuttons
if power = 1 then
power = 0
low pwrled
low pwrrly
mute = 1
high murly
low source0
low source1
low source2
low source3
low mtrA
high mtrB
gosub longpause
low mtrB
mute = 0
low murly
write 0, source
else
gosub setsource
power = 1
high pwrled
high pwrrly
mute = 0
low murly
endif
gosub stpmtr
'gosub debouncelong
return
volmute:
gosub resetbuttons
if mute = 0 then
toggle pwrled
mute = 1
high murly
else
mute = 0
low murly
endif
gosub stpmtr
'gosub debouncelong
return
sourceup:
toggle pwrled
gosub stpmtr
gosub resetbuttons
source = source + 1
if source = 5 then
source = 4
gosub debounce
return
ELSE
gosub setsource
gosub debounce
return
ENDIF
return
sourcedown:
toggle pwrled
gosub stpmtr
gosub resetbuttons
source = source - 1
if source = 0 then
source = 1
gosub debounce
RETURN
ELSE
gosub setsource
gosub debounce
return
ENDIF
return
setsource:
'high murly
low source0
low source1
low source2
low source3
pause 50
if source = 1 then high source0
if source = 2 then high source1
if source = 3 then high source2
if source = 4 then high source3
'pause 50
'low murly
return
longpause:
for temp = 1 to 25
high pwrled
pause 250
low pwrled
pause 250
next
return
stpmtr:
low mtrA
low mtrB
direction = 0
gosub debouncelong
return
resetbuttons:
button1 = 0
button2 = 0
button3 = 0
button4 = 0
button5 = 0
button6 = 0
return
scanir:
for ircount = 1 to 3
gosub irin
If irword > 2000 then
if irword = 2069 then button1 = button1 + 1
if irword = 2173 then button2 = button2 + 1
if irword = 2158 then button3 = button3 + 1
if irword = 2066 then button4 = button4 + 1
if irword = 2067 then button5 = button5 + 1
if irword = 2068 then button6 = button6 + 1
endif
next
return
irin:
ID = 0
irword = 0
pulsin IR_Sense, 0, st
IF st < 1100 or st >2600 Then Return
For bits=0 to 11
Pulsin IR_Sense,0,id ' Receive the IR bits
ir_word.0[bits] = 0
If id >=450+salt then irword.0[bits] = 1
Next
return
debounce:
pulsin IR_Sense, 1, st
'LCDOUT $FE, $C0, #st
IF (st >1200) or (st = 0) Then Return
goto debounce
debouncelong:
ir_word = 0
pulsin IR_Sense, 1, st
'LCDOUT $FE, $C0, #st
IF (st = 0) Then return
goto debouncelong
