Tartalom:
- Külső és belső memóriában történő numerikus adattárolás kényelmes megoldásai
- Memória cellák létrehozása
- Egyszerű adattárolás, összegzés, átlagolás, minimum és maximum érték képzés a tároló cellában
- Teljes forráskód, példa program
———————————————————————————————
Az utóbbi időben rákényszerültem külső memória használatára. Ennek kapcsán írtam egy olyan univerzális tároló függvényt, amivel különböző típusú adatokat lehet tárolni. Nem pusztán tárolja az adatokat, átlagol, minimum maximum értéket képez stb. Csak dobálom be az adatokat, és az jön ki, amire kíváncsi vagyok. Még egy érdekessége van ennek a programnak. A fiam elmagyarázta, hogyan lehet úgy használni egy függvényt, hogy meghíváskor a paraméterek száma különböző lehet, és ettől függően mást is csinál. A függvényt multimemo-nak neveztem el. 73 különböző adatot tud tárolni egy 512 byte-os ram-ban. Mind a 73 tároló cellája (én neveztem el így) különböző módon viselkedik, beállítható módon automatikusan képzi a bedobált adatoknak a minimumát, maximumát, átlagát, összegét, vagy csak simán az adatot is képes tárolni. Egy cella egyféle módon állítható be, ez gondolom egyértelmű. Meghívása nagyon kényelmes, így néznek a ki a különböző esetek:
- multimemo(cím,tipus) – létrehoz egy megadott típusú memória cellát (setup és reset)
- multimemo(cím,adat) – beír egy adatot a cím-el megadott cellába (write)
- multimemo(cím) – kiolvas a cimről egy adatot (read)
Miközben írtam a programot megtanultam használni az „enum” felsorolás típusú változók használatát is. Sokat segített a program megírásában és áttekinthetőségében, nem kell kódokat megjegyezni, kevésbé fordult elő, hogy összekevertem azokat a bizonyos kódokat.
A multimemo használat igen egyszerű! Meghívjuk a függvényt a cím és a típus megadásával. Ekkor létrejön a tároló cella, megjegyzi a saját típusát és alaphelyzetbe áll. Az alaphelyzet nem feltétlenül nulla tartalmat jelent, mert pl. a minimum tároló cella esetében a long típus lehetséges legnagyobb értékét kell megadni, hiszen ez a cella csak akkor tárolja a megadott tartalmat, ha az kisebb mint az éppen tárolt érték. Úgy írtam meg a függvényt, hogy ebben az alap állapotban 0-át ad vissza, de ha egyetlen értéket is megadsz, már rögtön az lesz a minimum. Az átlagoló cellánál az átlag képzéséhez a beírás számlálót is törölni kell alaphelyzetbe állításkor.
Ezt követően, már csak írogatni kell az adatokat. Ha meghívod a függvényt két paraméterrel, a címmel és az adattal, akkor történik aminek történnie kell. Itt egy kicsi összefoglaló az egyes típusok működéséről:
- MIN típusú cella: A tároló cella a beadott adatok közül mindig csak azt tárolja, ami kisebb az aktuálisan tárolt értéknél. Kezdő értéke 2.147.483.647, de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja visszaadni (vagy ha az lesz kisebb akkor azt). A 2.147.483.647 értékre mindig 0-at ad vissza, így a tárolható értéktartomány -2.147.483.648-tól 2.147.483.646-ig!
- MAX típusú cella: A tároló cella a beadott adatok közül mindig csak azt tárolja, ami nagyobb az aktuálisan tárolt értéktől. Kezdő értéke -2.147.483.648, de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja visszaadni (vagy ha az lesz nagyobb akkor azt). A ‑2.147.483.648 értékre mindig 0-at ad vissza, így a tárolható értéktartomány -2.147.483.647-tól 2.147.483.647-ig!
- SUM típusú cella: A tároló cella a beadott adatot hozzáadja az aktuális értékhez, így mindig az adatok összegét tudjuk. Kezdő érték 0.
- AVG típusú cella: A tároló cella átlag érték tárolásra lesz használva. Ha beleírunk egy értéket, akkor azt hozzáadja az előzőleg tárolt értékhez, de növeli a beírások számlálóját is. Ha lekérdezzük majd a cella tartalmát, a tárolt szumma érték és a beírás számláló hányadosát (azaz az átlagot) adja vissza. Beírást követően azonnal visszaadja az új átlag értéket. Csak egész értékeket lehet megadni, tehát ha tizedes értékekkel akarunk számolni a 10, 100 stb. szorosát adjuk meg, és kiolvasáskor ugyanannyival osztanunk kell (float-ra alakítva az eredményt). A hányados képzéskor egészre kerekít vagyis pl. 32,666-ra 32-őt ad vissza és nem 33-at, ami kerekítéssel helyes lenne. Erre esetleg érdemes figyelni. Ezért pontosabb eredményt kapunk, ha tizedesek számában többet használunk mint amit a pontosság megkövetel. Tehát egy tizedes pontosság esetén 100-al szorozzunk tároláskor, és 100-al osszunk kiolvasáskor.
- STO típusú cella: A beírt adat tárolásra kerül. Nem csinálunk vele semmit, csak tároljuk és kiolvasáskor visszaadjuk. Egy új adat beírásakor a régi felülíródik.
Írás után a függvény visszaadja a tároló cella új tartalmát. Ez ugyanaz, mintha kiolvasnánk a benne tárolt értéket.
Írtam egy demó programot a működés bemutatására. A setup részben csak néhány egyszerű művelettel mutatom be a működést. A loop-ban már véletlen szám generálással próbálkoztam. A véletlen szám generálás tulajdonságairól is szereztem tapasztalatokat, ezzel majd a végén még foglalkozok egy kicsit.
Íme a forráskód:
#include <Wire.h> //Az i2c címet az A2 és A1 kivezetések állapota határozza meg //Például, ha A2 = VCC és A1 = GND, írjunk: FRAM fram (0b10); byte A0A1=0b00; byte _i2cAddress= (0b101000 | A0A1)<<1; //_i2cAddress= (0b101000 | Address)<<1; //byte _i2cAddress= 0b1010000; byte Page=0; String anev; enum cella_tipus { MIN, MAX, SUM, AVG, STO }; long szam; void setup() { Wire.begin(); Serial.begin(9600); Serial.println("reset..."); multimemo(0,MIN); // A 0. fram cella minimum érték tárolásra lesz használva. Kezdő értéke 2.147.483.647, // de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja // visszaadni (vagy ha az lesz kisebb akkor azt). A 2.147.483.647 értékre mindig 0-at ad vissza // Az értéktartomány -2.147.483.648-tól 2.147.483.646-ig! multimemo(1,MAX); // A 1. fram cella maximum érték tárolásra lesz használva. Kezdő értéke -2.147.483.648, // de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja // visszadni (vagy ha az lesz nagyobb akkor azt). A -2.147.483.648 értékre mindig 0-at ad vissza // Az értéktartomány -2.147.483.647-tól 2.147.483.647-ig! multimemo(2,SUM); // A 2. fram cella szumma érték tárolásra lesz használva. Ha beleírunk egy értéket // az mindíg hozzáadódik az addig tárolt adathoz, és az lesz a következő tárolt érték. // Kezdő tárolt adat 0. multimemo(3,AVG); // A 3. fram cella átlag érték tárolásra lesz használva. Ha beleírunk egy értéket, akkor azt hozzáadja // az előzőleg tárolt értékhez, de növeli a beírások számlálóját is. Ha lekérdezzük majd a cella // tartalmát, a tárolt szumma éréték és a beírás számláló hányadosát (azaz az átlagot) adja vissza. // csak egész értékeket lehet megadni, tehát ha tizedes értékekkel akarunk számolni a 10, 100 stb. // szorosát adjuk meg, és kiolvasáskor ugyanannyival osztunk (float-ra alakítva az eredményt). // A hányados képzéskor egészre kerekít vagyis pl. 32,666-ra 32-őt ad vissza és nem 33-at, ami // kerekítéssel helyes lenne. Erre esetleg érdemes figyelni. Érdemes tizedesek számában többet // használni mint amit a pontosság megkövetel, tehát egy tizedes pontosság esetén 100-al szorozzunk tároláskor, // és 100-al osszunk kiolvasáskor. multimemo(4,STO); //A 4. fram cella tárolásra kerül. Nem csinálunk vele semmit, csak tároljuk. Serial.println("tárolás..."); // Sokféle értéket írunk a cellákba, hogy láthassuk a működést. A visszaadott érték a beírást // követő cella tartalmat adja vissza. Ha írni akarunk egy tároló cellába, akkor két paramétert // adunk meg, a cella címét és a tárolandó adot. Az adatot nem tároljuk, hanem értékeljük és tárolunk // attól függően, hogy milyen típusú a tároló cellánk. A cella típusát reseteléskor (alap beállításkor) // adjuk meg. Lásd előbbi két paraméteres meghívás, amikor a második paraméter string. Serial.print("MIN (10):");Serial.println(multimemo(0,10)); Serial.print("MIN (5):");Serial.println(multimemo(0,5)); Serial.print("MAX (20):");Serial.println(multimemo(1,20)); Serial.print("MAX (15):");Serial.println(multimemo(1,15)); Serial.print("SUM (30):");Serial.println(multimemo(2,30)); Serial.print("SUM (20):");Serial.println(multimemo(2,20)); Serial.print("AVG (42):");Serial.println(multimemo(3,42)); Serial.print("AVG (37):");Serial.println(multimemo(3,37)); Serial.print("AVG (19):");Serial.println(multimemo(3,19)); Serial.print("STO (50):");Serial.println(multimemo(4,50)); Serial.println("Kiolvasott cella tartalmak:"); Serial.print("MIN:");Serial.println(multimemo(0)); Serial.print("MAX:");Serial.println(multimemo(1)); Serial.print("SUM:");Serial.println(multimemo(2)); Serial.print("AVG:");Serial.println(multimemo(3)); Serial.print("STO:");Serial.println(multimemo(4)); //a loop-ban található teszt programban tárolt adatokhoz a tároló cellák létrehozása multimemo(5,MIN); // A 5. fram cella minimum érték tárolásra lesz használva. Ebben tároljuk a generált számok között előforduló minimális értéket multimemo(6,MAX); // A 6. fram cella maximum érték tárolásra lesz használva. Ebben tároljuk a generált számokban előforduló maximális értéket multimemo(7,SUM); // A 7. fram cella szumma érték tárolásra lesz használva. Ehhez adjuk hozzá a generált számot multimemo(8,SUM); // A 8. fram cella szumma érték tárolásra lesz használva. Ebben számoljuk a generált számok mennyiségét multimemo(9,AVG); // A 9. fram cella átlag érték tárolásra lesz használva. Ebben tároljuk a generált számok átlagát } void loop() { szam=random(-10000,20000); Serial.print("Generalt szam:"); Serial.print(szam); Serial.print(" MIN:");Serial.print(multimemo(5,szam)); Serial.print(" MAX:");Serial.print(multimemo(6,szam)); Serial.print(" SUM:");Serial.print(multimemo(7,szam)); Serial.print(" AVG");Serial.print(multimemo(9,szam)); Serial.print(" Db:");Serial.print(multimemo(8,1)); Serial.print(" szamitott atlag:");Serial.print(multimemo(7)/multimemo(8)); Serial.println(); delay(100); } long multimemo(byte cim) { /*************************************************************************************************************** * Ez a multimemo függvény akkor hívódik meg, ha csak egyetlen paramétert adtunk meg a függvény * * meghívásakor (csak olvasni akarunk a tároló cellából) * * A három paraméteres multimemo függvényt hívja meg, de default értékkel tölti fel a maradék két paramétert * * A megadott tároló cella címről adatot fogunk olvasni. * ***************************************************************************************************************/ long adat=0; bool iras=0; return(multimemo(cim,adat,iras)); } long multimemo(byte cim, long adat) { /*************************************************************************************************************** * Ez a multimemo függvény akkor hívódik meg, ha két paramétert adunk meg, a cella címét és a beírandó * * adatot, vagyis írni akarunk a cellába. A tároló cella formázását és alaphelyzetbe állítását végző * * két paraméteres multimemo függvénytől az különbözteti meg, hogy ennek második paramétere long típusú. * * A három paraméteres multimemo függvényt hívja meg, de a harmadik paramétert (iras vagy olvasás) default * * értékkel tölti fel (iras=1, azaz írunk). A megadott tároló cella címébe fogjuk az adatot beírni. * ***************************************************************************************************************/ bool iras=1; return(multimemo(cim,adat,iras)); } long multimemo(byte cim, long adat, bool iras) { /***************************************************************************************************************************************************************** * Ez a multimemo függvény akkor hívódik meg, ha három paraméterrel hívjuk. Ez végzi a tárolandó adat feldolgozását, tárolását, és visszaadja az eredményt * * visszatérő értékként. A tároló cella típusát az első tárolt byte adja meg, ezt az a multimemo függvény írja, melynek két paramétere van, és a második * * cella_tipus (enum-al definiált felsorolás) típusú adatot vár. * * A függvény bemenő paraméterei: * * cim: 0-73 memória cella, egy cella 7 byte, * * adat: long típusú 4 byte-os adat, amit beírunk a kijelölt memória cellába * * iras: ez mondja meg, hogy írunk vagy olvasunk a tároló cellából. 0-olvasunk, 1-írunk * * A tároló cella szerkezete: * * 0. byte típus: 0=minimum cella, 1=maximum cella, 2=summa cella, 3=átlag cella, 4=tároló cella * * 1-4. byte adat long adattípus, ez a tényleges tárolt long adat 4 byte-on * * 5-6. byte átlag esetén az összegzett adatok száma int adattípusú Csak az átlagoló tároló cella használja, ebben számolja az írások számát. * *****************************************************************************************************************************************************************/ int xcim=cim*7; byte page=0; byte adat0; byte adat1; byte adat2; byte adat3; if (xcim<256) {page=0;} else {page=1;xcim=xcim-256;} Wire.beginTransmission(_i2cAddress | (page&1)); Wire.write(xcim); Wire.endTransmission(); Wire.requestFrom(_i2cAddress | (page&1),7); byte xtipus=Wire.read(); //elkérjük az első byte-ot, ami a tárolt dat típusát adja meg long xadat=long(Wire.read()) | long(Wire.read())<<8 | long(Wire.read())<<16 | long(Wire.read())<<24 ; //elkérjük és betöltjük az adat aktuális értékét int xdb=int(Wire.read()) | int(Wire.read())<<8; //elkérjük és betöltjük az adatok számát if (iras==0 and xtipus!=3) {return(xadat);} //ha olvasás és nem átlagot kértünkvolt a művelet, akkor visszadjuk a kiolvasott long értéket if (iras==0 and xtipus==3) {if (xdb>0) {return((long)(xadat/xdb));} else {return(0);}} //ha olvasás és átlagot kértünk, akkor osztani is kell, de csak ha xdb nem 0 if (xtipus==0 and iras==1){ //ha írás ésminimum cella if (xadat>adat) { //csak akkor írjuk be az új adatot, ha az eddig tárolt adatnál kissebb multimemo_adatiras(page,xcim,adat); //visszaírjuk az új adatot a tároló cellába return(adat); } else {return(xadat);} //visszadjuk a cellában tárolt minimum értéket } if (xtipus==1 and iras==1){ //ha írás és maximum cella if (xadat<adat) { //csak akkor írjuk be az új adatot, ha az eddig tárolt adatnál nagyobb multimemo_adatiras(page,xcim,adat); //visszaírjuk az új adatot a tároló cellába return(adat); } else {return(xadat);} //visszadjuk a cellában tárolt maximum értéket } if (xtipus==2 and iras==1){ //ha írás és summa cella adat=xadat+adat; //összeadjuk az új adatot ez eddig beírt adatok (tárolt) összegével multimemo_adatiras(page,xcim,adat); //visszaírjuk az új adatot a tároló cellába return(adat); //visszadjuk az új cella értéket } if (xtipus==3 and iras==1){ //ha írás és átlag cella adat=xadat+adat; //összeadjuk az új adatot ez eddig beírt adatok (tárolt) összegével xdb=xdb+1; //növeljük a beírások számát 1-el Wire.beginTransmission(_i2cAddress | (page&1));Wire.write(xcim+1); //a cella első byte-ját már nem kell írni, azt beállított a cella reset, azért cim+1-től írunk Wire.write(adat & 0xFF);Wire.write((adat>>8) & 0xFF);Wire.write((adat>>16) & 0xFF);Wire.write((adat>>24) & 0xFF); //beírjuk az új összegzett adatot Wire.write(xdb & 0xFF);Wire.write((xdb>>8) & 0xFF); //beírjuk az írások számát Wire.endTransmission(); return((long)(adat/xdb)); //visszadjuk az új átlag értéket } if (xtipus==4 and iras==1){ //ha írás és sima tároló cella multimemo_adatiras(page,xcim,adat); return(adat); } } void multimemo_adatiras(byte page, byte xcim, long adat) { // az átlag cella kivételével mindet ugyanúgy kell beírni, ezért a konkrét írás ebben a közösen használt függvényben lett megvalósítva Wire.beginTransmission(_i2cAddress | (page&1));Wire.write(xcim+1); //a cella első byte-ját már nem kell írni, azt beállított a cella reset, azért cim+1-től írunk Wire.write(adat & 0xFF);Wire.write((adat>>8) & 0xFF);Wire.write((adat>>16) & 0xFF);Wire.write((adat>>24) & 0xFF); Wire.endTransmission(); } long multimemo(byte cim, cella_tipus tipus) { /******************************************************************************************************************************************************************* * Ez a multimemó függvény akkor hívódik meg, ha két paraméterrel hívjuk, és a második cella_tipus típusú változó, amit enum-al hoztunk létre a program elején. * * A függvény elvégzi egy cella típusának beállítását (a cella első byte-ja), és alaphelyzetbe állítja a tárolt adatokat. * * Bemenő paraméterek: * * cim: 0-73 db memória cella, egy cella 7 byte, * * típus: felsorolás típusú (enum) paraméter, ami meghatározza a cella tárolási módját. Lehetséges értékei 0-4 között. * * Típus által képzett cella típusok, és azok tárolási módja, az elvégzett műveletek leírása: * * MIN: Az íráskor megkapott adatot csak akkor tárolja, ha az kisebb mint az éppen tárolt adat. Mielőtt elkezdjük a minimumot gyüjteni, be kell írni * * a lehető legnagyobb long értéket, különben nem biztos, hogy megjegyzi a legelső értéket. A számláló cellarészt nem használja. * * MAX: Az íráskor megkapott adatot csak akkor tárolja, ha az nagyobb mint az éppen tárolt adat. Mielőtt elkezdjük a maximumott gyüjteni, be kell írni * * a lehető legkissebb long értéket, különben nem biztos, hogy megjegyzi a legelső értéket. * * SUM: Képzi a beírt adatok összegét. Alapértelmezetten a tartalma 0. * * AVG: képzi a beírt adatok átlagát. Minden beít értéket szummáz az adat mezőben, számolja a beírások számát, és kiolvasáskor osztja az adatot a beírás számmal * * Alapértelmezetten az adat és a számláló is 0. * * STO: csak úgy simán tárolja az adatot, nem csinál vele semmit, ha volt bent előtte adat, azt felülírja. Alapértelmezett tartalma 0. * *******************************************************************************************************************************************************************/ int xcim=cim*7; byte page; if (xcim<256) {page=0;} else {page=1;xcim=xcim-256;} Wire.beginTransmission(_i2cAddress | (page&1)); Wire.write(xcim); if (tipus==MIN){ // 2147483647 kezdő értéket írunk a tároló cellába, mert nincs nagyobb szám long esetén, így csak ennél kisebbek jöhetnek. Wire.write(0);Wire.write((long)2147483647 & 0xFF);Wire.write(((long)2147483647>>8) & 0xFF);Wire.write(((long)2147483647>>16) & 0xFF);Wire.write(((long)2147483647>>24) & 0xFF); Wire.write(0);Wire.write(0); Wire.endTransmission(); return(0); } if (tipus==MAX){ // -2147483648 kezdő értéket írunk a tároló cellába, mert nincs kisebb szám long esetén, így csak ennél kisebbek jöhetnek. Wire.write(1);Wire.write((long)-2147483648 & 0xFF);Wire.write(((long)-2147483648>>8) & 0xFF);Wire.write(((long)-2147483648>>16) & 0xFF);Wire.write(((long)-2147483648>>24) & 0xFF); Wire.write(0);Wire.write(0); Wire.endTransmission(); return(0); } if (tipus==SUM or tipus==AVG or tipus==STO) { //össegző mező esetén csak simán törölni kell mindent Wire.write(tipus);Wire.write(0);Wire.write(0);Wire.write(0);Wire.write(0); Wire.write(0);Wire.write(0); Wire.endTransmission(); return(0); } Wire.endTransmission(); }
…és a soros port-ra kiírt eredmény első néhány sora:
reset... tárolás... MIN (10):10 MIN (5):5 MAX (20):20 MAX (15):20 SUM (30):30 SUM (20):50 AVG (42):42 AVG (37):39 AVG (19):32 STO (50):50 Kiolvasott cella tartalmak: MIN:5 MAX:20 SUM:50 AVG:32 STO:50 Generalt szam:6807 MIN:6807 MAX:6807 SUM:6807 AVG6807 Db:1 szamitott atlag:6807 Generalt szam:15249 MIN:6807 MAX:15249 SUM:22056 AVG11028 Db:2 szamitott atlag:11028 Generalt szam:73 MIN:73 MAX:15249 SUM:22129 AVG7376 Db:3 szamitott atlag:7376 Generalt szam:3658 MIN:73 MAX:15249 SUM:25787 AVG6446 Db:4 szamitott atlag:6446 Generalt szam:18930 MIN:73 MAX:18930 SUM:44717 AVG8943 Db:5 szamitott atlag:8943
Érdekes eredményre vezetett ez a program. -10.000 és +20.000 közötti véletlen számot generáltam, és a multimemo segítségével tároltam a generált számok minimumát, maximumát, összegét, átlagát és ellenőrzési céllal minden generáláskor növeltem az egyik cella értékét. Az a nem meglepő eredmény született, hogy a véletlen generátor nem teljesen ideális. Ahogy növeltem a generált számok mennyiségét, az átlagnak 5.000-re kellett volna adódnia. Azonban nem így történt, kis mértékben mindig eltért tőle. Nem is olyan kicsi mértékben. Mivel kiírtam a generált db számot is, látható, hogy 20.000 véletlen szám átlaga az ideális 5000 helyett 5038.Ez szerintem elég durva eltérés. Másik érdekes megfigyelés lehet, hogy a maximum értéke 20000 generált szám esetében is csak 19992. Ez még nem rossz eredmény, nem számoltam ki a valószínűségét, hogy ennyi generált szám esetén mi a várható maximum. Pár sort ki is emeltem a program output-ból, hogy látható legyen miről beszélek:
Generalt szam:6807 MIN:6807 MAX:6807 SUM:6807 AVG6807 Db:1 szamitott atlag:6807 Generalt szam:15249 MIN:6807 MAX:15249 SUM:22056 AVG11028 Db:2 szamitott atlag:11028 Generalt szam:73 MIN:73 MAX:15249 SUM:22129 AVG7376 Db:3 szamitott atlag:7376 Generalt szam:3658 MIN:73 MAX:15249 SUM:25787 AVG6446 Db:4 szamitott atlag:6446 Generalt szam:-2793 MIN:-10000 MAX:19992 SUM:24894628 AVG4979 Db:4999 szamitott atlag:4979 Generalt szam:-4573 MIN:-10000 MAX:19992 SUM:24890055 AVG4978 Db:5000 szamitott atlag:4978 Generalt szam:5258 MIN:-10000 MAX:19992 SUM:24895313 AVG4978 Db:5001 szamitott atlag:4978 Generalt szam:-8634 MIN:-10000 MAX:19992 SUM:24886679 AVG4975 Db:5002 szamitott atlag:4975 Generalt szam:16085 MIN:-10000 MAX:19992 SUM:49578804 AVG4958 Db:9998 szamitott atlag:4958 Generalt szam:16315 MIN:-10000 MAX:19992 SUM:49595119 AVG4960 Db:9999 szamitott atlag:4960 Generalt szam:-1935 MIN:-10000 MAX:19992 SUM:49593184 AVG4959 Db:10000 szamitott atlag:4959 Generalt szam:13406 MIN:-10000 MAX:19992 SUM:49606590 AVG4960 Db:10001 szamitott atlag:4960 Generalt szam:-8997 MIN:-10000 MAX:19992 SUM:75662129 AVG5044 Db:14998 szamitott atlag:5044 Generalt szam:17916 MIN:-10000 MAX:19992 SUM:75680045 AVG5045 Db:14999 szamitott atlag:5045 Generalt szam:7885 MIN:-10000 MAX:19992 SUM:75687930 AVG5045 Db:15000 szamitott atlag:5045 Generalt szam:15235 MIN:-10000 MAX:19992 SUM:75703165 AVG5046 Db:15001 szamitott atlag:5046 Generalt szam:-8163 MIN:-10000 MAX:19992 SUM:100768475 AVG5038 Db:19998 szamitott atlag:5038 Generalt szam:-2033 MIN:-10000 MAX:19992 SUM:100766442 AVG5038 Db:19999 szamitott atlag:5038 Generalt szam:10914 MIN:-10000 MAX:19992 SUM:100777356 AVG5038 Db:20000 szamitott atlag:5038 Generalt szam:-798 MIN:-10000 MAX:19992 SUM:100776558 AVG5038 Db:20001 szamitott atlag:5038