Thanks for the links
I just bought a Moog Mother 32 recently. Enjoying it
That's why I wanted to build a VCO-555 first, because my Mother 32 needs another voice
It's actually quite cheap to make. One LM13700, 555 chip and a few TL071 TL072 type op amps. I think the most expensive parts are the pots, knobs & jacks (ouch).
Here's Thomas Henry's introduction of the VCO-55: discussion, schematics & BOM.
http://electro-music.com/forum/topic-54623.html
An example of my current limited electronics knowledge. A midi controller for Roland TR-808 & TB-303 VST plugin clones. Top left knobs controlled the bass and the rest are the drums (below). Top right was tempo. LCD panel showed you which parameters you were adjusting when you turned a knob along with its value.
Used an arduino micro for all these pots by using the lil 4051 multiplexer chips. Used 3 data pins on the arduino to set the 3 bit address to select which pin to read from. It just scanned everything over and over in a loop -- very rapidly -- and observed any changes. Set the variable with new value, sent the midi control message and updated the display.
Used chipboard and cardboard for this prototype lol.
Here's the code. Some of it pretty sloppy I'm sure.. just threw it together.
#include <LiquidCrystal.h>
//#define DEBUG /* uncomment this line to run in serial monitor debug mode */
#define NUM_KNOBS 14
#define NUM_SWITCHES 1
#define NUM_TOGGLES 1
#define KNOBS_CHANNEL 0
#define SWITCHES_CHANNEL 1
#define TOGGLES_CHANNEL 2
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int switches [NUM_SWITCHES];
int toggles [NUM_TOGGLES]; //pseudo toggles w/ momentary switches
int toggles_low_flag[NUM_TOGGLES];
int mux_select_pins[] = {7, 8, 9};
int knobValue[NUM_KNOBS];
int oldKnobValue[NUM_KNOBS];
int prevOldKnobValue[NUM_KNOBS];
int toggle = 1;
String lastKnobTitle = "";
String knobTitles[NUM_KNOBS] = {"TEMPO", "BASS VOL", "DRUMS VOL","ACCENT", "DECAY", "CUT OFF FREQ", "ENV MOD", "RESONANCE",
"BASS LVL", "BASS TUNE", "BASS DECAY", "SNARE LVL", "SNARE TUNE", "SNARE SNAP"};
void setup () {
memset(switches, 0, sizeof(switches));
memset(toggles, 0, sizeof(toggles));
memset(toggles_low_flag, 1, sizeof(toggles_low_flag));
#ifdef DEBUG
Serial.begin(38400); // serial monitor debugging instead of midi
#else
Serial.begin (31250); // set to midi baud rate
#endif
pinMode(mux_select_pins[0], OUTPUT);
pinMode(mux_select_pins[1], OUTPUT);
pinMode(mux_select_pins[2], OUTPUT);
pinMode(4, INPUT);
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("TB-303 & TR-808 ");
init_values();
}
void init_values() {
for (int i=0; i < NUM_KNOBS; i++) {
int analog_input_pin;
int analog_channel = i % 8;
int x = i / 8;
if (x == 0) {
analog_input_pin = A0;
} else if (x == 1) {
analog_input_pin = A1;
} else if (x == 2) {
analog_input_pin = A2;
} else {
analog_input_pin = A3;
}
delay(1);
knobValue[i] = readMux(analog_input_pin, analog_channel);
// write to midi channel
midi_ctrl_write(KNOBS_CHANNEL, i + 1, knobValue[i]);
}
}
void loop () {
// handle knob tweaks
for (int i = 0; i < NUM_KNOBS; i++) {
int analog_input_pin;
int analog_channel = i % 8;
int x = i / 8;
if (x == 0) {
analog_input_pin = A0;
} else if (x == 1) {
analog_input_pin = A1;
} else if (x == 2) {
analog_input_pin = A2;
} else {
analog_input_pin = A3;
}
knobValue[i] = readMux(analog_input_pin, analog_channel);
if (knobValue[i] != oldKnobValue[i]) {
if (knobValue[i] != prevOldKnobValue[i]) {
// write lcd info
if (lastKnobTitle != knobTitles[i]) {
lastKnobTitle = knobTitles[i];
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(knobTitles[i]);
}
if (knobValue[i] < 10) {
lcd.setCursor(13, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
} else if (knobValue[i] < 100) {
lcd.setCursor(13, 1);
lcd.print(" ");
lcd.setCursor(14, 1);
} else {
lcd.setCursor(13, 1);
}
lcd.print(knobValue[i]);
// write to midi channel
midi_ctrl_write(KNOBS_CHANNEL, i + 1, knobValue[i]);
prevOldKnobValue[i] = oldKnobValue[i];
oldKnobValue[i] = knobValue[i];
}
}
}
/*
// handle switches & buttons (momentary switches)
if (digitalRead(4) == HIGH) {
if (switches[0] == 0) {
midi_ctrl_write(100, 127);
switches[0] = 1;
}
} else {
if (switches[0] == 1) {
midi_ctrl_write(100, 0);
switches[0] = 0;
}
}
*/
/*
// handle toggles (momentary switches emulating toggles)
if (digitalRead(4) == HIGH){
if (toggles_low_flag[0] == 1) {
if (toggles[0] == 0) {
midi_ctrl_write(TOGGLES_CHANNEL, 100, 127);
toggles[0] = 1;
} else {
midi_ctrl_write(TOGGLES_CHANNEL, 100, 0);
toggles[0] = 0;
}
toggles_low_flag[0] = 0;
}
} else {
// LOW
toggles_low_flag[0] = 1;
}
*/
delay(10);
}
void midi_msg_write(int statusbyte, int data) {
midi_msg_write(statusbyte, data, -1);
}
void midi_msg_write(int statusbyte, int data, int data2) {
#ifdef DEBUG
Serial.print(statusbyte);
Serial.print(" ");
Serial.print(data);
if (data2 != -1) {
Serial.print(" ");
Serial.print(data2);
}
Serial.println();
#else
Serial.write(statusbyte);
Serial.write(data);
if (data2 != -1) {
Serial.write(data2);
}
#endif
}
void midi_ctrl_write(int channel, int controller_num, int controller_value) {
int statusbyte = 0XB0 + channel;
midi_msg_write(statusbyte, controller_num, controller_value);
}
int readMux(int common_analog_pin, int mux_channel) {
// select the mux channel for the knob value we want to read
digitalWrite(mux_select_pins[0], bitRead(mux_channel, 0));
digitalWrite(mux_select_pins[1], bitRead(mux_channel, 1));
digitalWrite(mux_select_pins[2], bitRead(mux_channel, 2));
// read knob value corresponding to the mux channel we just selected
return map (analogRead(common_analog_pin), 0, 1023, 127, 0) - 1;
}
Thanks I have a couple of old Commodore 64 SID chips laying around here (along with a fully functioning C64 I use from time to time -- have a thing for my first puter I guess lol). Would be cool to hook up the SID to an arduino and have the arduino receive MIDI data/notes and play them on the SID. Have some pots for cut offs etc. Also have CV/GATE control and perhaps integrate into a modular synth This seems more apporachable to me since most of it is digital electronics vs. building my own analog VCO with a bunch of TL071 TL072 LM31700 op amp chips along with loads of resistors and caps
Glad to see enthusiasm Jennifer. Check out Jeri Ellsworth. She has started a company called castAR now and hasn't posted in a long time.
https://www.youtube.com/user/jeriellsworth/videosShe completely built a C64 with FPGA.
Wish Jeri was more active, miss her.
Fran Blanch has become more active lately on her Youtube channel, I reached out to keep her going on her recent begathon.
Result of her recent fantastic pipe organ "teardown" video makes it worth my support. Used to record and stand in the things climbing around with the tons of audio recording equipment.
... I heard about this book before from the Muffwiggler forum, that it was particularly good. ...
I just had to go look that up. I learn a little every day...
Cool project and generally nicer code than usually seen :-)
I'd have used an array not a switch to choose analog_input_pin (as for mux_select_pins).
oldKnobValue and prevOldKnobValue are pretty funky. A bit of hysteresis to allow for imprecise A/D conversion?
I'm confused why you subtract 1 from the result of the map() in readMux. Is -1 a useful value? And anyway the map() could have done that :-)
Not criticising, just curious and I probably over optimise stuff ... I've certainly written plenty of "when it works it's Good Enough" code, especially for microcontrollers!
Hey.
I want to be the first to say...
seconded.
I too am making my own modular and started with a Thomas Henry design. I have made a VCO-1 VCF-1 and VCA-1. It sounds amazing and was a lot of fun so commited to a 5u setup 600mm wide and 2 rows tall. I plan on updating the vco-1 with a vco555, and adding a whole slew of Yusynth projects.
http://yusynth.net/Modular/index_en.htmlYves Usson did the design and stuff for the Arturia synths. I picked up a minibrute to interface with my modular, CV with an extra ADSR and LFO. It's awesome to see other diy'ers out and about (outside of the Muffwiggler and electro-music forums).
Thanks heaps to pitagoras aswell! I got quite a bit from those links that I hadn't seen before. Especially like the Prophet 6 breakdown.
I know little about the modern day microprocessor electronics, coming from a more guitar oriented background. Cutting my teeth on a silverface fender amp and redoing its power section has prepared me pretty well for not missing the small stuff/touching the wrong thing! I can't help but love the old way, turret boards and point to point artwork. But in the quest for DIY synthesis I'm keen to find out why X sounds different to Y. And I want to breadboard it up myself to see and hear the difference.
For instance I'm making two Yusynth VCO's at the moment. And like Jennifer my first oscillator was just there and worked. Now I can point out the parts and whys of the design. Mostly
Cool project and generally nicer code than usually seen :-)
I'd have used an array not a switch to choose analog_input_pin (as for mux_select_pins).
oldKnobValue and prevOldKnobValue are pretty funky. A bit of hysteresis to allow for imprecise A/D conversion?
I'm confused why you subtract 1 from the result of the map() in readMux. Is -1 a useful value? And anyway the map() could have done that :-)
Not criticising, just curious and I probably over optimise stuff ... I've certainly written plenty of "when it works it's Good Enough" code, especially for microcontrollers!
Regarding the prevOldKnobValue, actually the circuit didn't work right until I added that. Kind of proud of adding that actually; added it after I debugged a problem I was having. The potentiometer value jumps around at one given setting at times, so it constantly tells the scanner it's changing value hundreds of times per second, even though the user isn't turning it.
Again for the rest, I just threw it together, didn't spend time optimizing nor did I finish the project
I started then stopped after I decided I didn't want to use VST for TB-303 and TB-808. I wanted the physical hardware
Yes, as I suspected :-)
I wonder if this would work as well?
newValue = readMux(analog_input_pin, analog_channel);
if (abs(newValue - knobValue[i]) > 1) { knobValue[i] = newValue; ... }
Yes, as I suspected :-)
I wonder if this would work as well?
newValue = readMux(analog_input_pin, analog_channel);
if (abs(newValue - knobValue[i]) > 1) { knobValue[i] = newValue; ... }
I think I did something similar at first -- actually, I think the exact code you just shared now. However, it lowers the resolution of the changes. e.g. If the user is slowly turning the knob constantly left over a performance, with my code as is, it is changing in increments of one, smoothly. With the code you suggested, it would only change in increments of two and be rougher -- also, when you get to say a level of 1 you couldn't turn it down to zero.
Would be cool to hook up the SID to an arduino and have the arduino receive MIDI data/notes and play them on the SID.
I know someone who has built a SID player with a real SID. He used a big microcontroller, an AT91SAM7:
The simple solution for the clock was an 1 MHz external oscillator, which I sent him and helped him a bit with building this thing (see
http://www.mikrocontroller.net/topic/197960 ). He implemented a full C64 emulator in order to play SID files.
Of course, this might be too much for a poor Arduino, but it should be possible to create a 1 MHz signal with the PWM output of the Arduino and to program a simple MIDI synthesizer. Synchronization could be a problem with a standard 16 MHz Arduino, you might need inline assembler to set the data and address bits and from a timer interrupts, to met the timing requirements (setup and hold time etc.). Unfortunately on the Arduino you can't specify interrupt priority, like with the STM32 microcontrollers, so you might have to disable the millisecond interrupt, or try to do the synchronization inside this interrupt and call the original Arduino interrupt after your function, and poll the rest, like the serial port for the MIDI input.
With a full C64 you can build interesting hardware for it as well. This is one of my projects:
http://www.frank-buss.de/kerberos/index.html
Very cool!
I've read about cynthcart and wanted it. Nice to see your custom MIDI interface
I have easyflash, jiffydos and sd card reader on my c64 now
Here is a photo of my Commodore 64 I just snapped. I am particularly proud of the little 1541 sticker I made for the built in SD card reader
[Another example of my
very limited electronics experience lol.. pop in a board, find a way to mount it.. connect it up and go. After all these years, I am decent at soldering and de-soldering at least.]
Nice to be able to store thousands of c64 programs on one little chip. Who would of thought (back in the day)?! I remember my big tub of "single-sided" 5.25" floppy disks.. punched to be able to use the back side of the disk as well
I bet if the thread title was "Hello my name is Bob, I'm new here" I would have about half as many views.
Hello Jennifer.
Hello. Don't know what to say. I guess I wish there was a Welcome Wagon subforum here. Other forums have it. I guess I apologize for trying to do a friendly introduction.
I'd love it if the moderator would just delete all references to gender from this thread and any negativity I or others have caused. I feel awkward. Never had this issue before on other forums. Not even in the muffwiggler DIY section.
Or better yet, it might be more convenient to just delete this entire thread, please.
I bet if the thread title was "Hello my name is Bob, I'm new here" I would have about half as many views.
Hello Jennifer.
Hello. Don't know what to say. I guess I wish there was a Welcome Wagon subforum here. Other forums have it. I guess I apologize for trying to do a friendly introduction.
I'd love it if the moderator would just delete all references to gender from this thread and any negativity I or others have caused. I feel awkward. Never had this issue before on other forums. Not even in the muffwiggler DIY section.
Or better yet, it might be more convenient to just delete this entire thread, please.
Thread cleaned up as much as possible. Please don't take offence anyone who's post ws deleted, I've tried to leave just the technical stuff.
What do you think about using a SPICE program to learn all these lab circuits in this Learning the Art of Electronics book? I read something about LTSpice, but that is an older program. Is it still considered the best free SPICE program? Or are there better ones? Or perhaps I should spent a little for a better SPICE program. That's a lot of parts to buy if I do it physically.
On the subject of number crunching, I want to bring up wxMaxima as a Computer Algebra System (CAS). This program is superb! If you do a little search, you will find one of Simon's threads with some examples of solving his homework.
The learning curve seems a bit steep but there are a couple of books that break it down pretty well:
https://wxmaximafor.wordpress.com/Of course you can find a ton of help via Google but the User Manual isn't one of the easiest things to read. I tend to search for more specific topics and see what pops up.
I have only been playing with the program for a couple of weeks but it is now my #1 tool for verifying my grandson's Calculus I homework. Well, that and desmos.com (graphing) and symbolab.com (just about everything).
When you get to the lab experiment for charging a capacitor, wxMaxima rocks. For giggles, I decided to code this up and get a 2D plot.
What does the SPICE program have to do with the title of this thread?
The subject of this thread is only a first and very good presentation.
Jennifer should open a new specific topic for each technical question she wants to ask.
What does the SPICE program have to do with the title of this thread?
The subject of this thread is only a first and very good presentation.
Jennifer should open a new specific topic for each technical question she wants to ask.
It's a discussion with questions about how and where to get started. Seems quite relevant to me. What's the problem?
The problem is that somebody who looks for informations about this SPICE program will not find them because they are not related to the tittle of the thread.
I'm pretty sure everything will show up when using Search.
I just searched for wxMaxima and came up with a bunch of hits including the one of mine above. Lots of hits in Simon's homework thread.
You know very well than most of the people don't use the "Search" function, they simply look at the tittle of the threads...That's what I do....I look at the tittle and I only read the posts if the tittle interest me.
Its is a forum, not a chat !
The technical informations must be easily found by everyone....simply reading the tittle of the thread.
Yes, as I suspected :-)
I wonder if this would work as well?
newValue = readMux(analog_input_pin, analog_channel);
if (abs(newValue - knobValue[i]) > 1) { knobValue[i] = newValue; ... }
I think I did something similar at first -- actually, I think the exact code you just shared now. However, it lowers the resolution of the changes. e.g. If the user is slowly turning the knob constantly left over a performance, with my code as is, it is changing in increments of one, smoothly. With the code you suggested, it would only change in increments of two and be rougher -- also, when you get to say a level of 1 you couldn't turn it down to zero.
Yes, quite right. With your solution noise might get you there early sometimes, but you'll at least get there. Hmmm ... thinking ...
You know very well than most of the people don't use the "Search" function, they simply look at the tittle of the threads...That's what I do....I look at the tittle and I only read the posts if the tittle interest me.
Its is a forum, not a chat !
The technical informations must be easily found by everyone....simply reading the tittle of the thread.
If that is the case as the thread fast dissapearsd on the pile it still won't be of any use despite the title.
5) This is an electronics forum, so try to stay on-topic. We understand that threads drift off-topic, but try not to start deliberately and grossly off-topic stuff.
What is the definition of "off-topic" ?
The tittle of the thread seems to be the topic ....or not ?