Realtime Guitar Fret Scanning

Status
Not open for further replies.

teensy_ino

Active member
Hello forum,

With Teensy 3.2, I built a controller for realtime midi note recognition, but it only works with one string at the moment:


Frets (are not divided!) And strings function as two contacts of a switch. The frets are connected to each other with the same resistors via a voltage divider from + 5 V to PIN A1, the strings are each connected to GND (a hex pickup is not yet used).


When the strings are gripped, a resistance measurement (Ohmmeter Sketch) is triggered which the Teensy converts into Midi notes.
Works in the test setup with only one string so far without problems.

With more than one string I am faced with the problem that I need an additional trigger that gives me the information which string is currently being used ...

How can I implement this with Teensy, - maybe someone here has a brilliant idea?
It is clear to me that the polyphony with this system, because of the lack of split frets, will only work to a limited extent.


Greetings from Germany - and please stay healthy in these difficult times!

---

WIN 10
Teensy 3.2
Teensyloader 1.45
IDE 1.8.12
 
Hello forum,

With Teensy 3.2, I built a controller for realtime midi note recognition, but it only works with one string at the moment:


Frets (are not divided!) And strings function as two contacts of a switch. The frets are connected to each other with the same resistors via a voltage divider from + 5 V to PIN A1, the strings are each connected to GND (a hex pickup is not yet used).


When the strings are gripped, a resistance measurement (Ohmmeter Sketch) is triggered which the Teensy converts into Midi notes.
Works in the test setup with only one string so far without problems.

With more than one string I am faced with the problem that I need an additional trigger that gives me the information which string is currently being used ...

How can I implement this with Teensy, - maybe someone here has a brilliant idea?
It is clear to me that the polyphony with this system, because of the lack of split frets, will only work to a limited extent.


Greetings from Germany - and please stay healthy in these difficult times!

---

WIN 10
Teensy 3.2
Teensyloader 1.45
IDE 1.8.12




Hi forum,

No Answer ?
really has no idea how to solve this problem?

Greetings from Germany - and please stay healthy in these difficult times!
 
Greetings @teensy_ino

It seems from post #1 you have one string working and have a good idea at hand for that. Without code and perhaps drawings to visualize what that consists of a lot is on the reader to see what is there.

It seems the un-split frets is the problem as conductivity from multi touch is cross feeding the test and measure process? In some ways to read this might be like a button keypad. With each fret and string wired the contact point could be known.

Also - perhaps no affect here but TeensyDuino current is 1.51 with 1.52 in beta so any fixes or issues would be against the current release.
 
Greetings @teensy_ino

It seems from post #1 you have one string working and have a good idea at hand for that. Without code and perhaps drawings to visualize what that consists of a lot is on the reader to see what is there.

It seems the un-split frets is the problem as conductivity from multi touch is cross feeding the test and measure process? In some ways to read this might be like a button keypad. With each fret and string wired the contact point could be known.

Also - perhaps no affect here but TeensyDuino current is 1.51 with 1.52 in beta so any fixes or issues would be against the current release.



Hi defragster,

many thanks for your response !
Teensyduino is installed in my version 1.52.

Briefly again to explain:
I used a voltage divider to query the frets with a slightly modified ohmmeter sketch analog.
The voltage divider is on one side at + 5V, all frets are connected together in series with the same
resistance values ​​(3,3k, 1%).
The other end of the voltage divider is (currently) firmly on GND to close the circuit.
The measurement of the total resistance itself runs in a loop.
The string is also firmly on GND.
If the string touches a fret, GND bridges the relevant resistance of the fret and outputs the change
as a MidiNote.

Here is the circuit diagram (I use 3,3k Resistors at eachpoint):

Arduino_Multischalter_analog.jpg


For the sake of clarity, I only used 3 resistance values ​​/ midi notes in the sketch. I had successfully
tested this before on the breadboard with 24 resistors.

It is clear to me that the function with several strings should theoretically look like a keyboard matrix
consisting of columns and rows.

