2013. augusztus 19., hétfő

Another batch of attenuators


Hello there!
I already told some bits about how the attenuators are being made. Now I want to share the complete story with you.

First of all I mentioned there is no mass production. That is right, every attenuator is hand built at nights and on weekends at home.
Because of this, there is only a small quantity is built in one time.

But first, the basics, the PCBs are manufactured in a small local shop.
It is nicely made and has routed edges. As the finished attenuators, the boards are made by hand as well, the shop is not automated, and welcome small orders too.

Because of the generally low part availability here, the other parts are ordered from about five different suppliers, some local and some from other countries.
When everything arrives the building begins.

The finished units are being tested, every function plus the remote. Then it is packed and stored and waiting for its new owner to be arrived to.

Finished 8th note Stepped Attenuators

Doing this on a free time basis, I still thinking on new kits for next year, I hope I can do it. It also depends on the popularity of the stepped attenuators, and my free time. Until then, please follow the links to the 8th note Stepped Attenuator,
and don't hesitate to contact me if you have any questions.

The main page:
http://www.8thnote.eu

Product page of the attenuator:
http://www.8thnote.eu/attenuator_details.html

2013. augusztus 8., csütörtök

What is the 8th note Stepped Attenuator, and what it isn't?


I want to make Your decision easier. Is it for your project, or it is not?

One of my design rules amongst the first ones was simplicity.
The cleanest and finer look of an amplifier's face can be found in stereo amplifiers.  Every manufacturer made it, like Onkyo, NAD, Harman/Kardon to mention a few.
The basics of the user interface for a stereo amplifier are not more than a power button, and a volume knob next to a channel selector.
In fact, I am still using a stereo amplifier at my home that does not even have a remote. That's right. I walk there, to turn the knob.

So when the idea of the 8th note Stepped Attenuator came, I wanted it to let me use it with closed eyes. Still knowing where the knob is pointing, it is essential not to use rotary encoders, but traditional pots. Following this idea, turned out that the attenuator have only three LED indicators, to show some functions, but nothing more.

I made the following list based on the most asked questions, I hope it will make your decision easier:

What the 8nSA is?

-It is a superior attenuator for single ended and balanced amplifiers
-It mimics the conventional potentiometer in much higher quality
-It is designed for DIY projects, and needs some soldering
-It have remote control functionality as a secondary control
-It is made in simplicity and compactness in mind
-It is made by hand in low quantities for a limited time

What the 8nSA is not?

-It will not give you total flexibility, but the all the basic things you will need
-It does not have nice display, like numerical displays or similar, but if it is your thing, I made documentation to help you make one

The user experience is unique.
If you have not tried a stepped attenuator, you have to taste it. This unit will give all the clarity your ears desire, with a high tech brain to do it well.

If you choose to try it, you will experience the finest analog attenuation solution we know until now.

2013. augusztus 1., csütörtök

Using Arduino with the 8th note Stepped Attenuator

The gateway to external displays

This text is about how to use an Arduino to read data from the 8th note Stepped Attenuator.
The Arduino is an easy to use programmable hardware, wich is very popular amongst DIY-ers.
If you want to make an external display for your attenuator then this is where you must start.



What is possible?
There are digital ports on the driver board. Using these ports it is possible to read the following:
-is MUTE on?
-is LULO active?
-is SRC2 selected?
-what is the attenuation level?

What is it good for?
You can use these data to output text on a display, or make a led bar show the attenuation level, or do whatever you can think of to do with. You can find inspiring ideas in the last blog entry.

What skills are needed?
You need some experience in using Arduino and programming it. If you are not familiar with Arduino, then stop at Arduino's webpage first. There are many good articles to beginners, helpful communities, user forums and lots of example codes on the internet, which can help you in the first steps.
Because there are many infos out there about Arduino, I will not duplicate it here. This article will focus on helping users to write the 8th note specific part of their own program.

What will we do?
We will read the state of the MUTE, LULO and SRC2 LEDs, which is the simplest task. We will read the digital out (DO) port and decode the attenuation level.

Lets start it!
First you have to solder two unpopulated headers into the board. The one called DO (1x3 pin) and located on the bottom right corner of the driver board,
the other has no name and located next to the status LEDs (2x3 pins). We will use these headers or at least part of it.



The "LED header" (lets call it that way) contains pins to read the LEDs status.
You need to wire these pins to GPIO input pins:

You have to check these pins state on the Arduino, it has the value either HIGH or LOW. Choose pins that are not needed later for something else.
Please note, the pins status are LOW when the function (and its LED) is active.
The state of the pins can be read with the following (well known) way:

//let the pins connected to the following:
int mutePin = 7;
int luloPin = 8;
int src2Pin = 9;

//store the pin state in these variables
int mute_State = 0;
int lulo_State = 0;
int src2_State = 0;

void setup()
{
  pinMode(mutePin, INPUT);      // sets the digital pin as input
  pinMode(luloPin, INPUT);      // sets the digital pin as input
  pinMode(src2Pin, INPUT);      // sets the digital pin as input
}

void loop()
{
  mute_State = digitalRead(mutePin);   // read the input pin
  lulo_State = digitalRead(luloPin);   // read the input pin
  src2_State = digitalRead(src2Pin);   // read the input pin
}

Now if you have the variables then you can change your display according to it.

This was the easy part.

How to get the attenuation level?
The attenuation level can be read on the DO header of the driver board.
The DO port uses standard SPI communication. If you are not familiar with SPI, then follow this link to the Arduino SPI reference:
http://arduino.cc/en/Reference/SPI

