Műveletek törtekkel (tizedesjegy hossz probléma)

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Avatar
DOGMAN
Chipgyilok
Hozzászólások: 293
Csatlakozott: 2006. augusztus 27. vasárnap, 6:00

Műveletek törtekkel (tizedesjegy hossz probléma)

Hozzászólás Szerző: DOGMAN »

Helló

Az alábbi problémába ütköztem: a feladat két koordináta távolságát kiszámolni a földgömb felületén.

az alap egyenlet (php, java, vb6-ban jól működik)

Kód: Egész kijelölése


    $pi80 = 3.1415926535898 / 180;
    $lat1 * = $pi80;
    $lng1 * = $pi80;
    $lat2 * = $pi80;
    $lng2 * = $pi80;

    $r = 6372.797 ; / / Mean Radius Of Earth In Km
    $dlat = $lat2 - $lat1;
    $dlng = $lng2 - $lng1;

    $a = Sin($dlat / 2) * Sin($dlat / 2) + Cos($lat1) * Cos($lat2) * Sin($dlng / 2) * Sin($dlng / 2);
    $c = 2 * Atan2(sqrt($a) , Sqrt(1 - $a));
    $distance_meter = $r * $c * 1000;
Viszont - mint a Bascom könyvben Robi irja is, a Bascom fordító kb 9 tizedesjegynél levágja a single szám végét, ezért a képlet pár ezer méter távolság alatt 0 eredményt ad vissza.
Ott bukik el, hogy mikor kérem a 0.000000012 sinusát akkor az már nulla lesz mert amúgy a 0.000000000209 lenne de a vége ugye elveszik.

Próbáltam azt is hogy számítás előtt a kiinduló adatokat pl 1000-el megszorzom, így beleférek a 9 tizedesjegybe, de ha növelem a két pont távolságát úgy romlik a pontosság. És nem centiket, hanem több száz métereket.

A kérésem: hogy lehetne ezt megoldani/kikerülni?
Hajlandó vagyok az áramkörbe külön a főprocesszor mellé még egy kisebbet tenni ami soros porton beszélgetve csak ezzel foglalkozna, csak hát ugye ez nem segít a problémán...
Nem lehet pl a lebegőpontos tizedesek méretét növelni a sebesség kárára?
Vagy létezik-e olyan lib amit használva mondjuk 15 tizedesjegyig lehet a törteket ábrázolni?
Asm-ben meg lehetne írni az eljárást, több tizedesjegyre?

A példaprogram:

Kód: Egész kijelölése

'--- Alapadatok ---
$crystal = 4000000                                          'Sebesseg
'$regfile = "attiny45.dat"                                   'Chip
$regfile = "m8def.dat"                                      'Chip
$baud = 4800

$hwstack = 32                                               ' default use 32 for the hardware stack

$swstack = 32                                               ' default use 10 for the SW stack

$framesize = 64                                             ' default use 40 for the frame space

$sim

'$lib "FP_Trig.lbx"


Declare Function Tavolsag(byval Lat1 As Single , Byval Lng1 As Single , Byval Lat2 As Single , Byval Lng2 As Single) As Single

Const Dis_r = 6372.797
Const Dis_oszto = 57.2958

Const Pi = 3.1415926535898
Const Pi80 = Pi / 180


Dim Eredmeny As Single
Dim P1_1 As Single
Dim P1_2 As Single
Dim P2_1 As Single
Dim P2_2 As Single
'(
   P1_1 = 46.675640
   P1_2 = 17.646726
   P2_1 = 46.676075
   P2_2 = 17.647133
')
   P1_1 = 46.678339
   P1_2 = 17.614988
   P2_1 = 46.676075
   P2_2 = 17.647133
Do

   Eredmeny = Tavolsag(p1_1 , P1_2 , P2_1 , P2_2)


   'Print "er: " ; Eredmeny
   'Open "comb.1:9600,8,n,1" For Output As #1
   Print "text: " ; Eredmeny
   'Waitms 10
   'Close #1

Loop

End

