Hallo zusammen,
ich hoffe auf eure Hilfe bei einem kleinen Problem.
Aus AD-Wandlungen müssen viele Daten zwischengespeichert und ausgewertet
werden.
Das bisherige Variablenarray sieht folgendermaßen aus:
uint16_t temp_i16[1024][3];
Bei einer 16-Bit-Interger Variable bleibt einfach zuviel Speicher
ungenutzt.
Eine uint10_t Variable wäre mir am liebsten :)
Freue mich über jede Ideen und jeden möglichen Lösungsansatz.
Gruß Timo
wenns dir nicht auf rechenzeit und programmgröße ankommt sondern
wirklich auf minimalen speicher dann kannst du doch aus je 4 10bit
werten die "überflüssigen" 2 bit in ein neues byte packen, also aus 4
10bit variablen 5 8bit variable. könnte aber programmiertechnisch
aufwendig werden
Mit viel Aufwand könntest du in Assembler was basteln.
noch rel. einfach: 3 Byte für 2 Messwerte, also mit nibblen arbeiten.
Kannst selbstverständlich kannst du auch in 5Byte 4 Messwerte
unterbringen.
Mit einem Compiler sehe ich da kaum eine Chance.
Du solltest dann entweder in Richtung mehr RAM denken oder über
Datenreduktion nachdenken.
Das einfachste Verfahren: du speicherst je Messwert nicht die vollen
10bit, sondern nur die Differenz zum vorherigen. Je nach Signalform und
Abtastrate reicht das schon. Ist die Differenz zu gross, setzt du als
Wert 0xff, der nächste Wert ist dann wieder ein Absolutwert.
die 2 High-Bytes liest du ja getrennt aus, also würde ich diese extra
abspeichern. Immer 4 in einem Byte. Berechnung über MOD 4 aus der
Speicherstelle.
Hab mir eine mögiche Lösung ausgedacht.
Sie ist nicht schön... nicht kurz... und eigentlich nur aufwendig!
Da für jeden neuen Messwert mehrere If-Abfragen durchlaufen werden, ist
diese Lösung nichts für gute Performance. Die ständigen Berechnungen und
das laufende Setzen von Dateninhalten, wirken sich bestimmt auch nicht
vorteilhaft aus :)
Eure Meinungen zu dieser Wurst würden mich aber interessieren!
Gruß Timo
#include<avr/io.h>
//Globale Variable für 1024 Messwerte:
uint8_t messwerte[1024][4];
//
void bit16to10(uint16_t temp_i16_adc, uint16_t messwert_nr)
{
if(temp_i16_adc>255)
{
if(temp_i16_adc>510)
{
if(temp_i16_adc>765)
{
messwerte[messwert_nr][0]=255;
messwerte[messwert_nr][1]=255;
messwerte[messwert_nr][2]=255;
messwerte[messwert_nr][3]=temp_i16_adc-765;
}
else
{
messwerte[messwert_nr][0]=255;
messwerte[messwert_nr][1]=255;
messwerte[messwert_nr][2]=temp_i16_adc-510;
messwerte[messwert_nr][3]=0;
}
}
else
{
messwerte[messwert_nr][0]=255;
messwerte[messwert_nr][1]=temp_i16_adc-255;
messwerte[messwert_nr][2]=0;
messwerte[messwert_nr][3]=0;
}
}
else
{
messwerte[messwert_nr][0]=temp_i16_adc;
messwerte[messwert_nr][1]=0;
messwerte[messwert_nr][2]=0;
messwerte[messwert_nr][3]=0;
}
}
uint16_t bit10to16(uint16_t messwert_nr)
{
uint16_t temp_i16_1=0;
temp_i16_1 = messwerte[messwert_nr][0] + messwerte[messwert_nr][1] +
messwerte[messwert_nr][2] + messwerte[messwert_nr][3];
return temp_i16_1;
}
int main(void)
{
uint16_t temp_i16_1=780;
//Abspeichern der 10-Bit ADC in 4 8-Bit Variablen:
bit16to10(temp_i16_1,0);
//Überschreiben des temporäre Wertes:
temp_i16_1=22;
//Wiederherstellen der ADC:
temp_i16_1=bit10to16(0);
}
Das ist jetzt aber nicht dein Ernst?
Eine 10 Bit Variable wird gespeichert indem du 4 Bytes
dafür verbrätst ?!?
Da bist du ja noch besser drann, wenn du
uint16_t messwerte[1024];
benutzt.
> if(temp_i16_adc>765)> {> messwerte[messwert_nr][0]=255;> messwerte[messwert_nr][1]=255;> messwerte[messwert_nr][2]=255;> messwerte[messwert_nr][3]=temp_i16_adc-765;> }> temp_i16_1 = messwerte[messwert_nr][0] +> messwerte[messwert_nr][1] +> messwerte[messwert_nr][2] +> messwerte[messwert_nr][3];
So irgendwie hast du noch nicht durchschaut was es mit
einem Stellenwert-System so auf sich hat.
Bei 1456 haben die einzelnen Stellen unterschiedliche
Wertigkeiten! Um die Zahl zu erhalten rechnest du ja
auch nicht 1 + 4 + 5 + 6
sondern 6 + 10 * 5 + 100 * 4 + 1000 * 1
Das ist jetzt im 10-er System. Mit Bytes hast du halt ein
256-er System.
Wichtig sind nur 1024 Messungen mit 10-Bit (ADC)
> Bei 1456 haben die einzelnen Stellen unterschiedliche> Wertigkeiten! Um die Zahl zu erhalten rechnest du ja> auch nicht 1 + 4 + 5 + 6> sondern 6 + 10 * 5 + 100 * 4 + 1000 * 1
Ich glaube nicht, dass du das System der Funktion verstanden hast.
Die ADC ergibt Werte bis 1023 (10 Bit)
Mit einer 16-Bit Variable können Werte bis 65535 gespeicher werden.
Somit verschenke ich 1024 mal massig Speicherplatz!
In den Variablen messwerte[messwert_nr][0] bis
messwerte[messwert_nr][3]
Teile ich die max. 1023 auf 4 Variablen (8-Bit) auf. Da diese Variablen
Werte bis 255 Speichern können, addiere ich am Ende der Rückgabefunktion
alle Inhalte und erhalte den Ausgangswert. Diesen Wert gebe ich mir
return zurück.
Für die Abspeicherung der 10-Bit Messwerte benötigt man somit 4*8-Bit
Variablen und nicht eine mit 16-Bit.
Dies hat nichts mit der Stellenwertigkeit des Messwertes zutun.
Berichtige mich bitte,wenn ich nur Müll von mir gebe.
Timo
>Mit einer 16-Bit Variable können Werte bis 65535 gespeicher werden.>Somit verschenke ich 1024 mal massig Speicherplatz
Interessante Annahme. Es sind aber nur 6Bit...
>Für die Abspeicherung der 10-Bit Messwerte benötigt man somit 4*8-Bit>Variablen und nicht eine mit 16-Bit.
Da braucht man zum speichern von 10Bit auf einmal 32...
Interessant.
Lernt man Multiplikation und sowas nicht in der Grundschule?
4*8 = 32 = 2*16...
>Berichtige mich bitte,wenn ich nur Müll von mir gebe.
Berichtigung...
Vielleicht solltest du dir mal das binäre Zahlensystem genauer angucken.
Dass man inzwischen auch Bits komprimieren kann, wusste ich bis jetzt
noch nicht.
>> Bei 1456 haben die einzelnen Stellen unterschiedliche>> Wertigkeiten! Um die Zahl zu erhalten rechnest du ja>> auch nicht 1 + 4 + 5 + 6>> sondern 6 + 10 * 5 + 100 * 4 + 1000 * 1>> Ich glaube nicht, dass du das System der Funktion verstanden hast.
Ich glaube nicht, dass du das binäre System oder
Zahlensystem im Allgemeinen verstanden hast.
> Teile ich die max. 1023 auf 4 Variablen (8-Bit) auf
1023 kann mit 10 Bit dargestellt werden.
4 Variablen zu je 8 Bit macht aber in Summe 32 Bit.
Du willst mir doch jetzt nicht erzählen, dass es effizienter
ist, 10 Bit in insgesammt 32 Bit zu speichern anstatt in
einer Variable die 16 Bit gross ist.
Wenn du
uint16_t messwert[1024]
als Speichermedium benutzt, 'verschenkst' du bei jedem
Messwert 6 Bit
Wenn du
uint8_t messwert[1024][4]
als Speichermedium benutzt, 'verschenkst' du bei jedem
Messwert 22 Bits
Was ist also effizienter?
> Für die Abspeicherung der 10-Bit Messwerte benötigt man somit 4*8-Bit> Variablen und nicht eine mit 16-Bit.
Den Satz solltest du dir nochmal auf der Zunge zergehen
lassen.
Um 10 Bit abzuspeichern kann ich jeden Datentyp nehmen
der größer oder gleich 10 Bit ist. Und dann nehme ich
vorzugsweise den Datentyp der möglichst wenig über den
10 Bit liegt.
> und die 1024 Messwerte 'vertikal' zu speichern
Bring ihn nicht durcheinander :-)
Er hat so schon grosse Schwierigkeiten zu verstehen
wie ein Zahlensystem im Allgemeinen funktioniert.
@Timo
Das was du gemacht hast, ist equivalent zu:
Du musst dir merken wieviele Schafe auf der Weide sind.
Dazu sperrst du sie immer in 255-er Gruppen in eine
Koppel. Anschliessend sagst du: Um rauszukriegen wieviele
Schafe das sind, gehe ich alle Koppeln durch und addiere
die Anzahl der Schafe in jeder Koppel.
So funktionieren Zahlensysteme aber nicht. Ein Stellenwert-
system funktioniert anders. Es sagt: Wieviele Koppeln
sind denn mit 255 Schafen voll? Aha. Ich habe insgesammt
3 volle Koppeln und 1 Koppel mit 12 Schafen. Insgesamt
habe ich also: 3 * 255 + 12 gleich 777 Schafe. Um mir
das merken zu können brauche ich mir aber nur die Zahlen
3 und 12 zu merken. Nicht: 255, 255, 255, 12
Dieser Übergang vom:
In einem Beutel mit Steinen repräsentiert jeder Stein ein
Schaf. Wenn die Schafe auf die Weide gehen wird ein Stein
in den Beutel geworfen; wenn das Schaf nach Hause kommt
wird ein Stein aus dem Beutel genommen. Ist der Beutel
leer, so sind wieder alle Schafe zu Hause
zu
Für jeweils 10 Schafe wird ein Stein aus dem Beutel genommen
und dafür ein Stein in einen anderen Beutel getan (der
dann jeweils 10 Schafe repräsentiert). Ansonsten bleibt
alles andere gleich
..., dieser Übergang ist die Geburtsstunde der Mathematik
in der Menschheitsgeschichte. Ohne ihn würden wir heute
nicht dort sein, wo wir heute sind. Das ist die Geburtsstunde
eines Stellenwertsystems wo die gleichen Ziffern unterschiedliche
Dinge bedeuten, jenachdem an welcher Stelle einer Zahl sie
eingesetzt werden. Und es unterscheidet sich fundemental von
simplen Abzählsystemen.
@Karl heinz Buchegger
> ..., dieser Übergang ist die Geburtsstunde der Mathematik> in der Menschheitsgeschichte. Ohne ihn würden wir heute> nicht dort sein, wo wir heute sind.
Kurz vor dem Abgrund?
;-)
MFG
Falk
Falk wrote:
> @Karl heinz Buchegger>>> ..., dieser Übergang ist die Geburtsstunde der Mathematik>> in der Menschheitsgeschichte. Ohne ihn würden wir heute>> nicht dort sein, wo wir heute sind.>> Kurz vor dem Abgrund?>> ;-)
Wie ich immer sage:
Diesem Planeten kann nichts besseres passieren,
als dass wir uns selbst ausrotten.
Sagt ein Planet zum anderen
"Mir gehts gar nicht gut. Ich hab Homo Sapiens."
Sagt der andere
"Das geht vorbei"
:-)
Ich muss zugeben... ein sehr dummer Denkfehler von mir.
Egal sag ich da nur! :)
Fie Geschichte mit den Schafen hätte man sich sparen können. Hatte
meinen Irrtum bereits erkannt:
> Datum: 10.01.2007 16:10> man darf sich ja auch mal irren, oder?
Auch wenn meine "Lösung" sehr dürftig und völlig am Ziel
vorbeigeschossen ist, sollte das noch kein Grund sein sich über die
betreffene Person(diesmal leider Ich) lustig zu machen!
Warscheinlich sitzt ihr einfach schon zu lange am Computer und schaut
nur aus dem Kellerfenster...
Ich habe mir dazu folgendes ausgedacht 3x10bit in eine 32bit Variable,
man Verliert jeweils 2 Bits bei 1024 werten sind das also ca. 85.5byte
verlust.
Man brauxht also 1024/3=341.3 ~ 342x32bit Variablen: uint32_t temp[342]
und das macht 1368Byte anstatt 2048 wenn man einfach ein uint16_t Array
verwendet.
Hier beispiel:
1
#include<stdio.h>
2
#include<inttypes.h>
3
4
intmain()
5
{
6
7
uint32_ttemp,var32;
8
/*es werden hoestens 10bit verwendet*/
9
uint16_ta=342,b=1023,c=987;
10
11
/*3 10Bit a,b,c Variablen in eine 32Bit Variable codieren*/
12
var32=0;
13
14
temp=a;
15
temp=temp<<20;
16
var32|=temp;
17
18
temp=b;
19
temp=temp<<10;
20
var32|=temp;
21
22
temp=c;
23
temp=temp<<0;
24
var32|=temp;
25
printf("a:%u b:%u c:%u\n",a,b,c);
26
27
/*3 10Bit Variablen aus einer 32Bit Variable decodiern*/
28
temp=var32;
29
temp=temp>>20;
30
a=temp&0x3ff;
31
32
temp=var32;
33
temp=temp>>10;
34
b=temp&0x3ff;
35
36
temp=var32;
37
temp=temp>>0;
38
c=temp&0x3ff;
39
printf("a:%u b:%u c:%u\n",a,b,c);
40
41
return0;
42
}
Das funktioiert vorausgesetzt der Compiler trimmt die Arrays nicht auf
Werte 2^N.
> sollte das noch kein Grund sein sich über die> betreffene Person(diesmal leider Ich) lustig zu machen!
Ich mach mich doch nicht über dich lustig.
Das würde dann etwas anders aussehen.
Mir ist nur wichtig, dass du auch verstehst wo und
vor allen Dingen warum du falsch liegst und ev.
noch ein paar Dinge zum drüber nachdenken dazuzumixen.
Man kann sehr viele Dinge lernen wenn man die ganz
banalen Dinge im Leben beobachtet wie zb. wie sind
eigentlich unsere Zahlen aufgebaut, welche Eigenschaften
liegen da zugrunde. Diese Dinge sind ganz banal und einfach,
nur entdecken muss man sie erst mal.
Genauso wie ich ein eifriger Verfechter des 'gesunden
Hausverstandes' bin. Und der Hausverstand muss Alarm schlagen
wenn ich die Idee verteidige 10 bit in 32 bit zu speichern.
Aber hey. Ich verenne mich auch manchmal in Ideen bis jemand
kommt und sagt: Geh mal 2 Schritte zurück und schau dir das
nochmal an. Das kann so nicht sein, weil ...
>Ich mach mich doch nicht über dich lustig.
Ich aber.
Wer s0lchenen Mist verzapft, hat es meiner Meinung nach nicht anders
verdient. Zumindest wurde ich bisher genauso behandelt...
>Warscheinlich sitzt ihr einfach schon zu lange am Computer und schaut>nur aus dem Kellerfenster...
Mein PC steht auf dem Dachboden.
Wenn die Sonne scheint und das Wetter es zu lässt (die Sonne scheint
grundsätzlich, es sind nur häufig viele Wolken dazwischen, die auch noch
Pipi machen...), setze ich mich mit meinem Notebook auch gerne in den
Garten.
>Ok,Ok Arschloch.>Höflichkeit ist wohl nicht eine deiner Stärken...
Zumindest bin ich nicht ausfallend geworden...
Hallo
Jetzt mal zurück zur eigentlichen Frage.
Warum speicherst du denn die kompletten 10 bit ?
Wenn du die oberen 8 Bit speicherst, hast du eine Genauigkeit die in den
meisten Fällen wohl ausreichen wird.
Mindestens das letzte, wenn nicht sogar die letzten beiden Bits sind
sowieso durch das Signalrauschen am Eingang unbrauchbar.
Und somit benötigst du nur N * 1 Byte.
Woher willst du wissen, dass da so ein riesen Rauschen gibt, dass bei
10Bit Auflösung 1 oder 2 bits unbrauchbar sein sollen?
Wenn der Messbereich z.B 0-2V liegt, dann beträgt die Auflösung etwa
2mV, meistens ist doch das Rauschen erheblich kleiner.
1.
Les mal die Spec vom ADC. In (fast ) jeder Spec steht drin das die
Wandlung mit der Genauigkeit von +- 1 Bit erfolgt.
2.
Die Messung ist nur so genau wie die Referencespannung, d.h. Istzde Ref
Spannung von einem zb 7805 ist dort ein größerer Fehler drauf als wenn
es eine präzise Spannungsreference ist. Eine solche präzise
Spannungsreference ist vom Preis mit Sicherheit außerhalb einer
einfachen Bastelschaltung.
Super, wie sich hier gefetzt wird.
Ich habs jedenfalls gleich verstanden, was er meinte:
10 Bit in 16 Bit ergibt 37% Verlust
3 Worte a 10 Bit in 32 Bit aber nur 6%.
Ich denke aber eher, die Optimierung sollte besser an anderer Stelle
ansetzen:
Warum müssen unbedingt 3 * 1024 Meßwerte gespeichert werden ?
Wenn man diese Zahl verringert (Vorverarbeitung, Differenzspeicherung),
dann spart man wirklich was.
Peter
> Warum speicherst du denn die kompletten 10 bit ?> Wenn du die oberen 8 Bit speicherst, hast du eine Genauigkeit> die in den meisten Fällen wohl ausreichen wird.
Sehr pessimistisch. Was aber wohl richtig ist: in den meisten
Anwendungen wird keine so hohe relative Auflösung gebraucht, d.h. bei
Werten über 100 interessiert das letzte Bit nicht mehr usw.
In solchen Fällen kann man mit sehr wenig Aufwand eine 10-Bit-Zahl in 6
Bit plus 2 Bit Exponent umwandeln, die dann in einem Byte gespeichert
wird. Dann hat man bei kleinen Signalen noch einen Wert, bei größeren
Werten sinkt die absolute Genauigkeit, aber die relative Auflösung
bleibt.
Habe ich nie verstanden, weshalb das z.B. bei der Audio-CD nicht so
gemacht wurde (z.B. 12 Bit Mantisse + 4 Bit Exponent statt 16
Bit-Integer). Im Fortissimo werden Bits verplempert für Feinheiten, die
für das Ohr nicht wahrnehmbar sind, dafür hört man im Pianissimo das
Quantisierungsrauschen. Ist doch doof! Unser Ohr funktioniert relativ!
Zurück zum Thema: die Mantisse/Exponent-Codierung trägt auch dem Umstand
Rechnung, daß eine der größten Fehlerquellen die Nichtlinearität ist,
bei großen Werten ist die letzte Stelle also noch deutlich weniger wert.
> Ich habs jedenfalls gleich verstanden, was er meinte:>> 10 Bit in 16 Bit ergibt 37% Verlust> 3 Worte a 10 Bit in 32 Bit aber nur 6%.
Nur hat er das nicht implementiert :-)
Er hat 1 Wort a 10 Bit in 32 Bit
> Ich denke aber eher, die Optimierung sollte besser an anderer Stelle> ansetzen:>> Warum müssen unbedingt 3 * 1024 Meßwerte gespeichert werden ?
Jetzt kommt der Clou.
Es sind gar nicht 3*1024 Messwerte.
Es sind nur 1024 Messwerte. Aber er hatte jeden Messwert auf 3
uint16 verteilt.