Working on a project I needed extra digital in’s and extra digital out’s for my Arduino Uno (lots of LEDs, lots of buttons). I’ll use a CD4021 to extend the digital in’s and a 74HC595 to gain extra digital out’s. I decided it would be best to both access the data of the CD4021 and send data to the 74HC595 over the hardware SPI bus on the Arduino (see previous post). Turns out te be not that hard (fortunately ;) ). Here’s the eagle schematic for 1 4021 and 1 595. Of course you can cascade more IC’s if you need more in’s or out’s. Only difference is that you’ll have to interpret and send more bytes (1 byte per IC).
Here’s my Arduino code so far:
#include <SPI.h>
#define PIN_SCK 13 // SPI clock
#define PIN_MISO 12 // SPI data input
#define PIN_MOSI 11 // SPI data output
#define PIN_SS1 10 // SPI hardware default SS pin, 4021
#define PIN_595_1 9 // SPI 74HC595
// result byte for 4021
byte buttons8;
// global vars for button timeout and debounce
long button1timeout = 0;
long button2timeout = 0;
long debounce = 200;
void setup() {
Serial.begin(9600);
SPI.begin();
// set all IC select pins HIGH
digitalWrite(PIN_SS1,HIGH);
pinMode(PIN_595_1, OUTPUT);
digitalWrite(PIN_595_1,HIGH);
}
void loop() {
// SS1 = HIGH -> 4021 is gathering data from parallel inputs
// select 595
digitalWrite(PIN_595_1,LOW);
// send BIN number to 595 to light 1 LED (not necessarily the 1 example LED on the schematic)
SPI.transfer(B00000100);
// deselect 595
digitalWrite(PIN_595_1,HIGH);
// select 4021
digitalWrite(PIN_SS1,LOW);
// read CD4021 IC
buttons8 = SPI.transfer(0x00);
// button functions and debounces
// needs refactoring for smaller footprint
if((B10000000 & buttons8) && (millis() - button1timeout > debounce)) {
Serial.println("but1");
button1timeout = millis();
}
if((B01000000 & buttons8) && (millis() - button2timeout > debounce)) {
Serial.println("but2");
button2timeout = millis();
}
// deselect 4021
digitalWrite(PIN_SS1,HIGH);
}
The “ShiftIn” tutorial on the Arduino site (Parallel to Serial Shifting-In with a CD4021BE) is very clear on why and how to setup and test your Arduino in combination with a CD4021 IC. I needed extra digital inputs and decided to communicate via SPI with the CD4021 chip. Figured it out, it was actually pretty simple thanks to the easy SPI implementation in the Arduino software since version 0020 or so (?)
Setup as described in the Arduino tutorial. Reconnect the clock, the MOSI and the slaveselect as the #defines in the following code. And you’re all set.
#include
#define PIN_SCK 13 // SPI clock
#define PIN_MISO 12 // SPI data input
#define PIN_MOSI 11 // SPI data output
#define PIN_SS1 10 // SPI hardware default SS pin
void setup() {
Serial.begin(9600);
SPI.begin();
}
void loop() {
digitalWrite(PIN_SS1,HIGH);
// while gathering info from parallel inputs
// do some other processing
// for now I'll use
delayMicroseconds(200);
// select PIN_SS1 CD4021 IC
digitalWrite(PIN_SS1,LOW);
// read byte from CD4021 IC
Serial.println(SPI.transfer(0x00),BIN);
}
tip: buy some resistor arrays instead of all individual resistors
Wow! I decided to give Reason 6 a good try. First of all I wanted to recreate the sound of my last analog prototype (see and listen to the previous post). Oh, here’s a picture of that prototype btw:
In Thor I recreated the sound of a single analog oscillator like so:
A single Analog Osc generating a sawtooth waveform, no filters, enveloppe only sustain. Sounds… the same! Listen for yourself:
This recording was made via the buildin soundcard of my MacBook. Sound quality will improve when better audio interface hardware equipment is being used. The soundcloud conversion didn’t work out, not in PCM nor FLAC…
My soundcloud comment:
Tough upload, still sounds horrible. It’s not that important, just wanted to let you hear the hard-to-hear difference between my own VCO prototype and a construction in Propellerhead Reason’s Thor synthesizer.
This sawtooth is generated through an orange drop capacitor (sounded better then its wima counterpart) in a 100% analog sound path. Reset pulses are generated by an Arduino and the rise of the sawtooth waveform is controlled by a MCP4921 DAC. Each frequencies requires an exact voltage to level out the sawtooth. I haven’t calibrated these voltages yet so the sawtooth isn’t very precise yet. I like the raw sound though!
The VCA of this beta filter was built like the schematic supplied by Mooger5 (check older posts). The redesigned VCA based on a LM13700 should work also (check older posts).
Yesterday I tuned the LPF using my trusty old board o’ potentiometers…
Best sounding values came out like this:
which I, after some thinking, recognized as the original values like in the JUNO6! Very nice! Just had to replace the 100pF capacitor with a 240pF capacitor like in the original. Only thing missing is the “mystery resistor” on the + input of the OTA to ground. For now I just left this res out.
A fitting frequency range for the filter should be achieved by a good control current. According to the IR3109 specifications, transconductance should range from 1µƱ – 10mƱ. The expo converter from the previous post delivers a current ranging from 70nA to 1.65mA which translate to a transconductance of 1.34µƱ to 31mƱ. Ok for now.
I made a mockup of the JUNO6 board and the IR3109 ic:
I’m not sure. Did a lot of prototyping and these are the results.
Since I couldn’t figure out a proper way to calculate the cutoff frequency when using different current and resistor combination, I decided to use the default lowpass filter circuit from the LM13700 datasheet.
Hooked my expo converter up to pin 1 (100nA < Iabc < 1.1mA) and started testing. The Vout of this pole is the Vin of the second pole. Unfortunately I only had 1 LM13700 working left, since I blew up all my other’s ;). I experimented a lot with different capacitor and resistor combination and the only ok sounding combination is a 1nF capacitor with 10K big and 220Ohm small resistors. Check the following sound files for the results:
Oh, just for fun: a pic of the breadboard in action
left bottom: BA6110 based VCA. Right top: dual 2N3906 based expo converter. Right bottom: Only remaining LM13700 configured as a 2-pole lowpass filter.