Function Tavolsag(byval Lat1 As Single , Byval Lng1 As Single , Byval Lat2 As Single , Byval Lng2 As Single) As Single

'(
   Ez alaján megy a számítás,
   PHP, java és egyéb (PC-s) fordítókban jól működik, kb cm-es szórással ad jó eredményt

    $pi80 = 3.1415926535898 / 180;
    $lat1 * = $pi80;
    $lng1 * = $pi80;
    $lat2 * = $pi80;
    $lng2 * = $pi80;

    $r = 6372.797 ; / / Mean Radius Of Earth In Km
    $dlat = $lat2 - $lat1;
    $dlng = $lng2 - $lng1;

    $a = Sin($dlat / 2) * Sin($dlat / 2) + Cos($lat1) * Cos($lat2) * Sin($dlng / 2) * Sin($dlng / 2);
    $c = 2 * Atan2(sqrt($a) , Sqrt(1 - $a));
    $distance_meter = $r * $c * 1000;


')





   Dim E As Single
   Dim Dlat As Single
   Dim Dlng As Single
   Dim A As Single
   Dim A1 As Single
   Dim A1_temp As Single
   Dim A2_temp As Single
   Dim A3_temp As Single

   Dim B1 As Single
   Dim B1_temp_1 As Single
   Dim B1_temp_11 As Single
   Dim B1_temp_12 As Single
   Dim B1_temp_2 As Single
   Dim B1_temp_3 As Single
   Dim B1_temp_32 As Single

   Dim C As Single
   Dim C_temp_1 As Single
   Dim C_temp_2 As Single
   Dim C_temp_3 As Single


   Lat1 = Lat1 * Pi80
   Lng1 = Lng1 * Pi80
   Lat2 = Lat2 * Pi80
   Lng2 = Lng2 * Pi80

   Print " Lat1: " ; Lat1
   Print " Lng1: " ; Lng1
   Print " Lat2: " ; Lat2
   Print " Lng2: " ; Lng2



   Dlat = Lat2 - Lat1
   Dlng = Lng2 - Lng1

   Dlat = Dlat * 1
   Dlng = Dlng * 1

   Print " Dlat: " ; Dlat
   Print " Dlng: " ; Dlng

   A1_temp = Dlat / 2
   Print " Dlat / 2: " ; A1_temp
   A2_temp = Sin(a1_temp)
   Print " Sin(a1_temp): " ; A2_temp

   A1 = A2_temp * A2_temp
   Print " A1: " ; A1

   'E = A1

   B1_temp_11 = Cos(lat1)
   Print " Cos(lat1): " ; B1_temp_11
   B1_temp_12 = Cos(lat2)
   Print " Cos(lat2): " ; B1_temp_12
   B1_temp_1 = B1_temp_12 * B1_temp_11
   'Print " B1_temp_1: " ; B1_temp_1

   B1_temp_2 = Dlng / 2
   B1_temp_32 = Sin(b1_temp_2)
   Print " Sin( Dlng / 2): " ; B1_temp_1
   B1_temp_3 = B1_temp_32 * B1_temp_32

   B1 = B1_temp_1 * B1_temp_3
   A = A1 + B1
   Print " a: " ; A


   C_temp_1 = Sqr(a)
   C_temp_2 = 1 - A
   C_temp_3 = Sqr(c_temp_2)

   C = 2 * Atn2(c_temp_1 , C_temp_3)

   C = C * 1000                                             ' méterbe átváltás

   E = Dis_r * C



   Tavolsag = E

End Function
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Hozzászólás Szerző: winnerbt »

Szia!
Néha használják a uM-FPU V3.1 tipust, régebben volt egy
DIL8-as tokú co-proci is, de nem találom most a típust/adatlapot.
Viszont ezek is 32-bitesek, szóval nem vagy előrébb.
Lehet, Neked kellene megírni a nagyobb normálást és számításokat, mivel legtöbb cuccban csak 32-bites regisztereket találtam, tehát ki kell ott is terjeszteni az ábrázolási tartományokat. De majd jobb matekosok kijavítanak...
JAni
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Hozzászólás Szerző: winnerbt »

