It is currently Wed May 22, 2024 1:12 pm


Arduinos and Photo-interrupters -help!

Building organ consoles for use with Hauptwerk, adding MIDI to existing consoles, obtaining parts, ...
  • Author
  • Message
Offline
User avatar

vpo-organist

Member

  • Posts: 310
  • Joined: Wed Apr 29, 2020 6:49 am

Re: Arduinos and Photo-interrupters -help!

PostSat Jul 22, 2023 3:39 pm

I avoid some hard-coded values:
Code: Select all
const int dim1 = 8;
const int dim2 = 8;
const int hwpins = 8;


Pin access optimized:
Code: Select all
byte keysAx[hwpins] = { 17, 16, 15, 14, 2, 3, 4, 5 };
byte keysBx[hwpins] = { 22, 24, 26, 28, 30, 32, 34, 36};
byte keysCx[hwpins] = { 53, 51, 49, 47, 45, 43, 41, 39 };
byte keysDx[hwpins] = { 18, 18, 20, 21, A15, A14, A13, A12 };


Read for a division:
Code: Select all
void readKeys(int pin, int key, byte kb[dim1][dim2], byte pins[hwpins])
{
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);

    for (int i = 0; i <= 7; i++)
        kb[key][i] = digitalRead(pins[i]);

    pinMode(pin, INPUT);
}


Read all division:
Code: Select all
void readAllKeys()
{
   for (int pin = 6, k=0; pin <= 13; pin++, k++)
      readKeys(pin, k, keysA, keysAx);

   for (int pin = 38, k=0; pin <= 52; pin += 2, k++)
      readKeys(pin, k, keysB, keysBx);

   for (int pin = 37, k = 0; pin >= 23; pin -= 2, k++)
      readKeys(pin, k, keysC, keysCx);

   for (int pin = A11, k=0; pin <= A14; pin++, k++)
      readKeys(pin, k, keysD, keysDx);
}


This is still the old code without delay:
Code: Select all
void writeKeys(int& note, int key, int noteOn, int noteOff, byte kb[dim1][dim2], byte kbLast[dim1][dim2])
{
    for (int i = 0; i <= 7; i++, note++)
    {
        if ((kb[key][i] == 0) and (kbLast[key][i] == 0))
        {
            MidiSend(noteOn, note, velocity);
            kbLast[key][i] = 7;
        }
        if ((kb[key][i] == 1) and (kbLast[key][i] == 7))
        {
            MidiSend(noteOff, note, velocity);
            kbLast[key][i] = 0;
        }
    }
}


Write/send Midi for all divisions:
Code: Select all
void writeAllKeys()
{
    int note = 36; // is automatically incremented as a reference
    for (int i = 0; i <= 7; i++)
        writeKeys(note, i, noteOn1, noteOff1, keysA, lastA);

    note = 36;
    for (int i = 0; i <= 7; i++)
        writeKeys(note, i, noteOn2, noteOff2, keysB, lastB);

    note = 36;
    for (int i = 0; i <= 7; i++)
        writeKeys(note, i, noteOn3, noteOff3, keysC, lastC);

    note = 36;
    for (int i = 0; i <= 7; i++)
        writeKeys(note, i, noteOn4, noteOff4, keysD, lastD);
}


Edit: I have corrected two errors :-)
I don't have an Arduino, but the application of the loops should be shown.
Last edited by vpo-organist on Sun Jul 23, 2023 7:06 am, edited 4 times in total.
Offline
User avatar

vpo-organist

Member

  • Posts: 310
  • Joined: Wed Apr 29, 2020 6:49 am

Re: Arduinos and Photo-interrupters -help!

PostSat Jul 22, 2023 4:16 pm

I find the order strange:
Code: Select all
    delayMicroseconds(50);
    MidiUSB.sendMIDI(noteOff);
    MidiUSB.flush();


Is that perhaps more useful:
Code: Select all
    MidiUSB.sendMIDI(noteOff);
    MidiUSB.flush();
    delayMicroseconds(50);


In this code remove "| 0" - that is nothing. The smallest unit that makes sense is " | 1":
Code: Select all
midiEventPacket_t noteOn = { 0x09, 0x90 | 0, 63, velocity };
midiEventPacket_t noteOff = { 0x08, 0x80 | 0, 63, velocity };


Ah, I see here that you mean Channel 0 with "| 0". Still, this does not make sense, but it does not bother either

