tirsdag 18. juli 2017

BA662 pinout

While drawing up various uses of the Roland IR3109 VCF-chip, I needed to make an Eagle part for the OTA used in the resonance circuit. My initial circuit was the one from the Jupiter 4 service manual, and it uses a BA662, IC17:



The service manual only shows a part using four pins while the BA662 has 9:
This shows that the BA662 is actually an OTA and a buffer combined into one package. The buffer is apparently not used in the JP-4, so how is it disabled?

The Juno-6 and Juno-60 service manuals answers the question:
Pin four, the buffer control, is connected to -V and the buffer input is connected to +V. The buffer output, as expected, is not connected to anything.

Incidently, the IR3109 itself is just four OTAs, four buffers and an exponential converter connected to the control of each OTA.

onsdag 12. juli 2017

It's alive!

The XM8 just made its first ever sound - controlled by midi from a little phatty to the XM8 Voice controller, through the OMM and on through SPI to the DCO. Playing worked like a charm - pitch changes are delayed but that is to be expected since the SPI speed is set to a minimum right now. I had a lockup too, somewhere in the Voice controller code, but all in all I'm really pleased!

The tracking is awfull, I think I've used different intervals for semitones in the Voice controller code and the DCO, but it is very clearly playing semitones.

Woohooo! Videos to come.

onsdag 21. juni 2017

DCO - aribtrary reset point

I've been a bit worried about the fact that the DCO frequency may only be changed when the period reset timer runs. At low frequencies this may mean a noticeable loss of timing presision - worst case for a 20Hz signal would be 1/20 s off. At 120BMP, the duration of a 1/16th note is 1/32 second, so it will miss by a lot. If my calculations are correct, playing "flight of the bumblebee" at near-unhearably low frequencies will be impossible ;-) I am not sure how much of a problem the inaccuracy is in practice, but it is something to investigate further.

This constraint is there for a good reason, as we need a perfect match between charging voltage and reset time for the saw wave to get the correct amplitude.  If we choose to change the charge voltage at any given time, without changing the reset timer, the amplitude of the first cycle after the change will be either too high or too low.

Idea 1:
Ideally, we should change the remaining time of the reset timer too. This would be a case of subtracting the current remainder from the new period timer value, correcting for the time the calculation takes, and then updating the timer - IF the time the calculation took was less than the remaining time.

This is slightly more complicated than what it sounds like. As the current timer and the new timer may not have the same prescaler, we need to take this into account when calculating the correct reset values. We also need to make sure we don't mess up the reset pulse timer.

Idea 2:
A different approach would be to do the first reset in hardware. If we connect the saw output to a comparator, and check if the level is just slightly larger than the normal, correct amplitude, we could trigger a reset using the sync input, preventing a large amplitude error. The amplitude error that is inevitable because the reset point must be larger than the correct amplitude is hopefully small enough to be inaudible. This lets us change the charging voltage at any time and still not get a large amplitude error.

This will fix the case where the amplitude is too large, but the case where it is too small (e.g. the new charge voltage is lower) will not be fixed. To fix this, we must also reset the period timer at the same time. Doing so guarantees that the charging time is at least long enough for the new charging voltage to fully charge the cap. In most cases the charing time will be too long as it adds to the time already elapsed since the last reset, but then the previous comparator fix will reset the period at approximately the right time.

The disadvantages to this method may be:

  • Charging time may change slightly when the ambient temperature changes. Resistor values barely change so I have to check the effects on the charge capacitor.
  • The amplitude of the first period will always be slightly wrong after a frequency change. Not sure if that will be audible. It may possibly only be a problem for fast changing pitch.


Idea 3:
A third method would be to always reset the cap at the instant a frequency change occurs. The timing will then be as accurate as possible. The main disadvantages are

  • The saw wave will always start at the same position. Two DCOs running in parallel will then be in almost perfect sync.
  • A fast changing pitch will reset the timer multiple times per second, possibly hundreds or thousands of times. At low frequencies this means no saw wave runs to completion, giving us a way too low amplitude (though shifted to the maximum).


I will give the choice between 1 and 2 a more thorough thought and try to build 2 to see how it feels like. All options may be retrofitted to the current DCO even if the PCB has been created, as the comparator circuitry can be housed outside of the DCO itself..

onsdag 7. juni 2017

DCO core up and running

After spending a long time converting and optimising the DCO code for the PIC16F18325, I finally connected a DAC and tested the thing last night.

All frequency tests seemed ok, and the charge current tracked the frequency almost perfectly, charging the saw core capacitor to 5V even if frequencies changed. Only for the lowest frequency I tried (16.35Hz) did the cap not fully charge. I successfully tried frequencies up to 7000Hz. At 14000Hz the charge current was once again too low, but this was expected as the DAC output cannot reach a high enough level with the current combination of cap and charge current converter resistor (100kOhm). I tried swapping the resistor for a 56k one and the saw voltage swing doubled as expected, so a little experimenting with various resistor values will probably fix this issue.

I have had some issues with the saw core op amp oscillating. Not sure what causes it (well, I suspect it is due to the capacitor in the feedback loop), but some brands seem more susceptible to this than others.

I've tried the TL072CP and TL062CP from Texas Instruments and they both oscillate. TL072BD and 4556D from JRC work fine. Maybe the B/C difference could explain it.

The DCO uses modern, easily available components, the reset transistor is a 2N3906. The DAC currently used is a MAX541, with an SPI speed of 8MHz. The 'production version' will probably use a MAX5216 as this is way cheaper.

I was not aware that I could get such a high speed, now I consider moving the DAC update into the interrupt routine. It will probably double the time spent in the routine, but even this would only reduce the max transfer speed from the master controller to the DCO to around 950kbps, meaning we could still update the DCO 50.000 times per second (or rather, transfer new pitch values, the DCO will only update at period reset positions).

Next up is adding and testing SPI control, then recalculating the lookup tables to be centred around Cs (a C should be at 32768 = virtual 0V). Then finally breadboarding the wave shaper circuitry and deciding on voltage control and how to center the waves around 0V.

I must also decide the p-p voltage output. 12V seems to be the Juno way, this is the highest "safe" voltage possible since the saw is generated between gnd and the negative power rail (-15V). I assume that keeping the voltage as high as possible up to the point where several waves are summed is a good idea, to keep noise to a minimum.

The charge current is a bit too low at the lowest frequency





The dots above the peak of the saw wave is the reset pulse




The reset pulse gets more and more visible as the frequency increases and we zoom in

The charge current is too low above a certain frequency. This will be fixed.


mandag 29. mai 2017

Juno saw sub oscillator

Someone mentioned that there is such a thing as a juno sub osc mod that gives you a saw sub oscillator.

Now, I know nothing about this mod but I can immediately think of two ways of doing this:

1) Use my saw sub osc design that combines the saw with the square to shift and attenuate the saw wave and making a wave one octave down

2) Replicate the saw core - let the sub osc output control the reset transistor, and tap (a buffered version of) the charge voltage from the DAC output and attenuate it 50%

Should be an easy fix :)

søndag 16. april 2017

Juno 60 pre-filter level control

The Juno 60 mixes several waveforms before the filter, and it has a clever way of controlling the sub oscillator volume. As the sub oscillator output is a square wave, the wave is considered a binary on/off signal. It is connected to the base of a transistor, which when turned on and off either sinks its collector to ground or leaves it as it is.

