Hossa oberallgeier,
ach das meinst du mit der "Entscheidungsschwäche".
Ja, da hast du das gleiche Problem, das auch im Asuro bei den original Bauteilen vorhanden ist.
Hier mal die aus dem waste-Original-Thread gesammelten Daten:
robo.fr gibt in seinem Programm und seiner Tabelle folgendes an:
Code:
OCR2= 254-X Abstand[cm]
0 5
1 7
2 13
3 15
4 16
5 17
6 18
7 22
Ich hatte in der Tabelle ungefähr so etwas:
Code:
OCR2= 254-X Abstand[cm]
0 6
1 14
2 20
3 28
4 32
5 38
6 42
7 47
. .
32 120
Und inka hat laut seinem Beitrag die von mir ermittelten Abstände mathematisch halbiert auf:
Code:
OCR2= 254-X Abstand[cm]
0 3
1 7
2 10
3 14
4 16
5 19
6 21
7 23
. .
32 60
Unterm Strich sind die Programme extrem ähnlich.
Sternthaler und inka sind identisch, außer dass inka die Entfernungsberechnung (aber nicht die Ermittlung) angepasst hat.
robo.fr hat etwas umgebaut (Die Struktur sieht nach meinem Programm aus). Er hat vor allem in der Schleife zum testen von Pin D0, dahingehend geändert, dass 'nur' 30 mal geprüft wird. In der Schleife wird künstlich mit Sleep() gewartet.
Genau dieses Sleep()-Konstrukt hatte ich nach einigen eigenen Tests komplett aus meiner ersten veröffentlichen Version "Chirpen-über-IR" durch Massenmessungen ersetzt. Ich loope über der "teste Pin D0"-Stelle bewusst sehr häufig (1000 mal) ohne Sleep() damit die Statistik "erkannt / nicht erkannt" mit vielen Daten arbeiten kann. Das hatte sich bei mir mit höheren Messanzahlen bzw. mehr Statistik gut bewährt um relativ wenig "Entscheidungsschwäche" zu erhalten. Immerhin hatte ich damit bei mir festgestellt, dass ein 'Umschalten' von einem Entfernungsbereich in den Anderen, immer bei ca. 0,5 cm liegt. Bei einer Auflösung von ca. 3 cm ab ungefähr 40 cm hört sich das zwar nicht gut an, da der Chirp aber immer von 'Nah nach Fern' messen muss, nähern wir uns also immer aus der gleichen Richtung der 'tatsächlichen' Entfernung an, und somit gibt es dort keine Hysterese. Und das 'schlackern' vom Ergebnis am Umschaltpunkt ist nur relativ selten.
robo.fr und inka habe beide ungefähr die gleiche Beziehung zwischen OCR2-Wert und Entfernung. Bei mir ist 'nur' die Skalierung' anders.
Ich hatte ein graues Mauspad an die Wand gestellt und den Asuro, auf dem Fußboden stehend, die Messungen machen lassen.
robo.fr mag gerne Joghurt und nutzt diese Hindernisse.
Als logische Konsequenz muss inka somit auch Joghurt mögen.
Hier sollten wir eventuell mal eine genormte 'Test-Reflektorfläche' definieren und für teuer Geld verkaufen. Haben die Banken ja auch schon lange Zeit gute Erfahrung gemacht die Leute zu veräppeln. Früh genug aus dem Geschäft muss man halt nur aussteigen.
Wenn ich mir nun deinen Programmausschnitt ansehe, und deine Beschreibung dazu durchacker, dann bin ich mir relativ sicher, dass du auf den gleichen Mist gestoßen bist wie ich auch.
Die von dir angesteuerte "Kopier"-Led hängt an Port C0. Die Statistik, die du betreibst, liegt in deinen beiden for(k und n)-Schleifen. Aber auch die Auswertung ist noch innerhalb beider Schleifen. Somit sammelst du keine Daten in einer inneren Messschleife; betreibst Statistik; und schaltest dann nur die LED entsprechend. >= Ergo: Deine LED und natürlich der Oska 'flattern' wie die Weltmeister.
Genau das Problem hatte ich auch zu Anfang, bis ich eben diese Statistik eingebaut hatte und die Auswertung hinter die Statistik-Sammel-Loop gelegt hatte um dann erst daraus die Entfernung/Aktion ("Kopier"-Led) zu machen.
Ich habe das, wie oben schon angedeutet, mit 1000-fachem Statistik sammeln getan. Das entspricht deiner inneren for(m)-Loop. Und robo.fr hat weniger Statistik, verzögert mit einem Sleep() betrieben, und auch dann erst ausgewertet.
Somit ist ein 'flattern' der ermittelten Entfernung nur in der Frequenz reduziert, aber eben durch die Statistik besser 'untermauert'.
Hier noch mal dein Programmstück mit der von mir markierten Stelle, an der du ändern solltest für weitere Tests:
Code:
for (uint16_t k = 0; k <= 1000; k = k + 1)
{
for (uint16_t m = 0; m <= 2000; m = m + 1)
{
tmp = PINB;
if (!(tmp & 0x08)) // Aktionen für gelöschtes Bit
if (istaus > 0)
istaus = istaus--; // heisst: Counter runterzählen
else // .. wenn Bit nicht gelöscht, dann ist es gesetzt
{
inix = istaus; // Dummyaktion
}
else // wenns nicht gelöscht ist, ist es gesetzt :)
if (istaus < 1000)
istaus = istaus++; // also Counter raufzählen bis 1 000
else
{
inix = istaus; // DD doofer Dummy, nix machen
}
} // <==== Hier die Statistik-Sammlung OHNE AUSWERTUNG loopen lassen
// <==== Ab hier erst nach der Datenerhebung diese nun auswerten.
// ##### danach vergleiche was größer ist:
// ##### wenn über xxx, Port einschalten, wenn unter xxx Port ausschalten
if (istaus < 10)
{ // hier die Anweisungen, wenn das Bit gelöscht ist
PORTC &= ~(1<<PC0); // lösche PC0
}
else // .. wenn Bit nicht gelöscht, dann ist es gesetzt
if (istaus > 990)
PORTC |= (1<<PC0); // Setze PC0
else
{
}
// } // <==== Ist nun ueberfluessig
}
Als kleine 'Unschönheit' versaust du dir die Statistik auch noch an 2 Stellen:
1) Variable istaus wird bei dir zwischen 0 und 1000 begrenzt. Damit verlierst du Statistikinformationen.
2) Nach der Auswertung der Statistik machst du keinen Reset auf diese Variable. Du nimmst somit (das begrenzte) Vorgängerergebnis in die nächste Runde mit.
So, mehr Sermon kann ich im Moment nicht mehr von mir geben.
Berichte mal über deine Reflektorfläche(n), die du zum testen nutzt. Nicht die Hand, sondern so etwas wie Mauspads, Füchse oder Joghurtbecher meine ich
Gruß Sternthaler
P.S.: Das mit dem von mir angegebene 'Taktverhältnis von <40%' kommt aus dem I-Net von hier.
Ob ich da mit dem Verstehen klar gekommen bin müßt ihr entscheiden.
Wahrscheinlich ist die Angabe '2theta½: 55 °' eher zuständig. Aber damit kann ich rein gar nix anfangen.
P.P.S.: (Wenn schon lang, dann richtig) Im übrigen gefällt mir deine Platine sehr gut. Stecker deutet auf viele Anwendungsideen hin.
Lesezeichen