Forum: Mikrocontroller und Digitale Elektronik ATMega8: Kommunikation über RS232 mit C#-Programm


von Herbert G. (feuerfuchs)


Lesenswert?

Hi,

ich bin gerade am Experimentieren mit dem ATMega8 und möchte dass dieser 
mit einem selbst geschriebenen C# Programm kommuniziert.
Als Hardware nutze ich zur Zeit noch das Pollin Board, d.h. 
hardwaremäßig sollten keine Probleme auftreten.

Mittlerweile habe ich es hinbekommen, über eine Terminalsoftware (von 
Bascom) einen Text an den µC zu schicken und ich bekomme auch eine 
Antwort. Wenn ich den Text "Hallo" schicke, leuchtet eine LED für 2 
Sekunden auf.

Das Bascom Programm ist recht einfach:
1
$regfile = "M8def.dat"
2
$crystal = 1000000
3
$hwstack = 100
4
$swstack = 100
5
$framesize = 100
6
$baud = 4800
7
8
Portd.6 = 1 'eine LED
9
10
Dim Empfangen As String * 20
11
12
Print "Bitte sende mir etwas"
13
14
Do
15
   Empfangen = ""
16
    Input Empfangen
17
    If Empfangen = "Hallo" Then
18
      Portd.5 = 1 'eine andere LED
19
      Waitms 2000
20
      Portd.5 = 0
21
    End If
22
23
    Print "Antwort: " ; Empfangen 'Antwort des µC
24
Loop
25
End

Wenn ich allerdings mit einem C# Programm versuche, einen Text aus einer 
Textbox an den µC zu senden, leuchtet keine LED auf wenn ich "Hallo" 
sende, von einer Antwort gar nicht zu reden.
Angenommen ich sende zuerst "Hallo" und kurz darauf "Mikrocontroller", 
scheint sich nichts zu tun. Dann habe ich mein C#-Programm mal 
geschlossen und über den Bascom-Terminal "WieGehts" gesendet. Die 
unerwartete Antwort des Mikrocontrollers war: 
"HalloMikrocontrollerWieGehts". Seinbar scheint der Mikrocontroller also 
in der Inputanweisung stecken zu bleiben.

Mein C#-Programm sieht wie folgt aus:
1
using System;
2
using System.Collections.Generic;
3
using System.Drawing;
4
using System.Windows.Forms;
5
using System.IO.Ports;
6
7
namespace Seriell1
8
{
9
  public partial class MainForm : Form
10
  {
11
    SerialPort serialPort1;
12
    public MainForm()
13
    {
14
      InitializeComponent();
15
      serialPort1 = new SerialPort("COM1",4800,Parity.None,8,StopBits.One);
16
      serialPort1.Handshake=Handshake.None;
17
      serialPort1.RtsEnable=false;
18
        serialPort1.Open();
19
    }
20
    
21
    void BtnSendClick(object sender, EventArgs e)
22
    {
23
            serialPort1.Write(TBText.Text);   // Senden des Textboxinhaltes an den µC
24
        }
25
    
26
    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
27
        {
28
            string inputData = serialPort1.ReadExisting();  // Empfangen des zurückgesendeten Inhalts und Anzeigen in einer Messagebox
29
            MessageBox.Show(inputData);
30
        }
31
    
32
    void MainFormFormClosed(object sender, FormClosedEventArgs e)
33
    {
34
            serialPort1.Close();
35
    }
36
  }
37
}

Weiß jemand was falsch ist? Vermutlich liegt der Fehler im C#-Programm, 
aber ich finde ihn nicht.

Danke für eure Hilfe ;)
MfG feuerfuchs

von Krapao (Gast)


Lesenswert?

Wie erkennt das Input das Ende der Eingabe? Und welches Ende der Eingabe 
schickst du mit deinem C# Programm?

von Herbert G. (feuerfuchs)


Lesenswert?

Danke für deine schnelle Antwort. Das Input erkennt ja das Ende der 
Eingabe über das Stopbit, oder?
Ich dachte, dass dies beim C#-Programm mitgesendet wird. Falls nicht, 
wie sendet man es in C#?

von Thomas E. (thomase)


Lesenswert?

Herbert G. schrieb:
> Danke für deine schnelle Antwort. Das Input erkennt ja das Ende der
> Eingabe über das Stopbit, oder?
Das ist jetzt totaler Unsinn. Das Stopbit ist Bestandteil der 
asynchronen Übertragung.

Wenn du auf dem Terminal nacheinander "H"  "A"  "L"  "L"  "O" eingibst, 
leuchtet die LED?
Oder musst du noch "Return" drücken?

Wenn das so ist, muß das Programm das auch mitsenden und nicht nur den 
Inhalt der Textbox.

Also: serialPort1.Write(TBText.Text+ "\r\n");

mfg.

von Herbert G. (feuerfuchs)


Lesenswert?

Danke, jetzt läuft es (fast) perfekt!
Dein Tipp war goldrichtig, danach habe ich mich dem Empfang gewidmet, 
der zunächst nicht funktioniert hat. Da hat dann aber noch eine Zeile im 
Code gefehlt, so funktioniert es:
1
using System;
2
using System.Collections.Generic;
3
using System.Drawing;
4
using System.Windows.Forms;
5
using System.IO.Ports;
6
7
namespace Seriell1
8
{
9
  public partial class MainForm : Form
10
  {
11
    SerialPort serialPort1;
12
    public MainForm()
13
    {
14
      InitializeComponent();
15
      serialPort1 = new SerialPort("COM1",4800,Parity.None,8,StopBits.One);
16
      serialPort1.Handshake=Handshake.None;
17
      serialPort1.RtsEnable=false;
18
        serialPort1.Open();
19
        serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
20
    }
21
    
22
    void BtnSendClick(object sender, EventArgs e)
23
    {
24
            serialPort1.Write(TBText.Text+"\r\n");   // Senden des Textboxinhaltes an den µC
25
        }
26
    
27
    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
28
        {
29
      string inputData = serialPort1.ReadLine();  // Empfangen des zurückgesendeten Inhalts und Anzeigen in einer Messagebox
30
      MessageBox.Show(inputData.ToString());
31
        }
32
    
33
    void MainFormFormClosed(object sender, FormClosedEventArgs e)
34
    {
35
            serialPort1.Close();
36
    }
37
  }
38
}

Beim Empfang öffnen sich zwei Messageboxes nacheinander statt einer, 
aber der Empfang war eh nur zu Testzwecken insofern ist es nicht ganz so 
schlimm.

Nochmal vielen Dank! :)

von Thomas E. (thomase)


Lesenswert?

Herbert G. schrieb:
> Beim Empfang öffnen sich zwei Messageboxes nacheinander statt einer,

Du sendest hier zwei Strings, die beide mit einem Zeilenende(CRLF) 
abgeschlosen werden:
Herbert G. schrieb:
> Print "Antwort: " ; Empfangen 'Antwort des µC

Die werden dann hier nacheinander abgearbeitet:
Herbert G. schrieb:
> string inputData = serialPort1.ReadLine();
Deswegen zwei MBs.

mfg.

von feuerfuchs (Gast)


Lesenswert?

Hi,

so ganz funktioniert es mit dem Empfang leider doch noch nicht, offenbar 
scheint das vom C#-Programm gesandte nicht 100%-ig mit dem vom Terminal 
übereinzustimmen.

Wenn ich im Mikrocontroller ein Programm habe, dass den empfangenen 
String in eine Zahl umwandelt und damit per PWM die Helligkeit einer LED 
regelt, so funktioniert dies beim Terminal perfekt. Wenn ich dazu das C# 
Programm verwende, so funktioniert dies nur beim ersten Versenden. 
Danach muss ich wieder ein paar mal mit dem Terminal Zahlen versenden, 
bevor ich wieder über das C#-Programm versenden kann.

Meine Vermutung ist, dass das Problem iergendwas mit Zeilenumbrücken 
("\r\n") zu tun hat. Ich schon versucht im Mikrocontroller vor der 
Umwandlung des Strings in ein Byte "\r\n" zu ersetzen, aber das hat 
nichts gebracht.

Ich hoffe es ist genau genug beschrieben. Wenn ihr genauere Daten 
braucht (z.B. den Programmcode) kann ich den gerne noch senden.
Danke, MfG feuerfuchs ;)

von Krapao (Gast)


Lesenswert?

Lass mal das \n (Linefeed) weg und benutze nur \r (Return). Das macht 
wahrscheinlich das Terminalprogramm.

von Thomas B. (nichtessbar)


Lesenswert?

feuerfuchs schrieb:
> Umwandlung des Strings in ein Byte "\r\n" zu ersetzen

Unglücklich ausgedrückt oder wirklich in ein Byte? \r und \n sind JE ein 
Byte. Kannst du dir im Debugger die Empfangspuffer anschauen? Die wären 
interessant ;)

von MWS (Gast)


Lesenswert?

feuerfuchs schrieb:
> Meine Vermutung ist, dass das Problem iergendwas mit Zeilenumbrücken
> ("\r\n") zu tun hat. Ich schon versucht im Mikrocontroller vor der
> Umwandlung des Strings in ein Byte "\r\n" zu ersetzen, aber das hat
> nichts gebracht.

Braucht's auch nicht, man kann Bascom sagen wie es zu reagieren hat.
Passend zum Sendecode:
1
serialPort1.Write(TBText.Text+"\r\n");
wär' das:
1
Config Input = CRLF

von Herbert G. (feuerfuchs)


Lesenswert?

Danke für all die Antworten, ich habe das 1. ausprobiert und endlich 
funktioniert es, wie ich es will :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.