A short quote from it:
"Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers."


This is what we will do.
The SPI protocol uses a Clock and a Serial data line. When the clock ticks, the serial line state in the receiver is stored in a register. When it ticks again, it stores the next value in the register, until 8 bits are received.



In our case, the Master (and transmitter) will be the 8th note Stepped Attenuator and the Slave (and receiver) will be the Arduino. The SPI protocol defines a Slave Select (SS) pin what we don't use, because we have only one slave.
The DO port has the SCK (serial clock), the MOSI (Master Out Slave In) and a GND (ground) pins.


Note that MOSI, and SCK are available in a consistent physical location on the Arduino's ICSP header. You need to wire these pins.

Arduino ICSP header pinout

When finished with the wiring, lets think a little together.
The following is important and specific to the 8th note Stepped Attenuator:
  • The attenuator transmits data only on state change, in other words, you can not request a transmission
  • The transmitted data consists of 16 bits or 2 bytes, and repeated once
  • The two byte long data can be decoded to return the attenuation level

The transmitted data bits are mixed for design reasons, and can be decoded in a quick function that returns a byte between 0 and 127. The attenuator thus has 128 levels, each level means -0.5dB attenuation. So the total attenuation is -63.5dB. You do not have to bother with the repeated transmission, it differs in its bits, but when decoded it returns the same value. You do not need to omit any transmission, just decode it again, it won't hurt.

To receive the data, the Arduino must be listening. It has to receive two bytes, and store it in two variables. When two bytes has been received, call the decode function, so it can refresh the attenuation level variable.
If this is done in an interrupt, then the attenuation level variable keeps refreshing automatically and your display code can use or process this variable.

This flow chart explains the process:
Flow chart of the Arduino SPI receiver and data decoder routine interrupt


You can test and edit the following code for your needs.
Please note this code has not been tested yet, because I don't have my Arduino at the moment. But if you test it, and send me a report, I will update the code with your name.

// Sample Arduino code for 8th note Attenuator
// Written by Kara László
// 22. July 2013.
// Tested by: UNTESTED
// at:

/*
PLEASE NOTE:
The attenuator sends data only on state change. There is no method for requesting transmission.
The attenuation level is stored in the aLevel variable.
(aLevel == 0) means no attenuation or full volume
(aLevel == 127) means full attnuation or lowest volume

To translate the aLevel to dB:
 0 :    0dB
 1 : -0.5dB
 2 :   -1dB
 3 : -1.5dB
 4 :   -2dB
...
126:  -63dB
127:-63.5dB
*/

#include <SPI.h>

volatile byte FirstByte = 0; //the first storage
volatile byte SecondByte = 0; //the second storage
volatile boolean FirstByteReceived = false; // True if first byte is stored, second is transmitting
volatile byte aLevel = 0; // the attenuation level (0-127)
byte aLevel_Temp = 0; //temp to be able to compare the next aLevel with
float adB = 0; //attenuation in dB only for display

void setup (void)
{
// have to receive in "Master Out Slave In" pin
pinMode(MOSI, INPUT);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPI.attachInterrupt();
// set up Serial library at 9600 bps
Serial.begin(9600);
Serial.println("Hello 8th note Stepped Attenuator!"); // prints hello with ending line break
} // end of setup

//decoder function
byte DecodeaLevelData(byte data1, byte data2)
{
unsigned int inData = (data2) | ((unsigned int)(data1)<<8);
unsigned char decodedData = 0;
decodedData |= (unsigned int)(0b0000000000000010 & (inData))>>1;
decodedData |= (unsigned int)(0b0000000000001000 & (inData))>>2;
decodedData |= (unsigned int)(0b0000000000010000 & (inData))>>2;
decodedData |= (unsigned int)(0b0100000000000000 & (inData))>>11;
decodedData |= (unsigned int)(0b0001000000000000 & (inData))>>8;
decodedData |= (unsigned int)(0b0000100000000000 & (inData))>>6;
decodedData |= (unsigned int)(0b0000001000000000 & (inData))>>3;
return decodedData; //sending back 0-128 level
}

// interrupt routine on SPI transmission end
ISR (SPI_STC_vect)
{
// grab byte from SPI Data Register & put it in temp
byte temp = SPDR;
//if first byte is received then store it in FirstByte
if (!FirstByteReceived)
        {
        FirstByte = temp;
        FirstByteReceived = true;
        }else{
//if second byte is received then store it in SecondByte
        SecondByte = temp;
//now we have two bytes that need to be decoded
//aLevel will have the attenuation level
        aLevel = DecodeaLevelData(FirstByte, SecondByte);
//reset byte counter
        FirstByteReceived = false;
        }
} // end of interrupt routine SPI_STC_vect

// start of main loop
void loop (void)
{
if (aLevel != aLevel_Temp)
    {
    //calculating attenuation in dB
    adB = ((float)aLevel * (-0.5));
    //printing message
    //will output like "Attenuation: 31 dB"
    Serial.print("Attenuation: ");
    Serial.print(adB, DEC);
    Serial.println(" dB");
    //stores aLevel to temp
    aLevel_Temp = aLevel;
    }
} // end of loop

Considerations:
If you use the Arduino's MOSI pin, it can not be used for another SPI communication.
But If you need that, you can implement the SPI in any GPIO pin by software. You will not have time issues because the attenuator SPI transmission is slow.
The microcontroller of the attenuator runs on only 1MHz, compared to the Arduino's 20MHz.

I hope this article was useful, and easy to understand. If you have any questions, contact me. If you have a project, or idea You would like to share with others, feel free to do so in the comments area.