To do this you would have to have split frets that are not available ...
Ideally, every single split fret and additionally every single string would be wired (that would be the
matrix). But then also means 6 x 24 individual cables that somehow want to be housed in the guitar
neck ...- Apart from the amount of inputs that would then be needed ...

However, since it is not possible to get split frets, I chose the voltage divider approach (only 1 wire
plus resistors) and can then live with slightly restricted functions in polyphony.


Sketch:

Code:
// getestet mit Teensy 3.2, IDE 1.8.12 / Teensyduino 1.52, WIN 10
// USB-Type " MIDI"
// Widerstände messen
//              _____
//            -|_R1__|- VCC
//AnalogPin  -' _____
//           '-|_R2__|- GND

// R2 = zu messender Messwert (Reihenschaltung von mehreren 3,3k Widerständen)


const int channel = 1;
float Quellspannung = 3.30;
int AnalogPin = 0;
int R1 = 3280.0; //Wert des bekannten Messwerts(3,3k, nachgemessen = 3280)
long Messwert;
float SpannungR2; //Spannung über dem zu messenden Widerstand
float Widerstand = 0;
float WiderstandAlt = 0;
int midineu = 0;
int midiold = 0;

void setup()
{
//Pullups:
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);

  Serial.begin(115200);
  Serial.println("Widerstand ausmessen");
  Serial.println();
}
//==================================================================
void loop (){

  //5 Messungen machen und Mittelwert bilden
  Messwert = 0;
  for (int i = 0; i < 5; i++) {
    Messwert += analogRead(AnalogPin);
  }
  Messwert = trunc(Messwert / 5);

  //Spannung berechnen
  SpannungR2 = (Quellspannung / 1023.0) * Messwert;
  Serial.print("Spannung ueber R2 betraegt ");
  Serial.print(SpannungR2, 2);
  Serial.println(" Volt!");

  //Berechnung: (R2 = R1 * (U2/U1))
  Widerstand = R1 * (SpannungR2 / (Quellspannung - SpannungR2));
  Serial.print("Der Widerstand hat ");
  Serial.print(Widerstand, 2);
  Serial.println(" Ohm.");
  Serial.println();

  switch (int(Widerstand))
  {
    case 2970 ...  3630 : midineu = 60; break; // Widerstand 1. Fret
    case 5940 ...  7260 : midineu = 61; break; // Widerstand 2. Fret
    case 8910 ... 10890 : midineu = 62; break; // Widerstand 3. Fret, getestet mit 24 Frets
    default: midineu = 0; break; //wenn Alles nicht passt, dann Taste losgelassen
  }

  if (midineu != midiold) {
    //es hat sich was geändert
    if (midineu > 0)
      usbMIDI.sendNoteOn(midineu, 127, 1); // nur diese Zeile verändert
    if (midiold >= midineu)
      usbMIDI.sendNoteOff(midiold, 0, 1);
    midiold = midineu;

    // MIDI Controllers should discard incoming MIDI messages.
    while (usbMIDI.read()) {
      // read & ignore incoming messages
    }
    //delay(200); // Verzögerung zum Lesen der Anzeige, fliegt sonst raus!
  }
}
//===========================================================

To enable a differentiation by strings, I need an additional trigger. The only question is how?

But since the string is already electrically at GND in order to be able to bridge the resistance of the
fret, I cannot use the same string again as a trigger for string detection.
Anyway, at the moment I don't know how ...

Has anyone got an idea ?


Greetings from Germany !
 
Last edited:
Doesn't this require the player to avoid contacts other than the one they are intending to make with one fret and one string?

And if they do make a second contact won't the read voltage be different than if you don't and thereby make the whole thing unusable?

Can any player play cleanly enough to make the scheme usable?
 
Doesn't this require the player to avoid contacts other than the one they are intending to make with one fret and one string?

And if they do make a second contact won't the read voltage be different than if you don't and thereby make the whole thing unusable?

Can any player play cleanly enough to make the scheme usable?

Indeed chords would be right out - even playing one string and holding any other string would be misinterpreted. Perhaps an electrically active Pick with force sensor.
 
even playing one string and holding any other string would be misinterpreted
Yes... that's my point.. could you even play mono-phonically in any usable way or would you need to adopt a very clean 'zero-barre' playing that would be very limiting?
 
