Arduino based LDR volume and source selection controller

Would it be possible to program a "power off" sequence that sets the output to Mute before it powers down?

This is already in the code. Problem is power on, until arduino wakes up.

Here's the solution for volume burst after power on, when stored volume=0:

move this to the end of void setVolume():

if (isMuted == vol || (isMuted && vol))
setMute(vol);
 
Last edited:
So, does that resolve the issue? Or should I still be looking at some alternative, like leaving the Aurdunio powered all time, and shutting down the other power hungry portions of my project separately (DCB1 buffer)? (or even doing something like a master power on/off switch that mutes the output for a few seconds before transitioning to a new power state).
I got your board yesterday,thanks ! Tiny.. not sure what I was expecting but tiny..
 
This is already in the code. Problem is power on, until arduino wakes up.

Here's the solution for volume burst after power on, when stored volume=0:

move this to the end of void setVolume():

if (isMuted == vol || (isMuted && vol))
setMute(vol);

I've tried this amendment on mine but unfortunately I still get the volume burst.

I can't quite work out why it does this only when the stored volume is 0. It's an odd one.

Chris
 
Finally making some progress getting this into case...
 

Attachments

  • IMAG3609.jpg
    IMAG3609.jpg
    778.1 KB · Views: 872
Thanks, it seems to work well. The change was originally to prevent repeat codes from other remotes (TV etc...) from triggering volume up/down events some time, i.e. even hours, after initially adjusting the volume of the LDR unit using the Apple remote. It also, unintentionally but usefully, helps prevent the issue described by zdr.

I also moved the LCD fade-in call to only fade-in the LCD if a valid, non-repeat code is received, again to prevent the LCD from fading-in when receiving repeat codes from other remotes.



New global variable declaration:
Code:
unsigned long mil_onRemoteKey = 0; // Stores time of last remote command

Modification of the main loop:

Code:
	/////////////////////////////////////////////////////////////////////////////////////
	// IR Remote
#pragma region loop_remote
	if (millis() - mil_onRemote > TIME_IGNOREREMOTE_CMD && digitalRead(PIN_REMOTE) == LOW && (state == STATE_RUN || state == STATE_IO)) {

		IRkey = getIRkey();
		if (IRkey != 255 && IRkey != 2) {

			mil_onAction = millis();
			isIRrepeat = IRkey == 0;

			// Prevent repeating if a code has not been received for a while.
			if ((millis() - mil_onRemoteKey) > 750)  {
			   isIRrepeat = 0; 
			}

			if (IRkey == cIR_UP || IRkey == cIR_DOWN || IRkey == cIR_LEFT || IRkey == cIR_RIGHT || IRkey == cIR_PLAY || IRkey == cIR_MENU) {
				startLCDFadeIn();
			}                        
                        
			if (isIRrepeat && (previousIRkey == cIR_UP || previousIRkey == cIR_DOWN))  // Repeat the specified keys
				IRkey = previousIRkey;
			else
				previousIRkey = IRkey;

			mil_onRemoteKey = millis();

			//PRINT("IR: "); PRINTLN(IRkey);

			switch (IRkey) {

This seems to work well for me Chris. Well done. I can't stick it in the wrong direction anymore.
 
Yep, my mod is not a fix, just a workaround for my situation. I am not surprised to see it doesn't work with lcds. But I will build a variant with lcd soon, so I am eager to see proper solution myself.

I still get this issue with this mod too. What if we were to check for mute at power down and setvolume to 1 instead?

I've got so many projects and other things going on at the moment, and my LDR attenuator is working fine apart from this small bug that I've not been able to justify spending time on it.

Please do reply if you manage to fix the problem. I'll try to devote some time to it in a couple of weeks.

Chris
 
I'll try to devote some time to it in a couple of weeks.

Please do reply if you manage to fix the problem. I'll try to devote some time to it in a couple of weeks.

Chris

I managed to find some time to look at this tonight and I think I've solved the problem by amending setVolume to look like this:

Code:
void setVolume(byte vol) {

	bool goHighL, goHighR, goLowL, goLowR;
	byte i = vol - 2;

	if (vol == 1 || vol == 0) {
		setLSE_Range(HIGH); setRSE_Range(HIGH);
		setLSH_Range(LOW); setRSH_Range(LOW);
		setLSE(2); setRSE(2); setLSH(200); setRSH(200);
	}
	else if (vol == VOL_MAX_STEP) {
		setLSE_Range(LOW); setRSE_Range(LOW);
		setLSH_Range(HIGH); setRSH_Range(HIGH);
		setLSE(255); setRSE(255); setLSH(0); setRSH(0);
	}
	else {
		setLSE_Range(HIGH); setRSE_Range(HIGH);
		setLSE(dataL[i].pw_SE); setRSE(dataR[i].pw_SE);
		setLSH(dataL[i].pw_SH); setRSH(dataR[i].pw_SH);


		goLowL = dataL[i].i_SH >= 32768 && LSHrange == HIGH;
		goLowR = dataR[i].i_SH >= 32768 && RSHrange == HIGH;
		goHighL = dataL[i].i_SH < 32768 && LSHrange == LOW;
		goHighR = dataR[i].i_SH < 32768 && RSHrange == LOW;

		if (goLowL) setLSH_Range(LOW);
		else if (goHighL) setLSH_Range(HIGH);

		if (goLowR) setRSH_Range(LOW);
		else if (goHighR) setRSH_Range(HIGH);

		mil_onSetLDR = millis();
	}

	printTwoNumber(VOLCOL, vol);

	if (isMuted == vol || (isMuted && vol))
	setMute(vol);
}

Previously in setVolume() there was a condition that allowed the LDR current to be modified only if the requested volume was > 0. This meant that when setVolume was called with 0 then the LDR currents were not changed and the relays were used to mute the output via setMute().

I think that the problem was that at startup the LDR currents are being set to nominal values that persist if the startup volume is 0 as setVolume(0) previously had no effect on the LDR currents due to the conditional logic. As the relays are used to mute the outputs then the actual LDR current doesn't actually matter when the output is muted. However once the volume was incremented for the first time and the relay states were modified to take the unit out of mute then due to the settle time of the LDR current it took a fraction of a second for the LDR currents to be adjusted away from their initial nominal startup values to those suitable for a volume level of 1. This caused the output level to shoot up and then gradually settle to the requested level.

The change I have introduced ensures that if setVolume is called with a value of 0 then the LDR currents will be set to the same values as if setVolume had been called with a value of 1. Now when the volume is incremented from 0 following startup then the LDR currents will already be configured for a volume of 1 and there is therefore no level increase prior to settling. As the level of 0 is achieved by relay switching anyway there *should* be no detrimental effects by leaving the LDR currents adjusted as if the requested volume level was 1 whenever a level of 0 is requested. The mute functionality continues to behave as before.

Chris
 
Last edited: