C# a casovani v mikrosekundach   zodpovězená otázka

C#

Pekny den, chci v C# napsat api pro teplotni cip ds18b20. Problem je ze tento cip vyzaduje presne casove useky, ktere inicializuji cteni, zapis apod. Jelikoz mi cip neodpovida na master reset tak jediny roblem, ktery vidim je casovani. Otazka tedy zni je mozne tuto aplikaci napsat v Csharpu? Podle popisu TimeSpan by casovani melo byt presne, ale...

Vytvoril jsem si nasledujici fci:

private void usleep(long microsecond)
{
//                        one tick is 100 nanosecond; one microsecond has got 1000 nano, 
  Thread.Sleep(new TimeSpan(10 * microsecond));
}

Pote v kodu volam napr. usleep (480);

Cela fce pro kontrolu pritomnosti cipu na sbernici vypada takto 
public bool presence()
        {
            int i = 0;

            busToLog1(serPort.PortName);
            usleep(1000);
            busToLog0(serPort.PortName);
            usleep(480);
            busToLog1(serPort.PortName);
            usleep(60);

            while (true) {
                if (serPort.CtsHolding) {
                    CTSstatus = true;
                    i++;
                }
                else {
                    CTSstatus = false;
                    return true;
                }

                if (i == 20)
                    return false;
            }

        }

fce butToLog1 a 0
       private void busToLog1(string port)
        {
            serPort.RtsEnable = true;
            serPort.DtrEnable = false;
        }

        private void busToLog0(string port)
        {
            serPort.DtrEnable = true;
            serPort.RtsEnable = false;
        }
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pište s diakritikou, kdo má ten humus potom číst.

Pro použití přesných časovačů nastudujte toto:

http://msdn.microsoft.com/en-us/library/...

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Tak sem prostudoval materiály a zjistil že od .Net 2 je implementována classa StopWatch.Nasadil jsem ji tedy a změřil fci useep, která je realizována pomocí TimeSpan. zjištění je strašné rozdíli jsou extremní s přesností to nemá nic společného. Hledám tedy fci či implementaci nějaké dllky s funkcí pro přesné časování v řádech mikrosekund.

PS: jsem odpurce diakritiky, ale premohl jsem se a pouzil jsem ji v prizpevku - tedy pardon hnusu :))))

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

V článku je přímo implementace a příklad použití velmi přesného časování pomocí Windows API, nevím tedy co řešíte. Stopwatch, DateTime a podobné věci mají přesnost pouze +-15 ms.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Řeším přesnou pauzu po provedení nahození sběrnice. V odkazu je opakuji jen měření času na určitou operaci. A jak to pročítám tak tam nikde nic jiného není. Pokud jsem opravdu tak slepí a nebo neumím anglicky hoďte sem výtažek, o kterém si myslíte, že je to pravé pro mou aplikaci.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Stopwatch a +-15ms?

Spravil som skúšku:

    Sub Main()
        Dim s = Stopwatch.StartNew
        Threading.Thread.Sleep(1)
        Console.WriteLine(s.ElapsedTicks / Stopwatch.Frequency)
        Console.ReadLine()
    End Sub

A na konzoli som mal 0,001 a ešte aj niečo drobné. Tak akých +-15ms?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Myslím že .Net neumí přesně časovat. Ty rozdíly, které jsem při měření zjistil jsou strašné. Není to nic pro programování přesných časových intervalů a ještě v řádech microsekund.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Keď to chcete naozaj presne, tak to robte na hardwérovej úrovni pomocou elektronických kryštálov.Tie majú frekvenciu v rádoch desiatok MHz.Pre 10 MHz je odozva medzi dvoma tickmi a teda presnosť 1 mikrosekunda.Kryšály vyššej frekvencie sú ešte presnejšie.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

pozadavek je na hardwarovou nenarocnost. tzn pouziti max 1xtrnazistoru a nekolik pasiv soucastek. Jelikoz se mi nezadarilo napsat program v C# tak jsem se jal psani v Cecku. A i prez porodni obtize (usleep, nanosleep jsou nepresne asi jako timespan) je casovani hotove a cip odpovida. Je vsak skoda, ze mnou preferovany a vzdy propagovany jazyk me takhle sklamal.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Teraz som skúsil odmerať, koľko trvá .netu prepnúť dtr a rts naraz.

QueryPerformanceCounter - 276 mikrosekund.

System.Diagnostics.Stopwatch - 45 mikrosekund.

Tak ako môžete vravieť , že .net nevie presne časovať ?

A pán Linhart, aká je potom asi pravdivosť Vášho názoru o nepresnosti Stopwatch ?

Mimochodom, napísal som iba zlomok zo všetkých zobrazených číslic, bolo ich okolo 16, čo je presnosť typu System.Double.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Taktiež som si pozrel zdrojáky Stopwatch, a interne to používa práva QueryPerformanceCounter .Pokiaľ nie je dostupný, tak potom už presný nieje, pretože ako záložný zdroj používa niečo iné.Či to používa QueryPerformanceCounter môžete zistiť z premennej

