Vánoční nadílka Vánoční nadílka
Až 80% zdarma! Předvánoční BLACK FRIDAY akce. Více informací

Diskuze: Serial data recieved

C# .NET .NET (C# a Visual Basic) Serial data recieved American English version English version

Aktivity (3)
Avatar
Bohuslav Cink:29. července 16:45

Zdravím v programování jsem začátečník. Učím se na Arduinu, které chci ovládat aplikací v C# WindowsForm.

Zkusil jsem: Zkoušel jsem použít celou funkci pro "serialPort1.Da­taReceived += new SerialDataRece­ivedEventHandler(Da­taReceivedHan­dler)" a pokaždé co jsou data na příjmu, tak Visual Studio vyhodí chybu s nějakou vyjímkou a chybami.

Chci docílit: Z Arduina budu odesílat na serial 3 stavy nejlépe textem (např. ON,OFF, ERR) nebo v třímístném kódu (např. 101) .
V C# bych potřeboval tyto stavy přečíst nejlepe vypsat do řádku v textboxu, protože mám v plánu tento textbox ukladat do txt. a následně na základě stavu např. ON poslat na serial příkaz.

Nebyl by tu někdo ochotný mi pomoci. Nejlépe kousek kódu třeba pro můj případ.

Moc díky

 
Odpovědět 29. července 16:45
Avatar
Odpovídá na Bohuslav Cink
Tomáš Vitek:30. července 13:12

Napíšeš prosím, co to vyhazuje za chyby, popřípadě kus kódu, ve kterém se to děje?

 
Nahoru Odpovědět 30. července 13:12
Avatar
Odpovídá na Tomáš Vitek
Bohuslav Cink:30. července 15:38

Posilam printscreen.

 
Nahoru Odpovědět 30. července 15:38
Avatar
Tomáš Vitek:30. července 17:32

To je způsobené tím, že to běží na jiném vlákně, než samotný Form.
Ve zkratce vysvětleno: když máš spuštěný nějaký formulář, běží na nějakém vlákně, na kterém se pak spustí kód, i když např. klikneš na tlačítko. Když na něm zrovna běží nějaký Tebou napsaný kód, form Ti nebude reagovat (proto bys neměl přímo do kódu např. po kliknutí na tlačítko psát žádný kód, co trvá dlouho zpracovat - např. když tam dáš

Thread.Sleep(5000);

formulář na 5 sekund (5000 ms) "zmrzne".
Ze stejného důvodu běží ten tvůj serialPort1 na jiném vlánkě - pořád poslouchá, jestli něco nepřišlo. Kdyby to dělal na vlákně Tvého formu, celý formulář by vůbec nereagoval.
Problém s tím ale je, že z jednoho vlákna takto nemůžeš přímo přistupovat do druhého a právě proto Ti to vyhazuje tu chybu.
Řeší se to tak, že tu část kódu, kterou měníš něco ve formu spustíš na vlákně formu. Dělá se to přes metodu Invoke (viz příklad tady ).
Zkusím Ti sem napsat jakýsi úryvek řešení (nebudu celý program psát za Tebe), ale pokud ho chceš pochopit, musíš vědět, co jsou to delegáti, tudíž doporučuji projít (pokud si teda tak už neučinil) zdejší OOP sekci pro C#.

private delegate void NapsatNecoDoFormu(string neco);

private NapsatNecoDoFormu NapsatZpravuDoFormu = NapsatDoLabel1;

private void NapsatDoLabel1(string zprava)
{
        label1.Text = zprava;
}

// V příjmu dat ze SerialPortu:
// metoda Invoke funguje tak, že spustí daný delegát na hlavním vlákně formu a jako argumenty dosadí to, co je v poli objektů
Invoke(NapsatZpravuDoFormu, new object[] {zprava}); // zprava je typu string,

Kód jsem nezkoušel, ale víceméně by měl fungovat, kdyby ne, tak použij ten v oficiální dokumentaci, na kterou jsem Ti dal odkaz.
Pokud by Tě vícevláknové programování zajímalo, rozhodně doporučuji vyzkoušet zdejší sekci na vícevláknové programování v C#.

 
Nahoru Odpovědět 30. července 17:32
Avatar
Shade
Člen
Avatar
Shade:30. července 22:59

Zkráceně přes anonymní metodu:

string data;
data = serialPort1.ReadLine();
this.Invoke((MethodInvoker)(() => rTxtBoxMonitor.AppendText(data)));
Editováno 30. července 23:01
Nahoru Odpovědět  +1 30. července 22:59
Talk is cheap. Show me the code.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.