Forum: Mikrocontroller und Digitale Elektronik Probleme mit MIDI Controller nach Wechsel von Arduino zu Teensy


von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin dabei einen (Ersatz-)Controller für mein MIDI Keyboard zu 
basteln. Der Prototyp auf einem Breadboard und mit einem Arduino uno r3 
hat 1A geklappt, alle Tasten wurden richtig erkannt und die zugehörigen 
MIDI Daten korrekt ausgegeben.

Nun habe ich zwecks Umsetzung des Projekts die Schaltung auf eine 
Streifenrasterplatine übertragen (und auch alles ggf richtig 
durchtrennt) und verwende einen Teensy++2 (weil der mehr IO Ports hat 
und deutlich günstiger als ein Arduino MEGA und noch dazu kompakter 
ist).

Soweit so gut, nur leider "spinnen" die Tasten nun, halte ich eine Taste 
gedrückt wird sie, scheinbar zufällig, immerwieder neu ausgelöst (MIDI 
Note On und Note Off werden korrekt gesendet - nur halt sinnlos, weil 
ich halte die Taste ja gedrückt), seltsamerweise werden teilweise auch 
benachbarte Tasten und eher selten weiter entfernte Tasten ausgelöst. 
Für mein Empfinden scheint der Pegel bei gedrückter Tastete nicht gut 
gehalten zu werden oder die Leitungen stören sich irgendwie gegenseitig. 
Habe aber leider kein Ozioloskop zum nachsehen :(.
Einen Softwarefehler kann ich eigentlich ausschließen, da ich lediglich 
die Portnummern geändert habe und sonst den gleichen Code verwende wie 
mit dem Ardino, wo ich nie solche Probleme hatte.

Wo kann ich nun am Besten mit der Fehlersuche anfangen? Ich bin etwas 
ratlos ... die Lötstellen sehn eigentlich alle gut aus und durchgemessen 
habe ich das ganze auch schon ohne etwas auffälliges zu finden.
Meine Vermutung ist momentan, dass der Teensy vielleicht etwas 
empfindlicher auf Umwelteinflüsse reagiert? Was könnte ich dagegen tun? 
ist das überhaupt realistisch bei 5V?


Im angehängten Schaltplan ist der interessante Teil rot umrahmt. Dort 
befindet sich das Shiftregister, das die 8x20 Matrix für die Klaviatur 
(2 Buttons pro Taste) treibt und die 20 PullDown Widerstände sowie der 
Teensy (die 2x20 Pins in der Mitte).

EDIT: UPS da ist noch ein kleiner Fehler im Schaltplan .. "in Echt" sind 
die PullDown Widerstände natürlich alle an GND angeschlossen, habe 
gerade noch mal nach gesehen. ... wäre ja auch zu schön, wenn die 
Antwort so einfach wäre ;)


schon mal danke im Voraus,
Andreas

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ich vermisse im gesamten Plan die Entkoppelkondensatoren. Zu deinen 
Gunsten hoffe ich, das da welche eingebaut sind (am besten an jedem IC 
ein 100nF). CMOS reagiert zwar recht gutmütig, erzeugt aber 
Umschaltspitzen, die unbedingt abgefedert werden sollten.
Ebenso an den Midi-Out Buchsen, da schadet auch ein etwas dickerer Elko 
im 10-100µF Bereich sicher nicht. Übersprechen zwischen den Leitungen 
ist ausgeschlossen?
Dem Tennsy schadet es mit sicherheit auch nicht, wenn seine Versorgung 
nochmal extra entkoppelt wird.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

Hallo Matthias,

ich muss zu meiner Schande gestehen, dass ich Kondensatoren zur Zeit 
noch so ein wenig "ausblende" (das ist auch mein erstes größeres Projekt 
und ich komme eher aus der Informatik als aus der E-Technik ;) ).

Alle Kondensatoren die ich verwendet habe sind auch auf dem Schaltplan - 
d.h. ganze 3 Stück, die sind alle jweils vor den Shiftregistern (bei 
zweien davon, einer für 2 Register, da diese hintereinander geschaltet 
sind) und haben 1µF. Das ist auch das einzige Bauteil, was ich (neben 
dem Teensy) gegenüber dem Breadboard Prototypen ausgetaucht habe. Dort 
hatte ich 10nF Keramikkondensatoren und nun auf der Platine habe ich 1µF 
Elkos.

Die sind auch eigentlich nur dort, da ich es mal so in einem Tutorial zu 
ShiftRegistern gelernt habe - aber nach kurzen googlen hab ich den Sinn 
der Entkoppelkondensatoren erkannt ;)

d.h. ich sollte auch jeweils vor die Vcc und GND Pins der ShiftRegister 
und Multiplexer einen Kondensator 100nF packen - verstehe ich das 
richtig? und die aktuell schon eingebauten entkoppeln so mit das 
Latch-Siganal für die Register?


Zum Übersprechen, also ausschließen kann ich das nicht (mangelns 
Wissens, wie ich es sicher überprüfen kann). Lediglich das 
Flachbandkabel für die Treiber der 8x20 Matrix käme da doch in Frage 
oder? - das waren auf dem Breadboard nur einzelne Kabel. Allerdings 
kommen die Signale ja auch via Flachbandkabel ...

