Hi gleich nochmal ich... (PIC16F887) Prinzipiell möchte ich feststellen, ob ein Fader (Poti) nach oben oder nach unten bewegt wird... Jetzt wandle ich den Analogwert in einen Digitalen, speicher dieses ab... Führe eine zweite wandlung durch und vergleiche die beiden Werte: Wird das Zirobit gesetzt hat sich nichts bewegt... Wird das Carrybit gesetzt wurde der Regler nach unten bewegt... Wird das Carrybit nicht gesetzt nach oben.... Meine Frage: Geht das so? (haha: bei mir gehts nämlich nicht, aber theoretisch sollte es soch gehen oder) Danke! liebe Grüße Max Berg
Ich würde sagen, dass du so nicht feststellen kannst, ob der Fader bewegt wurde, weil der ADC normalerweise ein bisschen wackelt. Sonst klingt es aber richtig.
Wenn ich aber die sagen wir 2 niedrigsten BIT lösche (vom ADC) dann sollte es gehen?
Hi! Das Problem ist, dass du nicht einfach die niedrigsten Bit löschen kannst, dadurch umgehst du das Problem nur Teilweise. Denn wenn der Wert zwischen 2 Werten springt, die das 3. Bit betreffen (obwohls nur um 1 Bit schwankt kann ja das 3. Bit dabei sich trotzdem ändern). Also: Software"tiefpass" : Letzten Wert speichern, wenn der jetzige sich nur um +/- 2 verändert hat neuen Wert als alten Speichern aber keine Änderung signalisieren. Hat es sich mehr geändert dann den neuen Wert direkt weiternutzen ohne den "Alt" Wert zu ändern. Das funktioniert natürlich nur, wenn man die Glättungsgeschwindigkeit höher als die Fehlergeschwindigkeit aber schneller als die "gewollte Bewegungsgeschwindigkeit" hält, weil man sonst ja Bewegungen verpasst. (Dafür könnte man dann ne 2. Stufe des ganzen einführen, die sich den Wert davor merkt, aber das geht vll zu weit) Matthias PS: Genau diesen Denkfehler habe ich in meinem digitalen Midi-"Mischpult" gemacht - das hat noch ne Software aus meiner AVR Anfangszeit in ASM, die muss mal neu in C :-)
haha arbeite auch gerade an einem Midimischpult =) Danke für deinen Hinweis werd ich mal machen!! Muss das zwar erst verdauen sprich noch zweimal lesen, dann hab ichs aber =) Danke für deine Hilfe!
Max Berg wrote:
> haha arbeite auch gerade an einem Midimischpult =)
Darf man ein paar Eckdaten zu dem Projekt erfahren? Als Hobby-Radioist
und Technikbegeisterter suche ich immer nach interesannten Projekten zum
Modden meines DX 1000. ;)
Gruß
Dominique Görsch
Also eigentlich ganz einfach: Du hast 1 Array (A) mit den Fader-Wertern (8 Bit reicht - also den ADLAR setzen). Dann hast du noch 1 Array (B) mit den "korrigierten" Faderwerten (hier kannst du auch 8 Bit speichern effektiv nutzen wir aber weniger als in A). Jetzt liest du periodisch deine Fader ein: temp = ADC. dann vergleichst du temp mit dem Wert des Faders in A. Ist der Betrag der Differenz > 1 (also der Unterschied mehr als 1), so wird der neue Wert nach A und B gespeichert. Ist die Differenz nur 1 (oder 0...), so wird der neue Wert nur nach A gespeichert. Da bei "nur" 8 Bit, sofern du den ganzen Bereich des ADCs ausnutzt, das Rauschen von ADC und Poti an sich ("Zwischenstellung") schon fast 0 ist, sollte dieser Differenzvergleich mit 1 reichen, man kann aber statt 1 z.B. auch 3 nehmen (sofern einem denn dann unterm Strich ~ 6 Bit Auflösung reichen), dann wird das ganze garantiert komplett ruhig sein. Das einzige Problem dieser Lösung ist, dass wenn du das Poti so langsam bewegst, dass du sozusagen "gewollt" immer nur um "1 Bit" hochschiebst, so kommt diese Änderung niemals in Array B an. Das dürfte jedoch sehr unwahrscheinlich sein - seien 256 Werte auf 10 cm aufgeteilt, so haben wir 0,4 mm pro Bit - wer verschiebt das Poti gewollt über längere Zeit nur um 0,4 mm pro Samplezeit? (Natürlich darfst du dann NICHT mit 1 MHz oder so samplen - 100 Hz sollten selbst für schnellste Cutoffs oder so ausreichen). (-Gedankengang der eigtl. überlesen werden kann Die Erweiterung des ganzen mit einem Array C sieht dann so aus: Ausgangszustand, A = B = C. Wird jetzt gesampled und durch die zu kleine Differenz zu A festgestellt das wir die Änderung NICHT nach B übernehmen wird zusätzlich noch mit C verglichen. Ist hier die Änderung ebenfalls <=1 so übernehmen wir nach wie vor nicht. Ist nun aber die Änderung z.B. 2 so wird der neue Wert nach B und C gespeichert -Gedankengang ende) Und wie ich so beim Schreiben bin fällt mir auf, dass C eigentlich auch B sein kann - also: Stellen wir durch A fest, dass die Änderung nicht nach B kommt so vergleichen wir den neuen Wert nochmal mit B. Ist er größer als eine Schranke so übernehmen wir ihn doch nach B :-) Verständlich ausgedrückt? :-) Ich jedenfalls werde das so implementieren.
Aber gerne doch... Um genau zu sein arbeite ich an einem DAW-Controller (DAW = Digital Audio Workstation) Ist ja im Pronzip das selbe nur werden weniger MIDI-Effekte gesteuert sondern sämtlich Parameter einer DAW (das heist Mute, Solo, Record,..etc das üblich halt) Naja ich arbeite mit Cakewalk Sonar und habe für dieses ein Plugin geschrieben, und jetzt muss ich halt schaun das ich meine Hardware dazu bastel =) Habe einen PIC18F4550 als "Midi - USB converter".. an diesem angeschlossen [auf der midiseite] ist ein PIC16F887 als Master für einen I2C Bus... Und dieser Fragt 8 Slaves [auch PIC 16F887] ab (das heißt die gesetzten Werte wie Solo, mute..balbala... ) Habe schon fertig alles Buttons [kann alles prima steuern] Habe fertig die Rotary switches [für Pan, EQ, etc] und hänge an den fadern :) (Wie wertet man diesen Touch sense aus??) Bei fragen stehe ich gerne zu verfügung =) Liebe Grüße Max
@Matthias Larisch kleine Frage... Was sind die "korrigierten" werte? Tut mir leid bin etwas schwer von begriff.. aber ansonsten glaub ich hab ich das konzept durchschaut!
Das hab ich nur so genannt... Pseudocode:
1 | #define Potis 10
|
2 | #define temp_schwelle 1
|
3 | #define absolut_schwelle 2
|
4 | |
5 | int Potiwerte[Potis]; |
6 | int Poti_temp_werte[Potis]; |
7 | int i, temp; |
8 | |
9 | for(i=0;i<Potis;i++) |
10 | {
|
11 | ADC_SELECT_POTI_CHANNEL(i); |
12 | temp = ADC_READ(); |
13 | if((abs(temp - Poti_temp_werte[i]) > temp_schwelle) || abs(temp - Potiwerte[i]) > absolut_schwelle)) |
14 | Potiwerte[i] = temp; |
15 | Poti_temp_werte[i] = temp; |
16 | }
|
Hilft das? :-) Neuer Potiwert wird gesetzt, wenn er vom zuletzt gemessenen Wert um mehr als 1 abweicht oder von zuletzt gespeicherten Wert um mehr als 2. Bei genauerer Überlegung ist das schon wieder Käse, weil es reichen würde, den Wert zu speichern wenn er vom zuletzt gespeicherten um mehr als 2 abweicht... Was fabriziere ich hier für einen Mist? Irgendwie Denkblockade gehabt^^ also:
1 | for(i=0;i<Potis;i++) |
2 | {
|
3 | ADC_SELECT... |
4 | temp = ADC(); |
5 | if(abs(temp - Potiwerte[i]) > absolut_schwelle) |
6 | Potiwerte[i] = temp; |
7 | }
|
Sorry für die Verwirrung. Oder hab ich jetzt nen Denkfehler gemacht?
oh danke das ist perfekt =) Da checks ja ich sogar auch =) Das alpha und omega wäre es in PIC assembler und das am besten für einen PC16F887 ^^ haha na scherz! Danke für deine Hilfe!
Tja es scheitert doch echt am assembler =) So einfach ist das ganze kleiner da größer da und dann vergleiche wenn das um das größer ist doch nicht =)
Hmm, also soo schwer ist das doch nicht, in AVR Assembler würde ich nen Vergleich auf
so machen:
1 | mov r1, alter_wert |
2 | mov r2, neuer_wert |
3 | sub r2,r1 ;r2 = neu - alt |
4 | brpl positiv ; ergebnis ist bereits positiv -> vergleichen |
5 | neg r2 ; ergebnis war negativ: zweierkomplement und dann vergleichen |
6 | |
7 | positiv: |
8 | cpi r2, schwelle |
9 | brlo nicht_uebernehmen |
10 | ;rjmp uebernehmen |
11 | |
12 | uebernehmen: |
13 | ;wert aktualisieren |
14 | |
15 | nicht_uebernehmen: |
16 | ;wert nicht aktualisieren (bzw. nichts tun) |
Ist jetzt nicht getestet, sollte es aber tun. brpl springt, wenn Negativ-Flag nicht gesetzt (Negativ Flag wird gesetzt, wenn beim Subtraktionsergebnis das MSB gesetzt ist). brlo springt, wenn r2 kleiner als schwelle ist bei dem cpi dadrüber. Warum willst du das in Assembler programmieren?
OH Man Leute ich wollte euch mal danke! hatte schon alles probiert sieht man ja an der Uhrzeit. Ich weiss ist schon ein alter thread. Aber super danke Matthias Larisch. peace Felix
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.