The miniTS – DIY Synth

The Tiny-TS got bigger!
Say hello to the pocket WASP.

miniTSsynth

It now features a 2 octave touch keyboard in 165x65mm.

Still the same great synth engine, CV/Gate output and now also added MIDI IN/OUT.

The mini-TS can be built in a number of configurations  depending on if you want to use it as a synth, CV controller or MIDI controller.

Features:
Clickable rotary encoder and 128×32 graphic OLED display for parameter entry.
3.5mm Stereo jack audio output.
3.5mm Stereo Jack for CV 1volt/octave output and 1 CV input.
3.5mm Stereo jack for Gate output and 1 CV input.
PCB pads for MIDI Rx & Tx signals.
(The stereojacks are TRS-type and have CV inputs on the ring.)

It is open-source just like the Tiny-TS.

miniTS2_1024

Get the PCB and join the DIY build from start.

Order the mini-TS PCB $29 (PCB Only)

BOM:
IC1 = ATmega328 Preprogrammed with mini-TS OS 1.0
R1, R2, R3 = 1Kohm
R4, R5 = 4.7Kohm
R6, R7 = 22Kohm
C1 = 100nF
C2, C3 = 10uF
OLED1 = SSD1306 i2c 128×32 OLED display
ENC1 = Quadrature rotary encoder with switch
SW1 = SPDT Switch
Vbat = CR2032 or double AAA battery holder
PCB = mini-TS Touch Keyboard PCB

The same PCB can be built in 3 configurations:

The CV keyboard config
The simplest config is for using it just as a CV/Gate keyboard for modular gear. This mode is selected by shorting Pin17 and Pin18 on the chip.

miniTSconf1

The WASP config
This config uses CV/Gate/MIDI-IO and 6 external potentiometers for a WASP style synthesizer. This mode is selected by shorting Pin18 and Pin19 on the chip. This is the same config the Tiny-TS uses.

WASP

miniTSconf2

The full config
This uses a rotary encoder and a 128×32 OLED for synth parameter entry. It also has 2 CV inputs on the TRS jack rings and MIDI-IO.

miniTSconf3

Accessing the board peripherals.

If you want to get just the PCB and do your own programming you need to know how the keyboard, rotary encoder and display are accessed.

Reading the keyboard.

The keyboard is a capacitive touch keyboard just like on the Tiny-TS and Micro-TS.

Because it has 25 keys there aren’t enough GPIO’s to assign for each key. So the keyboard is arranged in a matrix of 5 columns and 5 rows.

Each key on the keyboard have 2 touch pads, 1 from a column and 1 from a row. That totals to 50 touch pads!

They are also cleverly arranged to minimize keyrollover.

miniTSpcb

This is the code for scanning and finding a keypress:

uint8_t capsenseCOLbase = 8; //Set capacitive touch Column sensitivity
uint8_t capsenseROWbase = 6; //Set capacitive touch Row sensitivity

//———- Capacitive Touch sensing —————————–

uint8_t capsensePORTD(uint8_t mask) {
   if ((mask&1)||(mask&2)) return 0; //Dont measure our MIDI pins
   PORTD &= 0x03; //Ground the PCB surface
   DDRD  |= 0xFC;
   asm(“nop”);
   cli();
   DDRD &= ~(mask); //Turn selected pin to input
   PORTD |= mask;   //With pullup
   uint8_t cycles = 0;
   if      (PIND & mask) { cycles =  0;}
   else if (PIND & mask) { cycles =  1;}
   else if (PIND & mask) { cycles =  2;}
   else if (PIND & mask) { cycles =  3;}
   else if (PIND & mask) { cycles =  4;}
   else if (PIND & mask) { cycles =  5;}
   else if (PIND & mask) { cycles =  6;}
   else if (PIND & mask) { cycles =  7;}
   else if (PIND & mask) { cycles =  8;}
   else if (PIND & mask) { cycles =  9;}
   else if (PIND & mask) { cycles = 10;}
   else if (PIND & mask) { cycles = 11;}
   else if (PIND & mask) { cycles = 12;}
   else if (PIND & mask) { cycles = 13;}
   else if (PIND & mask) { cycles = 14;}
   else if (PIND & mask) { cycles = 15;}
   else if (PIND & mask) { cycles = 16;}
   sei();
   DDRD  |= 0xFC;
   PORTD &= 0x03; //Ground the PCB surface
   return cycles; //Return measured cycles
}

