|
|
Mein Bruder baut Musikinstrumente aus allem, was Geräusch gibt. Eine seiner Ideen ist, Gegenstände durch Motoren angeschlagen zum Klingen zu bringen, und im zweiten Schritt die Motoren durch Kontakte aus einem Kinderpiano anzusteuern.Mehr oder weniger enttäuschend. Das Klingen der Gegenstände wird vom Schlagen des Motors gestört.
Wie wäre es, die Motorgeräusche selber zu nutzen? Der Motor hat eine nominelle Drehzahl von 3000 U/min, was einem doch recht tiefen G1 entspricht. Als erstes wäre also die Schlagfrequenz zu erhöhen, z.B. durch eine Scheibe mit acht Nylonschnüren. Das bringt schon mal höhere Töne zustande. Die Schnüre werden sich im Lauf der Zeit abnutzen, so dass ein fertig aufgebautes Instrument permanente Pflege erforderte.
Eine Scheibe mit aufgeklebten Magneten koppelt die Drehung des Motors berührungslos und damit verschleißfrei aus.
Ursprünglich sollten die Töne von den Gegenständen stammen, die Motoren also nur an oder aus geschaltet sein. Jetzt gilt es, die Motordrehzahl je nach gewünschtem Ton einzustellen. Dafür sorgt eine digitale Ansteuerung, die den Motor mit unterschiedlichen Spannungen betreibt, je nach gedrückter Taste.
Der folgende Aufbau verwendet eine kleine Konservendose als Membran, weshalb höhe Töne unverhältnismäßig laut klingen.
Das Magnetrad koppelt das Drehen des Motors verschleißfrei auf einen mit einer akustische Membran (hier ein Dosendeckel) verbundenen Stabmagneten. Die Magnetscheiben sind aus auf der Straße gefundenen Zigarettenpapierpackungen recykelt. Beim Aufkleben stören die doch deutlichen Kräfte zwischen den Scheiben. Mein Ausweg:
- einen guten Tropfen Sekundenkleber auf das Holzrad setzen
- Magnetscheibe auf den vorgesehenen Platz drücken
- auf den vorgequollenen Sekundenkleber Natron streuen, was diesen schnell aushärten lässt
- zur weiteren Verstärkung einmal Epoxidharzkleber rundum auftragen
- während das Epoxidharz aushärtet, den Motor langsam (!) drehen lassen, damit sich keine Tropfnasen bilden.
Ein Stück Fahrradschlauch soll Kräfte auf die Klebung bei evtl. Kollisionen dämpfen.
1. Die Lautstärke steigt mit der Umdrehungszahl, tiefen Tönen fehlt der "Bass". Hilfreich wäre eine größere Membran, die schnellen Bewegungen nicht mehr so gut folgen kann. Vermutlich wird die Resonanzfrewuenz dann zum ´Problem.
2. Die Motoransteuerung kann den Motor nicht aktiv bremsen. Besonders auffällig wird das in Pausen nach hohen Tönen, bei denen der Motor abheult (als Gegenteil zu Aufheulen). Vorgemerkt für Version 2.
3. Der Treiber für den BUK545 ist ein Inverter. Das ist nur wegen der Kompatibilität zu einem Steckbrettaufbau mit einem bedrahteten TCA4426 microchip.com ⇗. Problem: auch wenn das Compare Register des Timers auf 0xFFFF gesetzt ist, geht der Ausgang für einen Takt auf 0, entsprechend erhält das Gate einen kurzen On-Puls. Keine Ahnung, ob sich das per Registereinstellungen ändern lässt. Am einfachsten nicht invertiert ansteuern.
sn74ahct1g00 ti.com ⇗
BUK545 alldatasheet.com ⇗
Zuerst verwendete ich ein chinesisches LM2596 Modul, auf 5V eingestellt, zur direkten Versorgung der Schaltung. Just vor einer geplanten Vorführung des Aufbaus fiel dann das Prozessorboard aus, beim Anstecken der 24V. Als Ursache vermute ich eine Überhöhung der Ausgansspannung beim irgendwie ungünstigen Anlegen der 24V. Siehe Messungen dazu: LM2596.
In der Schaltung übernimmt jetzt ein analoger Regler die Erzeugung der 5V. Das DCDC Modul erzeugt dessen Eingangsspannung von 8V, damit dieser nur ca. 150mW Leistung verbraten muß.
Pin Farbe Belegung 1 gelb Anode LED (120R nach +5V) 2 grau Versorgung +5V 3 weiß Kanal B 4 grün Kanal A 5 braun GND Die verwendete Scheibe liefert 120 Pulse / Umdrehung.
Es war kein (schneller) 6N138S zur Hand, der normalerweise zur galvanischen Trennung von MIDI verwendet wird. Ein TLP281-Modul erwies sich als zu träge. Verkleinerung einer der Arbeitswiderstände auf 560+150 = 710R konnte dessen Übertragungsgeschwindigkeit soweit erhöhen, dass die 31,25kBaud Kommunikation möglich wurde.
Was zunächst als vorläufige Lösung gedacht war, ist weiterhin im fertigen Gerät enthalten.Eine Sache hielt mich ungebührlich lange auf: der Ausgang des TLP281-Moduls ist gegenüber einem 6N138S invertiert!
Ein kleiner Single-Gate Inverter liegt daher vor dem RX-Eingang der BluePill. A10 ist 5V tolerant, daher ist die Speisung des Inverters mit 5V kein Problem.
gewählt Port Pin Pin Port gewählt Out B12 28 GND In mit Pullup, zur Auswahl
des MIDI-SteuergerätsB13 29 GND B14 30 3V3 B15 31 RST A8 8 27 B11 A9 9 26 B10 RX: Midi Input A10 10 17 B1 A11 11 16 B0 A12 12 7 A7 A15 15 6 A6 Encoder weiß B3 19 5 A5 Encoder grün EXTI4 B4 20 4 A4 B5 21 3 A3 B6 22 2 A2 B7 23 1 A1 B8 24 0 A0 ADC1 opt. Poti für Parametereingaben ~ Motor PWM B9 25 34 C15 5V 33 C14 =1 wenn Interrupt aktiv GND 32 C13 LED 3V3 VBAT 5V tolerant BluePill
Arduino-IDE: 1.8.5. mit der Anpassung von rogerclarkmelbourne Installation ⇗
Das icon iKeyboard erzeugt MIDI-Nachrichten mit Pitches von 36..96 (61 Tasten), beginnend mit C
NOTE_ON. channel: 1, controller #36, value = 106
NOTE_ON. channel: 1, controller #36, value = 0
NOTE_ON. channel: 1, controller #96, value = 94
NOTE_ON. channel: 1, controller #96, value = 0Das MotorPiano hat 44 Tasten, es meldet Pitches von 16 .. 59 (44 Tasten), beginnend mit C.
Das ist keine Übereinstimmung. Mist.Ein Jumper muß über die Einstellung eintscheiden. Durch Verwendung zweier nebeneinander liegender GPIOs bleibt der Verdrahtungsaufwand minimal, nämlich 0.
Mit dem iKeyboard erzeuge ich C2 (65Hz, linke Taste) bis E5 (659Hz).
Für den Index in m_tones[] ziehe ich beim iKeyboard 23 von contoller ab (damit stimmen Tastenwert und Note überein). Die linke Taste sendet 36, 23 abgezogen gibt 13, m_tones[13] = C2.
Für das Motorpiano darf ich also nur 3 abziehen.
nested Interrupts
Takt, Überlauf Prio intern extern Pin Timer4 24MHz, 1024 CH4: MotorPWM PB9 CH3: opt. analoger Ausgang PB8 - ohne angeschlossene Interruptroutine Timer3 1MHz, 1000 14 Überlauf alle 1ms:
- g_millisec inkrementieren
- Regelroutine- - microsec() nutzt den Zählerstand Timer2 1MHz, 65535 3 Überlauf: Motor dreht zu langsam.
zählt die µs ab Encoderflanke.- EXTI4 5 Encoder. max. alle 100µs PB4
Tachometer: Encoderscheibe.
Die resourcensparendste Lösung wäre wohl, einen Timer duirch einen externes Signal automatisch die Zeit zwischen (acht) Encoderflanken messen zu lassen. Die programmiertechnisch einfacher implementierbare Lösung war, Timer2 im Encoderinterrupt auszulesen und neu zu starten:
void encoder () {
static uint32_t encCnt = 0;
encCnt += 1;
if ( encCnt >= 15) {
uint32_t et = Timer2.getCount(); // Timer auslesen
Timer2.setCount( 0); // und neu starten
g_encoderPps = 5000000 / et ;
if ( g_tim2Overflow) {
g_encoderPps = 0;
}
encCnt = 0;
}
}wobei g_tim2Overflow im Timer2 Überlaufinterrupt gesetzt wird. Das Aufsummieren von Encoderperioden erhöht die Genauigkeit, vor allem bei hohen Drehzahlen. 15 Encoderperioden ist die Zeit zwischen zwei Polpulsen (120 / 8 = 15).
Im ersten Ansatz verwendete ich micros() zur Bestimmung der verstrichenen Zeit. Es gab jedoch in den Messergebnissen immer wieder Ausreißer. Der Tiefpass vor PB4 brachte keine Verbesserung. Die Ursache liegt offenbar darin, dass micros() Zählerüberläufe nicht mitbekam, was vermutlich an der Verwendung von micros() innerhalb der Interruptroutine liegt. Nicht erschöpfend untersucht.
Problem: abgelaufene Mikrosekunden bestimmen. Beim Bestimmen der Rotationsgeschwindigkeit mit Strompulsen lief das, jetzt habe ich wieder Ausreißer. Urggh.
Was hilft: die Prio des 1ms Interrupts über die der Encoderroutine setzen - dadurch geht der Überlauf des Zählers garantiert in die g_millisec ein.
Jedoch erledigt der 1ms Interrupt auch die Regelung, welche potentiell so lange dauert, dass Encoderinterrupts verloren gehen!Aus der Interrupttabelle für die BluePill entnehme ich: Prio SysTick = 6. Ich setze Encoderprio = 7, Regelungsprio = 10 und verwende micros(), d.h. den Arduino µs Timer, von dem ich vermute, dass er mit SysTick läuft.
Weiterhin Ausreißer.Kann der Interrupt seine Prio dynamisch verringern?
Idee: mit EXTI4 den Timer2 resetten. Beim nächsten EXTI4 dessen Stand auslesen.
µs, über 8 Flanken aufsummieren. 65536 wird bei 1U/s erreicht.
Bei 3000U/min geht der Zähler noch bis auf 1333 - das erscheint mir ausreichende Auflösung.deepbluembedded.com ⇗ verwendet InputCapture: liest bei beiden Flanken den Timerstand und bildet die Differenz, berücksichtigt die zwischendurch aufgelaufenen Overflow Interrupts.
Leider komme ich mit dem RCM Beispiel nicht klar: wie ordne ich den Eingang zu, wie setze ich den Prescaler auf 8 events?
STM32 Timer Tutorial deepbluembedded.com ⇗ führt auf:Interrupt/DMA generation on the following events:
– Update: counter overflow/underflow, counter initialization (by software or internal/external trigger)
PI-Regler.
Datum Änderung 2024-04-16 angelegt, als Ableger von Motor-tachless In Motor tachless bestimme ich die Drehzahl eines Motors anhand seiner Strompulse, um damit eine Regelung aufzubauen. Um die Regelung erstmal stabil aufzusetzen, schob ich eine Drehzahlmessung mit Encoderscheibe ein. Die damit erzielte Regelung war super.
Mit dieser Schaltung möchte ich Albrecht einen Motor zur Verfügung stellen, der die Drehzahl eines Motors durch Midi gesteuert einstellt.2024-04-18 die Mikrosekunden ohne Slip ermitteln. Ich verwende Timer2 2024-04-21 veröffentlicht 2024-04-26 aufklappbares Inhaltsverzeichnis