relay volume control - POP!

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Hello,

I've made a PIC-controlled output attenuator per the Aleph P 1.7
schematic for my, well, for my Aleph P 1.7 clone. Funny how that
works.

It's pretty good in operation - but there are maybe 3 places
where there are audible pops in transition from one volume
setting to the next. The worst (surprise !!!) is when the msb
transitions.

Anyone got any advice on how to fix this?

I've thunk of a few things myself but it's a bunch of time to
try these out one by one until I get something that is good.

1) go to 0 volume as an interim from one volume setting to the
next. I'm thinking maybe 5 ms or so. Just enough to get rid
of overlaps. I can adjust the delay using my controller with
very little effort - it's just another download.

2) cascade the changes up one bit at a time when making a
change up and cascading the changes down one bit at a time
when making a change down.

Thanks for any help in this regard.

OK OK so I know now there will be some interest in what I did.

My amp is a 2-chassis job with the controller and power supplies
in one chassis and an analog-only chassis. There is no digital
noise in the analog chassis because the only time any digital
circuitry changes in that chassis is when a control input changes.
The digital control in the analog chassis is totally isolated from
the analog circuitry. They are connected at the transformer
primaries only and a 1k resistor to chassis ground in the power
supply chassis so that the digital common doesn't float WRT
ground.

I basically copied the entire analog part of the Aleph P 1.7
schematic with the following exceptions:

1) since I don't have the Pass Labs program to control the
amp, I made my own digital control subsystem. That part is
all mine - the board, the SW, etc. I used a PIC16F684 as the
controller, I have 8x 8-bit S-P converters to create a 64-bit
output field from the PIC, and I have encoders as inputs for
volume, balance, and select. I also have a mute input switch.
I have a turn-on output mute delay, volume is 8 relays
controlled from a 64 level lookup table with volume steps
chosen as 4 piecewise linear transfer functions, and I have
left and right volume 7-segment displays that are also driven
by lookup tables in the PIC. It almost looks professional.
hahahaha

2) I substituted 3300 uF caps for all the 1000 uF caps in the
power supply system.

3) I added 2x 10 uF WIMA film caps on all power rails in the
amps.

Other than that, it's an Apleph P 1.7 clone.

So now for the next bit that everyone wants to know. How it
sounds. To set the stage, I've been using a BoSoZ for a few
years now. All I can say is WOW. The P 1.7 is far more revealing
and fine. It finds all sorts of stuff I've never heard before.
And it drives better down low than the BoSoZ does. I find that
the soundstage has a lot more depth, or that it now has depth.
And probbably because my BoSoZ uses an input attenuator and
the P has an output attenuator, the P is spooky quiet. You can
set the volume to very high levels, press play, and then BLAM,
on a tune with a dynamic start, the sound just hits you in the
chest. You have no clue that it is on its way before it hits. Truly
dynamic.