[System.dll]System.Diagnostics.Stopwatch.IsHighResolution

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zdravim velmi zajimave udaje. Cas prepnuti respektive nastaveni hodnoty na pinu jsem nemeril. Meril jsem vsak delku trvani pouzy pomoci timespan a dosel jsem k vyse uvedenym zaverum. To ze trva prepnout dtr a rts 45 microsec je vcelku moc. Jelikoz nektere intervaly, ktrerych potrebuju dosahnout je treba nahozeni log 1 na pinu po dobu 6 microsecund. Pote zhozeni do nuly. Jetli ma csharp takove prodlevy tak pro tuto api je nevhodny. V Cecku probiha vse mrknutim oka, ale nesmime zapomenout, ze je to jazyk pracujici hodne blizko hardwaru a neprinasi nam takove pohodly jako Csharp. Uvazuji o vytvoreni dllky v cecku a pote ji importovat do csharpu. Ale to uz predbiham.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No tak tá pomalosť má korene presne v úrovni.C# je managed, pod správou .net runtime, zatialčo programy v C spravuje priamo OS.Preto je rýchlejší. A to dll - to potom musíte preniesť celú sekvenciu naraz cez P/Invoke alebo C++/CLI a až potom prepínať piny, pretože na prechode medzi unmanaged a managed svetmi sa tiež strácajú nejaké milisekundy.Teda nie po jednom, ale všetko až po bod, kde si môžete dať pohov na pár milisekund a nebude to čipu vadiť.Taktiež, keď chcete v C# rozbehať dll v C tak musíte v zdrojákoch C nastaviť príslušné funkcie ako EXTERN a taktiež treba v .netu duplikovať definície pre všetky štruktúry(struct) a konštanty(const) a funkcie v tvare pre .net . Na všetko sú .net príslušné atriúty, napr. StructureLayout, DLLImport a pod. O P/Invoke je na tomto serveri aj článok. Druhá možnosť je urobiť wrapper v C++/CLI, ale ten jazyk je dosť ťažký a aj tam je prechod medzi prostrediami obmedzený. Ak sa chcete c++/cli naučiť, aj o tom tu je článok, ale pre jednu malú knižnicu je jednoduchšie bežné P/Invoke v C# .

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Všechno záleží na tom, je-li IsHighResolution. Pokud není, použije se k měření klasický DateTime a tam je právě ta nepřesnost +-15 ms.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ano, ale to se stane dnes na opravdu historickém železe, anebo v Compact Frameworku na mobilech.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To není .NETem, ale systémem. Windows není realtime systém a nemáte už z principu kontrolu nad tím, kdy aplikace dostane přidělený procesorový čas.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To, že vám měřidlo vrátí hodnotu s přesností na 3 desetinná místa, ještě neznamená, že má přesnost 1 ms. Vtip je v tom, že když jej budete volat opakovaně za sebou, tisíckrát vrátí 0,012 a pak najednou skočí na 0,023 a zase to bude chvíli vracet.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No ja si nemyslím, že by meradlo vracalo číslice na 3 desatinné miesta a pritom nemalo tú presnosť.Keď by malo presnosť +-15ms, tak ako môže namerať napríklad 5ms ? To tie funkcie ako vracajú po dobu 15 ms hodnotu 5,4 podľa Vás ?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Na to pozor, DateTime.Now a Environment.TickCount mají opravdu přesnost +- 15 ms.

Ale StopWatch používá interně performance countery. Přesně ty, o kterých je článek, na nějž odkazujete ve svém následujícím příspěvku. Článek je z doby .NET Frameworku 1.x, kdy třída StopWatch nebyla a hned na začátku se píše, že v .NETu 2 je implementován wrapper nad těmi perfcountery.

System.Diagnostics.StopWatch používají interně DateTime, pokud hardware přesnější časování nepodporuje. Ale pokud ano (a to dnes naprostá většina počítačů), pak používají přesnější časovač s přesností v řádu desítek až stovek nanosekund.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nechci se hadat, ale pokud by bylo mozne dosahnout jak pisete presneho casovani v radek mikrosekund pak otazka zni jak? Kdyz jsem to testoval tak ta nepresnost byla strasna. A to me PC P4 Core2 Duo E8600 s 6GB RAM neni z tech pomalejsich. Hledal jsem i neco o HPET a jeho pouziti pro casovani v .Netu ale bohuzel taky nic kloudneho co by se dalo pouzit.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Stačí použít ty System.Diagnostics.StopWatch a ověřit, že mají k dispozici přesné časování (což mít velmi pravděpodobně budou).

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Otestuju az budu u PC s Win a pak dam vedet.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak jsem otestoval StopWatch. Jeden tick se rovna 100ns takze kdyz potrebuju pauzu 480us tak dam 480x10. Zaver je vsak stejny. Chip neodpovida coz znamena jedine a to spatne casovani. Respektive jak uz tady bylo zmineno muze mit na to vliv i dlouhy cas nahozeni ci zhozeni pinu com portu.

Stopwatch sWatch = new Stopwatch();
busToLog1(serPort.PortName);
sWatch.Start();
while (sWatch.ElapsedTicks < (480*10)) ;
sWatch.Reset();

...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Anebo to v tu chvíli může procesor přerušit a čas přidělit jinému procesu, což vygeneruje daleko větší zdržení.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback