Go Down

Topic: Digital Volume with CD4067 + ATtiny85 (Read 2499 times) previous topic - next topic

WilliamK Govinda

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

Code: [Select]
// 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;
}

Go Up