New polyhonic Teensy DIY Sampler

Hello everyone.
Because of the defective Teensy4 modules there are now changes in the circuit diagram of the Degenerator2.
There are changes to the Degenerator2 power supply circuit diagram. There is now only one +3.3 V power supply.
The +3.3 V power supply of the Teensy4 modules is no longer used.
@Rolfdegen: I think you meant "damaged" rather than "defective" on your Teensy4 modules. You wouldn't want a future reader to get the wrong impression...the T4s were working fine when you received them.

Mark J Culross
KD5RXT
 
Yes, that's right. I mean, damaged. I hope it doesn't happen again. I checked all the solder joints and connections again and found no errors. The new Teensys are arriving on Monday. I'm excited.
 
New Teensy's are arriving tomorrow, and I can continue working. Hopefully without damaged the Teensys. Why they had a short circuit on the TxD pin and the 3.3V pin remains a mystery to me :unsure:
 
Houston, we don't have a problem :)
The new Teensys work very well. Sound is great. Now I can continue working undisturbed.
 
News..
I've made some hardware changes. The 24 buttons are now controlled by two MCP23017 16-bit I/O expanders.
The encoders have been replaced with Alpha 360-degree endless rotary potentiometers.
The seven Alpha potentiometers are controlled by a 74HC4067 16:1 analog multiplexer and two analog inputs on the Teensy4.1.
Compared to encoders, the 360° Alpha potentiometers have the advantage that no time-critical query is required from the processor.
I've removed the seven ATtiny chips that were responsible for controlling the encoders, buttons, and potentiometers.

MPC23017 for key scanning
Screenshot 2025-06-12 111647.png


16:1 Analog Multiplexer 74HC4067
Screenshot 2025-06-12 111918.png

Alpha 360-degree endless rotary potentiometers
Screenshot 2025-06-12 112013.png
 
Hello friends,
The new Alpha potentiometers are a bit too stiff for me personally. For this reason, I was looking for a simple solution to make them a bit smoother.
Unscrewing or opening the Alpha potentiometers was out of the question, as I wanted to spare people who wanted to replicate the Degenerator2 the process. But a coincidence came to my aid. When I soldered the Alpha potentiometers in place, they became a little easier to turn. Once the potentiometer cooled down, they became stiff again. So I thought, just heat the thing. I quickly found a 330 ohm resistor, and the existing 12V power supply in the degenerator was available. I simply soldered the resistor over the Alpha potentiometer and connected it to the 12V supply. The resistor heats up and warms the Alpha potentiometer. Compared to a non-heated Alpha potentiometer, the heated Alpha potentiometer turns much more easily. The tactile feel is now similar to that of the encoders in the Blofeld.

Addendum: A dab of thermal paste improves thermal contact with the potentiometer ;-)

Alpha_470R.jpg


Addendum:
I've experimented a bit more and found that 470 ohm resistors are optimal for the Alpha potentiometers.
The 330 ohm resistors had overheated and made the Alpha potentiometers too easy to turn.
I used SG100X from Silverbead as the thermal adhesive.
 
Heated potentiometers... "The best ideas are always the unusual ones," someone once said.
This gives the Degenerator 2 an exceptional unique selling point ;)
 
So... the hardware is in place. Now comes the tricky part. Reading the Alpha potentiometers. There are seven in total. I use an analog input on the Teensy for this. The potentiometers are read via the 74HC4067 analog multiplexer. This has 16 analog inputs and three address lines for selecting the input channels.

Screenshot 2025-06-14 174018.png

20250614_172202.jpg
 
So... the hardware is in place. Now comes the tricky part. Reading the Alpha potentiometers. There are seven in total. I use an analog input on the Teensy for this. The potentiometers are read via the 74HC4067 analog multiplexer. This has 16 analog inputs and three address lines for selecting the input channels.

Make sure to read the datasheet for the 74HC4067 analog mux carefully. It works great, but you must respect the required settling time after setting the address lines & before reading the output.

Mark J Culross
KD5RXT
 
Reading 360° Endless Pot with library for eliminating noise in analogRead inputs

C:
#include <Arduino.h>
#include <ResponsiveAnalogRead.h>

// 74HC4067 Analog Multiplexer for Pots
int PotSel_1 = 2;
int PotSel_2 = 3;
int PotSel_3 = 4;
int PotSel_4 = 5;

// define the pin you want to use
const int ANALOG_PIN = A0;


// make a ResponsiveAnalogRead object, pass in the pin, and either true or false depending on if you want sleep enabled
// enabling sleep will cause values to take less time to stop changing and potentially stop changing more abruptly,
//   where as disabling sleep will cause values to ease into their correct position smoothly and more accurately
ResponsiveAnalogRead analog(ANALOG_PIN, true);
ResponsiveAnalogRead analog1(ANALOG_PIN, true);

// Setup -------------------------------------------------------
void setup()
{
    // init PotSel 74HC4067 Analog Multiplexer
    pinMode(PotSel_1, OUTPUT);
    pinMode(PotSel_2, OUTPUT);
    pinMode(PotSel_3, OUTPUT);
    pinMode(PotSel_4, OUTPUT);
    digitalWrite(PotSel_1, LOW);
    digitalWrite(PotSel_2, LOW);
    digitalWrite(PotSel_3, LOW);
    digitalWrite(PotSel_4, LOW);
    // init ADC Input for Pots
    analogReadResolution(10);
    analog.setAnalogResolution(1024);
   
}

// read Pots ---------------------------------------------------
void read_Pot()
{
    if (readPot_Timer > 5)
    {
        readPot_Timer = 0;
       
        // select Pot
        digitalWrite(PotSel_1, LOW);
        digitalWrite(PotSel_2, LOW);
        digitalWrite(PotSel_3, LOW);
        digitalWrite(PotSel_4, LOW);

        // read channel 1
        analog.update();
        // read channel 2
        digitalWrite(PotSel_1, HIGH);
        analog1.update();

        if (analog.hasChanged() && analog1.hasChanged())
        {
            int value_A = analog.getValue();    // value_A  0 - 1022
            int value_B = analog1.getValue();   // value_B  0 - 1022

            Serial.print(value_A);
            Serial.print("  ");
            Serial.print(value_B);
            Serial.print("  ");

            // Compute current angle and dial position
            double fx = ((double)value_A / 511.5) - 1;   // range -1 to +1
            double fy = ((double)value_B / 511.5) - 1;
            double angle = atan2(fx, fy)/PI;               // range -pi to +pi
            Serial.println(angle);
           //int dialPosition = map(angle, -PI, PI, 0, 128);
        }
       
    }
}

// Loop ---------------------------------------------------
void loop()
{
   read_Pot();

 
How can I calculate the parameter value for a volume level, for example :unsure:
The volume is set to 50% in the menu. I turn the potentiometer to the right and increase it to 90%
 
Hallo..
I found a solution using the map() function. StartPos is 0 or the last displayed parameter value in the menu. EndPos is the maximum end value of the potentiometer. If the potentiometer makes a 360 degree rotation then the value is from 0 - 127;

C:
// read Pots ---------------------------------------------------
void read_Pot()
{
    if (readPot_Timer > 5)
    {
        readPot_Timer = 0;

        // select Pot
        digitalWrite(PotSel_1, LOW);
        digitalWrite(PotSel_2, LOW);
        digitalWrite(PotSel_3, LOW);
        digitalWrite(PotSel_4, LOW);

        // read channel 1
        analog.update();
        // read channel 2
        digitalWrite(PotSel_1, HIGH);
        analog1.update();

        if (analog.hasChanged() && analog1.hasChanged())
        {
            int value_A = analog.getValue();  // value_A  0 - 1022
            int value_B = analog1.getValue(); // value_B  0 - 1022

            Serial.print(value_A);
            Serial.print("  ");
            Serial.print(value_B);
            Serial.print("  ");

            // Compute current angle and dial position
            double fx = ((double)value_A / 511.5) - 1; // range -1 to +1
            double fy = ((double)value_B / 511.5) - 1;
            double angle = atan2(fx, fy); // range -pi to +pi
            Serial.print(angle);
            Serial.print("  ");
            int StartPos = 0;
            int EndPos = 127;
            int dialPosition = map(angle, -PI, PI, StartPos, EndPos);
            Serial.println(dialPosition);
        }
    }
}
 
Hello everyone :)
I hope you had a nice sunny day. I worked a little and then went for a ebike ride.
I also continued working on Degenerator 2 and programmed the query function for the "heated" Alpha potentiometers ;-)
It's not quite finished yet, but in principle, it's already working quite well, as you can see in the video below.


Greetings from germany. Rolf
 
  • Like
Reactions: Pio
Back
Top