Veel schakelaars aan een Arduino koppelen

Hoi allen,

Ik wil voor een project ten minste 264 schakelaars (reed switches) uit kunnen lezen met een Arduino voor een digitale piano (3 reed contacten per toets, 88 toetsen in totaal).

Is dit te doen met behulp van multiplexers? Het gaat dus puur om schakelaartjes. Hoeveel multiplexers zijn er aan 1 arduino te koppelen? Welke multiplexers kan ik hier het beste voor gebruiken? Wat is de snelheid bij zoveel schakelaars voor het uitlezen van al deze 264 schakelaars in 1 loop?

Is er nog een andere manier waarop ik dit kan bouwen of is een Arduino hier sowieso niet toe in staat? Ik zie op internet ook led cubussen die 8x8x8 zijn, alleen werken die met een geavanceerde techniek met 8 verschillende 8x8 matrixen die heel snel achter elkaar worden afgedraaid, zodat het lijkt alsof je 512 leds kunt aansturen. Zou ik deze techniek eventueel ook kunnen gebruiken voor INPUT? Dit gaat dan waarschijnlijk wel ten koste van de snelheid?

Wie helpt mij verder?

Je kan de switches inderdaad in één grote matrix verbinden. Je zet dan één rij laag (alle andere rijen in Hi-Z) en kijkt welke kolommen ook laag zijn. Die switches zijn dan gesloten. Zo scan je over alle rijen.

Een nadeel is dat je voor elke switch een diode nodig hebt.
Hoe vierkanter de matrix, hoe efficiënter. (Bv. 16×17 in jouw geval.)
De 16 kolommen kan je erg snel via direct port manipulation inlezen als 2 bytes.

Kijk eens naar de Teensy bordjes. Die hebben genoeg IO, en zijn erg snel. Ze ondersteunen ook MIDI over USB (als je dat nodig zou hebben).

Pieter

Bedoel je met jouw oplossing dat de 16x17 matrix rechtstreeks op de Arduino aangesloten zit, dus dat ik 33 I/O poorten nodig heb? Of heb je deze nog weer aan de multiplexers zitten?

Ik zie op internet ook oplossing met multiplexers, maar die gebruiken geen diodes. Ik twijfel alleen over die oplossing, omdat ik dan met de 16 input multiplexers er 17 nodig heb. Ik denk niet dat dat gaat werken.

Ik ben inderdaad van plan om de scanresultaten om te zetten in MIDI signalen naar een MIDI OUT DIN connector. Hier kan dan een kabeltje aan verbonden worden die de MIDI signalen verzend naar een PC.

Of een zooi io expanders via i2c

PieterP:
Kijk eens naar de Teensy bordjes. Die hebben genoeg IO, en zijn erg snel. Ze ondersteunen ook MIDI over USB (als je dat nodig zou hebben).

Wat is een Teensy precies? Is het de keuze Teensy of Arduino of kan ik de Teensy koppelen aan de Arduino om het scannen van de matrix eenvoudiger te maken?

cornestrijkert:
Bedoel je met jouw oplossing dat de 16x17 matrix rechtstreeks op de Arduino aangesloten zit, dus dat ik 33 I/O poorten nodig heb?

Inderdaad.
Als je zou willen kan je die 33 I/O poorten natuurlijk ook multiplexen. Het gemakkelijkste is in dat geval om voor de rijen serial-in, parallel-out shift registers met een open collector (open drain) uitgang te gebruiken. Hiermee kan je met 3 uitgangen erg gemakkelijk over alle rijen scannen. Je zet één rij laag, en geeft dan telkens een clockpuls om de geselecteerde rij "door te schuiven/shiften". Zeker als je de klokpulsen met direct port manipulation doet, is dit enorm snel.
Voor de kolommen kan je parallel-in, serial-out shift registers gebruiken. Zo lees je alle kolommen in één keer serieel in (via de SPI interface of gewone IO (trager dan SPI)) en heb je maar 3 pinnen nodig.
Dat lijkt me een erg elegante oplossing.

cornestrijkert:
Ik zie op internet ook oplossing met multiplexers, maar die gebruiken geen diodes. Ik twijfel alleen over die oplossing, omdat ik dan met de 16 input multiplexers er 17 nodig heb. Ik denk niet dat dat gaat werken.

Dat zouden heel veel multiplexers zijn inderdaad. Maar in theorie zou het mogelijk zijn. Het voordeel is dat je dan geen diodes nodig hebt, en dat je niet moet scannen. De bedrading is misschien net iets eenvoudiger dan met de matrix, maar die wordt sowieso een rommelboel.

