C# Serial Port readline()

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Bob_check_
  • Registratie: Februari 2009
  • Laatst online: 02-10-2024
Dag iedereen,

wij hebben een laboratorium apparaat, dat met een seriele poort aan de computer is verbonden. Ik heb een windows service geschreven, die de datareceived event gebruikt om de data te ontvangen van dat apparaat en vervolgens verwerkt. Hierin gebruik ik de methode SerialPort.Readline();
Dit werkt perfect, helemaal geweldig.

Nu hadden wij vervolgens een lastige situatie ergens door een machine die te ver weg stond van enig pc, en de seriele kabel van dat ding mocht niet langer zijn dan 7 meter, want dan ging de data verloren.
Oplossing was; een tussenapparaatje dat serieel als input heeft, en netwerk aansluiting als output. Dat tussenapparaatje (TryCom C31S) is redelijk cool, programmeerbaar via software en via webbrowser.
De software maakt ook een virtuele com-poort aan op de pc, en zoekt automatisch het apparaatje in het netwerk (dus je kan hem gewoon in de switch stoppen).

Nu is het volgende het probleem. Ik heb het apparaatje goed gevonden, goed de baudrate, data & stop-bits, parity, allemaal goed ingevuld en goed gemapped met de virtuele com-poort. Als ik HyperTerminal gebruik ziet hij ook perfect alle data binnenkomen (ongeveer 8 regels).

Maar als ik vervolgens mijn eigen Windows C# service gebruik, verwerkt hij maar 2 regels! En als ik nog een keer op zend druk op het laboratorium-apparaat - wat dus alle regels opnieuw moet zenden- krijg ik de volgende 2 regels! Ik begrijp er vrij weinig van. Na een hoop gegoogle heb ik veel gelezen over handshakes om de flow te controleren, dus heb ik daar ook alles settings geprobeerd maar geen resultaat. Ook heb ik gelezen dat de Readline() methode de stroom even blokkeert (dus dit leek me misschien logisch omdat hij maar 2 regels verwerkt, maar nog steeds vind ik het vreemd dat hij dan niet maar 1 regel verwerkt) Ik heb ook readExisting() geprobeerd, maar dan krijg ik ook maar 2 regels binnen. Dus ik ben redelijk gefrustreerd en geen idee wat hier aan de hand is. Waarom krijgt hyperterminal wel alles in 1 keer binnen en ik maar 2 regels?

Alle suggesties zijn welkom :)

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Je moet een "redelijke" tijd wachten( met een maximum natuurlijk) om het geheel tijd te geven alle data naar je machine te krijgen. Het lijkt er nu op dat je een read doet en verwacht dat alle data binnen is, maar het kan heel goed zijn dat de helft binnen is en de rest nog onderweg of nog niet vertrokken uit je apparaat/serieel-ethernet omzetter.

Er is misschien ook wel een mogelijkheid om aan het bericht te zien of alles binnen is, bijvoorbeeld doordat eerst de lengte van het bericht door het apparaat vertuurd wordt of doordat er start/end delimiters worden verstuurd.

[ Voor 4% gewijzigd door farlane op 21-01-2010 16:17 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Bob_check_
  • Registratie: Februari 2009
  • Laatst online: 02-10-2024
zou het zin hebben dan misschien om zodra mijn event is geraised een Thread.Sleep toe te voegen zodat hij lang genoeg wacht? Met Hyperterminal trouwens is alle data wel binnen 1 ms binnen.
Maar het kan zijn dat zodra mijn ding zegt er is data binnen dat ik dan te vroeg mijn readline doe of zoiets dus?

Acties:
  • 0 Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 01:05

Reptile209

- gers -

Ik zou bijna zeggen: probeer je eigen idee even, het kan geen kwaad. Post anders eens wat (relevante!) code, dan kunnen we met je meekijken waar dingen mogelijk misgaan.
Experimenteer anders eens met Read() in plaats van ReadLn(), misschien dat die onnodig blocked op een newline die er niet lekker doorheen komt. Met Read heb je wat meer controle over wat je binnenkrijgt (en kan je het direct naar je scherm dumpen).

Zo scherp als een voetbal!


Acties:
  • 0 Henk 'm!

  • Bob_check_
  • Registratie: Februari 2009
  • Laatst online: 02-10-2024
Hier mijn code van de DataReceived Handler; (erg weinig uiteraard)
public void DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
try
{
System.Threading.Thread.Sleep(500);
processLine(sp.ReadLine());
}
catch (Exception e1)
{
loge("An error has occurred \r\n" + e1.ToString());
}
}

Met 500ms heb ik niet meer regels binnen, dus misschien probeer ik wel een langere sleep van een paar sec...

Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
500 msec zou genoeg moeten zijn, vooral als het apparaat op een lokaal netwerk draait.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 16-09 20:58

Guldan

Thee-Nerd

Bob_check:

Wat krijg je binnen als je sp.ReadExisting gebruikt.. Krijg je dan wel alle gegevens? Readline stopt op het moment dat hij een /r (of /n (dat weet ik niet zeker, dat kun je instellen)) tegenkomt. Dus het kan zijn dat je daarom te weinig binnen krijgt.

edit: en je krijgt gewoon 2 regels binnen? je hebt niet bijvoorbeeld de baud rate verkeerd ingesteld?

[ Voor 16% gewijzigd door Guldan op 22-01-2010 11:27 ]

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Stel je krijgt regel 1 binnen en krijgt dit event, daarna krijg je nog een keer dit event als de tweede t/m vierde regel binnen komen wat gebeurt er dan?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Bob_check_
  • Registratie: Februari 2009
  • Laatst online: 02-10-2024
Ik kreeg idd 2 regels binnen en readline() blockt volgens mij ook meteen de input. In normale seriele communicatie is dat niet erg, want dan gaat hij daarna gewoon verder, maar omdat dit via een netwerk-kabel ging wordt alles in 1 keer verstuurd en is er niet echt een flow control meer.
Maar gelukkig is het opgelost, door eerst een Sleep van 6 sec. te doen en daarna een while loopje erbij met If(port.bytesToRead > 0) readline();
nu krijgt ie alles mee. Ik krijg wel standaard een read error aangezien blijkbaar de bytesToRead niet altijd goed werkt, maar die catch ik gewoon en doe ik verder niets mee. Bedankt voor de hulp!
Pagina: 1