ja, Single helyett Double 64-bites formával nem jó a cucc?
(nem tudom, hogy az alkalmazott LBX ezt tudja-e)
JAni
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

A gépnek jobban megy a bináris számolás, mint a decimális!
Próbálj meg te is úgy gondolkozni! Ne 10000 *, hanem 2 hatványával mondjuk 16384 *.
Ez 14* balra shifttelés , szorzáskor. Ugyan ennyiszer jobbra osztáskór. És közben nincsen kerekítés.
Avatar
DOGMAN
Chipgyilok
Hozzászólások: 293
Csatlakozott: 2006. augusztus 27. vasárnap, 6:00

Hozzászólás Szerző: DOGMAN »

Óóóó köszönöm, double-val megy rendesen, 2500 méteren 5 cm az eltérés a PHP kódhoz képest, 550 Km-en pedig "csak" 223 méter.
minél közelebb vagyok a célhoz annál pontosabb az eredmény...

Szóval ez már jó lesz!

Az összes változót átraktam double-ra most szépen megpróbálom a helyigény csökkentés miatt az egyes részeket (ahova elég csak 9 tizedesjegy) visszarakni single-ba...
Avatar
DOGMAN
Chipgyilok
Hozzászólások: 293
Csatlakozott: 2006. augusztus 27. vasárnap, 6:00

Hozzászólás Szerző: DOGMAN »

Találtam egy ilyet:
http://micromegacorp.com/umfpu-v2.html
uM-FPU V2 Floating Point Coprocessor
Adatlapok pdfben a lap alján.
I2C, SPI buszon kommunikál 64 bitesig mindegyik lebegőpontos műveletet ismeri.
2 óra googlizás után találtam hozzá mindenféle basic stamp, gcc és egyéb libeket, doksikat, csak bascom-osat nem...

Azt meg sem néztem még, hogy egyáltalán beszerzhető-e nálunk.
Össze tudnánk ezt hozni bascommal?

hogy működik? Gondolom, elvileg hogy i2c-n átküldöm hogy melyik parancsot akarom végrehajtani, majd átküldöm magát az adatot, és ha kész akkor kiolvashatom az eredményt?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Arduino-s lib van hozzá, az majdnem Bascom....
Igen. Átküldöd, hogy mivel mit csináljon....

Kell a 64bit pontosság?:)
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Hülye ötlet: Bascom 32bites pontosságú.
Ha a számodat szétszeded tartomany szerint, és úgy számolsz vele? (szorzás: többszörös összeadás, stb)
Avatar
DOGMAN
Chipgyilok
Hozzászólások: 293
Csatlakozott: 2006. augusztus 27. vasárnap, 6:00

Hozzászólás Szerző: DOGMAN »

Robert írta:Hülye ötlet: Bascom 32bites pontosságú.
Ha a számodat szétszeded tartomany szerint, és úgy számolsz vele? (szorzás: többszörös összeadás, stb)
Írtam példát fent: pl ha a két pont mondjuk 54 m távolságra van egymástól, akkor az egyenletben két részen is 0.00000000000_és_itt_jön_az_érték hosszúságú tizedes fordul elő.

Hogy szedem ezt szét tartomány szerint?

Arra gondoltam, mivel double esetén jól számol csak sok flasht megeszik (~2060 byte), hogy lesz a főprocesszor (Mega168, később SD kártya miatt Mega32) ez kezeli a gombokat, menüket, karakterkészletet a grafikus LCD-hez, olvassa be a GPS-t HW soros porton, menti a tracket i2c eepromba, sw soros porton kommunikál a PC-vel, és ugyenezen sw soros porton kommunikál egy mega8-al ami csak a lebegőpontos számításokat végzi.
Jól emlékszem ha két AVR-t egy kristályról hajtok akkor frankón szinkronban fognak futni? (3.6864 Mhz-re gondoltam a 3.7 volt, és a baudok err-je miatt)

