Kódování HEX pro sériové kominikaci   zodpovězená otázka

VB.NET

Zdravím,

pokouším se rozchodit digitální odměřování na sériovém portu. Funguje to tak, že na port odešlu dva bajty např. tímto způsobem:

com1.Write(Convert.ToChar(CInt(&H11))) 'číslo osy = 1
com1.Write(Convert.ToChar(CInt(&H00))) 'dotaz na aktuální pozici

Což je dotaz na pozici první osy. Odměřovíní odpoví třemi bajty pozpátku v hex podobě. Např. tedy ED 4D 00 = 19949. Já to pomocí tohoto kódu odchytím a převedu na číslo:

Dim buff As String

'přečte data
buff = com1.ReadExisting

'otočit poředí (bajty chodí pozpátku)
'převést znaky na hex kód
Label4.Text = Microsoft.VisualBasic.Right("00" & Hex(Asc(buff.Substring(2, 1))).ToString(), 2) & Microsoft.VisualBasic.Right("00" & Hex(Asc(buff.Substring(1, 1))).ToString(), 2) & Microsoft.VisualBasic.Right("00" & Hex(Asc(buff.Substring(0, 1))).ToString(), 2)

'převede na dec číslo
Label6.Text = Convert.ToInt32(Label4.Text, 16).ToString()

Můj problém spočívá v kódování. Při různém kódování mi vrací program pokaždý jiný přečtený bajt.

com1.Encoding = System.Text.Encoding.GetEncoding(28605)
&H80 = &H3F

com1.Encoding = System.Text.Encoding.GetEncoding("Windows-1252")
&H83 = &66

Dá se toto kódování nějak obejít?

Výše uvedené kódy jsou z testovací aplikace. Zatím se snažím vůbec zjistit, jak správně přečíst data.

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

Zdravím,

snažil bych se pracovat s čísly a ne s řetězci, kód je pak velmi nepřehledný a špatně se v něm loví chyba. Pokud se ale ze sériové linky vrací řetězce a ne pole bytů jak by se dalo předpokládat, tak bych to převedl nějak takto, omlouvám se za C# ve VB to neumím, snad to i tak pomůže :-) . Je to možné pustit přímo v LinqPadu


void Main()
{
	string stringDataReverted = "00 4D ED";
	string[] stringNumbers = stringDataReverted.Split(new string[] {" "}, StringSplitOptions.RemoveEmptyEntries);
	
	byte[] numbers = stringNumbers.Select(d => byte.Parse(d, NumberStyles.HexNumber)).ToArray();
	
	int resulNumber = (numbers[0] << 16) | (numbers[1] << 8) | numbers[2];
	
	Console.WriteLine(resulNumber);	
}

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

Díky za info. Ještě jsem něco zkoušel a nakonec mi to funguje s tímto kódem:

Na začátku musím testovat jestli byly poslány 3 bajty, jinak se program zasekne (v případě že tri vyslány nebyly).

Ale netuším, jestli je dobrá volba takhle číst ty jednotlivý bajty. Přecejenom je to 3x čtení. V případě delšího řetězce to trvá asi dýl a zbytečně to zpomaluje program(?)

If com1.BytesToRead = 3 Then

            Cislo1 = com1.ReadByte
            Cislo2 = com1.ReadByte
            Cislo3 = com1.ReadByte

            PocetPuslu = Cislo1 + (Cislo2 * 256) + (Cislo3 * 65536)
End if
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zdravím,

program se zasekne, protože používáte blokovanou metodu ReadByte() nejspíše v UI vlákně aplikace, která čeká na další data.(1 byte)

Ideální je samotné čtení dat dát do jiného vlákna, které pak přečtená data posílá dál k dalšímu zpracování.

Také je důležité si definovat nějaký protokol pomocí kterého zařízení na sériové lince komunikuje. Byť i tak jednoduchý který říká že na otázku vždy následuje odpověď v délce tří bytů. Všechno ostatní je pak možné považovat za chybu, zalogovat, zahodit apod.

Čtení dat jako takové program nezpomaluje pokud běží v jiném vlákně. V tomto množství dat je to zcela neznatelné. Určitě je ale efektivnější použít tuto metodu: https://msdn.microsoft.com/en-us/library...

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

Ještě drobná poznámka k "zaseknutí". Sériová linka umožňuje zadat timeout na zápis a na čtení. Implicitně bude nulový, takže jde o blokovací čtení. Zadáním nenulové hodnoty v ms, docílíte že se vyvolá výjimka když nebudou v přijímacím bufferu žádné znaky. Jen je potřeba vložit více "catch" větví. Jedna bude ošetřovat pouze timeout a není z hlediska aplikace chybou. Druhá větev řeší obecné výjimky (někdo vyškub USB-RS232 převodník).

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