Erklärung zum Bild: Untern in der Mitte, der Teensy++ 2, links und 
rechts davon, jeweils 8 + 8 und 12 + 8 Anschlüsse für die 8x20 Matrix 
(aufgeteilt auf 2 Hälften des Keyboards. Die PullDown Widerstände sind, 
etwas schwer zu erkennen, zwecks Platzersparnis als Widerstandsnetzwerke 
ausgelegt.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas H. schrieb:
> d.h. ich sollte auch jeweils vor die Vcc und GND Pins der ShiftRegister
> und Multiplexer einen Kondensator 100nF packen - verstehe ich das
> richtig?

Ja, bitte. Damit werden sich schon einige Probleme von alleine lösen. 
Rund um den Teensy auch, also an Vcc und Gnd.

Andreas H. schrieb:
> Allerdings
> kommen die Signale ja auch via Flachbandkabel

Gerade Flachbandkabel sind beste Kandidaten für Übersprechen und über 
längere Strecken recht gute Koppelkondensatoren, wenn nicht zwischen 
jedem Signal ein GND zwischengelegt ist. Vermeiden kannst du das nur mit 
entsprechend niederohmigen Signalen oder eben durch abwechselnde 
Signal-GND-Signal-GND Belegung. So ist das z.B. bei IDE-UDMA Kabeln auch 
gelöst.

von Andreas H. (guitar1)


Lesenswert?

Okay, das mit den Kondensatoren werde ich tun.

Nochmal zum Flachbandkabel. Sind diese 10cm die ich da verwende schon zu 
viel? ich würde ja eher denken nein - zumal ja beim Treiber maximal eine 
der 8 Leitungen aktiv ist (also +5V). Und der original Controller (der 
leider hinüber ist) hatte ja dieselben Flachbandkabel von der Klaviatur 
kommend (die sind so ca 50cm lang).

Aber vermutlich werden die Kondensatoren helfen, dass würde auch das 
eine oder andere merkwürdige Verhalten beim Lesen der analogen Werte für 
die Potis erklären :D

Ich berichte wenn es Neues gibt - danke so weit schon mal!

von Peter D. (peda)


Lesenswert?

Andreas H. schrieb:
> nur leider "spinnen" die Tasten nun

Wenn die Entprellsoftware ordentlich funktioniert, darf das nicht 
auftreten. Gegebenenfalls von 2-fach auf 3- oder 4-fach Abtastung 
erhöhen.

Allerdings ist der 595 ein Problem. Wenn man mehrere Tasten drückt, 
können dessen Ausgänge kurzgeschlossen werden. Daher mit jedem Ausgang 
noch eine Diode in Reihe.
Es sei denn, in der Tastatur sind schon Dioden integriert.

von Andreas H. (guitar1)


Lesenswert?

@Peter

Nein entprellen ist hier (leider/glücklicherweise) kein Problem, Dioden 
sind ebenfalls schon in der Klaviatur integriert. Das sind auch keine 
richtigen "Taster" ich weiß nicht wie die Teile heißen, solche leitenden 
Gumminoppen die auf das PCB drücken und einen Kontakt herstellen. Davon 
jeweils 2 pro Taste, man muss die Zeitdifferenz zwischen den beiden 
Kontakten je Taste messen um ermitteln zu können, wie "stark" die Taste 
gedrückt wurde - es geht hier ja nicht um ein Spielzeug Keyboard ohne 
Anschlagsempfindlichkeit ;)

Und am Prototypen klappte es ja auch einwandfrei ohne Entprellung - 
allerdings hatte ich da immer nur die einzelnen Komponenten des 
Controllers geteste und nicht alle auf einmal, weshalb sich das mit dem 
entkoppeln sehr vielversprechend anhört - nur leider muss ich noch 
warten bis die Kondensatoren da sind ... so viele hatte ich davon nicht.

von Peter D. (peda)


Lesenswert?

Andreas H. schrieb:
> allerdings hatte ich da immer nur die einzelnen Komponenten des
> Controllers geteste und nicht alle auf einmal

Also hast Du doch die SW geändert und nicht nur die Pinzuweisungen. 
Teste doch erstmal das gleiche Programm, wie von Arduino.

Andreas H. schrieb:
> man muss die Zeitdifferenz zwischen den beiden
> Kontakten je Taste messen

Welchen Meßbereich brauchst Du denn dafür?
Es kann sein, daß der AVR damit schon voll ausgelastet ist und keine 
weiteren Tasks mehr kann.

von Andreas H. (guitar1)


Lesenswert?

@Peter:

Das habe ich bereits getan, ich hab das alte Programm vom 
Prototyp-arduino genommen und lediglich die PIN nummern angepasst (und 
auch im "richtigen" Programm ist das Auslesen der anderen Komponenten 
zur zeit auskommentiert).

Der Messbereich liegt etwa bei 1,5 bis 300ms, das klappt also ganz gut, 
ich habe auch schon beim Prototyp testweise delays von mehreren ms 
eingearbeitet um das Auslesen andere Komponenten zu simulieren - hat 
alles trotzdem super geklappt ;)

Die Tasten der Klaviatur werden dabei auch deutlich häufiger ausgelesen 
als die anderen Komponenten. Außerdem hätte ich ja dann eher das 
problem, dass die Tasten nicht ausgelöst werden, als dass sie zuoft 
ausgelöst werden, oder? (und vorallem wie liese sich damit erkären, das 
andere Tasten (die ich gar nicht berühre) auslösen?).

Was ich noch mal Testen werde ist den Arduino an die eingelöteten ICs 
anzuschließen, um zu sehen ob er dort die gleichen Probleme wie der 
Teensy hat (wenn alles nicht auf dem Breadboard sondern auf der Platine 
steckt).

von Andreas H. (guitar1)


Lesenswert?

Also, ich habe gerade mal den Arduino anstelle des Teensy an die Platine 
angeschlossen und dort auch Probleme - allerdings nicht die selben, 
wärend der Teensy die Noten wild wiederholt hat neigt der Arduino eher 
dazu gar nicht zu reagieren sondern lösst nur sehr selten aus.

Andersherum habe ich nun auch mal den Teensy an den Breadboard 
Prototypen angeschlossen. Dort hat nach anpassen der Pins wieder alles 
geklappt wie es soll. Mir ist aber auch aufgefallen, dass der Teensy 
deutlich empfindlicher auf Umgebungseinflüsse reagiert, den Arduino kann 
ich im Betrieb berühren wo ich will und alles klappt einwandfrei, wenn 
ich dem Teensy allerdings zu nahe komme werden auch wieder wild Noten 
ausgelöst (wenn ich die entsprechenden Pinlötstellen berühre) - demnach 
sind die Entkoppelungskondensatoren wohl die richtige Lösung. Wenn sie 
eingebaut sind werde ich mich nochmal melden und berichten oder weiter 
fragen ;).

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

So die Kondensatoren sind nun da und die nötige Zeit auch ;)

Aber bevor ich nachher "doppelt" Löten muss, hier nun mal wie ich die 
ICs bestücken würde. Ist das so ok?

Im Anhang hab ichs mal exemplarisch für den 4051 und 595 gezeichnet. Wie 
sieht es mit dem MR und OE vom 595 aus - das ist ja keine 
Versorgungsspannung an den Pins, demnach sind dort auch keine 
Entstör/Abblockkondensatoren nötig oder?
Ansonsten müssen die Kondensatoren ja physikalisch möglichst nah an die 
Pins und es darf keine "Schleichwege" am Kondensator vorbei geben. Muss 
ich sonst noch auf etwas achten?

Danke schon mal!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas H. schrieb:
> Ist das so ok?

Es schadet sicher nicht, zwei Entkoppelkondensatoren pro IC zu setzen, 
aber nötig ist es auch nicht. Einer pro IC ist durchaus ok, wenn du sie 
nahe am IC plazieren kannst. Wichtig ist auch, das die 
Versorgungsleitungen keine superdünnen Drähtchen sind, sondern ruhig ein 
wenig stärker ausgelegt sein sollten, als reine Signalleitungen.
Sehe für die Schaltung auch noch dicht am Teensy einen Platz für einen 
mittleren (gepolten) Elko der 10µF-100µF Klasse über der 
Betriebsspannung vor. Wenn der Teensy so eine 'Dreckschleuder' ist, 
schadet es nicht, seine Störimpulse vom Rest der Schaltung fernzuhalten.

von Andreas H. (guitar1)


Lesenswert?

Soo .. also ich habe jetzt die ICs mit je 2 Kondensatoren (100nF) 
bestückt (das war in den meisten Fällen einfacher als nur einen zu 
nehmen.)

Der Teensy hat einen 100µF Elko bekommen.

gebracht hat es aber leider nur bedingt etwas. Einige Tasten 
(hauptsächlich die am weitesten vom Anschlusskabel entfernten) 
funktionieren jetzt fehlerfrei (allerdings erkenne ich noch kein 
zuverlässiges Muster, normalerweise verhielten sich die Tasten in 8er 
Blöcken immer gleich (beim spinnen), aber diesmal sind die Oberen 26 ok 
- also 2 "zu viel".

Das Flachbandkabel des Treibers zur 2. Wannenbuchse habe ich probeweise 
auch mal entfernt - das brachte aber keine Änderung.

Was wäre denn kein "superdünnes" Drätchen? - ich habe bisher für alles 
AWG 26/28 verwendet, die Flachbandkabel sind AWG 30/32. Ansonsten hätte 
ich noch Klingeldraht.

Nachher update ich noch mal den Schaltplan und das Foto - aber 
vielleicht gibts ja auch jetzt schon weitere Verbesserungsvorschläge :)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Mit den Dioden in der Tastaturverharfung und dem Flachbandkabel bist du 
natürlich nicht so auf der pegelsicheren Seite. Deswegen kann es 
durchaus hilfreich sein, zusätzlich zu den internen Pullups des AVR auch 
externe, recht niederohmige hinzuzufügen, so in der Gegend von 3k3 bis 
10k, evtl. direkt an den Ports des Teensy. Gut geeignet sind sogen. 
Widerstandsmatrizen wo z.B. 8 oder 10 Widerstände des gleichen Typs 
schon mit einem gemeinsamen Pol herausgeführt werden.
Auf der Punktrasterplatte wird dir nichts anderes übrigbleiben, als die 
von unten an den IC Sockel zu löten, aber einen Versuch ist es mit 
Sicherheit wert. Flachbandkabel sind nun mal sehr gute 
Koppelkondensatoren und führen schnell zu Übersprechen.

Andreas H. schrieb:
> Was wäre denn kein "superdünnes" Drätchen?

Das bezog sich auf die Betriebsspannungsleitungen. Auf meinen 
Punktrasterprojekten nehme ich z.B. starren Kupferdraht mit ca. 0,5 mm 
für Masse und Vcc und die Signalleitungen mache ich mit CuL 0,15mm 
Fädeldraht.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

Hmm, ich verwende schon Wiederstandsmatrizen mit 10k ;) ... das sind 
allerdings Pulldowns, vor den lesenden Pins des Teensys ... ich werd mal 
versuchen, ob ich durchs Tauschen der Litzen durch Draht an den 
Versorgungsleitungen etwas verbesser kann.

Anbei der aktuelle Schaltplan und ein aktuelles Foto (die Klinkenbuchsen 
sind übrigens noch nicht angeschlossen - nur als Info)

Kann es vielleicht auch sein, dass sich irgendwo ein ungewünschter 
Schwingkreis gebildet hat? Auf dem defekten Originalboard (das ich 
allerdings keineswegs 1:1 nachbaue, sind auch noch ein paar 
Induktivitäten drauf), habe davon auch mal ein Bild angehängt ... 
allerdings wurde da schon hier und dort ein Teil recyclet ;)

von Andreas H. (guitar1)


Lesenswert?

Also das Austauschen der Litzen durch Drähte (bei den 
Versorgungsleitungen) hat leider nichts gebracht, kein Unterschied zu 
davor, noch immer die gleichen Probleme.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas H. schrieb:
> sind auch noch ein paar
> Induktivitäten drauf

Das ist am DC Eingang eine stromkompensierte Drossel und das Teil um U19 
scheint ein kleiner Schaltregler mit Speicherdrossel zu sein.
Bist du dir denn mit deiner Stromversorgung sicher? Liefert die eine 
saubere Speisespannung? Hast du ein Oszi in Reichweite? Denn so langsam 
wirst du eines brauchen.
An den Tasten mit den meisten Störungen könnte es sich auch bemerkbar 
machen, wenn du die Flachbandkabel auseinandertrennst.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

Hmm einen Oszi könnte ich aller frühstens Dienstag nutzen - allerdings 
kann ich den nicht mitnehmen und ich wollte ungern mit einer ausgebauten 
76er Klaviatur Busfahren :D da könnte ich nur schauen, wie sich das 
Board an sich verhält. Was würde ich denn da am besten so alles 
überprüfen?

... Also momentan kommt die Stromversorgungen noch über USB (also über 
die Buchse des Teensys, die sollte ja eigentlich ganz ok sein.

Irgendwie wundert es mich doch sehr, dass das auf dem Breadboard so gut 
funktioniert hat - hätte nie gedacht, dass sich die ICs gegenseitig so 
stören können ...


So ich habe noch ein bisschen nachgemessen / ausprobiert (dabei habe ich 
die Pins jeweils DIREKT mit einem Jumperkabel verbunden - also hier 
können auch keine Störungen aus dem langen Flachbandkabel zur Klaviatur 
aufgetreten sein) ... und zwar welche Kanäle probleme machen und welche 
nicht, dazu das Bild im Anhang.
Die grünen Kanäle klappen wunderbar, die gelben nur in verbindung mit 
Treiber[0] sonst Störungen und die blauen haben immer Störungen.
Übereinanderliegende Pärchen sind jeweils für eine Taste (da ja pro 
Taste 2 Taster existieren - also habe ich jeweils einen Treiberpin und 
ein Pärchen zum Testen verbunden). In der Mitte wäre natürlich der 
Teensy, den hab ich nur der Übersichthalber weggelassen. Die Treiberpins 
kommen von dem 1. Shiftregister links des Teensys, wobei Treiber[0] = Q0

Das Flachbandkabel das die Treiberpins verbindet kann es nicht gewesen 
sein, das habe ich jetzt auseinandergetrennt.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas H. schrieb:
> Was würde ich denn da am besten so alles
> überprüfen?

Wenn du die Klaviatur nicht mitnehmen kannst, bleibt dir nur, die 
Multiplexsignale und die Rückleitung mal roh zu prüfen, d.h., ob auf den 
Rückleitungen die Mux Signale liegen per Übersprechen.

Andreas H. schrieb:
> Die grünen Kanäle klappen wunderbar, die gelben nur in verbindung mit
> Treiber[0] sonst Störungen und die blauen haben immer Störungen.

Es ist also ein gewisses System drin. Du könntest jetzt versuchsweise 
mal die Multiplex Rate senken und/oder die Tastenauswertung so 
verändern, das öfter auf Plausibilität ('ist die Taste auch wirklich 
gedrückt') geprüft wird.

Andreas H. schrieb:
> ... Also momentan kommt die Stromversorgungen noch über USB (also über
> die Buchse des Teensys, die sollte ja eigentlich ganz ok sein

Aaarghh - der Teensy verseucht damit die Restschaltung. Ich bin mir auch 
wirklich nicht sicher, ob der Kleine die harten Impulse der Mux Treiber 
und Analogschalter über das Board glätten kann. Probier auch mal, den 
Teensy nicht aus dem Rechner zu speisen, sondern nur über einen Hub mit 
Netzteil, der vom Rechner getrennt ist. USB Versorgungen sind oft mit 
Rechnerpulsen verseucht.

Andreas H. schrieb:
> Hmm einen Oszi könnte ich aller frühstens Dienstag nutzen

Wenn du auch zukünftig komplexere Projekte bauen willst, kann ich dir 
nur empfehlen, auf eines zu sparen. Du wirst es nicht bereuen und ein 
gutes (kann auch analog sein) Oszi wird dich viele Jahre begleiten. Ein 
gebrauchtes 2-Kanal von Hameg o.ä. kostet nicht viel beim 
Netzauktionshaus und ist extrem hilfreich. Ich prophezeie dir, das du 
mit einem Oszi schon längst wüsstest, wo der Hase im Gewürz liegt.

von Andreas H. (guitar1)


Lesenswert?

Matthias Sch. schrieb:
> Es ist also ein gewisses System drin. Du könntest jetzt versuchsweise
> mal die Multiplex Rate senken und/oder die Tastenauswertung so
> verändern, das öfter auf Plausibilität ('ist die Taste auch wirklich
> gedrückt') geprüft wird.

also ich habe jetzt mal in den Multiplex Loop ein delay von 50µs pro 
Schleifendurchlauf eingefügt - und jetzt wirds interessant - alles was 
an der rechten Buchse angeschlossen ist (die oberen 4 Oktaven) klappt 
einwandfrei (außer dem zulangen Delay natürlich). Alles was links 
angeschlosse ist hat aber Störsignale, auch die 2 Pins, die vorher (ohne 
Delay) richtig funktioniert haben.

Ab etwa 35µs kommen die Störungen dann auch auf den oberen Oktaven 
wieder. Auf den Unteren bleiben die Störungen selbst bei 3ms noch 
erhalten, jedoch werden sie deutlich langsamer (bzw der Abstand zwischen 
2 falsch ausgelösten Noten wird größer). Allerdings sind die Störungen 
nicht (immer) regelmäßig sondern eher zufällig - also es ist nicht so, 
dass sie in einer festen Frequenz auftreten.

Das mit der Plausabilitätsprüfung ist so eine sache, bei MIDI wird ja 
ein Signal gesendet, wenn die Taste gedrückt wird und eines wenn sie 
wieder losgelassen wird - zwischen drin wird nichts gesendet. Außerdem 
in der Frequenz wie die Fehlauslösungen auftretten glaube ich nicht, 
dass man das softwaremäßig lösen oder auch nur mildern kann. Ohne das 
Delay erzeugen die Fehlauslösungen ja fast schon einen eigenen Ton durch 
die hohe Frequenz des Auftretens - ähnlich wie die Selbstoszilation bei 
Filtern - und es wir ja auch nicht weniger mit der Zeit sondern bleibt 
konstant (aber zufällig - also keine feste Frequenz).


... ich werds dann jetzt wohl mal mit nem Oszi versuchen - ich habe ja 
mittlerweile herausgefunden, dass ich die Störungen auch ohne Klaviatur 
hab, was den Transport ja enorm erleichtert :)

An der Stromversorgung lag es übrigens nicht, habe den Teensy über ein 
USB-Netzteil von ner Digicam angeschlossen, das hatte aber keinerlei 
erkennbare Auswirkungen.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

So jetzt hab ich ein Oszi (OWON SDS7102) zur Verfügung das ich auch mit 
nehmen konnte. Ich habe erstmal hier und dort etwas herumgemessen und 
bis auf eine Sache eigentlich nichts gefunden was mich verwundert hätte 
(wobei ich zuvor aber auch noch nie mit einem Oszi gearbeitet hab und 
folglich auch nicht weiß, was man vielleicht sonst noch so messen 
könnte, also Vorschläge sind willkommen ;) ).

Kommen wir zu der einen Sache (siehe dazu Screenshot). Kanal 1 
entspricht dem Q7, Kanal 2 dem Q0 des Shiftregisters der 8x20 Matrix, 
also dem Treiber.
Die links zu sehenden Pulse sind wie erwartet: gleich lang und direkt 
aufeinander foglend. Bei der 2. Serie erkennt man aber deutlich, dass 
der Puls auf Q7 etwa doppelt so lang ist wie er sein sollte. Vorallem 
irritiert mich dieses Verhalten, weil das ja der Treiber ist, der 
eigentlich nur sturr in eine Schleife nach einander ein Bit durchs 
Register schiebt (bzw. je 8 Bits, aber die 1 ist immer eins weiter). Das 
Phanomän beschränkt sich auch ausschließlich auf Q7 alle anderen Pulse 
haben immer die richtige Länge (soweit ich das beurteilen kann). Das 
Auftreten schein mir auch zufällig zu seien. Einzige regelmäßigkeit, es 
scheint nie 2 dieser langen Pulse direkt hintereinander zukommen, es ist 
offensichtlich immer mindestens ein "richtiger" dazwischen. Und der 
Fehler tritt nur auf, wenn ein Treiber Pin mit einem Pärchen der 
"blauen" Pins (auf der Abbildung vom Post 15.06.2013 22:37) verbunden 
ist. Verbinde ich ein "grünes" Pärchen, nur einen Pin oder gar keinen 
Pin habe ich den Fehler nicht.

Die eigentlich Störung (mehrfaches Auslösen einer MIDI Note) kann ich 
mir damit allerdings auch noch nicht erklären, da die nachfolgenden 
Pulse ja verschoben sind, somit kann ja nicht falsch sondern nur 
"später" ausgelesen werden, was ja eigentlich kein Problem sein sollte.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

Noch ein Update, der Data Pin des Shiftregisters zeigt ein ähnliches 
Verhalten wie Q7. Im Screenshot Kanal 1 der Data Pin, Kanal 2 der Q7.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ich kenne deine Software nicht, aber irgendwann muss ja der MC auch was 
anderes machen, als Pulse für die Schieberegister zu produzieren. Lass 
als Hilfe mal in der Multiplexroutine noch einen Ausgang des MC 
mittoggeln, damit du weisst, wann die Routine aktiv ist und leg dir 
diesen Puls auf einen Oszi Kanal.
Einen Kurzschluss in der Klaviatur oder im Anschlusskabel kannst du 
grundsätzlich ausschliessen? Sieht mir allerdings auch nicht so aus, 
sonst würden die Pegel anders verlaufen.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Andreas H. schrieb:
> ... das sind allerdings Pulldowns, vor den lesenden Pins des Teensys ...

hm... dann hast du aber die internen Pullups abgeschaltet, oder?

gruß
Christopher

von Andreas H. (guitar1)


Lesenswert?

Christopher B. schrieb:
> Andreas H. schrieb:
>> ... das sind allerdings Pulldowns, vor den lesenden Pins des Teensys ...
>
> hm... dann hast du aber die internen Pullups abgeschaltet, oder?
>
> gruß
> Christopher

Ich formulier es mal so: ich habe sie nicht eingeschaltet. Aber da ich 
ja im Moment das ganze noch mit dem Arduino Framework programmiert habe 
sollten die Pullups aus sein, wenn sie nicht explizit angeschaltet sind.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Ok,
gut. Aber deine Schalter schalten schon auf HIGH, oder?
Muss man ja erstmal ausschließen.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

@Christopher:
Was genau meinst du mit "schalten auf HIGH"? das sind Taster 
(schließend), die stellen ja nur eine Verbindung her. Also über den 
Treiber wird ein HIGH gesendet, wenn der Taster dann entsprechend 
geschlossen ist kann ich dann ja ein HIGH lesen (deshalb auch 
PullDowns). Die Taster ansich funktionieren ja auch, mit dem Prototypen 
auf dem Breadboard und nemm Arduino hat das ja alles super geklappt. Nur 
seit das ganze (mit allen Komponenten (weitere Shiftregister und 
Multiplexer für Analoge Signale (Potis))) auf der Streifenrasterplatine 
sitzt und ich den Teensy benutze gibt es Probleme. Die Software ist bis 
auf die Pin Nummern auch gleich geblieben. Und zur Zeit sind auch alle 
weitern Komponenten auskommentiert.


Matthias Sch. schrieb:
> Ich kenne deine Software nicht, aber irgendwann muss ja der MC auch was
> anderes machen, als Pulse für die Schieberegister zu produzieren. Lass
> als Hilfe mal in der Multiplexroutine noch einen Ausgang des MC
> mittoggeln, damit du weisst, wann die Routine aktiv ist und leg dir
> diesen Puls auf einen Oszi Kanal.

Das stimmt, wobei das einzige was er sonst noch macht ist das MIDI via 
UART zu senden (ich hab mir auch mal den TX Pin zusammen mit Q7 
angeschaut, da erkenne ich keinen Zusammenhang zwischen dem Senden und 
den längern Blöcken auf Q7).
Die andere Messung hab ich mal in den Anhang gepackt eine Flanke bei 
Kanal 2 bedeutet, dass dort der Treiber wieder bei Q0 anfängt. Sonst ist 
da auch nichts drin in dem (main) Loop.

hier mal der Quellcode (Anmerkung: debug ist false):
1
boolean debug = false;
2
3
const byte testPin = 31;
4
boolean test = false;
5
6
/* shift registers */
7
const byte clk = 4;
8
const byte data = 1;
9
const byte latch_LED = 0;
10
const byte latch_Buttons = 26;
11
const byte latch_Keys = 27;
12
13
/* buttons */
14
const byte buttons0 = 39;
15
const byte buttons1 = 38;
16
const byte buttons2 = 5;
17
18
/* lower keys */
19
const byte keys0 = 25;
20
...
21
const byte keys7 = 18;
22
23
/* upper keys */
24
const byte keys8 = 17;
25
...
26
const byte keys19 = 6;
27
28
boolean keysRow0 = 0;
29
...
30
boolean keysRow19 = 0;
31
32
/* multiplexer */
33
const byte muxSel0 = 45;
34
const byte muxSel1 = 44;
35
const byte muxSel2 = 43;
36
const byte mux0 = A4;
37
const byte mux1 = A3;
38
const byte mux2 = A2;
39
40
const byte shiftBits[] = {B00000001,
41
                          B00000010,
42
                          B00000100,
43
                          B00001000,
44
                          B00010000,
45
                          B00100000,
46
                          B01000000,
47
                          B10000000};
48
                          
49
const byte digits[] = {SEG7_0, SEG7_1, SEG7_2, SEG7_3, SEG7_4, SEG7_5, SEG7_6, SEG7_7, SEG7_8, SEG7_9};  
50
51
const byte keyToMidi[10][8] = {
52
                      /*  0 */  {24, 23, 22, 21, 0, 0, 0, 0},       // A0 to C1 // 0 = not available on keyboard
53
...
54
                      /*  9 */  {96, 95, 94, 93, 92, 91, 90, 89}    // F6 to C7
55
                              };
56
                          
57
boolean keyPressed[8][10]; // nessesary for sending NoteOff
58
boolean keyInWatchList[8][10];
59
unsigned long keyFirstButtonTime[8][10];
60
61
// sends NoteOn
62
void MIDINoteOn(byte note, byte chan, byte velo) {
63
  Serial1.write(0x90 | chan); // note on
64
  Serial1.write(note); // note value
65
  Serial1.write(velo); // velo
66
}
67
68
// sends NoteOff
69
void MIDINoteOff(byte note, byte chan) {
70
  Serial1.write(0x80 | chan); // note off
71
  Serial1.write(note); // note value
72
  Serial1.write((byte) 0); // velo
73
}
74
75
inline void processFirstButton(byte col, byte row){
76
  keyFirstButtonTime[col][row] = micros();
77
  keyInWatchList[col][row] = true;
78
}
79
80
inline void processSecondButton(byte col, byte row){
81
  // calculate velocity
82
  unsigned long timeDiff = micros() - keyFirstButtonTime[col][row];
83
  char velo = 847e-10 * timeDiff * timeDiff - 678e-5 * timeDiff + 136;
84
  
85
  if (velo < 1) {
86
    velo = 1;
87
  }  
88
  if (velo > 127) {
89
    velo = 127;
90
  }
91
  
92
  if (debug) {
93
    Serial.print("Velocity Time: ");
94
    Serial.print(timeDiff);
95
    Serial.print("us Velo: ");
96
    Serial.println(velo);
97
  }
98
  
99
  // send MIDI Note On
100
  MIDINoteOn(keyToMidi[row][col], 0, velo);
101
  //MIDI.sendNoteOn(keyToMidi[row][col], 0, velo);
102
  
103
  // mark key as pressed
104
  keyPressed[col][row] = true;
105
106
  // remove button from watch list
107
  keyInWatchList[col][row] = false;
108
}
109
110
// drives the 8x8(7) matrix for the LEDs and 7Segments
111
void driveLEDs(byte v1, byte v2){
112
  digitalWrite(latch_LED, LOW);
113
  shiftOut(data, clk, LSBFIRST, v2);
114
  shiftOut(data, clk, LSBFIRST, v1);
115
  digitalWrite(latch_LED, HIGH);
116
}
117
118
// drives the 8x3 matrix for the buttons
119
void driveButtons(byte value){
120
  digitalWrite(latch_Buttons, LOW);
121
  shiftOut(data, clk, MSBFIRST, value);
122
  digitalWrite(latch_Buttons, HIGH);
123
}
124
125
// drives the 8x20 matrix for the keys
126
void driveKeys(byte value){
127
  digitalWrite(latch_Keys, LOW);
128
  shiftOut(data, clk, MSBFIRST, value);
129
  digitalWrite(latch_Keys, HIGH);
130
}
131
132
// reads the values from the 3 4051-Mulitplexers
133
void readMuxes(){
134
  if (debug) {
135
    Serial.println("muxes:");
136
    
137
    for(byte i = 0; i < 8; i++){
138
      Serial.print("(");
139
      if (i & B100) {
140
        Serial.print(1);
141
        digitalWrite(muxSel2, HIGH);
142
      } else {
143
        Serial.print(0);
144
        digitalWrite(muxSel2, LOW);
145
      }
146
      if (i & B010) {
147
        Serial.print(1);
148
        digitalWrite(muxSel1, HIGH);
149
      } else {
150
        Serial.print(0);
151
        digitalWrite(muxSel1, LOW);
152
      }
153
      if (i & B001) {
154
        Serial.print(1);
155
        digitalWrite(muxSel0, HIGH);
156
      } else {
157
        Serial.print(0);
158
        digitalWrite(muxSel0, LOW);
159
      }
160
      Serial.print(") ");
161
      Serial.print(i);
162
      Serial.print("mux0: ");
163
      
164
      Serial.print(analogRead(mux0) >> 2);
165
      Serial.print(" mux1: ");
166
      Serial.print(analogRead(mux1) >> 2);
167
      Serial.print(" mux2: ");
168
      Serial.println(analogRead(mux2) >> 2);
169
    }
170
  }
171
}
172
173
void setup() {
174
  pinMode(testPin, OUTPUT);
175
  
176
  // shift registers
177
  pinMode(clk, OUTPUT);
178
  pinMode(data, OUTPUT);
179
  pinMode(latch_LED, OUTPUT);
180
  pinMode(latch_Buttons, OUTPUT);
181
  pinMode(latch_Keys, OUTPUT); // <-- für die Klaviatur
182
  
183
  // lower keys
184
  pinMode(keys0, INPUT);
185
  ...
186
  pinMode(keys7, INPUT);
187
  
188
  // upper keys
189
  pinMode(keys8, INPUT);
190
  ...
191
  pinMode(keys19, INPUT);
192
  
193
  // buttons
194
  pinMode(buttons0, INPUT);
195
  pinMode(buttons1, INPUT);
196
  pinMode(buttons2, INPUT);
197
  
198
  // multiplexers
199
  pinMode(muxSel0, OUTPUT);
200
  pinMode(muxSel1, OUTPUT);
201
  pinMode(muxSel2, OUTPUT);
202
  pinMode(mux0, INPUT);
203
  pinMode(mux1, INPUT);
204
  pinMode(mux2, INPUT); 
205
206
  Serial.begin(9600); // <-- nur fürs debuging, ist aber deaktiviert (ist der Serial Port der über USB gesendet wird)
207
208
  Serial1.begin(31250); // <-- der Hardware Serial Port (der die RX, TX Pins ansteuert), hier wird das MIDI gesendet
209
}
210
211
212
void loop() { 
213
  if (test) { // setzt die Testflanke
214
    digitalWrite(testPin, HIGH);
215
    test = false;
216
  } else {
217
    digitalWrite(testPin, LOW);
218
    test = true;
219
  }
220
  
221
  // keys
222
  for (byte testCol = 0; testCol < 8; testCol++) {
223
    driveKeys(shiftBits[testCol]);
224
225
    // odd = 2nd buttons; even = 1st buttons
226
    keysRow0 = digitalRead(keys0);
227
    keysRow1 = digitalRead(keys1);
228
    ...
229
    keysRow18 = digitalRead(keys18);
230
    keysRow19 = digitalRead(keys19);
231
    
232
    if (debug || 0) { // debug ist false
233
      Serial.print(keysRow0);
234
      ...
235
      Serial.println(keysRow19);
236
    }
237
    
238
    // process 2nd buttons if the key is not yet pressed and they are in the watch list
239
    if (!keyPressed[testCol][0] && keyInWatchList[testCol][0] && keysRow1){
240
      processSecondButton(testCol, 0);
241
    }
242
    
243
    ...
244
    
245
    if (!keyPressed[testCol][9] && keyInWatchList[testCol][9] && keysRow19){
246
      processSecondButton(testCol, 9);
247
    }
248
    
249
    // process 1st buttons
250
    if (keysRow0) {
251
      if (!keyPressed[testCol][0] && !keyInWatchList[testCol][0]) { // key is not yet pressed and not in watch list
252
        processFirstButton(testCol, 0);
253
      }
254
    } else {
255
      if (keyPressed[testCol][0]) { // key was pressed
256
        MIDINoteOff(keyToMidi[0][testCol], 0); // send MIDI Note Off
257
        keyPressed[testCol][0] = false; // mark key as not pressed
258
      }
259
    }
260
261
    ...
262
263
    if (keysRow18) {
264
      if (!keyPressed[testCol][9] && !keyInWatchList[testCol][9]) { // key is not yet pressed and not in watch list
265
        processFirstButton(testCol, 9);
266
      }
267
    } else {
268
      if (keyPressed[testCol][9]) { // key was pressed
269
        MIDINoteOff(keyToMidi[9][testCol], 0); // send MIDI Note Off
270
        keyPressed[testCol][9] = false; // mark key as not pressed
271
      }
272
    }     
273
  }
274
  
275
  //delay(4);
276
  
277
  if (debug || 0) {
278
    Serial.println("-----");
279
    delay(10);
280
  }
281
  
282
  // LEDs
283
  if (debug) {
284
    for (byte i = 0; i < 3; i++){
285
      if (i == 0) driveLEDs(B00000001, digits[1]);
286
      if (i == 1) driveLEDs(B00000010, digits[2]);
287
      if (i == 2) driveLEDs(B00000100, digits[3]);
288
    }
289
  }
290
  
291
  // buttons
292
  if (debug) {
293
    Serial.println("Buttons:");
294
    for (byte testCol = 0; testCol < 8; testCol++) {
295
      driveButtons(shiftBits[testCol]);
296
      
297
      boolean btnRow0 = digitalRead(buttons0);
298
      boolean btnRow1 = digitalRead(buttons1);
299
      boolean btnRow2 = digitalRead(buttons2);
300
      
301
      Serial.print(testCol);
302
      Serial.print(": ");
303
      Serial.print(btnRow0);    
304
      Serial.print(btnRow1);    
305
      Serial.println(btnRow2);
306
    }
307
    delay(100);
308
  }
309
  
310
  // knobs, faders etc.
311
  if (debug) {
312
    readMuxes();
313
  }
314
315
}
Ich denke eigentlich, dass der Code klappen sollte (mit dem Arduino tat 
er das ja ;) )

Kurz noch zur Idee, damit du nicht den ganzen Code lesen musst ;): jede 
Taste der Klaviatur besteht aus 2 Tastern.
Wird Taster 1 gedrückt, speichere ich die Taste in der "watchList" und 
ich speichere den Zeitpunkt zu dem das geschah.
Wird Taster 2 gedrückt, vermerke ich das die tastet nun "pressed" ist, 
messe den Abstand zum Druck von Taster 1, berechne die Velocity und 
sende das MIDI Note On
Wird Taster 1 nicht mehr gedrückt, aber die Taste ist noch als "pressed" 
markiert sende ich MIDI Note Off und setzte für die Taste wieder alles 
zurück.


> Einen Kurzschluss in der Klaviatur oder im Anschlusskabel kannst du
> grundsätzlich ausschliessen? Sieht mir allerdings auch nicht so aus,
> sonst würden die Pegel anders verlaufen.
Ja kann ich ausschließen - das Kabel ist in einwandfreiem Zustand und an 
der Klaviatur noch "vom Werk" angelötet, die selbst angelöteten Buchsen 
auf dem Board haben auch definitiv keinen Kurzschluss.

von Andreas H. (guitar1)


Angehängte Dateien:

Lesenswert?

Ich habe gerade meine Pulse in den +5V wieder gefunden (Kanal 1 = Q7, 
Kanal 2 = +5V), die Differenz zwischen den maximalen und minimalen 
Pegeln liegt bei etwa 70 bis 50 mV. Ist das (zu) viel? Mir fehlt für 
solche Größen noch etwas das Gespühr, mein Bauchgefühl sagt mir aber, 
dass das zu wenig zum "Stören" ist...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas H. schrieb:
> mein Bauchgefühl sagt mir aber,
> dass das zu wenig zum "Stören" ist...

Naja, Gefühl ist hier so 'ne Sache, Störungen sind Störungen und ohne 
is' immer besser :-) Gerade die CMOS ICs sehen sowas gerne mal als 
gültiges Signal.
Die Sache mit den dicken Masseleitungen hast du ja hoffentlich gemacht, 
und das ist es recht einfach, noch ein paar 'strategische' 
Entkoppelkondensatoren über die Schaltung zu verteilen.

Andreas H. schrieb:
> if (debug || 0) {
>     Serial.println("-----");
Das Konstrukt muss dir mir mal erklären 'If debug OR null' - m.E. ist 0 
immer wahr. Nur für Tests?

Andreas H. schrieb:
> for (byte testCol = 0; testCol < 8; testCol++) {
>       driveButtons(shiftBits[testCol]);
>  // Sächelchen weggelassen
>       Serial.print(btnRow1);
>       Serial.println(btnRow2);
>     }
>     delay(100);

Hier ist klar, das er in shiftBits[7] länger drin bleibt als in allen 
anderen Zuständen. Du könntest dein shiftBits Array mal um Zustand 
Nummer 8 erweitern, indem alle Matrix Ausgänge auf 0 stehen. In diesem 
Zustand verlässt du dann die Scan Routine.

Generell ist die Arduino Library von der Verarbeitungszeit nicht 
optimal. digitalWrite() ist zwar sehr universell angelegt, braucht aber 
extrem lange im Vergleich zum direkten Port schreiben. Es kann nicht 
schaden, früher oder später mal auf richtiges C umzusteigen.

von Andreas H. (guitar1)


Lesenswert?

Matthias Sch. schrieb:
> Andreas H. schrieb:
>> mein Bauchgefühl sagt mir aber,
>> dass das zu wenig zum "Stören" ist...
>
> Naja, Gefühl ist hier so 'ne Sache, Störungen sind Störungen und ohne
> is' immer besser :-) Gerade die CMOS ICs sehen sowas gerne mal als
> gültiges Signal.
> Die Sache mit den dicken Masseleitungen hast du ja hoffentlich gemacht,
> und das ist es recht einfach, noch ein paar 'strategische'
> Entkoppelkondensatoren über die Schaltung zu verteilen.

ja, die dickeren Leitungen zur Stromversorgung habe ich angebracht. Wo 
wären den solche "strategischen" Kondensatoren angebracht. Vor 
Abzweigungen? Und eher "kleine" (bis 100nF) oder "große" (mehr als 
100nF)?


> Andreas H. schrieb:
>> if (debug || 0) {
>>     Serial.println("-----");
> Das Konstrukt muss dir mir mal erklären 'If debug OR null' - m.E. ist 0
> immer wahr. Nur für Tests?

\* räusper * - ja das war nur zu Testzwecken, ich wollte nicht, debug 
auf 1 setzten weil das zu viel (unnötigen) Output gegeben hätte und hab 
dann kurzer Hand ein "OR 1" dahinter gehängt (aber 0 (als Zahl) ist 
immer falsch, es ist ja nicht NULL (als unbekannter Wert)) ;)

> Andreas H. schrieb:
>> for (byte testCol = 0; testCol < 8; testCol++) {
>>       driveButtons(shiftBits[testCol]);
>>  // Sächelchen weggelassen
>>       Serial.print(btnRow1);
>>       Serial.println(btnRow2);
>>     }
>>     delay(100);
>
> Hier ist klar, das er in shiftBits[7] länger drin bleibt als in allen
> anderen Zuständen. Du könntest dein shiftBits Array mal um Zustand
> Nummer 8 erweitern, indem alle Matrix Ausgänge auf 0 stehen. In diesem
> Zustand verlässt du dann die Scan Routine.

Ja, aber zur Zeit debug ja false, d.h. dieser Code wird nie ausgeführt, 
aber klar, das würde dann zu einem längern Zustand führen. Ist so ein 
Matrixeintrag mit B00000000 denn zu empfehlen? - sprich stört es, wenn 
dort ein HIGH "liegen bleibt"?

> Generell ist die Arduino Library von der Verarbeitungszeit nicht
> optimal. digitalWrite() ist zwar sehr universell angelegt, braucht aber
> extrem lange im Vergleich zum direkten Port schreiben. Es kann nicht
> schaden, früher oder später mal auf richtiges C umzusteigen.

Ja, das habe ich auch noch vor, der Teensy eignet sich auch gut für C 
Programmierung, aber den Prototypen hatte ich halt mit dem Arduino 
gemacht, weil grad nix anderes da war und ich wollt ja erst mal nur 
einen "Proove of Concept", wofür die Arduino Library ja gut geeignet ist 
- zwecks Übersichtlichkeit :).

Ich muss dir zwischen drin auch schon mal Danke sagen ;) - so lang wie 
der Thread mittlerweile schon geworden ist will ich nicht mehr bis zum 
hoffentlich baldigem Ende warten :D

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas H. schrieb:
> ja, die dickeren Leitungen zur Stromversorgung habe ich angebracht. Wo
> wären den solche "strategischen" Kondensatoren angebracht. Vor
> Abzweigungen? Und eher "kleine" (bis 100nF) oder "große" (mehr als
> 100nF)?

Schau dir einfach nochmal den originalen Controller an. Eine ähnliche 
Strategie ist vermutlich gar nicht dumm. Also eine saubere 
Stromversorgung und dann die grösseren Verbraucher mit Elko und Kerko 
entkoppeln (den Teensy und die Treiber, die den Strom liefern). Kleinere 
Kerkos dann an den kleineren Teilen.
Übrigens sind auch CMOS Analogschalter nicht unendlich schnell und 
'kleben' nach dem Umschalten auf einen anderen Kanal noch kurz auf dem 
alten. Verhindern könntest du das mit dem Sperren und Freigeben des 
'Enable' Eingangs oder durch leicht längeres Warten, bevor du den 
Schalter dann einliest. Lass dir doch mittels deines Test Ausgangs mal 
den Zeitpunkt anzeigen, wo du wirklich den Tastenwert einliest und 
vergleiche die kritischen Tasten mit den unkritischen.
Eine andere Strategie wäre noch, die Matrixroutine so zu ändern, das du 
beim Verlassen der Schleife schon mal die nächste Spalte und Zeile 
voreinstellst und beim Eintritt zuerst diesen Wert liest. Das ganze wäre 
mit einer Timer ISR gut zu machen, die Timerperiode ist dann direkt die 
'Settle' Zeit deiner Matrix.

