Here's a small project I did to add a Digital Stereo Volume on my Car-Stereo using 2x CD406, 1x ATtiny85 and just one touch-sensitive button: single click = volume down, double click + hold = volume up.
I adapted the following circuit: http://english.cxem.net/izmer/measured3-2.jpg
And here's the code for the ATtiny85. It uses the libs and explanations from the Beat707 BigTime code.
https://github.com/Beat707/Beat707-BigTime
// Arduino Stereo Volume - by WilliamK @ Wusik.com & Beat707.com - October 04 2011 - V 1.0.0 //
#include <EEPROM.h>
/*
The system uses a Touch Pin (Capacitive Touch) to do the following: single click = volume down / double click = volume up (also supports "holding & repeat" for both actions).
We use two C4067 multiplexers chips (we had those in our old-stock) with different resistors on each input and a ATtiny85 to controll the system.
ATtiny85 pins:
8 = 5V
4 = Ground
3 = Touch Sensor
5 = C4067 S0
6 = C4067 S1
7 = C4067 S2
2 = C4067 S3
4067 pins:
1 = Output
24 = 5V
12 = Ground
10 = S0
11 = S1
14 = S2
13 = S3
15 = Ground
9 = Input 0 (no volume)
8 = Input 1 (Volume 1)
7 = Input 2 (Volume 2)
6 = Input 3 (Volume 3)
5 = Input 4 (Volume 4)
4 = Input 5 (Volume 5)
3 = Input 6 (Volume 6)
2 = Input 7 (Volume 7)
*/
// ------------------------------------------------------------------------------------------------------------------------ //
#define outPinSel0 PINB0 // Output pin for the S0 4067 Multiplexer - Pin 5 on the ATtiny85
#define outPinSel1 PINB1 // Output pin for the S1 4067 Multiplexer - Pin 6 on the ATtiny85
#define outPinSel2 PINB2 // Output pin for the S2 4067 Multiplexer - Pin 7 on the ATtiny85
#define outPinSel3 PINB3 // Output pin for the S3 4067 Multiplexer - Pin 2 on the ATtiny85
#define touchPin PINB4 // Pin 3 on the ATtiny85
#define doubleClick 200 // Time for the Double Click in ms (Volume Up)
// ------------------------------------------------------------------------------------------------------------------------ //
int def2, num1, num2, num3, def = 0;
uint8_t isOn = false;
uint8_t prevIsOn = false;
unsigned long lastMillis = millis();
uint8_t prevButton = 0;
uint8_t curButton = 0;
uint8_t wasButtonLow = 1;
uint8_t volumeSelector = 0;
uint8_t isDoubleClick = 0;
// ------------------------------------------------------------------------------------------------------------------------ //
void setVolumeOutputTo4067Chip()
{
digitalWrite(outPinSel0, bitRead(volumeSelector,0));
digitalWrite(outPinSel1, bitRead(volumeSelector,1));
digitalWrite(outPinSel2, bitRead(volumeSelector,2));
digitalWrite(outPinSel3, bitRead(volumeSelector,3));
}
// ------------------------------------------------------------------------------------------------------------------------ //
void setup()
{
pinMode(outPinSel0, OUTPUT);
pinMode(outPinSel1, OUTPUT);
pinMode(outPinSel2, OUTPUT);
pinMode(outPinSel3, OUTPUT);
pinMode(touchPin, INPUT);
/*digitalWrite(outPinSel0, HIGH);
digitalWrite(outPinSel1, HIGH);
digitalWrite(outPinSel2, HIGH);
digitalWrite(outPinSel3, HIGH);
delay(250);*/
digitalWrite(outPinSel0, LOW);
digitalWrite(outPinSel1, LOW);
digitalWrite(outPinSel2, LOW);
digitalWrite(outPinSel3, LOW);
prevButton = getcap(1<<touchPin);
}
// ------------------------------------------------------------------------------------------------------------------------ //
void loop()
{
curButton = getcap(1<<touchPin);
if (curButton != prevButton)
{
prevButton = curButton;
if (wasButtonLow == 1 && curButton > 1)
{
wasButtonLow = isDoubleClick = 0;
// Detect Double Click //
delay(doubleClick);
if (getcap(1<<touchPin) <= 1)
{
delay(doubleClick);
if (getcap(1<<touchPin) > 1) isDoubleClick = 1;
}
if (isDoubleClick) { if (volumeSelector < 8) volumeSelector++; } else { if (volumeSelector > 0) volumeSelector--; }
setVolumeOutputTo4067Chip();
if (getcap(1<<touchPin) > 1) delay(400);
while (1)
{
if (getcap(1<<touchPin) <= 1) break;
if (isDoubleClick) { if (volumeSelector < 8) volumeSelector++; } else { if (volumeSelector > 0) volumeSelector--; }
setVolumeOutputTo4067Chip();
delay(400);
}
}
if (curButton <= 1) wasButtonLow = 1;
}
}
// ------------------------------------------------------------------------------------------------------------------------ //
char getcap(char pin)
{
char i = 0;
DDRB &= ~pin; // input
PORTB |= pin; // pullup on
for(i = 0; i < 2; i++)
{
if( (PINB & pin) ) break;
}
PORTB &= ~pin; // low level
DDRB |= pin; // discharge
return i;
}