uint8_t capsensePORTB(uint8_t mask) {
   if ((mask&2)||(mask&8)||(mask&16)||(mask&32)) return 0; //Dont measure our Audio and CV pins
   PORTB &= 0x3A; //Ground the PCB surface
   DDRB  |= 0xC5;
   asm(“nop”);
   cli();
   DDRB &= ~(mask); //Turn selected pin to input
   PORTB |= mask;   //With pullup
   uint8_t cycles = 0;
   if      (PINB & mask) { cycles =  0;}
   else if (PINB & mask) { cycles =  1;}
   else if (PINB & mask) { cycles =  2;}
   else if (PINB & mask) { cycles =  3;}
   else if (PINB & mask) { cycles =  4;}
   else if (PINB & mask) { cycles =  5;}
   else if (PINB & mask) { cycles =  6;}
   else if (PINB & mask) { cycles =  7;}
   else if (PINB & mask) { cycles =  8;}
   else if (PINB & mask) { cycles =  9;}
   else if (PINB & mask) { cycles = 10;}
   else if (PINB & mask) { cycles = 11;}
   else if (PINB & mask) { cycles = 12;}
   else if (PINB & mask) { cycles = 13;}
   else if (PINB & mask) { cycles = 14;}
   else if (PINB & mask) { cycles = 15;}
   else if (PINB & mask) { cycles = 16;}
   sei();
   DDRB  |= 0xC5;
   PORTB &= 0x3A; //Ground the PCB surface
   return cycles; //Return measured cycles
}

//—————————————————————–

//—————— Key scanner —————————–
  uint8_t keydown=0;
  uint8_t keydownC=0;
  uint8_t keydownR=0;
  uint8_t keycol=0;
  uint8_t keyrow=0;
  for (uint8_t column=0;column<5;column++) {
   if ((column==0)&&(capsensePORTD(4)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if ((column==1)&&(capsensePORTD(8)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if ((column==2)&&(capsensePORTD(16)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if ((column==3)&&(capsensePORTB(64)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if ((column==4)&&(capsensePORTB(128)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    } 
  }
  for (uint8_t row=0;row<5;row++) {
   if ((row==0)&&(capsensePORTD(32)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if ((row==1)&&(capsensePORTD(64)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if ((row==2)&&(capsensePORTD(128)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if ((row==3)&&(capsensePORTB(1)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if ((row==4)&&(capsensePORTB(4)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    } 
  }
 
  if ((keydownC)&&(keydownR)) {
    key=(keyrow*5)+keycol;
    keydown=1;
  }

//—————————————————————–

The OLED display

The display is a standard 128×32 graphics i2c OLED. It is connected to the ATmega328 SCL/SDA i2c pins with 4.7K pull-up resistors.

Any library that can handle the SSD1306 display can be used. Be warned that Adafruits GFX library uses 2/3 of the available flash space.

In the code I’m using the SSD1306xled library.

IMG_20170415_152520

The 128×32 graphics display shows the synth parameters in realtime for editing.

OLED_TS_10

The Rotary Encoder

The encoder is a standard quadrature encoder with 20 pulses per revolution.

It is clickable and clicking grounds Arduino pin D12.

The QA/QB outputs are connected to Arduino pins A0/D14 and A1/D15.

When D14 transitions from High to Low you check the D15 pin to find out if it should count up or down.

In my code I read it using Graycode:

int8_t read_encoder() {
  static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static uint8_t old_AB;
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}

encoder

The Analog interface

D/A converters are the same as the Tiny-TS.

An 8-bit PWM audio DAC on Timer2 Arduino pin D11 and a 11-bit PWM CV DAC on Timer1 Arduino pin D9.

The mini-TS does not have a linear regulator and run directly from a 3-5v battery so a trick is required to keep the CV output tuned to 1V/octave. It reads the battery voltage and continuously tune the PWM range. Neat.

The Gate is output on Arduino pin D13.

New are the 2 CV inputs on the CV/Gate TRS jack rings. They are routed to analog pins A2 and A3 through 22K resistors for protection.

LminiTSdev

MIDI Interface

The MIDI interface uses the ATmega328 USART port with the MIDI bitrate of 31250bps.

It can use the Arduino MIDI library but you need to add an optocoupler for MIDI input.

DIY for the masses

This is DIY. You can just grab the code here, tape up 50 touch pads with copper tape, breadboard the circuit and it will work.

But I suggest you at the least get the PCB for a professional looking synth and to support my development.

Otherwise It’s all open-source.

One of the mini-TS versions will be the Breadboard synth.
The keyboard provides CV/Gate/MIDI and a square wave oscillator and you may breadboard up any synth you can imagine your self on the breadboard.

BreadboardSynth

The mini-TS OS code 0.9

This is the code that the mini-TS in the demo runs at the moment.

Click here for code on Github

Advertisements

%d bloggers like this: