Forum: Mikrocontroller und Digitale Elektronik Fader auswerten


von Max B. (maxberg)


Lesenswert?

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

von Dussel (Gast)


Lesenswert?

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.

von Max B. (maxberg)


Lesenswert?

Wenn ich aber die sagen wir 2 niedrigsten BIT lösche (vom ADC) dann 
sollte es gehen?

von Matthias L. (matze88)


Lesenswert?

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 :-)

von Max B. (maxberg)


Lesenswert?

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!

von Dominique G. (dgoersch)


Lesenswert?

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

von Matthias L. (matze88)


Lesenswert?

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.

von Max B. (maxberg)


Lesenswert?

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

von Max B. (maxberg)


Lesenswert?

@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!

von Matthias L. (matze88)


Lesenswert?

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?

von Max B. (maxberg)


Lesenswert?

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!

von Max B. (maxberg)


Lesenswert?

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 =)

von Matthias L. (matze88)


Lesenswert?

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?

von Flex (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.