Hi defragster,

It was already clear to me that I had to use a separate data source for each string. The question is, how exactly?


No matter whether I wire each fret individually or use the system with a voltage divider, in both cases I have to put GND on the strings to make a switching function possible ...
At that moment, however, I can no longer put the strings on separate entrances, or have I overlooked something important here (mistake in thinking?)?
Here the devil is in the details.

An Hexpickup would initially only give me AC voltages that at least cannot be processed directly with an Arduino. I'm not sure if the teensy can do that directly?
It would be conceivable to rectify this signal, but this would also lead to further problems ...
What is the best way to proceed here?

The system with voltage divider would have the charming advantage of only having to use a single input for the fingerboard. Also means just a single connecting wire plus resistances between the frets, instead of having to lay 20 - 24 individual wires in the guitar neck ... An advantage that should not be underestimated for mounting on the instrument.

---

Another approach is that of OMB (only for the grippinghand ):

https://youtu.be/_2oKTh247GY
https://youtu.be/xJBNYEIt4R8
https://youtu.be/WI2mhZyxzVA
https://youtu.be/okO0UjgtaOI


Capacitive scanning is carried out here. In the videos you can see that all frets are connected to each other and only one wire runs to the controller.
The strings are used individually by direct galvanic contact (without hex pickup) ...
The system should also be available for retrofitting, works completely polyphonic ...

It would be very interesting to do something like this with the Teensy ...

Maybe someone has good ideas?


Greeting from Germany
 
Hi defragster,

It was already clear to me that I had to use a separate data source for each string. The question is, how exactly?


No matter whether I wire each fret individually or use the system with a voltage divider, in both cases I have to put GND on the strings to make a switching function possible ...
At that moment, however, I can no longer put the strings on separate entrances, or have I overlooked something important here (mistake in thinking?)?
Here the devil is in the details.

An Hexpickup would initially only give me AC voltages that at least cannot be processed directly with an Arduino. I'm not sure if the teensy can do that directly?
It would be conceivable to rectify this signal, but this would also lead to further problems ...
What is the best way to proceed here?

The system with voltage divider would have the charming advantage of only having to use a single input for the fingerboard. Also means just a single connecting wire plus resistances between the frets, instead of having to lay 20 - 24 individual wires in the guitar neck ... An advantage that should not be underestimated for mounting on the instrument.

---

Another approach is that of OMB (only for the grippinghand ):

https://youtu.be/_2oKTh247GY
https://youtu.be/xJBNYEIt4R8
https://youtu.be/WI2mhZyxzVA
https://youtu.be/okO0UjgtaOI


Capacitive scanning is carried out here. In the videos you can see that all frets are connected to each other and only one wire runs to the controller.
The strings are used individually by direct galvanic contact (without hex pickup) ...
The system should also be available for retrofitting, works completely polyphonic ...

It would be very interesting to do something like this with the Teensy ...

Maybe someone has good ideas?


Greeting from Germany
 
I think the OMB might be using electrical reflection timing looking for the earliest electrical reflection on each string but I can not see the a how-it-works section.

Not sure how the per-string triggering works... how does it not send a note-on as soon as you form the chord? Maybe you have to play as if it is all hammer-ons?





Each string is electrically connected at the bridge (and yes every fret to ground)
 
Last edited:
Given the metal on metal at the bridge - it seems the nut at the top of the fretboard - if it has insulating properties as expected - would have the source signal applied between the tuning pegs and the nut. Each fret would need to be an input to read the signal passing the nut. And perhaps grounding the bridge would prevent reflectance from open strings? But that may still be 'noisy' if multiple string are powered at once.

That would still indicate fret contact - not actual striking of the string without feedback from a pickup.
 
Given the metal on metal at the bridge - it seems the nut at the top of the fretboard - if it has insulating properties as expected - would have the source signal applied between the tuning pegs and the nut. Each fret would need to be an input to read the signal passing the nut. And perhaps grounding the bridge would prevent reflectance from open strings? But that may still be 'noisy' if multiple string are powered at once.

That would still indicate fret contact - not actual striking of the string without feedback from a pickup.



Hi oddson hi defragster

Thank you for your answers !


And yes that is correct, is also described in one of the Videos.

in the OMB videos it is shown / explained that the strings have direct electrical contact to obviously different PINs of the control. A hex pickup
is not used there.
However, all frets are directly electrically connected to one another (thus also have the same electrical potential) and are only routed to the
controller via a single PIN (capacitive?).
Another OMB video mentions that it is a capacitive measurement with direct contact between the string and frets ...

Incidentally, the whole system only works for the gripping hand, i.e. no detection of the right hand !


I tried to use the TouchSense PIns with the Teensy, (tested each with the 1 or 2 wire method, with / or without different resistance values,
with / without Libary):
The output values ​​change very strongly, even if you try not to move yourself and not to touch the sensors at all ...

Direct switching by touch is possible - but I don't know how it can be used to implement position detection ...?

If OMB actually uses the capacitive evaluation for the fingerboard, it should work similarly to a slider that returns a very constant value per position ...

I haven't done that with TouchSense yet - but it seems to work for OMB. The only question is how?


Do you have any ideas on how this can be implemented / experience with TouchSense?


Greetings from Germany
 
no - done minimal testing with touch - but on single pads. This with ~2 dozen frets and then 6 strings that are bridged on one end.

Seems like something other may have done in this context on the WWW? what might work capacitance, voltage, current measure from what to what would all be experiments and I just gave my guitar to the neighbor kid - assuming this was on an electric guitar which the look of I know somewhat. An acoustic guiter wouldn't seem to have a metal bridge? Not sure if the electric guitar could have the string bridge end restrung in a way to be insulated - with shrink tube or other?
 
Hi everyone, Hi defragster,
too bad that apparently nobody has any experience with Touch Sense ...

I have just found a guide for finger position detection of the gripping hand on the net that apparently also works except for a few small things:

LINK 1

LINK 2
Please take a look at the code and the circuit used there!

The system does NOT use split frets and no hex pickup. Here, each fret is individually connected to a digital input (DigitalRead) and each string individually to a digital output PIN (DigitalWrite).

In this way, every fret can be identified. - But unfortunately also has restrictions in polyphony due to the non-divided frets ...

Maybe there is a solution for that anyway.
If I understand the code correctly, the string PINs switch from Hi to Low there, but all at the same time ... which also leads to the polyphony problem.

What if you did the Hi / Low switchover, for example, only ever for one string PIN after the other in the loop (eg with a certain frequency)?
Shouldn't the polyphony problem be solved because only one string is queried "at a time"?

In principle, it is similar to light barriers that are modulated with certain frequencies (e.g. ~ 38 KHz) to become insensitive to ambient light ...
(Unfortunately, "pulsing" has the same effect on the loop as "Delay" ...)


Greetings from Germany
 
I think the button lib does that - strobes one axis while doing a scan read across the other. The problem may be the bridge continuity - as soon as one wire hits a fret - to some degree that will transmit through the bridge metal bar to all the other strings.

Again assuming this is an electric guitar with metal bridge putting continuity to all wires in some fashion.
 
The guitars in OMB and this home build both have insulation steps for the strings to isolate them electrically.
 
Hi everyone,

By the way: I use a bass with 5 strings: H- E- A- D- G (the strings are isolated from each other).

How and what would have to be changed in the code so that all string PINs in the loop are queried one after the other?
Could someone take a look at that?

Original code:

//Midi_Guitar, Guitorgan Style
//Michael Niemi, <a href="https://github.com/mvniemi/midi_guitar"> https://github.com/mvniemi/midi_guitar
</a>
#define NUM_STRINGS 4
#define NUM_FRETS 8
#define VELOCITY 100
#define noteON 145
#define noteOFF 129

//This is where you pick what note you want your lowest string to start at
#define BASENOTE 28

//Set up for standard tuning of fourths
int stringOffsets[] = {0,5,10,15,19,25};
//This is for my bass, add more pins for a 6 string
int stringPins[] = {4,5,6,7};
int fretPins[] = {22,23,24,25,26,27,28,29};
int currentNote[NUM_STRINGS];

//
void setup() {
//Serial to send midi commands over
Serial.begin(115200);

//Initialize read pins
for (int i=0; i< NUM_FRETS; i++){
pinMode(fretPins, INPUT);
}
// Initialize write pins?
for (int i=0; i< NUM_STRINGS; i++){
pinMode(stringPins, OUTPUT);
digitalWrite(stringPins, LOW);
currentNote=0;
}
}

void loop() {
//Scan Strings: We will scan down the neck string my string and set
// the note as the highest detected fret
// Currently setting the note after each string instead of after all strings
for (int i=0; i < NUM_STRINGS; i++){

//Turn String High
digitalWrite(stringPins, HIGH);
//Set current note to zero
int newNote=0;

for (int k=0; k < NUM_FRETS; k++){
if (digitalRead(fretPins[k]) == HIGH){
newNote=k+1;
}
}

//Turn String Low
digitalWrite(stringPins, LOW);
if (newNote != currentNote){
MIDImessage(noteOFF, (currentNote+stringOffsets+BASENOTE), VELOCITY);

if (newNote != 0){
MIDImessage(noteON, (newNote+stringOffsets+BASENOTE), VELOCITY);
}
currentNote = newNote;
}
// delay();
}
}

void MIDImessage(int command, int MIDInote, int MIDIvelocity) {
Serial.write(command);//send note on or note off command
Serial.write(MIDInote);//send pitch data
Serial.write(MIDIvelocity);//send velocity data
}


Greetings from Germany
 
Hi everyone,

By the way: I use a bass with 5 strings: H- E- A- D- G (the strings are isolated from each other).
...

That is important info … placed in post #19.

simple matrix if the frets are wire individually. And probably other options given the isolation ...
 
That is important info … placed in post #19.

simple matrix if the frets are wire individually. And probably other options given the isolation ...


Hi defragster and everyone else

That is the point !
In my case, at least the 5 strings are isolated from each other ...


I don't want to be annoying, but
How and what would have to be changed in the code so that all string PINs in the loop are queried one after the other?
Could someone take a look at that?

By the way:
Maybe the system's polyphonic limitations weren't quite clear yet?
They only occur when several strings are gripped on the same or an adjacent fret.


I have to translate your answers with Google, so sorry if I sometimes have to follow up more often (the
translation is often not really good ...)

stay healthy - greetings from Germany
 
Last edited:
Hi everyone,

must pick up the topic again:
I am thinking of carrying out the fretscanning alternatively with the Teensy 3.2 TouchSense PINs (similar to the OMB Guitar).

With OMB scanning, however, I am still not clear how exactly it works there :confused::

All strings are recorded there separately, - but the fingerboard has (as can be seen in the the third video from above at #8 / #9) only ONE single sensor (contact) that goes to the control (all frets are firmly connected
to each other, no resistances in between ...) ...
An XY scan using the keyboard method would not work like this ...

Unless:
Theoretically, it would be conceivable to see the individual strings like a individual wiper contact of a potentiometer (whereby each
string / wiper is controlled individually and one after the other in the code), and the entire fingerboard act llike one carbon layer of a potentiometer ... - .Only on a capacitive way- (like a slider) .

The prerequisite for this would be that a few millimeters, different but constant capacitive values could be provided so that such
position detection works. The string would be the X, the fingerboard the Y coordinates ...

Which (possibly also external) capacitive touch sensor could be used in this way?

---

For example, if I use the principle of the X-Y keyboard scan in my case (frets and strings wired individually, without voltage divider),
I need a total of 29 PINs (5 strings, 24 frets). The Teensy has "only" 12 ...:(

  • Can a "normal" I / O expander (MPR 121, Unfortunately EOL...) be used for this?
  • Does the TouchSense extension work as in this LINK
    also with Teensy 3.2 (which is at least mentioned there), who knows more here ?
  • If so, what is the difference to the existing TouchSense PINs?

would be happy to hear your answers / ideas / suggestions!


Stay healthy - greetings from Germany
 
Last edited:
Status
Not open for further replies.
Back
Top