cornestrijkert:
Ik ben inderdaad van plan om de scanresultaten om te zetten in MIDI signalen naar een MIDI OUT DIN connector. Hier kan dan een kabeltje aan verbonden worden die de MIDI signalen verzend naar een PC.

Dat is nergens voor nodig, als je de juiste Arduino kiest gaat dat gewoon rechtstreeks over USB. Je kan altijd nog een MIDI Out DIN toevoegen als extra uitgang als dat nodig is.

cornestrijkert:
Wat is een Teensy precies? Is het de keuze Teensy of Arduino of kan ik de Teensy koppelen aan de Arduino om het scannen van de matrix eenvoudiger te maken?

Het is een Arduino-compatibel microcontroller bordje. Het voordeel is dat het veel sneller is, MIDI over USB ondersteunt, en meer IO heeft dan een standaard Arduino.

Pieter

PieterP:
Inderdaad.
Als je zou willen kan je die 33 I/O poorten natuurlijk ook multiplexen. Het gemakkelijkste is in dat geval om voor de rijen serial-in, parallel-out shift registers met een open collector (open drain) uitgang te gebruiken. Hiermee kan je met 3 uitgangen erg gemakkelijk over alle rijen scannen. Je zet één rij laag, en geeft dan telkens een clockpuls om de geselecteerde rij "door te schuiven/shiften". Zeker als je de klokpulsen met direct port manipulation doet, is dit enorm snel.
Voor de kolommen kan je parallel-in, serial-out shift registers gebruiken. Zo lees je alle kolommen in één keer serieel in (via de SPI interface of gewone IO (trager dan SPI)) en heb je maar 3 pinnen nodig.
Dat lijkt me een erg elegante oplossing.

Ik ben eigenlijk op zoek naar de meest snelle oplossing. Meer ingewikkelde code kom ik wel uit, ben programmeur van beroep. Is de matrix direct op de I/O poorten aansluiten de meest snelle? Zo ja, zou ik eventueel ook om de bedrading iets eenvoudiger te maken 2 matrixen kunnen maken of meerdere kleine matrixen? Of kost dit dan weer meer scantijd? Mijn hele project valt of staat met de snelheid van het geheel. Als de piano pas geluid geeft wanneer ik al 3 akkoorden verder ben dan heeft het geen nut.

Of ben ik dan heel onhandig aan het doen en kan ik beter gebruiken maken van een multiplex oplossing zoals:

  • Dual shift register mux (dit is jouw idee volgens mij)
  • Shift register alleen voor de kolommen of rijen
  • 3 naar 9 decoder

Is het multiplexen alleen maar aan te raden bij te weinig I/O pins? Wat betreft bedrading maakt het niet zo heel veel uit volgens mij.

Ik lees namelijk hier dat shift registers ook vertraging opleveren en dat 'interupt lines' voor het onmiddelijk opvragen van de stand van zaken niet mogelijk is. Met SPI zou het sneller moeten zijn, alleen is SPI nieuw voor mij. Is de code voor de rest hetzelfde als je SPI gebruikt? Is er ergens een website die dit helder omschrijft?

meer dan je ooit wil weten van SPI --> Gammon Forum : Electronics : Microprocessors : SPI - Serial Peripheral Interface - for Arduino

Ik zou me niet al te veel zorgen maken om snelheid. digitalWriteFast duurt zo'n 21 ns op een Teensy 3.0, en waarschijnlijk nog sneller op de nieuwere modellen. De SPI-bus loopt standaard aan 4 MHz als ik me niet vergis. Meer dan genoeg tijd dus om twee of drie bytes (17 kolommen) in te lezen per rij.

Erg ruwe berekening: 3 bytes = 24 bits, (24 / 4 MHz = 6 µs) dus minder dan 10 µs, als je CS en overhead meerekent. Dan moet je nog de geselecteerde rij veranderen, dat zijn 4 digitalWrites (6 voor de eerste rij), en is dus te verwaarlozen. Dat doe je 16 keer, dus dan duurt het scannen van de hele matrix rond de 150 µs. Dat is veel sneller dan je ooit zult merken/horen. Als je wilt kun je de SPI klok nog wat hoger laten lopen, tot 30MHz op de Teensy 3.6 geloof ik.

of je pakt een mega daar kan het in een keer op, geen last van dubbel werk etc, gewoon ingangen en uitgangen definieren, wel moet er een diode bij elke reed, dan kun je ook dubbele toetsen zien. scannen is beter dan 0.1 milliseconde dus ook daar is geen probleem.