My system so far: (it's a journey....)
Aleph 2 clone monoblocks
Aleph P 1.7 clone
Classe CDP0.3 CD player
home grown "maxx/utopia" mutt speakers
 
jh6you: There are diodes across the coils. #1 - I can't see why this
would matter to the relay outputs. If there are no diodes, then it
would kick back the controller, not the amp. #2 - There are only
3 step transitions where you can hear any pop at all. These are NOT
the max transition points (that is, the highest number of relays is
changing value) but rather they are when the msb or 2nd msb change
value. It's a good point but I can't see that it is the problem.

janneman - there is no DC offset. The output is AC coupled and the
attenuator is after the caps. Also - why then would it only be 3 steps
where there is a pop ? So again, good point and thanks but that's
not it unless I don't understand what you mean.

The problem, as I understand it, is that for maybe 1 or 2 ms or so, the
msb relay is connecting before other relays are disconnecting - meaning it
goes to almost full volume for a short period of time, then settles
at the correct volume. This is heard as a loud popping noise from the
speakers.

Any other takers or am I getting this wrong ???

W.
 
Perhaps using a different type of relay with a stack that opens fast will solve your problem?

If you have old phone relays for example, you can use a tab bender to set the make-break ratio of the relay which will set how far the armature must move before the contacts open and close.

I know this is a bit of work, but if your problem is caused by relays not opening in time, I would suggest that as a means to rid yourself of the problem at its root.

PS: Have you tried any other relays in your circuit?
 
AX tech editor
Joined 2002
Paid Member
wayne325 said:
jh6you: There are diodes across the coils. #1 - I can't see why this
would matter to the relay outputs. If there are no diodes, then it
would kick back the controller, not the amp. #2 - There are only
3 step transitions where you can hear any pop at all. These are NOT
the max transition points (that is, the highest number of relays is
changing value) but rather they are when the msb or 2nd msb change
value. It's a good point but I can't see that it is the problem.

janneman - there is no DC offset. The output is AC coupled and the
attenuator is after the caps. Also - why then would it only be 3 steps
where there is a pop ? So again, good point and thanks but that's
not it unless I don't understand what you mean.

The problem, as I understand it, is that for maybe 1 or 2 ms or so, the
msb relay is connecting before other relays are disconnecting - meaning it
goes to almost full volume for a short period of time, then settles
at the correct volume. This is heard as a loud popping noise from the
speakers.

Any other takers or am I getting this wrong ???

W.


If there is no DC offset there can be no pop. Even with AC coupling, the bias current from the amp input will come from the amp input and flow "backwards" through the attenuator to charge the AC coupling cap to a certain DC. Depending on the switching that DC will also be switched and that gives the plop. Especially when you switch the msb because there the change is max.
Try to measure the DC at the input pin (after the cap, no signal) then switch the msb. What is the difference?
Do you have a schematic of that input stage you can post?

Jan Didden
 
Jan,

"If there is no DC offset there can be no pop"

I believe that if you connect the output of a preamp to a power amp
for 3 ms at fulll volume, then return it to normal, it will sound like a
"pop" or a "bang".

This is an output attenuator, not an input attenuator. It's the attenuator
from the Aleph P 1.7.

Alain, have you had this problem before and solved it by muting for a
second ?

I'm proposing to do this:
detect need for input change
set all relays to 0
wait x ms
set all relays to new volume setting.

What I'm concerned about is that when the relays all get set to their
new value, do I still get a pop - or do I get pops in different places on
the map?

I don't want to mute at volume changes because that means the mute
relays will take a pounding. Maybe this isn't a problem ?

Clearly, I can't change relays to fix this problem. The time and cost
would be huge.

W.
 
Hi,
Relays have different make/break times, and typically, the latch off time is shorter than the latch on time by a few milliseconds (1 to 2 ms, check your relays' datasheet). Then, when changing from one volume combination to an other one, you'd have to first activate the relays that will be going from off to on, leaving the previously activated relays on, and a few millisecond later (corresponding to the difference between the lach on and the latch off), you'll have to switch off all the relays that need to be off... Doing this, the moment when relays actually switch on and off should be the same, and the POP should be gone...
Dunno if I'm clear here... But since your attenuator is µC driven, it's quite easy to implement using a parametrable time out interrupt to do this, and you can modify the timeout delay to match your relays' specifications...

Hope this helps :xeye:
 
Cheff,

OK so what you've described got me thinking. What I'm going to try
first is a mix of what I was going to do originally and what you described
in your post.

So here's the plan:

Volume is at setting X
input change detected
Set all relays to 0
one by one from lsb to msb, set relays to new setting with 1 ms between.
Volume is now at setting X+1 or X-1.

Example:

01111111 start value
input change = "add 1" (because this is the most interesting case)
00000000 (set to 0)
wait 1 ms
00000000 (load new lsb which is still 0)
wait 1 ms.....
00000000 (load new bit 1 which is also 0)
etc
00000000 (load new bit 6 which is also 0)
wait 1 ms
10000000 (load new bit 7 = msb which is 1)
and voila - no pop.

But there will be an 8 ms silence. I wonder what that sounds like.

I'll let you all know how it goes.

W.
 
OK so here's what I tried and it works much better - no more pop:

You just set all the relays off for a short time then give them the
new setting. I have a 3 ms delay right now and it's good. I'll play
with it by a ms here and there and see if I can improve it. There are
still some noises once in a while but nowhere near what it was.

Thanks for the ideas...

W.
 
Disabled Account
Joined 2002
wayne325 said:

jh6you: There are diodes across the coils. #1 - I can't see why this
would matter to the relay outputs. If there are no diodes, then it
would kick back the controller, not the amp. #2 - There are only
3 step transitions where you can hear any pop at all. These are NOT
the max transition points (that is, the highest number of relays is
changing value) but rather they are when the msb or 2nd msb change
value. It's a good point but I can't see that it is the problem.

I agree.

By the way, I have experienced with similar "pop" noise between step movement from one point to another of a volume attenuator. That was due to an instant "open" of the lower resistor arranged between the tap (output voltage point) and the ground when the tap was instantly in between the two step points, e.g. one step (v1)-->"max v"-->second step (v2).

Hoping this info will help your trouble shooting, in a way.

Regards
 
wayne325 said:
OK so here's what I tried and it works much better - no more pop:

You just set all the relays off for a short time then give them the
new setting. I have a 3 ms delay right now and it's good. I'll play
with it by a ms here and there and see if I can improve it. There are
still some noises once in a while but nowhere near what it was.

Thanks for the ideas...

W.

Ok Wayne,

Nice if you've got rid of pops ;)
I haven't tested for now what I've explained, that was just how I plan to do for the preamp I'm building :cool:

Jus to be clearer, here's how I would implement it :

When a volume change is detected, take the old value, make a logical OR with the new value (assuming the relays are active on a logical one), and send the result to the relays. After the (LatchOn-LatchOff) time is elapsed, send the new volume value to relays.

Example :
Old volume : 01100111
New volume : 01101000
ORed Value : 01101111
This ORed value is send to the relays. In this case, only the forth relay will begin to latch on.
In the same time, the time out is launched, and when elapsed, the new volume value is sent, making the first three relays to latch off...
I made the delay user-adjustable to find the best delay for given relays...

But it's only prospective, and your solution may be easier and more efficient :cool:
Cheers,
 
Hey guys,

Just noticed this thread and thought I might share my experiences.

First, janneman hit part of it right on the head, no DC means no pop, as long as the is no music when you are changing volumes. Constant DC offset will mean very bad relay attentuator performance, and actually shorten the life of the relays.

Unforutnately you can still get some pop when the music is playing because of the "momentary DC" that an AC waveform represents at the moment a relay switches.

Here is a section of source code from my Joshua Tree relay controller. It works very well for me and I get no noticible pops while changing volumes.

It works by setting "0" or "relay off / attenuated stage" bits first in a cascade one at a time then setting "1" or "relay on / pass through stage" bit cascading upward to final value. That way there are never a large number of switches that have to open or close at the same time, and thus no huge jump or fall in impedance to the circuit.

Code:
void change(unsigned char val) {
	unsigned char temp = last;
	unsigned char diff = val & last;
	int i,b;
	// set the attenuated stages first (0 bits)
	// most significant to least
	for (i = 6; i >= 0; i--) {
		b = 1 << i;
		// set attenuated - 0 - bits
		if ((temp & b) != (diff & b )) {
			temp -= b;
			RELAYS = temp;
			wait(SWITCH_TIME);
		}
	}
	// now set the pass through stages (1 bits)
	// least significant to most
	for (i = 0; i < 7; i++) {
		b = 1 << i;
		// set non-attenuated - 1 - bits
		if (((val & b) == b) && ((temp & b) != b)) {
			temp += b;
			RELAYS = temp;
			wait(SWITCH_TIME);
		}
	}
	RELAYS = val;
	last = val;	
}

I hope that helps.

Cheers!
Russ
 
Russ,

I am still getting small pops at some transitions. I am not totally
happy with it the way it is - but I was previosuly concerned about my
speakers and so I knew where the pops were and I would change the
select to an unused input to go past the pop point and then reengage
the correct input. I no longer have to do that so it is far far better.
I am no longer concerned for my speakers.

I think what you have done is the best way I have seen so far and this
is what I was going to try next. SO I'm happy to find someone else
who has had good results with it.

Cheff: I think your algorithm will not work ???
What will it do for this:
10000000 -> 01111111 ??? I think it goes to full volume first before
setting to the new value. So it is OK going up in volume buit not down.
I'm betting Russ has the "best" way.... First silence, wait a short time,
then load the relays bit by bit from lsb to msb.

THis is a good thread guys - thanks for the input.
 
Wayne,

Normally no, the volume won't have the time to go to full...

Just remember that the trick is to make the CONTACTS of the relay SWITCH on and off at the same time. Since the latch on time is larger than the latch off one, in your "worst case" (going up) the MSB relay will BEGIN to activate (the contact is still not made) , and during the "rising" period of the activated relay, all the other relays will be switched off, and the delay should be adjusted in such a way that both latch on and latch off time are equal.
In the "going down" case (100000->0111111), the same applies : all the LSB to MSB-1 relays will BEGIN to go up, and after a delay, the MSB relay will Begin to go down, in such a way that the contacts are switched on and off at the same time...
Or in other words, we try to match the time when the contact becomes actually closed and the moment when the contact is actually open.

There is a mechanical delay between the moment when you apply the voltage to the coil and the moment when the contact is made or open, and this delay is greater when the coil attracts the actuator that operates the switch than the delay occuring when the voltage disappears from the coil, and the spring and/or gravity takes control on the actuator and opens the switch... And we try to compensate for this difference...

That's the way I see it, and I will try it before the end of this month and report my findings, wether it works or not ;)

But for now, we've got at least three ways of doing this :D. This thread is great, gentlemen :cool:
 
Cheff,

Let us know how it goes for you.

Here's what I found after more experimentation this evening - I have
basically what Russ described. This is what my program does now and
it is the best it has been:

volume setting N
signal to change to N+1
set all relays to 0
wait 1ms
one by one re-energize the relays from lsb to msb

The combination of a small time to turn off then turn back on again
stops the pops from happening. It sounds good now on the volume
level transitions both up and down.

Here's some PIC code snippet:

update_relays_volume
call update_volume_levels
call update_displays
bcf STATUS, RP0 ; work in bank 0

movlw 0x00 ; blank out the volume relays
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x00
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
call delay_1ms

movlw 0x01 ; allow bit 0 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x01
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0x03 ; allow bit 1 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x03
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0x07 ; allow bit 2 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x07
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0x0F ; allow bit 3 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x0F
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0x1F ; allow bit 4 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x1F
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0x3F ; allow bit 5 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x3F
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0x7F ; allow bit 6 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0x7F
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers
;call delay_500us

movlw 0xFF ; allow bit 7 to go active
andwf table_right_vol, W
movwf right_volume_relays
movlw 0xFF
andwf table_left_vol, W
movwf left_volume_relays
call load_shift_registers

return




; this task will load the daisy chain registers from registers that will have the bits
; activated one by one.
load_shift_registers
bcf STATUS, RP0 ; work in bank 0
movf display_right_low, W ; farthest SR in daisy chain
call serial_shift_8
movf display_right_high, W
call serial_shift_8
movf display_left_low, W
call serial_shift_8
movf display_left_high, W
call serial_shift_8
movf select_leds, W
call serial_shift_8
movf select, W
call serial_shift_8
movf right_volume_relays, W
call serial_shift_8
movf left_volume_relays, W ; closest SR in daisy chain
call serial_shift_8
call parallel_shift ; update all the outputs to the relays at one time
return


; this function writes to the outputs 8 bits serially in order from msb to lsb, the
; W register contains the value to be shifted when the function is called.
serial_shift_8
movwf temp8
movlw 0x08
movwf loop_count
loop_point
rlf temp8, F
movf STATUS, W
movwf write_reg_c
movlw 0x01
andwf write_reg_c, F
bsf write_reg_c, 3
movf write_reg_c, W
movwf PORTC
bsf write_reg_c, 1
movf write_reg_c, W
movwf PORTC
decfsz loop_count, F
goto loop_point
return


; this function wiggles the parallel shift output so that the serially shifted data
; in the SR daisy chain can be presented to the relays at one time. IF it turns out
; that we need to do something fancy with the reloading of registers because of loud
; glitches when the volume relays change values, it'll probably have to go into this
; area.
parallel_shift
movlw 0x08
movwf PORTC
movlw 0x0C
movwf PORTC
movlw 0x08
movwf PORTC
return



; use the internal clock to make a 1 ms delay used for debouncing and other such
; things that require a delay. The clock is 1 MHz, so 1 ms is about 250 timer tics.
; Since the timer counts once per instruction, each instruction is 4 clock ticks.
; The timer counts UP and we get an interrupt when it rolls over. So set the clock
; to 2^16 - 250 decimal = 65536 - 250 = 65,286 = FF06.
delay_1ms
bcf STATUS, RP0 ; bank 0
bsf timer1_loop_test, 0 ; set a flag to end loop if ISR has returned
clrf T1CON ; clear out the timer

movlw 0x06 ; wait for 700 decimal
movwf TMR1L
movlw 0xFF
movwf TMR1H

bcf PIR1, TMR1IF ; clear the interrupt for timer 1 before enabling
bsf STATUS, RP0 ; bank 1
bsf PIE1, TMR1IE ; enable the timer1 interrupt
bcf STATUS, RP0 ; bank 0
bsf INTCON, PEIE ; enable the peripheral interrupt
bsf INTCON, GIE ; enable the global interrupt
movlw 0x05 ; turn on timer1
movwf T1CON

wait_delay_1_ms ; drop into loop to wait until interrupt hits
nop ; you return here when the timer ISR is finished execution
btfsc timer1_loop_test, 0
goto wait_delay_1_ms

bcf STATUS, RP0
bcf T1CON, TMR1ON ; disable timer1
return
 
plops

Hi Wayne,

I had the same experience as you with my A1.7 with the original relay volume control.
The most simple and effective sollution is a RC filter at the base of each switching transistor. In my case i use 100k 0.57uf .
I use takamisawa 24v relais.

Now the control is as quiet as a mouse.

Regards,
Johan.
 
Latest update...
I removed the 1 ms delay after the relay blanking and before
cascading up the new value and still no pop and a better sound
than with the delay. So I'm going to leave it like this for a while.
Meaning - the PIC is slow that running the bare code with no added
delays gives enough delay to get rid of the pops. It only runs 250,000
instructions per second, so 250 instructions is about 1 ms and I think
there are about 1,000 instructions resetting the relays. I suppose I
could run the simulator and figure out how many but I'm too lazy right
now. It works pretty well so I'm going to lave it for now.

Thanks for the suggestions gents - but I was really looking for a
software solution (no parts, no hacking with boards, it takes 10 minutes
instead of 3 hours....) and I found one.

W.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.