|
Post by duddex on Nov 21, 2021 19:09:18 GMT
I have created an Arduino Sketch for GRAINS which provides a Bernoulli Gate module. Inspired by the Branches Module by Mutable Instruments. Input "A" is used as gate-input. If a gate is detected, the module flips a coin and decides if the gate is sent to output "OUT" or output "D". The probability of the outcome of the coin toss can be influenced by "P1". When P1 is in the middle position, the probability of the coin flip (output "OUT" or output "D") is 50/50. The more P1 is turned to the left, the higher the probability of sending the gate to output "OUT". The more P1 is turned to the right, the higher the probability of sending the gate to output "D". I send the gate to PINs 9 and 11. So it does not matter if the switch is set to "G" or "M". Here is a short video that shows the module in action: The code is very short: void setup() { pinMode(A2, INPUT); pinMode(A4, INPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(11, OUTPUT); digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(11, LOW); }
boolean gate = false; boolean oldgate = false;
void loop() { // Check for gate on GRAINS input "A" (Arduino Pin A4) // "analogRead()" returns values between 0 and 1023 // If the value is bigger than 700, this is considered as "gate on" gate = analogRead(A4) > 700;
// React only if state changed if (oldgate != gate) { if (gate) { // Output probability depends on the value of "P1": // -> The more P1 is turned to the left, the more "OUT" will be triggered // -> The more P1 is turned to the right, the more "D" will be triggered if (random(1024) > analogRead(A2)) { digitalWrite(8, HIGH); // send gate to "D" } else { // Send gate to "OUT". Switch setting to "G" or "M" does not // matter because both outputs are set digitalWrite(9, HIGH); digitalWrite(11, HIGH); } } else { // no gate on input "A" -> set all outputs to zero digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(11, LOW); } oldgate = gate; } }
|
|
|
Post by duddex on Nov 21, 2021 19:16:53 GMT
I probably have mixed up the terms "gate" and "trigger" - but you get the idea TODO: Implement "Toggle mode" and "Latch mode" (which the Branches module provides)
|
|
|
Post by rockysmalls on Nov 21, 2021 19:17:01 GMT
excellent ... i think i might find a use for this. muchos graçios
|
|
|
Post by pt3r on Nov 21, 2021 19:33:08 GMT
Excellent little firmware. I was first wondering why you did not opt for the use of an interrupt, but the A4 input can of course not use an interrupt and this firmware can use both gates and triggers.
Edit: you should definitely share also this in the programming sub forum.
|
|
namke
wonkystuff
electronics and sound, what's not to like?!
Posts: 686
|
Post by namke on Nov 21, 2021 22:22:00 GMT
Well, that's another firmware off my to-do list! Thank you!!
|
|
|
Post by duddex on Nov 22, 2021 6:49:41 GMT
Thank you all for your feedback. I am happy that this is useful for others.
I am still quite new here in this forum and I didn't realize that there is a "programming sub forum". I will post this in the other forum as well. And I also will share this firmware on Github.
I think using interrupts would be much more elegant. If I understood correctly, this is only possible on digital PINs. Or better: it is easier with digital PINs. I found some hints that the built-in comparator can be used. But I have to admit: I do not understand (yet) how this works.
|
|
|
Post by pt3r on Nov 22, 2021 7:08:07 GMT
|
|
|
Post by m4vrick on Nov 22, 2021 8:32:55 GMT
Hello, That's a great small sketch, very simple and efficient. If I can suggest an little update you should use the randomseed() function to have a real random generate each time. Without using it the Atmega is generating always the same sequence of numbers each time. See www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/Only need to choose an unused and unconnected input, you have to check the grains schematic to find one.
|
|
namke
wonkystuff
electronics and sound, what's not to like?!
Posts: 686
|
Post by namke on Nov 22, 2021 15:22:01 GMT
Here is a 1:1 translation of that code for the core1.æ module (firmware audio file is attached!) // Version of 'Bernoulli Gate' firmware by duddex. // Translated for core1.æ by J Tuffen. // 2021 // // (It works, but I may rewrite it later!) // // Inputs: // * Input to cv-b (turn knob B fully counter-clockwise) // * Threshold control on cv-c (knob C) // // outputs: // * m-c // * s-c
void setup(void) { pinMode(A1, INPUT); pinMode(A3, INPUT); pinMode(0, OUTPUT); pinMode(1, OUTPUT); digitalWrite(0, LOW); digitalWrite(1, LOW); }
boolean gate = false; boolean oldgate = false;
void loop(void) { // Check for gate on core.æ input B // "analogRead()" returns values between 0 and 1023 // If the value is bigger than 700, this is considered as "gate on" gate = analogRead(A1) > 700;
// React only if state changed if (oldgate != gate) { if (gate) { // Output probability depends on the value of "knob C": // -> The more the knob is turned to the left, the more "M" will be triggered // -> The more the knob is turned to the right, the more "S" will be triggered if (random(1024) > analogRead(A3)) { // send gate to "M" digitalWrite(1, HIGH); } else { // Send gate to "S". digitalWrite(0, HIGH); } } else { // no gate on input "A" -> set all outputs to zero digitalWrite(0, LOW); digitalWrite(1, LOW); } oldgate = gate; } }
Attachments:sketch_nov22b.ino.wav (264.35 KB)
|
|
|
Post by duddex on Nov 22, 2021 18:05:33 GMT
[...] If I can suggest an little update you should use the randomseed() function to have a real random generate each time. [...] Oh - I totally forgot to add the randomseed(). Thank you. I will add this and upload the sketch to Github later
|
|
|
Post by rockysmalls on Nov 23, 2021 12:39:37 GMT
Here is a 1:1 translation of that code for the core1.æ module (firmware audio file is attached!) // Version of 'Bernoulli Gate' firmware by duddex. // Translated for core1.æ by J Tuffen. // 2021 // // (It works, but I may rewrite it later!) // // Inputs: // * Input to cv-b (turn knob B fully counter-clockwise) // * Threshold control on cv-c (knob C) // // outputs: // * m-c // * s-c
void setup(void) { pinMode(A1, INPUT); pinMode(A3, INPUT); pinMode(0, OUTPUT); pinMode(1, OUTPUT); digitalWrite(0, LOW); digitalWrite(1, LOW); }
boolean gate = false; boolean oldgate = false;
void loop(void) { // Check for gate on core.æ input B // "analogRead()" returns values between 0 and 1023 // If the value is bigger than 700, this is considered as "gate on" gate = analogRead(A1) > 700;
// React only if state changed if (oldgate != gate) { if (gate) { // Output probability depends on the value of "knob C": // -> The more the knob is turned to the left, the more "M" will be triggered // -> The more the knob is turned to the right, the more "S" will be triggered if (random(1024) > analogRead(A3)) { // send gate to "M" digitalWrite(1, HIGH); } else { // Send gate to "S". digitalWrite(0, HIGH); } } else { // no gate on input "A" -> set all outputs to zero digitalWrite(0, LOW); digitalWrite(1, LOW); } oldgate = gate; } }
well well..... now i don’t know if i need to buy another Core.ae OR another grains ( annoying Juno don’t stock them )
|
|
|
Post by tIB on Nov 24, 2021 20:02:04 GMT
Ooh nice - so it's a 50-50 randomisation of a gate/trigger, of have I missed something?
|
|
|
Post by duddex on Nov 27, 2021 7:10:07 GMT
It's a randomisation of a gate/trigger, where you can influence the randomness with IN1/P1. When the P1 knob is in the middle, the chance of sending the incoming gate to either output "OUT" or output "D" is 50/50. Turning the button to either side (or sending CV to IN1) influences the chance of sending the gate to one of the outputs
|
|
|
Post by duddex on Nov 28, 2021 11:44:52 GMT
|
|
|
Post by duddex on Nov 28, 2021 11:53:32 GMT
I am happy and proud to let you know, that my code is now part of the AE Modular GRAINS Github repository: github.com/aemodular/GRAINS/tree/master/Grains-BernoulliGateYou can find some more information in the README on the Github page or in my original post. I plan to update the module with the "latch" mode next: When the latch mode is enabled, an output stays at +5V until the other output gets activated.
|
|
|
Post by duddex on Dec 22, 2021 18:13:09 GMT
Update: I have implemented the "latch" mode. P1 Sets the probability of the outcome of the coin toss (heads/tails) and P2 switch between "normal" mode and "latch" mode. Turn P2 to the left for normal mode. Turn P2 right for latch mode. This video shows how it works:
|
|
|
Post by MikMo on Dec 23, 2021 13:19:59 GMT
Somehow i managed to read the heading of this thread as:
"Bernoulli Gate for Brains"
Which would be quite descriptive for my current state of mind, being at work the day before Xmas.
|
|
|
Post by maydonpoliris on Dec 23, 2021 19:50:18 GMT
Nice work. this update reminds me I need to try this out next patch. cool.
|
|