Meg még a TQFP tokozások forrasztásával kell megküzdenem, mert így is alig fog elférni...:)
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Hát, ezt sehogy nem kapod szét:(
Főproci:
M168->M328
M32->M644/1284
Ebbe nem fér el?


SW sooportot felejtsd inkább el. csak gond lesz vele.
M32 helyett: M324P/644P/1284P. Ezekben már 2 sorosport van!

Ign, futtatható 1 quartrol a 2. DE: a kvarc vedelme es a rezgesstabilitas miatt a főproi CLKO (clock out) lábáról hatjsd a másik pocit (ha semmiképp nem férsz gybe.
De én nagyobb proc, magasabb órajel-ben goldolkodnék:
- fogyasztás alacsonyabb, mint 2 külön procinál.
- nem kell vacaolni az adatküldő/fogadó rutinokkal (az is 150...40 byte lenne)
- kisebb a nyák.

Bármilyen Quartrol jarathatod, ha a sorosan vised at az adatot. Nem az abszolut hiba lenyekg, hanem a 2 egymashoz kepest RELATIV hibaja. Azaz 16 MHzrol jar, 9600 a sorosport -> 0.16%hiba. De ha mindket AVR errol jar: mindkettonek 0.16% hiba -> egymashoz kepest 0%!

Igy mukodik az Arduino UNO. 16 MHz, 57600 bps: 3.1 % hiba. De mindét procinál, így a relatív hiba: 0%! Azaz tökéletes a sebesség:)

Ha nem sorosan beszélgetsz 2 chippel, jobban jársz:
- I2C, SPI: van saját órajele és ahhoz szinkronzál mindent. Tökmindegy a sebesség :)


TQFP forrasztas:
- Sirleslie rutinos benne már....

Tipp:
- folyasztoszer, femtisztara takaritott rezfelulet (vagy gyari onozott nyak)
- az egyik sarkon egy pottyel megfogod, majd atellenesen a tuloldalt is.
- utana a maradek 2 oldal beforraszt. ha osszefolynak a labak: onszivo sodrattal leszeded.

Sima pillanatpakaval, es 0.5 mm-es huzallal siman megy.
Ha meg egyszerusiteesz: pillanatpaka helyet kihegyezed, 0.7-0.5 mm-re igaz gyorsabban fogy, de tuti, mint egy tupaka....
Avatar
DOGMAN
Chipgyilok
Hozzászólások: 293
Csatlakozott: 2006. augusztus 27. vasárnap, 6:00

Hozzászólás Szerző: DOGMAN »

Tegyük fel hogy M324P két soros portját használom, most így hirtelen adatlap olvasgatás nélkül: lehet a két hw soros portot aszinkron módon hajtani?
GPS: 4800 baud gyárilag (először ennyivel kell csatlakoznom hozá még akkor is ha később átállítom pl 9800-ra, de az átállító parancsot csak 4800-on veszi be) szóval ezt vegyük fix 4800-nak.
Akkor a másikat ami a PC-re adatok oda-vissza töltését kezelné, ott lehet pl 19200?
sw SPI kezeli a nokia kijelzőt, ic2 az lesz (hőmérő, eeprom, digit iránytű) de akkor most átnézem a nagyobb procikat amikben van hw soros port...

Még a végén ARM/linux kernel cucc lesz belőle :lol:
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Igen.

$baud és $baud1 - külön kezeled a 2 sorosportot.

Kód: Egész kijelölése

$baud=4800
'$baud1=19200
Open "COM2:19200,8,n,1' for random as #2
Print "valami" 'uzenet a GPS-nek
Print #2,"uzenet2" 'uzenet a PC fele
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

SPI és I2C lehet SW alapú is.... :P
Na jó, az SPI esetén nem mindíg jó/szerencsés (sebesség miatt)....
Avatar
DOGMAN
Chipgyilok
Hozzászólások: 293
Csatlakozott: 2006. augusztus 27. vasárnap, 6:00

Hozzászólás Szerző: DOGMAN »

Köszi az infót.

HW SPI-t ma du. kipróbálom, hogy ha a nokia LCD az stk500- al közös lábakon van akkor az hogyis működik bascomban...
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Soros ellenallas a kommunikacioba. STK500 a AVR chip laban legyen!
Válasz küldése