Andreas H. schrieb:
> Ich muss dir zwischen drin auch schon mal Danke sagen ;)

Hehehe, da nich' für :-)

von Andreas H. (guitar1)


Lesenswert?

Matthias Sch. schrieb:
> Übrigens sind auch CMOS Analogschalter nicht unendlich schnell und
> 'kleben' nach dem Umschalten auf einen anderen Kanal noch kurz auf dem
> alten. Verhindern könntest du das mit dem Sperren und Freigeben des
> 'Enable' Eingangs oder durch leicht längeres Warten, bevor du den
> Schalter dann einliest. Lass dir doch mittels deines Test Ausgangs mal
> den Zeitpunkt anzeigen, wo du wirklich den Tastenwert einliest und
> vergleiche die kritischen Tasten mit den unkritischen.

Das war es!!! :) - wärend ich keysRow0 und keysRow1 ausgelesen hab war 
der Treiber noch gar nicht auf HIGH. Warum das jetzt alles so dermaßen 
durcheinander gebracht hat weiß ich noch nicht genau, aber durch ein 
kleines Delay von 16µs ist jetzt alles im Lot und die Tasten 
funktionieren einwandfrei :) - zum Glück hab ich noch nicht angefangen 
die Kondensatoren zu verlöten, das hätte an einigen Stellen ein echt 
unschönes Platinenlayout gegeben :D.
Das mit dem Enable Pin werde ich auch noch mal testen. Bei meiner 
Anwendung sind Delays ja eigentlich eher ein Tabu :D

Man hat das lange gedauert und soo eine einfach Lösung .. na gut, ich 
hab viel gelernt dabei! Also noch mal vielen Dank für die Tipps!
1
...
2
void loop() { 
3
  // keys
4
  for (byte testCol = 0; testCol < 8; testCol++) {
5
    driveKeys(shiftBits[testCol]);
6
    delayMicroseconds(16);
7
    
8
    // odd = 2nd buttons; even = 1st buttons
9
    keysRow0 = digitalRead(keys0);
10
    keysRow1 = digitalRead(keys1);
11
...

von Deltor (Gast)


Lesenswert?

Andreas H. schrieb.
1
  if (velo > 127) {
2
    velo = 127;
3
  }
Dir ist schon klar, dass der Code nix tut?!
Ein char kann keinen Wert größer 127 haben.
Wundert mich, dass Dein Compiler Dich nicht gewarnt hat.

Geht das tatsächlich erst bei einem Delay von 16µs?
Meines Erachtens sollten 1 bis 2µs fett reichen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Deltor schrieb:
> Geht das tatsächlich erst bei einem Delay von 16µs?
> Meines Erachtens sollten 1 bis 2µs fett reichen.

Das ist sehr knapp. Ein 4051/52/53 Analogschalter hat lt. Datenblatt 
eine Verzögerung von max. 1µs vom Setzen des Schalters bis zum 
Durchschalten. Das gilt bei 5V. Je höher die Versorgungsspannung ist, 
desto 'munterer' wird er, bei 10V sinds nur noch 360ns und bei 15V dann 
240ns.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.