Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Bohuslav Cink:29.7.2018 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.7.2018 16:45
Avatar
Odpovídá na Bohuslav Cink
Tomáš Vitek:30.7.2018 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.7.2018 13:12
Avatar
Odpovídá na Tomáš Vitek
Bohuslav Cink:30.7.2018 15:38

Posilam printscreen.

 
Nahoru Odpovědět
30.7.2018 15:38
Avatar
Tomáš Vitek:30.7.2018 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.7.2018 17:32
Avatar
Shade
Člen
Avatar
Shade:30.7.2018 22:59

Zkráceně přes anonymní metodu:

string data;
data = serialPort1.ReadLine();
this.Invoke((MethodInvoker)(() => rTxtBoxMonitor.AppendText(data)));
Editováno 30.7.2018 23:01
Nahoru Odpovědět
30.7.2018 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.