Test of VCO first Revision
So this release is in beta status, working :-) and with non commercial backround. The expo converter and VCO is based on the publication from Robin Mitchell with additional waveformer for Sine, *PWM and *Saw. The PCB is made for the eurorack format.
If you need support or if you see any improvement, please contact me over mail minarterfurt@yahoo.de
Thanks
*twofold frequency as TRI & Sine
Some years I made my PCB's with UV lamp and etching, but this was every time a nightmare.
I found an easy process, thanks to youtube ;-), calls "toner transfer method".
The only tree things you need are a laser printer, heat transfer paper (standard paper also working) and a hot iron.
Below you will find the full process wich will work very well.
1. print out your layout on the toner transfer paper and cut out the copper PCB
2. Carefully position the PCB with your layout on toner transfer paper.
Place kitchen paper under and over all and go over with the iron for about 2min (full temperature).
3. afterwards lie the PCB with the paper in water for about 2min, then you can easy peel off the paper.
Nice ;-)
4. etch with sodium persulfate.
Done, it looks really nice. The toner you can remove with petrol.
Simple nice to have module to visualize your sounds like an oscilloscope. Patch your synth output directly to the input of the sound visualizer and adjust the voltage level with the amplitude potentiometer.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Display-Definition
#define SCREEN_WIDTH 128 // OLED Display Breite
#define SCREEN_HEIGHT 64 // OLED Display Höhe
#define OLED_RESET -1 // Reset-Pin (nicht verwendet bei I2C)
#define SSD1306_ADDRESS 0x3C // I2C-Adresse des Displays
// Display-Objekt erstellen
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// 'Minart Modular final', 128x64px
const unsigned char image [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x10, 0x88, 0x80, 0x08, 0xc4, 0x13,
0x00, 0xff, 0xfc, 0xff, 0xef, 0xfe, 0xff, 0xff, 0xf7, 0xbc, 0xff, 0xf9, 0xbf, 0xff, 0x9f, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
0x01, 0xc3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x01, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x02, 0x00, 0x20, 0x07, 0x00,
0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x63, 0xe9, 0x14, 0x40, 0x00, 0x00, 0x07, 0x00,
0x00, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0x83, 0x83, 0xfe, 0xfe, 0xc0, 0x00, 0x00, 0x06, 0x00,
0x00, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x00,
0x01, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3b, 0x07, 0x00,
0x00, 0xc0, 0x3f, 0x04, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x03, 0x07, 0x00,
0x00, 0xc0, 0xfd, 0xde, 0x3f, 0x00, 0x03, 0x0e, 0x01, 0xf8, 0x07, 0x08, 0x3f, 0xfe, 0x05, 0x00,
0x00, 0xc1, 0x87, 0xff, 0xff, 0x87, 0x0f, 0xff, 0x83, 0xff, 0x1f, 0xbe, 0x7f, 0xf8, 0x07, 0x00,
0x00, 0xc1, 0xf3, 0xc7, 0xc7, 0x9f, 0x87, 0xef, 0xc7, 0x3f, 0x87, 0xde, 0x1e, 0x00, 0x07, 0x00,
0x00, 0xc0, 0xe3, 0xc7, 0xc7, 0x87, 0x87, 0xc3, 0xc0, 0x07, 0x87, 0x80, 0x0e, 0x00, 0x03, 0x00,
0x00, 0xc0, 0x03, 0xc7, 0xc7, 0x87, 0x87, 0xc7, 0xc0, 0x07, 0x87, 0xc0, 0x1f, 0x00, 0x07, 0x00,
0x01, 0xc0, 0x02, 0xc7, 0xc7, 0x87, 0x87, 0xc3, 0xc1, 0xfd, 0x87, 0xc0, 0x1f, 0x00, 0x06, 0x00,
0x00, 0xc0, 0x03, 0xc7, 0xc7, 0x87, 0x83, 0xc3, 0xc7, 0x87, 0x87, 0x80, 0x1f, 0x00, 0x07, 0x00,
0x01, 0xc0, 0x03, 0xc7, 0xc7, 0x87, 0x83, 0xc7, 0xcf, 0x07, 0x87, 0x80, 0x0f, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x03, 0x47, 0xc7, 0x87, 0x87, 0xc3, 0xcf, 0x87, 0x87, 0x80, 0x1e, 0x30, 0x07, 0x00,
0x00, 0xc0, 0x07, 0xe7, 0xce, 0xcf, 0xc7, 0xc7, 0xef, 0xff, 0xe7, 0xc0, 0x3f, 0xe0, 0x06, 0x00,
0x00, 0x00, 0x03, 0xc3, 0x07, 0x87, 0xc7, 0xc3, 0xc1, 0xe3, 0xc3, 0xc0, 0x0f, 0x80, 0x42, 0x00,
0x01, 0x00, 0x00, 0x80, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x01, 0xc0, 0x00, 0x31, 0x8e, 0x01, 0x01, 0x60, 0x00, 0x06, 0x02, 0x03, 0x10, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0xff, 0xff, 0x87, 0xc7, 0xfc, 0xe3, 0x8e, 0x0f, 0xc7, 0xfc, 0x00, 0x07, 0x00,
0x00, 0xe0, 0x00, 0x39, 0xc7, 0x39, 0xe3, 0x9c, 0xf3, 0x87, 0x19, 0xe3, 0x98, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x39, 0xe7, 0x30, 0xe3, 0x9c, 0x73, 0x87, 0x00, 0xe3, 0x80, 0x00, 0x06, 0x00,
0x00, 0xc0, 0x00, 0x39, 0xe7, 0x38, 0xe3, 0x9c, 0x73, 0x8e, 0x07, 0xe3, 0x80, 0x00, 0x07, 0x01,
0x00, 0xc0, 0x00, 0x39, 0xe7, 0x38, 0xe3, 0x9c, 0x73, 0x8e, 0x38, 0xe3, 0x80, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x39, 0xe7, 0x3c, 0xe3, 0x9c, 0x7f, 0x8e, 0x38, 0xe3, 0x80, 0x00, 0x06, 0x00,
0x00, 0x80, 0x00, 0x7d, 0xef, 0x9f, 0x8e, 0xf3, 0xff, 0xff, 0xbf, 0xf7, 0xe0, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x10, 0x01, 0x00, 0x00, 0x80, 0x20, 0x82, 0x08, 0x41, 0x80, 0x00, 0x06, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc7, 0xc7, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00,
0x08, 0xc3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0x00,
0x00, 0xc3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x87, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x02, 0xfc, 0x48, 0x71, 0xb7, 0xfd, 0x42, 0x3d, 0x56, 0xa2, 0x9e, 0x5a, 0x9f, 0x87, 0xcf, 0x00,
0x00, 0x7f, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xff, 0x9f, 0xfe, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20
};
// Analog Pins
int channelAI = A0; // Probe
int delayAI = A1; // Delay Potentiometer
float delayVariable = 1; // Verzögerungsvariable
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[128];
void setup() {
// Serielle Kommunikation starten
Serial.begin(9600);
// Display initialisieren
if (!display.begin(SSD1306_ADDRESS, 0x3C)) {
Serial.println(F("SSD1306 Initialisierung fehlgeschlagen"));
for (;;)
; // Endlosschleife bei Fehler
}
// Display löschen
display.clearDisplay();
// 1. Bild anzeigen
display.drawBitmap(0, 0, image, 128, 64, WHITE);
display.display();
delay(2000);
// Sinuswelle animieren
animateSineWave(1); // Sinuswelle für 2 Sekunden anzeigen
// Display löschen
display.clearDisplay();
}
void loop() {
// Messwerte visualisieren
plotAnalogSignalWithScaling();
}
// Funktion zur Sinuswellen-Animation
void animateSineWave(int durationInSeconds) {
unsigned long startTime = millis();
const int amplitude = 20; // Amplitude der Sinuswelle
const int midpoint = SCREEN_HEIGHT / 2; // Mittellinie
while (millis() - startTime < durationInSeconds * 1000) {
display.clearDisplay();
for (int x = 0; x < SCREEN_WIDTH; x++) {
float angle = 2.0 * PI * x / SCREEN_WIDTH; // Berechnung des Winkels
int y = midpoint + amplitude * sin(angle); // Sinuswert berechnen
display.drawPixel(x, y, WHITE); // Pixel für die Welle setzen
}
display.display();
delay(50); // Animation verlangsamen
}
}
void plotAnalogSignalWithScaling() {
// Zeitbasis in Millisekunden pro Division
float timebase = 10.0; // 10 ms pro Division
int pixelsPerDivision = 16; // 8 Divisionen (128 / 16)
float delayPerPixel = timebase / pixelsPerDivision; // Verzögerung pro Pixel
const int displayHeight = 50; // Höhe des Bereichs für das Signal
const int midpoint = SCREEN_HEIGHT / 2; // Fixierter Nullpunkt in der Mitte des Displays
const int triggerThreshold = 30; // Schwellwert für Triggerung
const int baseline = 500; // Standard 512 / Baseline für kein Signal (ADC-Mittelwert)
float scaleFactor = 0.6; // Skalierungsfaktor (1.0 = volle Höhe, <1.0 = kleiner, >1.0 = größer)
int readings[128];
bool signalDetected = false;
// Messwerte aufzeichnen
for (xCounter = 0; xCounter < SCREEN_WIDTH; xCounter++) {
int rawValue = analogRead(channelAI);
// Trigger prüfen: Signal nur darstellen, wenn über Threshold
if (abs(rawValue - baseline) > triggerThreshold) {
signalDetected = true; // Signal erkannt
}
// Wenn kein Signal erkannt, baseline anzeigen
if (!signalDetected) {
readings[xCounter] = baseline;
} else {
readings[xCounter] = rawValue;
}
delay(delayPerPixel); // Zeitbasis
}
// Signal-Darstellung vorbereiten
int minValue = baseline - (displayHeight / 2) / scaleFactor; // Untere Grenze
int maxValue = baseline + (displayHeight / 2) / scaleFactor; // Obere Grenze
// Signal zeichnen
display.clearDisplay();
for (xCounter = 1; xCounter < SCREEN_WIDTH; xCounter++) {
int y1 = midpoint - map(readings[xCounter - 1], minValue, maxValue, -displayHeight / 2, displayHeight / 2) * scaleFactor;
int y2 = midpoint - map(readings[xCounter], minValue, maxValue, -displayHeight / 2, displayHeight / 2) * scaleFactor;
// Nur Werte innerhalb des darstellbaren Bereichs zeichnen
if (y1 >= 0 && y1 < SCREEN_HEIGHT && y2 >= 0 && y2 < SCREEN_HEIGHT) {
display.drawLine(xCounter - 1, y1, xCounter, y2, WHITE);
}
}
display.display();
}
Diese Webseite wurde mit Jimdo erstellt! Jetzt kostenlos registrieren auf https://de.jimdo.com