To control the wave volume, the collector input is connected to the panel potentiometer (through a series of buffers/mux/demuxes, but that doesn't really matter, the principle is the same). The wave's amplitude (or "on value") will then equal the level of the panel potentiometer, though negative as the potentiometer value is inverted by IC17 on panel board A. The voltage is passed through an analog switch, IC16, which in turn is controlled by the Sub oscillator on/off switch, to completely disable the sub oscillator (incidentally, this feature has been removed from the Juno 106, here the potentiometer voltage is connected directly to the transistor collector).

Interestingly, the same arrangement exists for the pulse wave, only this time the analog switch connects the transistor to -15V instead of to a variable voltage. If one would like a controllable pulse wave volume, it would likely be easy to inject the control signal here.

As for the saw wave, it also has a switch and a transistor connected to it. However, as the saw wave is not binary, it cannot be controlled the same way. Instead, the wave is connected to the collector, and the transistor base is connected to the analog switch on panel board A. The wave is then sunk to ground if the transistor is on. In other words, the saw wave has no pre-filter volume control, only an on/off switch.

The noise input has its own volume control on panel board A (all voices use the same noise generator).

Oh, and by the way - all waveforms have a range of 0 to maximum -15V (the datasheet says the saw wave is 12V p.p, I have not checked the others but they have to be about the same to be mixable - the sub oscillator level for example originates as a 0 to +5V voltage but is inverted and amplified by IC17, and the pulse wave level is always 0 to -15V). They are fed through a 10uF non-polar capacitor (C5) just before the filter, which probably centers them around 0V.



onsdag 5. april 2017

Juno 106 vs 6/60 DCOs

There are some differences between the DCOs in the Juno 106 and the Juno 6/60 - except for the fact that the DCOs on the 106 are integrated into a single chip.

First of all, according to the datasheet, the 106 uses an NPN instead of a PNP transistor to reset the integrator (saw wave converter).

More interestingly, the way they sum the saw wave and the pulse waves are very different.

The Juno 60 has a separate control line for the pulse wave, connected to TR2. It looks just like the one for the saw wave (TR3) so one can assume that it turns on and off the pulse output. Also, the output of the pulse is sent through D2 which will block any positive halves of the pulse (? which sort of makes sense as the saw wave is also negative only).

The 106 on the other hand, has no such control line, which means that the pulse output is always on. The pulse output has a diode to ground which I assume means that it will never be negative (?).

So how can the 106 output a saw wave and no square wave? One theory may be that if the user selects saw wave only, the pwm is set to 50%. Summing the sqare and saw waves will chop up the saw wave just as it reaches its half period, and move the remainder upwards. If the amplitude of the saw and square waves are equal, the saw wave will magically realign with its phase shifted half a period, this time centered around 0V.

DISCLAIMER: This is only my initial theory after studying the datasheets, no measurements have been made. 

But how about when both the saw and pulse waves are on? Wouldn't this mess up how the wave turns out? Since the saw wave is positive and the pulse is negative, couldn't the total amplitude end up being double?

Well, the high part of the pulse will always come at the second half of the period, thus it will never "lift" the saw wave from higher that minus half the total voltage p-p. Also, The parts that are lifted will only be lifted by 1 x the voltage p-p.

In practice, this means that if we could set the duty cycle to 0%, the output would be a saw wave that starts at 0 and drops to minus the total voltage p-p. If the duty cycle is 50%, we get a saw wave with the same amplitude centered around 0V.

This is interesting and may reveal a flaw in my assumptions. As the wave is centered around 0V by a capacitor later, summing a pulse and saw wave this way will only shift the saw wave phase! I need to check if the polarity and phase assumptions for the square wave actually holds. What happens if instead the polarity is reversed or the phase shifted by half a period?


TODO: Write about SUB OSC and level control (done by using the output from the DAC) and how the passing through a diode affects the signal (reversed in one)- one uses NPN and the other uses PNP, 60 has a resistor to GND at the transistor base. The 106 has no on-off switch for the SUB OSC, only a volume control.

Both the 106 and the 60 DCOs have their outputs mixed with noise (with adjustable volume) right before a 10uF non-polarized cap and injected into the IR3109/800170 filter chips. The mixing point has no opamp connected to it so I assume this job is done by the chips. I guess the cap is there to filter out any DC component and center the waves around 0V. I have not looked closely at this - what happens here when the frequency changes for example, will still stay centered during the transition because the amplitude is still the same?

BTW: NP in the juno datasheet means Non-polarized (capacitor). MF means metal film (resistor).  G (capacitor) may mean 2% (needed for accuracy in the integrator).


mandag 3. april 2017

DCO saw core testing

I built the DCO saw core on a prototyping board Friday evening, and after some initial trouble, I got it working very well.

The core is heavily inspired by the Juno 6/60 DCO. The output of the MCU charges a capacitor, turning the output square wave into positive/negative spikes on each square wave edge. These in turn briefly switch on a transistor that discharges a capacitor. When the transistor is off, the capacitor is charged using a constant-current scheme where the cap is connected across an opamp (just like in a normal saw core VCO, see section "That old opamp trick again" of http://xonik.no/theory/vco/reference_current.html).

The Juno 60 uses a 2SA1015 PNP transistor. I tried replacing this with both a 2N3906 and a BC557, they both work very well.

MCU output pulse train (top) vs. transistor control spikes (bottom). top is 5V/square, bottom is 1V/square and shifted down to make both visible

I had no DAC available for the trial, so the charging current was regulated using a potentiometer as a voltage divider, buffering the output with an opamp and piping the result through a resistor to convert it to a current. After initially screwing up and connecting the center pin of the pot to ground, things started working very well.
A perfect 5v p-p saw wave generated from the pulse train on top. 

A few challenges still persist:

1) The output wave starts at 0 and goes downwards until it is reset. It has to be centered

2) My calculations are based on an assumption that the maximum voltage should be 5V. I completely forgot that it has to be 5V on each side of the wave, making the full wave 10Vp.p.

3) For some reason, the charging stops at -8V. Not sure if this is due to the opamp or something else, but it has to be fixed. The Juno 60 service manual says they have a 12Vp-p output, so it should be possible to fix this.
The charging of the cap maxes out at 8V (looks like 10V here but Y-offset was wrong).
4) Charging starts at the negative going edge of the MCU output wave while the MCU output wave is first high then low through the course of a cycle. This has to change, either in code or by replacing the PNP with an NPN transistor (The Juno 106 service manual says it uses an NPN but I couldn't get this working immediately. I'll look into it).

5) With a 100k charging current resistor, the charging current won't be strong enough for the highest frequencies. A 39k resistor may work (but not for a 10Vp-p wave).

6) I should check if a constant reset timer interval may work (e.g. not a 50/50 duty cycle for the MCU output wave). If so I'll save some clock cycles during frequency calculations.

torsdag 30. mars 2017

Alternative approach - DCO MCU

It would be possible to use a lower-end PIC32 MCU as the DCO MCU. We'll get a few advantages:

1) It can run at a higher speed so calculations will be faster
2) It may have enough ROM to store a full lookup table, or where we may only have to interpolate every second sample. As the MCU is 32bit, interpolation is a simple case of adding two adjacent samples and shifting right by one (dividing by 2).
3) Even with a lookup table, 16 bit multiplications are supported in hardware so calculations will be very fast
4) Both input and output SPIs are buffered so we need not fear losing bytes
5) It natively supports I2S so interfacing with cheap DACs from ebay is possible.

Cons:
1) It may possibly be harder to write an accurate timer as it has a different architecture with more complex pipelining?
2) Price (but not an issue if using DACs from ebay).

BTW: a faster interpolation without the use of a derivative lookup table is also possible on the PIC18F if we choose one with at least 64k program memory, such as the PIC18F26k40. Chosing the PIC18F27K40 means we will not have to do any interpolation at all as it has 128k program memory.

søndag 26. mars 2017

SPI Daisy chaining

Just  a quick tip from the PIC18F datasheet: SPI interfaces on multiple MCUs may be daisy chained, connecting the output of one to the input of the next. They will then function as a long shift register, shifted 8 bits for every SPI send. NB: Chip select must be connected to all MCUs if used.

DCO: SPI and DAC accuracy

A few compromises have to be made when making the DCO. There are however a few things that must be done right.

First of all, we cannot afford to lose any input commands. This will put the SPI input buffer in an unknown state, possibly locking up the DCO.

With this in mind, we can do a few calculations.

First of all - each frequency update is based on a 16bit integer. The SPI buffer is only 8 bits long, so two bytes must be transferred. Each transfer triggers an interrupt, and that interrupt must copy the transferred byte from the SPI buffer to somewhere else before the next byte arrives.

Fortunately, the SPI buffer is, as it says, buffered. This means that it is not written until the last bit of the byte is received. In addition, there is a short delay between bytes.

As an example, when running the SPI bus at 200kHz, a byte is 40uS long. The delay between two bytes is 7.5uS (when output from node.js on a Raspberry PI).

Running the MCU at 20MHz we have an instruction clock of 5MHz, and each instruction takes 0.2uS. This means that with a 200kHz SPI bus and 20MHz clock, we have 237 instruction cycles to handle a received byte.

This is of course much more than we need - as long as the interrupt handler triggers immediately. But for the DCO to be as accurate as possible, we have given priority to the timer that sets the output wave period. The SPI interrupt will be blocked if a timer interrupt has been received and will not be treated until the timer interrupt handler returns. Thus, we have to make sure the time it takes to enter the timer interrupt handler, do whatever it needs to do, return from the handler and then enter the SPI (low priority) interrupt handler, takes less than 237 instructions - if not, we may be inside the timer interrupt handler when the next SPI byte arrives and we'll lose the previous byte.

This sounds all good, right? The time it takes to reset the timer is not that long. Well, we do actually have a problem. If we are to both reset the timer AND change the DAC value (that controls the current that charges the integrator capacitor making the saw wave), we run into trouble. The DAC is written to using SPI, and we have to write three bytes to set it. Unless the DAC SPI runs at several MHz, we do not have time to write to it within the 47uS we have available. In simple terms, we cannot write to the DAC inside the interrupt handler.

So what is the consequence of this? 

The only other place to write to the DAC is inside the main program loop. As we will be at an arbitrary place in the code when a timer interrupt triggers, we will get a delay from when the timer triggers to where the DAC update call is found (+ the time spent writing to the DAC).

To reduce the maximum delay, we may check if a DAC update has been requested and update the DAC at several spots in the main loop.

But how big is the consequence of delaying the DAC?

At 200kHz, updating the DAC takes approximately 135uS = 675 instruction cycles. This delay is unavoidable.

The longest single method within the main loop, recalculating the frequency, takes 723 cycles. If we break this up into 5 intervals, we'll add around 150cycles to the maximum delay, which will then be around 825 cycles or 165uS.

What does this mean?

It means that for 165uS, the DAC will output the wrong voltage, and the capacitor will charge too fast or too slow. If it charges too slow, the capacitor will be at less than 5V when the charging is reset by the period timer. If it charges too fast, it will be at more than 5V. But how much?

Let's look at the two extremes:

Going from 16.5Hz to 20kHz

Here, the DAC will have a very low charge current. The period at 20kHz is 50uS. This means that for a little more than three periods, the charging will be way too low, in fact probably so low that the wave will look completely flat. However, this is only for 3 of 20.000 cycles within a second. Question is if it is audible.

Going from 20kHz to 16.5Hz

The DAC will have a very high charge current. It charges at the same level as when the frequency is 20kHz, which means that after 50uS, the output value is 5V and after 150uS it has reached 15V (but the buffer opamp or other parts of the circuit probably saturates, keeping the maximum at around 14.3V. The cap stays at this level for one full charging cycle, around 61mS. This is not a very ideal situation.

This is of course in the extreme cases. Most often the change in pitch will be small, but a few octaves are still likely.

What can be done to remedy this?

1) Increased DAC SPI speed - pushing the speed to 2MHz will reduce the write delay to 13.5uS, with a total of 43.5uS including the delay before we reach the reset DAC code. This is if the MCU and DAC can handle the increased SPI speed

2) Increase the MCU speed from 20MHz to 32MHz - this will reduce the maximum time before the DAC write is started from 30uS to 18.75uS (as each instruction now takes 0.125uS instead of 0.2uS.

3) Check more often if we need to update the DAC, further reducing the maximum time before the DAC is written to

4) If the DAC SPI speed is sufficiently high, put the write back into the interrupt routine, removing the delay before a write altogether.

If 1) is possible, and the rest of the timer interrupt handler takes less than 47.5uS - 13.5uS = 34uS, 4) is certainly the best option.


Input SPI speed

We chose 200kHz as the SPI speed at the start of this post. At this speed, 16 bytes will take 47.5uS to transfer (inc delay between bytes), giving an effective transfer rate of 21kB/s.  The Xonik M8 voice controller runs at less than 4k updates/second, so this is sufficient for updating tree DCOs at that rate. The PIC32 has a multi-byte SPI buffer, so we may actually write all bytes to the SPI buffer and forget about them, leaving the voice card MCU to do other duties while the buffer is written (though we have to write to the separate DCOs one at the time as the chip select lines must be changed between the DCO writes.

To further improve the performance of the main MCU (and reduce the delay between when a frequency update is requested and a new frequency is visible on the output), we should calculate the maximum time spent in the period timer interrupt handler and optimize the SPI speed such that the time spent transferring a byte is just barely longer than this.


Maximum delay

The maximum delay from a byte request has been received at the main voice controller to it is visible at the DCO input may be calculated as follows:

2 x matrix calculation time
+ 2 x byte transfer time
+ 1 x transfer delay
+ 1 x time spent calculating new frequency params
+ 1 x delay writing to timer registers
+ 1 x time that must be left for an update
+ 1 x longest cycle time
+ 1 x time within period interrupt handler
+ 1 x maximum delay before DAC write starts
+ 1 x DAC write time.

2 x matrix calc time because the command may arrive just after a calc has started and be written at the end of a calc update


Update: SPI and DAC speeds

The MAX5216 SPI can run at 50Mhz. The PIC SPI runs at maximum Fosc/4, which equals 5MHz with a 20MHz crystal, 8MHz with a 32Mhz. In any case, transferring 24 bits takes approx 27 instruction cycles, so setting the DAC in the interrupt routine is well within what is feasible. Thus, the delay from period start to the DAC is set is 27 * 0.125uS = 3.4uS + any cycles between the timer reset and the call to set the DAC - 7 cycles + the time it takes to call the SPI function - an estimate may be 40 cycles = 5uS in total (at 32MHz).

This means that in the case of a too-high charging current, the cap will be charged at max for about 1/10th of the charge time at 20kHz, contributing about 0.5V too much to the end result (5.5V instead of 5V). This is probably tolerable.

Similarly, the whole interrupt function will take 33 cycles (timer) + 40 cycles (DAC). Add 10 cycles to enter and store the SPI byte and the total is 83 cycles or 10.4uS. Transmission speed will then have to be more than 1.3uS per bit, which gives a max SPI speed of 769kHz (at 32MHz)

Update 2:

The only times we should have to update the charging current will be right after we have calculated and set a new frequency. For most frequencies, this update will happen right after an SPI write (for low frequencies we will get a delay, though). If we keep the DAC update outside of the interrupt handler, we will still normally not be inside the calculation routine for a new frequency when the interrupt returns, so the delay between timer update and DAC update will be minimal. We may still encounter a large delay as it may take up to one period from frequency calculation to the frequency has been set. If SPI bytes arrive faster than this (as they most likely will if the main controller runs at 2-4kHz), we may still be inside the calculation routine.

By moving the DAC update we'll shorten the delay to 43 cycles = 5.38uS, giving us a bit time of 0.673uS and a max SPI speed of 1.49MHz (at 32MHz clock speed)

Ultimately it all comes down to what is most important - a high SPI speed to minimize the time the master spends writing or a short delay before the DAC is set to assure a high max voltage accuracy.

As mentioned previously, we may use the multi-byte SPI buffer on the PIC32 based voice controller, so the exact write speed is not all that important (as we do writes as fire-and-forget) but faster is still better - we will have to write some special code that writes to the DCOs at regular intervals through one matrix recalculation cycle as we cannot afford wasting calculation time waiting for a write to complete before filling the SPI buffer with the next DCO values (Though perhaps it would be possible to come up with a chaining scheme where six bytes are clocked through the three DCOs before they are "commited" and the values read - perhaps by a chip select line going low or similar. The PIC32 is capable of generating an interrupt once the SPI buffer is empty, so it's easy to add a single line change when transmission is complete).

onsdag 22. mars 2017

SPI from raspberry PI to PIC18F

This is mostly for my own reference later:

The following is confirmed to work:

I've connected the raspberry PI as an SPI master. Only output and clock from the PI must be connected, not the PIC18F SPI out, as the PI is not 5V tolerant.

In my special PI-to-xonik m8 voice controller cable, the following pins are used:

PIN0: Signal (Master out/slave in, PI is master)
PIN2: Clock
PIN7: GND - NB - NOT PIN9!

These must be connected to the following on the EasyPIC 3 card:
RC3: Clock
RC4: Signal (SPI in)
RC9: GND

With this connection, the following settings work:

PIC18F:
SPI1_Init_Advanced(
SPI_SLAVE_SS_DIS,
SPI_DATA_SAMPLE_MIDDLE,
SPI_CLK_IDLE_LOW,
SPI_HIGH_TO_LOW
);

(incidentally the same as in my libstock example)

Raspberry PI:
let mode = 'MODE_1';     // clock idle low, clock phase active to idle.

function initSPI(){

  var spiConfig = {
    'mode': SPI.MODE[mode],   
    'chipSelect': SPI.CS['none'], 
    'maxSpeed': 200000
  };

  spi = new SPI.Spi(
    config.spi.device, 
    spiConfig, 
    function(s){
      s.open();
    }
  );

}

lørdag 18. mars 2017

Vocoder analysis/synthesis boards arrived

I picked up the vocoder analysis/synthesis boards yesterday. They look good as always, though I noticed some differences. Nothing to be alarmed about but I get why they are a bit cheaper than other boards:

- The silk screen is a bit misplaced on some boards
- The holes aren't always dead center on the pads
- One of the boards isn't completely flat, i.e. the fibre glass is slightly bent.

These are just very tiny deviations and well within what is acceptable, they just aren't perfect.

I'm very excited to get started on the build, to see if I've managed to get the circuit and layout right :)






mandag 27. februar 2017

ETI Vocoder voltage to current converter

The VCAs in the  ETI vocoder use a voltage to current converter that is slightly different than what I'm used to. This post tries to understand what is going on. It may be wrong, so do not use the findings without verifying them first.

The transistor in the vocoder has its base tied to ground, collector connected to the control pin of the LM13600 and the emitter to the output of an opamp (and a trim pot) through a resistor.

Unlike other converters I've seen, it does not have the transistor inside the feedback loop of the op amp.

I suspect that the converter does not rely on the \(\beta\) or Hfe of the transistor, it only has to be high enough. I believe that what is important is the relationship between \(V_b\), \(V_e\) and the output voltage of the op amp.

I've chosen the VCA in the internal excitation circuit as my reference when analysing the circuit.

R34 is a 10k resistor, you can see these in most all designs using the LM13600 OTA. It's most likely there to protect the lm13600 from self destructing - the maximum control current of an LM13600 is 2mA. See my post on the Xonik VCA for an explanation of its value.

So how do we calculate the collector current (which is what controls the OTA, Iabc)?

Here is a page that explains how a transistor may be used as a constant current source:

http://www.radio-electronics.com/info/circuits/transistor/active-constant-current-source.php

It says that

\(I_{load} = \frac{\beta \cdot V_e}{(\beta + 1) \cdot R_e}\)

If \(\beta\), the transistor gain, is large, \(\frac{\beta}{\beta + 1}\) is approximately 1 (and thus \(I_{load} = I_c = I_e\)). Also, \(V_e\) is always one diode drop below \(V_b\) when the transistor is on (\(V_e = V_b - 0.6V\)), which means that the formula above may be simplified to

\(I_{load} = \frac{V_b - 0.6V}{Re}\)

In our case, \(I_c = I_{load}\) and \(R_e = R32\) (=22k).

What the page above fails to mention is that the bottom of \(R_e\) must be connected to ground, or at very least that \(V_e\) is the voltage across \(R_e\).

This final detail is of importance to us, because in our case the voltage at the op amp end of \(R_e\) (R32) is what varies, not the voltage at the base. The base is stuck at 0V/GND. Thus, the voltage across the resistor is not \(V_e\), it is \(V_{out} - V_e\), where \(V_{out}\) is the output voltage of the opamp (IC8b).

We also have to take into account that the vocoder uses a PNP transistor, not an NPN as in the constant current source above. while the emitter of an NPN transistor is 0.6V below the base, the emitter of a PNP transistor is 0.6V above the base. Thus, for a PNP transistor:

\(V_e = V_b + 0.6V\)

Now we can calculate the emitter current = current through \(R_e\), which will also be approximately the collector current if \(\beta\) is large:

\(I_e = \frac{V_{out} - V_e}{R_e} = \frac{V_{out} - V_b -0.6V}{R_e} = \frac{V_{out} - 0V -0.6V}{22k}\)
\(I_e = \frac{V_{out} - 0.6V}{22k}\)

What does this mean

Well, first of all, Ie is independent of the transistor \(\beta\), which means that we can replace the BC212L transistor with something else without having to look too hard for a perfect match.

Second, we can calculate the maximum current through the base. Knowing that

\(I_e = (\beta + 1) \cdot I_b\)

we get that

\(I_b = \frac{\frac{V_{out} - 0.6V}{22k}}{\beta + 1}\)

The vocoder uses a +/-12V power supply. Thus, the maximum output value of the opamp is +/-12V (in practice it will be a bit lower than this, and the vocoder may even be designed to use an even lower control voltage, but the absolute theoretical maximum is +/-12V).

The transistor only conducts if the emitter is more positive than the base. Thus, only \(V_{out}\) values > 0.6V will turn on the transistor. As the maximum \(V_{out}\) is 12V, the maximum \(I_b\) can be found as

\(I_e = \frac{12V - 0.6V}{22k} = \frac{11.4V}{22k} = 0.52mA\)


\(I_b = \frac{0.52mA}{\beta + 1}\)


Thus, when selecting the transistor to use, we need to make sure that it has a maximum \(I_b\) higher than this when entering its \(\beta\) in the formula above.

Also, we can see that \(I_e = I_c = 0.52mA\) is well within the 2mA maximum for the LM13600.

Trimming

As for the trimmer potentiometer PR1 and its associated resistor R33, I assume they add a constant current that trims the 0-point of the VCA.

The potentiometer acts as a voltage divider, so the maximum current through R33 will be:

positive:

\(\frac{12V - 0.6V}{470k} = 0.024mA\)

negative:

\(\frac{-12V -0.6V}{470k} = -0.027mA\)


A final note

I suspect that the diode D5 in the op amp feedback loop is there for this reason:

When the opamp positive input is at 0V, the opamp output must be at 0.6V (one diode drop above to keep the negative output at 0V. This means that the opamp output always stays 0.6V above its positive input, which cancels out the -0.6V from \(V_e\) in the calculations above.

The voltage to current conversion formula will then be

\(I_e = \frac{V_{out} - 0.6V}{R_e}\)
\(I_e = \frac{V_{in} + 0.6V - 0.6V}{R_e}\)
\(I_e = \frac{V_{in}}{R_e}\)

where \(V_{in}\) is the input voltage at the positive opamp input terminal, i.e. the control voltage.

I tried breadboarding the circuit to confirm my suspicions.

R31, D5 and IC8b form what is called a simple precision rectifier, see this wikipedia post: https://en.wikipedia.org/wiki/Precision_rectifier. As we tap the output at the opamp output instead of at the negative input, we should see the 0.6V offset.

My measurements clearly showed that this is indeed true. The positive input and the output of IC8b follow each other closely, with a difference of 0.6V.

Input at the bottom, output on top. The difference is almost exactly 0.6V

Also, to confirm that this is indeed the precision rectifier from the wikipedia article, once the input goes below 0V, the output immediately drops to the negative rail - no surprises there. As the input is connected to the previous rectifier however, this doesn't really matter, the CV will never be negative.

The output saturates to the negative rail once the input is less than 0V



As for R31, removing it makes the circuit act like a normal buffer. Increasing the value from 3.9k to 12k has no effect at all. Replacing the diode with a wire also changes the circuit back to a buffer.


Some transistor rules:
The load should always be on the collector side
\(V_b = V_e + 0.6V\) for NPN
\(V_b = V_e -0.6V\) for PNP
The \(V_b\) to \(V_e\) relationship stays constant, the currents are what change.

If \(\beta\) is large, \(V_c = V_e\). Good designs do not rely on \(\beta\) as is varies widely.

torsdag 23. februar 2017

TL0x2 opamps - difference

- TL062 is the low power version of the TL082. 
- TL072 is the low noise version of the TL082. 

So: the TL062 uses less power, but is more noisy than the TL072.


From: http://www.freestompboxes.org/viewtopic.php?f=17&t=328

onsdag 22. februar 2017

ETI Vocoder article errors - internal excitation

There is a mismatch between the schematics and the parts list for the internal excitation module.

Schematics says C11 is 22nF, parts list says 220nF.

C11 forms a low pass filter together with R39. Together with the 100k resistor on each channel of the analysis card - the whole setup is called an inverting amplifier filter or active inverting op amp low pass filter.

According to wikipedia:

https://en.wikipedia.org/wiki/Low-pass_filter

the cutoff frequency is 1 / 2 * pi * R*C

where R is the resistor in the feedback loop of the op amp.

For 22nF this is 1 /  6.28 * 47000 * 22 * 10^-9 = 154Hz
For 220nF it is 1 / 6.28 * 47000 * 220 * 10^-9 = 15.4Hz

In comparison, C12 and R40 gives:

1 / 6.28 * 10000 * 1 * 10^-6 = 1 / 0,01 = 15.9Hz.

The output from the analysis boards is the value of the envelope follower. If the volume of a frequency band is at its max continously, the envelope follower will be a DC voltage with a similar max value.

The two circuit parts sum up channels 1-9 (for the <2kHz input) and channel 13 and 14 (for the >4kHz input). For the sums to be comparable, the max sum of each parts must be the same.

R39 and R40 are selected to achieve this:
The gain of <2kHz is -10k/100k = -0.1
The gain of >4kHz is -47k/100k = -0.47

Multiplied by the number of channels on each input we get a 'maximum' sum for each input:
<2kHz: 9 channels * -0.1 = -0.9
>4kHz: 2 channels *-0.47 = 0.94

These are similar enough to be compared.

The low-pass filter is there to make sure the Vocoder only reacts to slow changes in envelope amplitudes. It is reasonable to assume that they should be roughly the same. The capacitor has been matched with the feedback resistor (R39, R40), which in turn was selected to give correct gain as described above.

The closest matching alternatives are then 15.4Hz and 15.9Hz. Thus, the correct value for C11 is 220nF.

tirsdag 21. februar 2017

Transistors in the ETI Vocoder

Many of the transistors in the ETI vocoder are either hard to find or very expensive (or both). I am trying to figure out if alternatives are available.

For the internal excitation board, two BC182L (NPN) and two BC212L (PNP) are used.

Q1 is definitely replaceable, probably with a 2N3904. It only acts as a logical inverter together with R20 and R21. It is similar to the one found here:

http://www.cs.unca.edu/~brock/classes/Fall2012/csci255/labs/lab05.html

Not sure if we have to change the resistor values, but probably not.

Q2 is a voltage to current converter. I am not entirely sure how it is meant to work so I cannot say for sure right now what parameters to look for. The same converter circuit can be found in the analysis/synthesis section, so if one is solved, both are solved. I think looking at the exponential converter theory I've written earlier may solve some of it - the way it works is that the base is tied to ground while the emitter is connected to the output of IC8b which probably follows the envelope follower. D5 is similar to what I have in my Xonik VCA. R33 and PR1 probably adds a constant current to trim offness or similar.

Q3 and Q4 control two switches. Again, I believe they are considered binary - the output of the comparator is either high or low and the switches are also controlled by high or low voltages. We should definitely try 2N3904 and 2N2906 here.

Update: I've confirmed that Q2 is not depending on Hfe and may thus be replaced by a difference transistor (see my post on the ETI voltage to current converter). The BC557 has the same pin-out (CBE, PNP) and at least the 557B has a Hfe in the same region.

As for the BC182L, it seems that its pin out (ECB, NPN) is harder to find. However, the BC182 is still available from Farnell and RS Components (though not mouser). If the circuit board is redesigned, using a different transistor will be problem free.

BTW: Here is a nice comparison page for different transistors: http://www.edutek.ltd.uk/Transistors_NPN.html

As for the BF244 N-channel JFET, I have yet to find a replacement. It could possibly be replaced with a J112 (which also has interchangeable source and drain). I would have to look at the exact function of the transistor but I suspect that it is only used as a switch. The difference between J111/112/113 is the gate-source cutoff voltage, the zero-gate voltage drain current and the drain-source on resistance. The cutoff voltage for the BF244 varies widely, more than between the various J variants, as does the zero gate voltage drain between the versions (A,B,C) of the BF244. The vocoder article does not specify a particular version of the BF244 so this may not be very important either.


søndag 5. februar 2017

Linear interpolation

As I intend to use lookup tables for the DCO frequency and amplitude, I started looking for ways to do linear interpolation of the values in such a table to keep the number of entries low.

I may have mentioned it in a previous post, but I bought an early 80s digital sound creation book, and it has a thorough description of how to do this fast and efficiently. It is particulary space saving for symmetric waves such as sines but may be of some help even to me. Here is the text (for me to remember):




søndag 29. januar 2017

DCO

I've started working on a DCO circuit, as this will probably require fewer (but perhaps more expensive) parts and be easier to tune.

I want the DCO to work for all midi notes (C0-B8) and be within 1 to 3 cents of the correct frequency for all notes.

Looking at the Juno 6/60/106 and JX-3P DCOs I've so far set up a google docs spreadsheet, calculating all periods to get correct frequencies and the necessary voltages (currents) to get a constant amplitude.

A short intro to DCO theory

DCOs are (often) based around a relaxation oscillator, exactly like a saw core VCO (http://xonik.no/theory/vco/reference_current.html - this also explains how the capacitor is charged). A current charges a capacitor and a transistor short circuits and discharges it to restart the period.

DCOs are stable because they use a digital timer to control the discharging of a capacitor instead of relying on an accurate charging current - the period and thus frequency is computer controlled and highly accurate. For the saw ramp to reach the same amplitude as the charging period (time available to charge the capacitor during a cycle) changes, the DCO instead changes the charging current. As the frequency changes exponentially with rising notes, so must the charging current.

In my spreadsheet I have calculated two important aspects for a physical circuit - the accuracy of the timer generating the period/frequency and the accuracy of the charging current generation.

Frequency

A microcontroller timer has two properties - the minimum period and the maximum count. These limits the length of an output period and the accuracy of its length. A 16bit timer can at most count to 65535 and has a maximum accuracy of +/- 0.5 times its minimum period. For example, if the timer frequency is 8MHz, each tick of the timer is 0.125uS and the accuracy is thus +/-0.0625uS. Its maximum output period length is 65536 * 0.125uS = 8192uS or 8.19mS. The consequency is that a 16 bit timer running at 8MHz has a minimum output frequency of 1/8192uS = 122Hz. (Here we assume that the timer restarts the period whenever it has counted to its maximum).

The accuracy limitation is most important to the upper end of the frequency range. The maximum needed frequency (B8 = 7902,13282Hz) has a period of 126,55uS. An inaccuracy of 0.0625 equals an error of about 0.05%. The human ear is able to hear a difference between two notes played after eachother of about 10 cents/0.6% if the notes are sine waves, less if they are complex tones. Thus, this inaccuracy is well within what is acceptable.

But what can we do to make the timer count long enough for deeper notes? We can either use a bigger timer (32bit) or more often, use a prescaler that divides the clock running the timer. If we use a prescaler of 2, the timer frequency changes from 8MHz to 4MHz, the minimum period changes from 0.125uS to 0.25uS and the maximum time from 8.19mS to 16.38mS. This makes the lowest possible frequency 61Hz. Changing the prescaler to 8 gives a minimum frequency of 15.25Hz, which is low enough for C0.

Unfortunately, increasing the prescaler also decreases the accuracy as the minimum period gets longer. I have set 3 cents as the maximum error acceptable at the highest frequency. Using a prescaler of 8 makes some of the notes at the top of the frequency range fall outside the target accuracy.

In short - using a 16bit timer, we cannot use a single prescaler value and achieve both the frequency range and the accuracy needed. To solve this, we need to change the prescaler somewhere towards the lower end of the frequency scale. To get a constant time used setting up the timer, i propose always setting the prescaler when reloading the timer.

Amplitude

DCOs use different ways of creating a control current. As mentioned previously, the necessary charging current changes exponentially as the notes change. The Juno 6/60 seems to use an exponential converter (I may be wrong about this though, I haven't studied it closely) to achieve this, but such a converter has the same temperature dependency problems as the one controlling the pitch in a VCO (but the effect in the DCO is on the amplitude, not the pitch, and will thus not be as noticeable).

The Juno 106 and JX-3P however just feed the output of a DAC through a resistor and into the integrator (saw ramp generator). This means that the DAC must generate a voltage that accurately approximates the exponential curve needed throughout the note range (the voltage is converted to a current through a resistor). This may be problematic as the rate of change is very small at one end then suddely very large at the other.

I've once again used the spreadsheet to calculate first the real the charging voltage needed, then the current created using a DAC of arbitrary resolution. By rounding off the needed current to the nearest value achievable with the DAC, then multiplying with the per-step voltage, then using the capacitor charging formula with the known period as t, we will find the real amplitude of the wave and thus the maximum error per note.

Using a 16bit DAC and charging a 1nF capacitor through a 100k resistor, we are able to charge the capacitor to within 0.02V (of a maximum of 5V), or 0.4% of the wanted amplitude for all notes.

When calculating the capacitor charging, I've assumed that we can follow the same formula as in my older VCO research, where I found that the voltage across the capacitor at a time t after the charging starts, V(t) = t * I/C. I is found by dividing the DAC voltage Vdac with the input resistor R. Rearranging for Vdac gives us Vdac = V(t) * C * R / t, and to calculate the resulting max charging voltage, V(t_max) = Vdac * t_max / C * R.

My calculations can be found here: https://docs.google.com/spreadsheets/d/1ROhU0L4UZ2CWLu3h5LHopaB0Jv7ewNRziecj5I6D27M/pub?gid=0&single=true&output=pdf

Further work:
- Figure out how to calculate timer values and dac settings (lookup tables?)
- How to interpolate efficiently between values in the lookup table to reduce its size while still allowing input pitch to be a 16 bit value
- How to do DCO sync
- Possibly: Changing timer/charge voltage in the middle of a cycle in order for the DCO to respond instantly (the Juno DCOs apparently only change pitch at the start of a cycle.

søndag 8. januar 2017

The ETI Vocoder

I can't remember if I've posted about this earlier, but for quite some time now I've planned on building the ETI Vocoder. I was approached by a guy who wanted me to help him etch the circuit boards, and we spent at least a year planning for this, touching up the original drawings and adding/moving connectors etc.

In the end though, after buying presensitized PCBs and doing a few test etchings, I decided not to do this at home anyway. I simply have too few time slots long enough to do the setup, etching and cleanup.

What I ended up doing instead was redoing the boards and send them off to be professionally produced. I have shrunk all the boards as much as possible (while still using through hole components). I've split the internal excitation board into two separate pcbs so that all pots are soldered to a board.


In addition, I've combined the LP/BP/HP versions of the voice board into a single circuit. This means that you have to add some solder bridges and that some parts are left out for some of the boards, so populating them is slightly harder. However, it also means that I was able to make dual channel boards that, when repeated 7 times, turns into the full voice board. Using a service like dirtyPCBs, 7 similar smaller cards are much cheaper than one large one.


In retrospect I've realized that I could possibly simplify the circuits a bit, since the left channel on a card will never be HP and the right never LP (or the other way around, I can't remember).

I've also managed to jam all the non voice boards (except one of the internal excitation parts) into two 10 x 10 cm pcbs, keeping the cost really low.



lørdag 30. juli 2016

The Ultrasaw explained

While looking at the Matrixbrute from Arturia I noticed that it has an additional waveform called the Ultrasaw. I have heard about it previously, but got curious about exactly what it was and started looking at the documentation.

Apparently it is two additional saw waves with the same frequency as the first one, but phase shifted. The phase shift varies and is controlled by two built in LFOs. One wave has a constant phase shift rate while the other one is user variable.

I began thinking about how I would create such a circuit. Then I discovered that Yves Usson, designer of the xxxBrutes, had actually posted the MiniBrute circuit diagram on his site Hack a Brute.

I have studied the circuit closely and it seems half of the design matches my initial thoughts, but how the wave is phase shifted is really quite simple and ingenious. It resembles how my saw sub oscillator works, by shifting parts of the original wave up and down.


Let me explain.



The circuit looks like this (disclaimer: I do not own this circuit diagram, nor have I asked for the permission of Arturia or Mr. Usson to post it here. It is not in the public domain and is only reprinted here for educational use).

Figure 1

I have separated the circuit into three logical parts:
- The LFOs controlling the rate of phase change (left)
- The phase shifter (center)
- The wave mixer and volume control (right)

The LFOs

The LFOs consists of two main parts. To the left is a triangle wave oscillator. According to the MiniBrute documentation, the top one is fixed at 1Hz while the bottom one is user variable between 0.1Hz and 10Hz. The triangle wave design is the exact same one as the one in Texas Instruments' "Op amps for everyone", see Circuit 1-9 here or A.5.8 on page 446 of the original book. (PS: The book uses a unipolar power supply while the MiniBrute has a bipolar (+/- 12V) PSU).

To the right of the triangle wave oscillators is a triangle-to-sine wave converter. Its design is the same as the one in mr Usson's Yusynth VCO module.

Formula A-49 in the TI book gives us the amplitude of the triangle wave oscillator: Amplitude = +/- 24V * 47kOhm / 2 * 120kOhm = +/- 4.7V.

I have not calculated the output amplitude of the sine converter. Neither do I know the amplitude of the input saw wave, but it would be a reasonable guess that it is +/- 5V, a common value in synths.

A sine wave amplitude of +/- 5V would give a +/-100% phase shift in the phase shift in the next stage. Since a phase shift of -10% is really the same as a +90% percent shift, it seems unnecessary to have a shift larger than +/- 50%. It could even be that a smaller range is desireable, who knows. In the next section I'll assume that both the phase shift CV (sine LFO output) and the saw wave amplitudes are +/- 5V. It makes no difference for the understanding of the circuit.

The phase shifters

This is the funny part. The phase shifter circuits take a control voltage (the output from the LFOs) and the output from the MiniBrute's saw wave oscillator, and shifts the saw wave phase back or forward.

But how?

For simplicity, lets forget that the CV is coming from an LFO and instead treat it like a constant value. The control voltage (CV) desides how much we want to shift the saw wave back or forth. It does this by comparing the CV with the saw wave. When the rising input saw wave reaches the same value as the CV, thats where the shifted wave will start its cycle. This means that the phase shift is relative to the frequency of the input wave, it stays the same (in percent or degrees) even if the input saw wave's frequency changes. (This, by the way, was what I got right in my initial idea).

When the circuit has found where it wants to reset the saw wave, it sort of "chops off" the top of the input wave and moves it to the bottom of the wave instead. It then re-centers the wave for an even amplitude, and voilà, the saw wave has been shifted.

The detection and shifting happens in three sub circuits that are then summed to get the shifted wave:
1) The original saw wave
2) A comparator that compares the saw wave and the CV
3) An inverter that inverts the CV

Number 1 and 3 are simple to understand, but number 2 requires a bit of explanation.

An op amp without any feedback acts as a comparator. Whenever the input on the positive terminal is higher than the input on the negative terminal (usually called V ref), the output will instantly change to equal the positive supply voltage. If the input on the positive terminal is below the input on the negative terminal, the output will change to equal the negative supply voltage.

In our circuit the saw wave is connected to the negative terminal and acts as Vref:

Figure 2

Here is a graph that shows the how the input saw wave and the CV relate to the output of the comparator:
Figure 3

Again, whenever the saw wave is lower than than the CV, the output is 12V. When the saw wave is higher than the CV, the comparator output drops to -12V.

The output is scaled by the 220kOhm resistor and the diode at its output. PS: I have not thought enough about what the diode actually does. It may chop of the negative output from the comparator. For now we'll assume that the output is bipolar and scaled to +/- 5V.

Now, this is where the magic happens. The output from the comparator is summed with the original saw wave and the inverted CV, and out pops a shifted wave. Lets see how.

First, lets see what happens when we sum the saw wave with the comparator output
Figure 4

To make things easier to understand, I've color coded the parts where the CV is higher than the wave red and the parts where the CV is lower than the wave blue. As mentioned earlier, the point where the color changes from red to blue is the point where we want the phase of the output wave to start.

Summing the saw wave and the comparator output effectively moved the blue parts down and the red parts up, in a way that makes the lines align again. the fourth graph in the figure above shows how the result (red) is phase shifted in relation to the initial saw wave (grey dotted lines). It is however also shifted vertically.

So how do we fix this? Take a closer look at the first graph in figure 4. The top corner of the red triangles are what becomes the top corners of the resulting wave. The top corner should be at exactly 5V in the output. The comparator output will move the tip upwards 5V, but since the corner starts at a positive voltage instead of 0V it will end up higher than 5V. Thus, we have to move it back down a bit. How much? Well, things had been ok if the corner was initially at 0V, But it is at CV volts (remember, that is the definition of the corner, the intersection between the CV and the saw wave). Thus, we have to move everything downwards by CV volts:


The last graph in figure 5 shows the result - the saw wave has been phase shifted. The two operations in figure 4 and 5 plus the scaling of the comparator output happens simultaneously in the summer of the Phase Shift blocks of the circuit.

Finally the two saw waves are summed and sent through the SuperSaw (!) amount pot RP1A, which acts as a voltage divider scaling the output to between 0 and 100%. The SawAnimator out is then mixed with the raw saw wave elsewhere.

torsdag 14. juli 2016

XM8 progress

I've been working a lot on the xm8 lately. All the work has been gui related, and now I have a working matrix, virtual controllers, setup for nodes, controllers, links and more. I am working on a visual tool to create whole control surfaces and it's looking pretty good. No major feature is missing except for a gui for wifi configuration. I still have a bit of work to do on input configuration serialization (and deserialization on the microcontroller) but things are coming along nicely. Of course there are tons of things to add, like voice assignment, arpeggiator or sequencer functionality, cloud storage etc, but these aren't necessary in the initial version.

Screenshots will be up soon.

onsdag 25. mai 2016

A dac as a replacement for a VCA

A DAC may be used to digitally control the attenuation of a signal by connecting the signal to the DACs Voltage reference input. Most DACs only allow a positive reference voltage lower than the positive supply voltage, so one has to use a device called a multiplying DAC, such as the MX7521.

A circuit like this may be called a NCA (numerically controlled amplifier) or DCA (digitally controlled amplifier)

Some possible devices:
MX7520 - single 10bit dac @ NOK 32,-
MX7501 - single 12bit dac @ NOK 51,-
AD5414 - dual 12bit dac @ NOK 96,-
DAC8803 - quad 14bit dac @ NOK 211,-

lørdag 26. mars 2016

T-baneklokke - coundown clock

Some time ago I grew tired of my wife asking if she had to leave soon to get to the metro in time. I did what any sensible techie would and made her a battery powered countdown clock.

The clock counts down to a selectable time, and repeats the countdown every 15 minutes (the normal interval for the metro over here). Three minutes before it is time to leave, the clock display starts flashing slowly to get your attention. Then, once you should have left, the clock counts UP, blinking fast, as you still have time to make it if you walk briskly. Once your time is TRULY up the countdown to the next metro starts.

To save batteries, the clock goes into as low power mode as possible after about an hour, and you have to switch it off and on again to restart it.

The clock is built using an Arduino, and has a battery powered real time clock to remember the time while powered off.

To make it truly stand alone I added the possibility to set the time and time-to-leave using buttons.

The clock was built into a custom made plexiglass box, and the outside covered with a design printed onto photo paper with a sticky back side. I used my wife's Cameo vinyl cutter printer to cut the paper - I just love that machine!

Here are some pictures from the process:
The Arduino with the RTC module to the right, time-set buttons in the middle and 7 segment display at the bottom.

To keep the top and bottom of the case in place while gluing on the sides, I built a little Lego rig. We all use Legos for prototyping, don't we?


The finished box

Sanded down to make the photo paper stick. 

Power switch and stand-offs added.

Everything fits snuggly. Notice that I kept the USB input to be able to update the software if necessary


Voila! The finished product. Now my wife is never late for the metro ever again. Riiight.


søndag 6. mars 2016

Roland resistor nets for the IR3109

While researching IR3109 based filters I came across the schematics for the Jupiter 6. It has a neat multi mode filter, but the schematics show three resistor networks, and the resistor values for those are not shown.

Luckily, someone has figured out that the same resistors are used in the MKS80, which has most of the values - though not all of them.

From a bit of guessing I have come up with what I believe is the values and internal connections.

RM0688 - The schematics do not show the value for the resistor between 2 and 3, but it is rather safe to assume that it is a 100k resistor like all the others.

RM0690 - The MKS80 schematics shows a 7.7k resistor between 2 and 1. The Jupiter 6 schematics show two resistors without values, one from 1 to 2 and one from 1 to 3. As a 33k and a 10k resistor in parallel equals a 7.7k resistor, and these values are already used in the net, it is very likely that these are the missing values. If we at the same time assume that the positions are reverse those in the other half of the net, just like in the RM0688, we get the schematics above. PS: I have yet to see a usage of this net where 2 and 3 are not connected, so it is in reality only the combined value that matters.

RM0891
The resistor nets have different part numbers and designations in the various synths:

13919128 - RM0688 - RKM8C066
13919130 - RM0690 - RKM8C068
13919132 - RM0891 - RKM9F561/683GP

fredag 26. februar 2016

typedef, structs and function pointers

Just a quick reminder about structs and typedefs in C:


A named struct is created like this:

struct MyStruct{
  int anInt;
}

A custom type like this:

typedef int MyType;


The two syntaxes may be combined like this

typedef struct MyStruct{
  int anInt;
} MyType;


In use you can then either write

void myFunction(struct MyStruct someValue);

or

void myFunction(MyType someValue);


in the latter case omitting the struct keyword.


Function pointers


A variable containing a pointer to a function can be written like this:

returnType (*pointerName)(parameterType)

For example:

void (*myFunctionPointer)(int)


The pointer is then for example assigned like this:

myFunctionPointer = &someFunction;


Combined with typedef you can get:

typedef void (*myFunctionPointerType)(int)

and then use myFunctionPointer as a type:

myFunctionPointer aFunction = &someFunction;

søndag 21. februar 2016

XM8 32 channel CV works

I've spent some time the last few days getting the sample and hold part of the 32 channel DAC to work properly.

As is usual, I messed some things up in the initial design. The DAC board is connected to the 32ch sample/hold via a connector. This goes in a U-shape but I forgot that this means that pin 1 on connector one becomes pin 2 on the other and vice versa. As power as well as signals are transferred through this connector, nothing worked right. Weirdly enough though, nothing broke, it just got very hot.

From the initial tests I learned a few things:

- The type of opamp used with the DAC matters, at least visibly on the scope. Using a stock TL07x opamp produces slight a slight overshoot when the DAC output changes a lot. Using a AD8672 precision opamp instead removes the overshoot.

The S&H circuit shows a similar overshoot when it is set. As the S&H is all TL074 it could be that it is fixed in a similar manner. I just don't know how much it matters.
The output as seen between the DAC and the sample and hold shift register - the initial rising curve shows the output from the DAC. The drop is caused by the enabling of the shift register, connecting the DAC to the sample and hold which is currently at its most negative, so it takes a short amount of time before it charges to the same level as the DAC. The peak is where the charging of the sample and hold capacitor overshoots. It is of the same kind but more dramatic than then one we see in the DAC output photos above and may be caused by the TL074.
A more detailed photo showing the charging and overshoot.

- I connected the output of the S&H to the pitch and filter inputs of a Moog Little Phatty. It worked very well, but I got an audible clicking noise four times per second. It went away when I removed sampling of all but one input potentiometer from the PIC32, so it may not be a problem in real life where the potmeters will be sampled from a completely separate circuit.

- At very high frequencies there is a slight ringing to the sound, I presume this is some kind of aliasing. I could not hear much of it when I turned off sampling of all potmeters but it should be investigated further.

- Oscilloscopes have a horizontal scale calibration potmeter. I spent hours trying to understand why the results I got did not seem to match the output frequency I was expecting, untill I realised that I had made two crucial mistakes: The oscilloscope scale was way off (fixed by connecting a function generator) and I had not set the internal PLL divider in the PIC32 correctly (it was running five times slower than expected!)


The output of one of the 32 sample and hold cells when running at full speed with 32 operating cells. DAC switches between +/- 5V.


Just for fun: My test rig. From left: Four potmeters that sets the CV (read using the ADC in the PIC32), a solderless breadboard that just reconfigures one of the ribbon cables, the EasyPIC fusion 7 development board from Mikroelektronika, which contains the PIC32, and on top of it: four quarter inch jacks connected to outputs 29,30 ,31 and 32 of the DAC circuit. To the right: My Moog Little Phatty