You can make it more readable with
Code: Select all
#define CHANNEL(c) c
#define NOTEOFF 0x80
#define NOTEON 0x90


Use the defines with:
Code: Select all
midiEventPacket_t noteOff = { 0x08, NOTEOFF | CHANNEL(0), 63, velocity };
or
[code]midiEventPacket_t noteOff = { 0x08, NOTEOFF | CHANNEL(1), 63, velocity };
etc.
Offline

larason2

Member

  • Posts: 771
  • Joined: Thu Feb 04, 2016 9:32 pm

Re: Arduinos and Photo-interrupters -help!

PostSat Jul 22, 2023 8:26 pm

Ha! Now you see that I don't really know how to program either. I studied some programming in high school, including figuring out how to program my graphing calculator, then sat down with my organ, some web tutorials, and the Arduino IDE until I had something that worked! I attempted to do loops, but I couldn't figure out how to nest them so they would function, so I abandoned them. Already, I don't understand a lot of the modifications you're making. I hope it works for you!
Offline
User avatar

vpo-organist

Member

  • Posts: 310
  • Joined: Wed Apr 29, 2020 6:49 am

Re: Arduinos and Photo-interrupters -help!

PostSun Jul 23, 2023 7:25 am

I have now logged any pass and have corrected another error in a loop. You see, I am not perfect either. Code should not be written late at night ;-)

But the log now reflects your code:
// Read Keyboard A
pinMode(6, OUTPUT);
digitalWrite(6, LOW);
keysA[0][0] = digitalRead(17);
keysA[0][1] = digitalRead(16);
keysA[0][2] = digitalRead(15);
keysA[0][3] = digitalRead(14);
keysA[0][4] = digitalRead(2);
keysA[0][5] = digitalRead(3);
keysA[0][6] = digitalRead(4);
keysA[0][7] = digitalRead(5);
pinMode(6, INPUT);

Log:
pinMode: 6, OUTPUT
Pin 6 LOW
Read Pin 17
Store [0][0] = 1
Read Pin 16
Store [0][1] = 2
Read Pin 15
Store [0][2] = 3
Read Pin 14
Store [0][3] = 4
Read Pin 2
Store [0][4] = 5
Read Pin 3
Store [0][5] = 6
Read Pin 4
Store [0][6] = 7
Read Pin 5
Store [0][7] = 8
pinMode: 6, INPUT

The numeric assignments ("Store") are just a sequential number in my test program.

Next pass:
pinMode(7, OUTPUT);
digitalWrite(7, LOW);
keysA[1][0] = digitalRead(17);
keysA[1][1] = digitalRead(16);
keysA[1][2] = digitalRead(15);
keysA[1][3] = digitalRead(14);
keysA[1][4] = digitalRead(2);
keysA[1][5] = digitalRead(3);
keysA[1][6] = digitalRead(4);
keysA[1][7] = digitalRead(5);
pinMode(7, INPUT);

Log:
pinMode: 7, OUTPUT
Pin 7 LOW
Read Pin 17
Store [1][0] = 9
Read Pin 16
Store [1][1] = 10
Read Pin 15
Store [1][2] = 11
Read Pin 14
Store [1][3] = 12
Read Pin 2
Store [1][4] = 13
Read Pin 3
Store [1][5] = 14
Read Pin 4
Store [1][6] = 15
Read Pin 5
Store [1][7] = 16
pinMode: 7, INPUT
Offline

Coenraads

Member

  • Posts: 73
  • Joined: Fri Feb 01, 2019 10:13 pm

Re: Arduinos and Photo-interrupters -help!

PostMon Jul 24, 2023 5:27 pm

I am most curious about how one would scan a matrix of photo-interrupters. How does one activate one row at a time as the columns are scanned?

Personally I have decided to totally dispense with matrices and diodes. When I give advice to those building their own VPO, using parallel wiring prevents a lot of complications and problems. Yes this means one Arduino Mega per keyboard but Arduinos are cheap. Then I simply daisy chain the Arduinos and the code I use even automatically assigns different channel numbers to each Arduino. This approach is simple and reliable judging from the reports I get from those using it.

https://sites.google.com/site/casavanto ... el-scanner

I've also found that photo-interrupters reliably pull the Arduino inputs low when using the built in pull-up resistors.
"Go Parallel" is now my motto. :)
Previous

Return to DIY organ consoles / MIDI

Who is online

Users browsing this forum: No registered users and 2 guests