|
Post by dizzeesatchel on Aug 1, 2022 23:48:37 GMT
Inspired by the DIY chat from pt3r about the humble comparator. The logic seemed fairly simple (but please correct me if i've completely misunderstood the concept), and it seemed like a reasonable first foray into core.ae programming.
The code is fairly self-explanatory, send a signal into input B and the m-c output will output 5v when that signal passes the reference point. Reference can be set either by sending a signal into input C, or using knob C to set it manually. You can use knob D to offset the reference CV input, although typing this out I realise you could do that anyway with knob C oh well
(I don't think there's any way to read the CV input separately from the knob position of that same input...right? Otherwise you could have multiple comparators quite easily)
// Super-amateur comparator for core.ae! // (with thanks to pt3r for introducing the concept) // Set all knobs fully counter-clockwise. // Input CV-B is your main signal. // Input CV-C is the reference signal. // Alternatively, with nothing patched to CV-C, use knob C to manually // set a reference voltage. // Knob D is summed to the input on C, so can be used as an offset. // When signal is greater than reference, output m-c is HIGH, // output s-c is inverted. // Try using the m-a and s-a outputs for a slightly slewed output.
void setup() { // initialise the pins pinMode(A1, INPUT); pinMode(A2, INPUT); pinMode(A3, INPUT); pinMode(PB1, OUTPUT); pinMode(PB0, OUTPUT); digitalWrite(0, LOW); digitalWrite(1, LOW); }
void loop() { // compare two voltages, high if signal is greater uint16_t sigV = analogRead(A1); uint16_t refV = analogRead(A3); uint16_t offset = analogRead(A2); int reference = refV + offset; if (sigV > reference) { digitalWrite(1, HIGH); digitalWrite(0, LOW); } else { digitalWrite(1, LOW); digitalWrite(0, HIGH); } }
Attachments:comparator.wav (147.7 KB)
|
|
|
Post by dizzeesatchel on Aug 2, 2022 20:12:31 GMT
Realised I pulled the trigger too soon and there's a much better way to do this. New version has two modes, selected by knob A, you can choose between having one comparator with an inverted signal on the other output, or two comparators both using the same reference point.
Thinking that i might well need more than one Core.ae... being able to build these little functions is great, but I also really like some of the audio firmwares, and switching can be a bit of a pain..... eeek!
/* v1.8 comparator now with switchable modes! (with thanks to pt3r for introducing the concept) ------------------------------------------------ Set all pots fully counter-clockwise to begin. Input CV-B is your first signal. Input CV-C is an optional second signal. You can set the reference voltage either manually with pot D or by sending a CV into that input.
Position of pot A determines the mode:
A = counter clockwise: 1 comparator (signal in B) vs. reference (D), m-c is triggered while signal > reference, output s-c is inverted.
A = clockwise: 2 comparators (signals in B & C) vs. 1 reference (still D), m-c triggered when B-in > reference, s-c when C-in > reference, no inverted output in this mode.
Try using the m-a and s-a outputs for a slightly slewed output. */
uint16_t mode;
void setup() { // initialise the pins pinMode(A0, INPUT); // A input, we'll use this to switch modes pinMode(A1, INPUT); // B (signal 1) pinMode(A2, INPUT); // D (reference voltage) pinMode(A3, INPUT); // C (signal 2) pinMode(PB1, OUTPUT); // m out pinMode(PB0, OUTPUT); // s out digitalWrite(0, LOW); digitalWrite(1, LOW); }
void loop() { // get the value of our 'mode' position uint16_t sig1V = analogRead(A1) | 0x0003; uint16_t refV = analogRead(A2) | 0x0003; uint16_t sig2V = analogRead(A3) | 0x0003; mode = analogRead(A0); if (mode <= 768) // A is CCW { sig2V = 0; // not using this input // compare one signal against reference voltage if (sig1V > refV) { digitalWrite(1, HIGH); // main output digitalWrite(0, LOW); // 2nd output is inverted } else { digitalWrite(1, LOW); digitalWrite(0, HIGH); } } else // A is CW { if (sig1V > refV) // set status of m-c output { digitalWrite(1, HIGH); } else { digitalWrite(1, LOW); } if (sig2V > refV) // set status of s-c output { digitalWrite(0, HIGH); } else { digitalWrite(0, LOW); } } }
Attachments:comparator_v1_8.wav (147.7 KB)
|
|
|
Post by pt3r on Aug 3, 2022 8:09:10 GMT
This is exactly the same kind of route I went first before 4COMP, which works fine one LFO signals but I started to notice some 'lag' on audio signals 'cause your processor can only run the comparisons that fast. And once I figured out the 'analog' way to do it, it eventually it felt like a waste of processing power, if that makes sense.
|
|
|
Post by dizzeesatchel on Aug 3, 2022 9:57:29 GMT
Yeah, i've only tested this with LFOs so far. The Wonkystuff library has defined functions for audio rate calculations, maybe that would increase the efficiency - need more practice to learn my way around that though
|
|
namke
wonkystuff
electronics and sound, what's not to like?!
Posts: 686
|
Post by namke on Aug 3, 2022 14:56:32 GMT
Yeah, i've only tested this with LFOs so far. The Wonkystuff library has defined functions for audio rate calculations, maybe that would increase the efficiency - need more practice to learn my way around that though ... also the wonkystuff 'library' needs extending I expect that you could also set up the ADC to free-run and do the 'trigger stuff' in the interrupt handler... Maybe I'll give that a go. Good idea for the comparator though!
|
|
namke
wonkystuff
electronics and sound, what's not to like?!
Posts: 686
|
Post by namke on Aug 3, 2022 15:03:06 GMT
(I don't think there's any way to read the CV input separately from the knob position of that same input...right? Otherwise you could have multiple comparators quite easily)
You're right - the voltage read by the code will be the sum of the input CV and the voltage on the knob - e.g. if you set the knob to the half-way point (2.5v) and had a 1v CV input, the code would read 3.5v. (EDIT: Oops, should have read your code more closely - you've already got that! ignore below ) You could implement a pair of comparators fed from the same input, e.g. m_c = (input B > input C) s_c = (input_B > input D) ... or a window comparator outputting +5v if (input C < input B < input D) or something
|
|