Forum: PC-Programmierung ReadLine soll uC lesen


von Dell (Gast)


Lesenswert?

Hallo zusammen,

Ich habe ein bisschen mit der seriellen Schnittstelle und einem Atmega32 
rumgebastelt. Geschrieben wird in C# (Programm) und C(uC)

So schalte ich beispielsweise eine LED an, wenn ich einen Button in 
meinem Programm drücke: (Einfache Funktion zu Testzwecken)

PC:
 private void button5_Click(object sender, EventArgs e)
        {
            long bitWert = 0xFF;
            string bitString = Convert.ToString(bitWert, 2);
            serialPort1.Open();
            serialPort1.WriteLine(bitString);
            serialPort1.Close();
        }

uC:
receiveData= uart_getc();
if (receiveData == 0b11111111){
 PORTA ^= (1 << PA0);
 receiveData=0;
}


Funzt wunderbar.

Nun in die andere Richtung!!

PC:
 private void button6_Click(object sender, EventArgs e)
        {
            string test;
            serialPort1.Open();
            test = serialPort1.ReadLine();
            serialPort1.Close();
            textBox11.Text = test;
        }

uC:
uart_putc(100); //iwas...
uart_putc(0x0A);//...und Linefeed anhängen



So einfach scheint es nicht zu gehen...


Mein Programm wartet und wartet und wartet...
Habe auch schon versucht die NewLine-Eigentschaft zu ändern und ein 
anderes (weniger kryptisches) zu verwenden.

Es mag vielen sicher sehr leicht vorkommen, aber wie lese ich nun einen 
8-bit Wert mit meinem Programm ein, wenn ich mit dem Mikrocontroller zum 
beispiel nur uart_putc(100); schreibe.

Möchte den Weg über das Datareceived Event NICHT gehen.

Ich möchte nachher einen Code vom Programm aus senden, der dem 
Mikrocontroller signalisiert: "Hey, schicke mir doch mal bitte deinen 
ADC-Wert vom x. Kanal".
Der Mikrocontroller soll daraufhin den 8-bit Wert senden und dieser soll 
entsprechend im Programm eingelesen werden.


LG

Dell

von Quizbart (Gast)


Lesenswert?

Dir ist aber schon klar, dass du synchronen Code in deinem GUI Thread 
ausführst? Damit dürfte die ganze Anwendung hängen und unbenutzbar 
werden.

Dell schrieb:
> Möchte den Weg über das Datareceived Event NICHT gehen.

Genau das solltest du aber tun.

von P. E. (philenotfound)


Lesenswert?

Dell schrieb:
> uC:
> uart_putc(100); //iwas...
> uart_putc(0x0A);//...und Linefeed anhängen

Mach dazwischen noch ein uart_putc(0x0d);
Unter Windows werden Zeilen mit "\r\n" abgeschlossen.

von Dirk (Gast)


Lesenswert?

Du kannst das Rad auch neu erfinden!
Meine Empfehlung nimm das einfache MODBUS-Protokol.
Dann brauchst du dich nicht selber um CRC und dergleichen zu kümmern.

von Dell (Gast)


Lesenswert?

Dirk schrieb:
> Du kannst das Rad auch neu erfinden!
> Meine Empfehlung nimm das einfache MODBUS-Protokol.
> Dann brauchst du dich nicht selber um CRC und dergleichen zu kümmern.

Hast du überhaupt meinen Beitrag gelesen, oder nur die Überschrift und 
hast dann etwas dementsprechend Kluges zu sagen?!

Sorry, aber das entspricht doch überhaupt nicht meiner 
Fragestellung/anforderung.


Nach weiterer Recherche kam ich dazu, dass es wohl Eventgesteuert sein 
MUSS. RS232 zu pollen soll wohl sehr schlecht funktionieren.

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Es mag vielen sicher sehr leicht vorkommen, aber wie lese ich nun einen
> 8-bit Wert mit meinem Programm ein, wenn ich mit dem Mikrocontroller zum
> beispiel nur uart_putc(100); schreibe.

mit read.

von Dirk (Gast)


Lesenswert?

Dell schrieb:
Ich möchte nachher einen Code vom Programm aus senden, der dem
> Mikrocontroller signalisiert: "Hey, schicke mir doch mal bitte deinen
> ADC-Wert vom x. Kanal".
> Der Mikrocontroller soll daraufhin den 8-bit Wert senden und dieser soll
> entsprechend im Programm eingelesen werden.

Das deutet daraufhin, dass su noch mher vor hast. Ich wollte Dir einen 
Tipp geben, damit du (aus meiner über 20 jährigen Erfahrung mit 
Protokollen heraus) nicht in die falsche Richtung läufts.
Wenn du jetzt deine Augen aufmachst, bekommst du ziemlich viele 
Implementierungen zu dem Thema Modbus.

zu deinem Problem:
Du solltest dir einfach mal die Doku zu dem Thema ReadLine und Read 
ansehen.
Wenn du das getan hättest, würdest du sehr schnell feststellen, das 
Readline immer ein CR zum Abschluß erwartet und so lange den Prozeß 
einfriert. Also die denkbar schlechteste Wahl.
Wenn du unbedingt mit CR arbeiten willst (dein problem!) dann lese 
wenigsten die Zeichenkette mit Read ein und prüfe bei jedem empfangenen 
Zeichen auf CR.

von Dirk (Gast)


Lesenswert?

Sorry, wenn ich dir helfen wollte!

von Dirk (Gast)


Lesenswert?

Muss mich korrigieren bei C# ist CRLF nicht CR

von arc net (Gast)


Lesenswert?

Das
1
long bitWert = 0xFF;
2
string bitString = Convert.ToString(bitWert, 2);
3
serialPort1.Open();
4
serialPort1.WriteLine(bitString);
5
serialPort1.Close();
6
7
receiveData= uart_getc();
8
if (receiveData == 0b11111111){
9
    PORTA ^= (1 << PA0);
10
    receiveData=0;
11
}

kann eigentlich nicht funktionieren...
Convert.ToString gibt einen String zurück "11111111" d.h. beim 
Controller kommt 0b00110001, 0b00110001, ... an...
Sollen wirklich alle Werte von 0 bis 255 ohne Probleme ankommen, sollte 
das Encoding passend eingestellt werden
serialPort.Encoding = System.Text.Encoding.GetEncoding(28591);
Geschrieben werden kann dann bspw. mit serialPort.Write((char)255) etc.

ReadLine kann man durchaus verwenden: Wenn das Blockieren nicht stört 
und man die Timeouts passend einstellt oder ReadLine in einen eigenen 
Thread, BackgroundWorker etc. verpackt, wo das nicht den GUI-Thread 
stört.

von Dell (Gast)


Lesenswert?

Danke für die Antworten und die shcnelle Hilfe.

Dirk, ich wollte dir nicht zu Nahe treten, aber für mich waren deine 
ersten hinweise nun mal wenig hilfreich und aus dem zusammenhang 
gerissen, bzw. für meinen fall/bedürfnisse nicht hilfreich. Das mag sich 
vll noch ändern. Die Doku habe ich gelesen. Sonst würde ich kein Thema 
starten. Immer erst selber nachdenken/suchen/machen bevor man hier um 
Hilfe bittet.. :)


Habe nun einen Eventhandler eingefügt, aber mit ReadLine wills immernoch 
nicht so recht. Habe nun aber verschiedene Sachen ausprobiert, die 
leider ohne Erfolg blieben.

Der mir sinnvollste Lösungsansatz:

PC:
 private void button5_Click(object sender, EventArgs e)
        {
            string WrittenLine;
            int Test = 0xFF;
            WrittenLine = Convert.ToString(Test,2);
            textBox10.Text = WrittenLine;
            serialPort1.WriteLine(WrittenLine);
        }

uC:
receiveData= uart_getc();
if (receiveData == 0b11111111){
  PORTA ^= (1 << PA0);
  receiveData=0;
  uart_putc(0xFF);
  //uart_putc(0x0A); //LF
  //uart_putc(0x0D); //CR


Die Daten kommen an und die LED geht an.

Nun zurück zum PC:
 void serialPort1_DataReceived(object sender, 
SerialDataReceivedEventArgs e)
        {
            ReceivedLine = serialPort1.ReadChar();
            if (ReceivedLine == 0xFF) {
                Teststring = "Hallo";
            }
        }


Teststring und ReceivedLine sind global. Die ankommende Nachricht wird 
via Timer in eine Textbox geschrieben, da es sonst zu Threadproblemen im 
Data_receive Event kam. Vielleicht unsauber aber zum testen reicht es 
ja.

Habe wie gesagt im Receive_event unterschiedliche Reads benutzt. Z Bsp 
ReadLine und dementsprechend LF und CR angehangen.
Ebenfalls habe ich versucht den empfangenen char-Wert zu konvertieren 
und dann in eine Textbox zu schreiben. Da zeigte er mir immer nur "0" 
an. Deshalb habe ich auch den Vergleich angestellt und daraufhin einen 
Teststring geschrieben,um mögliche konverierungsfehler zu umgehen.


Verbinde ich TX und RX auf der PC Seite, so erhalte ich mein Echo sauber 
zurück und kann es auch über ReadLine zurücklesen, eben weil ich mit 
WriteLine sende und so das NewLine zeichen angehangen wird.
Auch mit verschiednene NewLine-values habe ich rumgebastelt. Keine 
Lösung..


Das Problem ist sicher leicht zu lösen. Bin auch etwas frustriert, dass 
nach mehreren Stunden nix bei rumkam. Normalerweise macht man zumindest 
kleine Fortschritte ...


LG und nochmal danke ;)

Peter

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> void serialPort1_DataReceived(object sender,
> SerialDataReceivedEventArgs e)
>         {
>             ReceivedLine = serialPort1.ReadChar();
>             if (ReceivedLine == 0xFF) {
>                 Teststring = "Hallo";
>             }
>         }

das kann nicht gehen, In den Event darf/musst so so viele zeichen Lesen 
wir aktuell da sind nicht mehr und nicht weniger.

dafür gibt es serialPort1.BytesAvailable (oder so ähnlich)

von Dell (Gast)


Lesenswert?

nachtrag:

arcnet:

es funzt aber :)

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> void serialPort1_DataReceived(object sender,
>> SerialDataReceivedEventArgs e)
>>         {
>>             ReceivedLine = serialPort1.ReadChar();
>>             if (ReceivedLine == 0xFF) {
>>                 Teststring = "Hallo";
>>             }
>>         }
>
> das kann nicht gehen, In den Event darf/musst so so viele zeichen Lesen
> wir aktuell da sind nicht mehr und nicht weniger.
>
> dafür gibt es serialPort1.BytesAvailable (oder so ähnlich)

Lese ich mit ReadExisting, konvertiere das Ergebnis und gebe es in eine 
Textbox aus, kommt wiederum "0" raus...

Daten vom uC gehen auf jeden Fall raus. Habe einen 2. uC angehangen und 
überprüft, ob die richtige Botschaft rausgeht. Das tut es..

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Lese ich mit ReadExisting, konvertiere das Ergebnis und gebe es in eine
> Textbox aus, kommt wiederum "0" raus...

du hast aber keine Strings. ReadExisting liefert einen String. Verwende 
doch bitte die byte funktionen dafür.

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> Lese ich mit ReadExisting, konvertiere das Ergebnis und gebe es in eine
>> Textbox aus, kommt wiederum "0" raus...
>
> du hast aber keine Strings. ReadExisting liefert einen String. Verwende
> doch bitte die byte funktionen dafür.

Dementsprechend habe ich natürlich auch die Formate angepasst bzw 
konvertiert. Ganz blöd bin ich auch nicht...

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Dementsprechend habe ich natürlich auch die Formate angepasst bzw
> konvertiert. Ganz blöd bin ich auch nicht...

Wenn du meinst, das du mit strings besser zurecht kommst dann mache es 
so. Ich würde es nicht machen.

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> Dementsprechend habe ich natürlich auch die Formate angepasst bzw
>> konvertiert. Ganz blöd bin ich auch nicht...
>
> Wenn du meinst, das du mit strings besser zurecht kommst dann mache es
> so. Ich würde es nicht machen.

Es geht ja im ersten Schritt nur darum überhaupt den Wert aus dem Puffer 
raus zu holen. Da hapert es ja.

Stellen wir die Frage einfach mal allgemeiner:

Der uC schreibt mit uart_putc(0xff) einen Wert in den Puffer. Nun möchte 
ich diesen Wert per Data_Receive-Event einlesen und in eine Textbox 
ausgeben. Der Code dürfte doch nur wenige Zeilen betragen. Ich bin es 
selber auch nicht gewohnt, dass es so hapert..Alles andere im Projekt 
hat nach Recherche, basteln und probieren immer geklappt..

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Der uC schreibt mit uart_putc(0xff) einen Wert in den Puffer. Nun möchte
> ich diesen Wert per Data_Receive-Event einlesen und in eine Textbox
> ausgeben.

dann mach es doch mal mit der read und der BytesAvailable funtion. Dann 
sieht du auch gleich wie viele Byte denn empfangen werden.

von Dell (Gast)


Lesenswert?

Nach weiterem rumbasteln, war ich es Leid und habe mir erstmal ein 
leeres neues Projekt gemacht um nur den serial port zu testen.

TX und RX krzgeschlossen fürs Echo hat auch geklappt.

Hier der C# Code:
1
public partial class Form1 : Form
2
    {
3
4
        byte[] ToSend = new byte[] {0x8a,0xf0,0xff};
5
        byte[] ToReceive = new byte[3];
6
        int Anzahl;
7
        string Test;
8
9
        public Form1()
10
        {
11
            InitializeComponent();
12
            serialPort1.DataReceived+=new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived);
13
        }
14
15
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
16
        {
17
            Anzahl = serialPort1.BytesToRead;
18
            serialPort1.Read(ToReceive, 0, Anzahl);
19
        }
20
21
        private void button1_Click(object sender, EventArgs e)
22
        {
23
            if (!serialPort1.IsOpen)
24
            {
25
                serialPort1.Open();
26
                label1.Text = "Port ist offen";
27
                button1.Text = "Port schließen";
28
            }else{
29
                serialPort1.Close();
30
                label1.Text = "Port ist geschlossen";
31
                button1.Text = "Port öffnen";
32
33
            }
34
        }
35
36
        private void button2_Click(object sender, EventArgs e)
37
        {
38
            textBox1.Text = Convert.ToString(ToSend[0], 2).PadLeft(8, '0');
39
            serialPort1.Write(ToSend,0,1);
40
        }
41
42
        private void button3_Click(object sender, EventArgs e)
43
        {
44
            textBox2.Text = Convert.ToString(ToReceive[0], 2).PadLeft(8, '0');
45
        }
46
    }

Was geschieht:
Button 1 drücken-->Port wird geöffnet
Button 2 drücken-->Das gesendete Byte wird in Textbox 1 angezeigt
Data_receive------>Wert wird in ToReceive Array geschrieben
Button 3 drücken-->Wert im ToReceive Array in Textbox schreiben

Habe es so gemacht, damit ich mich vorerst nicht um die Threads kümmern 
muss.
Hatte bei Button 3 auch noch eine Ausgabe der "Anzahl" drin. Diese war 
aber immer 0, obwohl er erst die Anzahl der zu lesenden Zeichen in 
"Anzahl" schreibt und danach liest. Müsste eigntl nicht immer die 1 
auftauchen, da erst erkannt wird, dass 1 byte vorhanden ist und er 
danach erst liest?! Das wunderte mich ein wenig. Als ich 
serialport1.read(xyz) auskommentiert habe, ging die Anzahl mit jedem 
Senden dementsprechend hoch. Wie erwartet. Aber warum schreibt er mir 
eine 0, wenn er doch erst danach liest?!
Naja. Das ist ein anderes Thema.

Auf dem Mikrocontroller schauts wie folgt aus:
1
#include "UART.h"
2
3
int main(void)
4
  {
5
  DDRA |= (1 << PA0);
6
7
  uart_Init();
8
  
9
  unsigned char receiveData;
10
  
11
  while (1)
12
    {
13
14
    receiveData= uart_getc();
15
16
    if (receiveData ==0x8a){ 
17
      PORTA ^= (1 << PA0);
18
      receiveData=0;
19
      }
20
    
21
  }
22
}

Die LED geht aber nicht an. Wenn ich mir alein das Echo ansehe, stimmen 
die Daten aber (wie oben beschrieben).

Lese ich vll mit dem uC falsch ein?

Die putc-Funktion ist die gleiche wie ausm Tutorial.

Baud, Databits, Parity etc habe ich im C#-Programm fest vergeben um mir 
die paar Zeilen zu sparen.
9600Baud, 8Daten, 2 Stoppbits, No Parity, No Handshake

Spielt sicher keine Rolle, aber verwende einen MM232 UART-to-USB 
Converter.  Wird auch wunderbar als COM-Port erkannt. Da sollte alles 
wunderbar laufen.

Liebe Grüße und danke

von Peter II (Gast)


Lesenswert?

serialPort1.Read(ToReceive, 0, Anzahl);

du musst auch den Return auswerten, denn dort steht die Anzahl drin 
wiviel wirklich gelesen wurde.

von Dell (Gast)


Lesenswert?

Nachtrag: Kanns am encoden liegen? Würde gern mit Rohwerten arbeiten, so 
wie zwischen 2 uCs. Denn da hab ich ich nie Probleme gehabt :) Bits 
einlesen, vergleichen, fertig...
Hat niemand etwas geschrieben ála:
uC schickt mit putc(0x67);  und mit dem C# programm wird der 0x67 Wert 
in eine Integer Variable geschrieben?

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> serialPort1.Read(ToReceive, 0, Anzahl);
>
> du musst auch den Return auswerten, denn dort steht die Anzahl drin
> wiviel wirklich gelesen wurde.

Ist mir bekannt, aber ich benutze "Anzahl" ja um erstmal zu erkennen 
wieviel zu lesen ist. Wieviel gelesen wurde ist zwar auch gut zu wissen, 
aber so oder so, dürfte sich der Wert in "Anzahl" doch nicht ändern, 
wenn ich NACH dem schreiben in "Anzahl" erst den readbefehl ausführe?!

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Nachtrag: Kanns am encoden liegen?

nein, denn das passiert nur wenn man mit Strings arbeitet.

Dell schrieb:
> Ist mir bekannt, aber ich benutze "Anzahl" ja um erstmal zu erkennen
> wieviel zu lesen ist. Wieviel gelesen wurde ist zwar auch gut zu wissen,
> aber so oder so, dürfte sich der Wert in "Anzahl" doch nicht ändern,
> wenn ich NACH dem schreiben in "Anzahl" erst den readbefehl ausführe?!

warum nimmst du nicht einfach den debugger, setze ein paar breakpoint 
und schau wo die Variable geändert wird. Man kann auch debugausgaben 
schreiben, dann muss man nicht mit irgendwelche Textboxen und Buttons 
arbeiten.

von Dirk (Gast)


Lesenswert?

Hallo Dell,
Also dein µC Programm sieht gut aus.
Wenn die Baudraten richtig berechnet sind sollte es passen.
Nimm doch einfach mal ein einfaches Terminal Programm und übertrage zum 
test einfach mal "Standard Zeichen", die dann auswertest.
oder mit nem Debugger einen Brechpunkt auf den Vergleich!
Dirk

von Peter II (Gast)


Lesenswert?

private void serialPort1_DataReceived(object sender, 
System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Anzahl = serialPort1.BytesToRead;
            system.Diagnostic.Debug.WriteLine("Anzahl: {0}", Anzahl );
            Anzahl = serialPort1.Read(ToReceive, 0, Anzahl);
            system.Diagnostic.Debug.WriteLine("Anzahl: {0}", Anzahl );
            system.Diagnostic.Debug.WriteLine("Daten:");
            for( int i = 0; i < Anzahl; i++ ) {
               system.Diagnostic.Debug.Write("{0},", ToReceive[i] );
            system.Diagnostic.Debug.WriteLine("");

        }

von Dell (Gast)


Lesenswert?

Danke für den Debug Tipp. Den kannte ich noch nicht.

Kann mir jetzt noch einer sagen, warum am uC die LED nicht angeht?
Irgendwas im Code ersichtlich?
Baud etc. ist richtig eingestellt. Da bin ich mir 100% sicher ;)

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Irgendwas im Code ersichtlich?

nein, wie sehen zu wenig code:

uart_getc();

wie sieht denn uart_getc aus?

von Dirk (Gast)


Lesenswert?

Der Code sieht gut aus!
Debugger einsetzen!
Oder hast du den Watschdog enabled ?
Dann könnte es ein Problem geben, da uart_getc glaube ich auf ein 
Zeichen wartet.

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> Irgendwas im Code ersichtlich?
>
> nein, wie sehen zu wenig code:
>
> uart_getc();
>
> wie sieht denn uart_getc aus?

Bin grad am anderen Rechner, aber ist die gleiche wie aus dem Tutorial. 
Vergewisser mich nachher aber nochmal. Aber die Kommunikation zwischen 2 
uCs hat damit ja auch wunderbar geklappt.

Dirk:
Watchdog ist aus.

von Dirk (Gast)


Lesenswert?

Dann ist dein Code im µC soweit in Ordnung.
Nimm doch mal einfach ein Terminal auf dem PC,
vergleichst im µC auf z.b.. "a" und sendest ein "a"
dann solltes klappen.
ggfs. echost du einfach mal das was empfangen hast zurück
auf nach dem getc ein putc mit dem selben wert

    receiveData= uart_getc();
    uart_putc(receiveData);

    if (receiveData == "a"){ // oder wars 'a' (springe ständig zwischen 
Pascal und C hinundher
      PORTA ^= (1 << PA0);
      receiveData=0;

von Dell (Gast)


Lesenswert?

private void serialPort1_DataReceived(object sender, 
System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Anzahl = serialPort1.BytesToRead;
            Test = Convert.ToString(Anzahl);
            MessageBox.Show(Test);
            Anzahl = serialPort1.Read(ToReceive, 0, Anzahl);
            Test = Convert.ToString(Anzahl);
            MessageBox.Show(Test);
        }

Spuckt mit 1,1,0,0 aus.
Scheinbar wird mein Event ein zweites mal gefeuert. Aber warum? 
Schließlich ist nichts da zum lesen, was mir die 0,0 ja auch bestätigt..

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Scheinbar wird mein Event ein zweites mal gefeuert. Aber warum?

keine ahnung, ist bei mir noch nie vorgekommen, liegt eventuell an 
deiner Messeagebox in der Eventbehandlung.
Warum verwendst du nicht die Debug ausgaben?

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> Scheinbar wird mein Event ein zweites mal gefeuert. Aber warum?
>
> keine ahnung, ist bei mir noch nie vorgekommen, liegt eventuell an
> deiner Messeagebox in der Eventbehandlung.
> Warum verwendst du nicht die Debug ausgaben?

Weil ich nicht wusste, wo ich die sehen kann und nach einer Google Suche 
habe ich festgestellt, dass ich wohl noch ein paar Einstellungen 
vornehmen muss, damit das klappt. Da fand ich die MessageBox angenehmer 
und leichter.

Mit:
1
 private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
2
        {
3
            DataReceiveCount++;
4
            AnzahlBytesToRead = serialPort1.BytesToRead;
5
          //  Test = Convert.ToString(AnzahlBytesToRead);
6
          //  MessageBox.Show(Test);
7
            AnzahlBytesReceived = serialPort1.Read(ToReceive, 0, AnzahlBytesToRead);
8
         //   Test = Convert.ToString(AnzahlBytesReceived);
9
         //   MessageBox.Show(Test); 
10
        }

Ist mein DataReceiveCount trotzdem auf 2. An der Messageboxen liegts 
nicht. Hätte mich auch gewundert...

von Dell (Gast)


Lesenswert?

Meine Variable in dem ToReceive Array bleibt nach dem zweiten Lesen 
übrigens die gleiche. Also wird der Wert nicht überschrieben. Ergo wird 
der Readbefehl auch nicht ein zweites mal ausgeführt. Das liegt denk ich 
daran, dass AnzahlBytesToRead beim 2. feuern 0 ist.

Aber warum feuert er überhaupt ein zweites mal, wenn er doch nix zu 
lesen hat?!

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Weil ich nicht wusste, wo ich die sehen kann

welche IDE verwendest du? Im VisualStuido kommt es einfach im Fenster 
Debug - da muss man nichts einstellen.

> Hätte mich auch gewundert...
mich nicht, weil du das aulesen verzögerst.

Evnetuell macht es ja deine Treiber so, dann mach einfach return wenn 0 
byte da sind.

von Peter II (Gast)


Lesenswert?

> Aber warum feuert er überhaupt ein zweites mal, wenn er doch nix zu
> lesen hat?!
was noch sein kann ist, das du den Eventhandler 2 mal registeriert hast. 
Dann kann genau das passieren.

von Dell (Gast)


Lesenswert?

Peter II schrieb:
>> Aber warum feuert er überhaupt ein zweites mal, wenn er doch nix
> zu
>> lesen hat?!
> was noch sein kann ist, das du den Eventhandler 2 mal registeriert hast.
> Dann kann genau das passieren.

Das ist er...Aber wo? In meinem Code habe ich die Zeile auskommentiert. 
Also steckte sie noch iwo anders drin. Mein ReceiveCount ist jetzt 
schonmal 1 :)
Mal sehn wie es weiter geht..

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Das ist er...Aber wo? In meinem Code habe ich die Zeile auskommentiert.
> Also steckte sie noch iwo anders drin. Mein ReceiveCount ist jetzt
> schonmal 1 :)

du hast in bestimmt in der GUI bei den Events eingetragen. ObjetEditor 
vom SerialPort

von Peter II (Gast)


Lesenswert?

Du solltest dich wirklich erstmal mit deiner IDE vertraut machen. Das 
klingt alles als ob du zum erstmal mit dem Studio arbeitest. Du schaffst 
dir damit deine Probleme selber.

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> Das ist er...Aber wo? In meinem Code habe ich die Zeile auskommentiert.
>> Also steckte sie noch iwo anders drin. Mein ReceiveCount ist jetzt
>> schonmal 1 :)
>
> du hast in bestimmt in der GUI bei den Events eingetragen. ObjetEditor
> vom SerialPort

Hab ich auch. Hatte ich vollkommen vergessen...Hatte dieses mal zum 
ersten mal die ganzen Events über die Objekte eingefügt, anstatt 
manuell. Daher wars doppelt drin..

Am uC kommt trotzdem nichts an...

von Dell (Gast)


Lesenswert?

Dell schrieb:
> Peter II schrieb:
>> Dell schrieb:
>>> Das ist er...Aber wo? In meinem Code habe ich die Zeile auskommentiert.
>>> Also steckte sie noch iwo anders drin. Mein ReceiveCount ist jetzt
>>> schonmal 1 :)
>>
>> du hast in bestimmt in der GUI bei den Events eingetragen. ObjetEditor
>> vom SerialPort
>
> Hab ich auch. Hatte ich vollkommen vergessen...Hatte dieses mal zum
> ersten mal die ganzen Events über die Objekte eingefügt, anstatt
> manuell. Daher wars doppelt drin..
>
> Am uC kommt trotzdem nichts an...

Oder um es korrekter zu sagen: Es kommen 00000000 an. Also wohl ein 
leerer Buffer.
1
#include "UART.h"
2
3
int main(void)
4
  {
5
  DDRA=0xff;
6
7
  uart_Init();
8
  
9
  unsigned char receiveData=0xff;
10
  
11
  while (1)
12
    {
13
14
    
15
    receiveData= uart_getc();
16
    PORTA=receiveData;
17
/*
18
    if (receiveData ==0x8a){ 
19
      PORTA ^= (1 << PA0);
20
      
21
      receiveData=0;
22
      }
23
  */    
24
    
25
  }
26
}

Am PORTA hängen 8 LEDs

von Dell (Gast)


Lesenswert?

Wenn ich mit Putc(0x88); schreibe, kommt in meinem C# Programm 00000000 
an. Mein DataReceiveCount geht flott hoch. Schcike alle 500ms die 
Nachricht.
Selbst wenn Baud etc falsch eingestellt sein sollte, sollte Mist 
rauskommen und evtl immer unterschiedliche Daten, aber nicht IMMER 
00000000...

Also passieren tut ja scheinbar was.. ;P

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> Also passieren tut ja scheinbar was.. ;P

steck in Oszi an und Prüfen die Leitung und die Baudrate.

von Dell (Gast)


Lesenswert?

uC while-schleife:
1
if((PIND & (1<<PD6))){
2
    uart_putc(0x88);
3
    PORTA^=0x01;
4
    _delay_ms(500);
5
    }

Im C# Programm erhalte ich 2 (!) DataReceive-Events und Daten 00000000.
Echo ich mein C# Programm erhalte ich nur 1 DataReceive-Event, so wie es 
sein soll und die richtigen Daten.

Sende ich von uC an einen anderen uC auf dem die while-Schleife so 
aussieht:
1
receivedData=uart_getc();
2
    if(receivedData==0x88){
3
    PORTA^=0x01;
4
    }

funktioniert es auch wunderbar.


Sende ich mit C# irgendetwas raus und frage beim uc irgendetwas ab:
1
receivedData=uart_getc();
2
PORTA^=0x01;
3
_delay_ms(500);

..so geschieht rein gar nicht. Er hängt in der uart_getc() fest. Da kann 
ich so oft senden wie ich will und was ich will. Die LED bleibt aus.
Sollte nicht wenigstens irgendein Zeichen verfügbar sein, damit er aus 
der uart_getc() wieder raus kommt?!

von Dell (Gast)


Lesenswert?

Und ich bin mir 100% sicher, dass die Frame-Formate richtig eingestellt 
sind..

von Peter II (Gast)


Lesenswert?

sende doch mal von µC die zeichen '0' bis '9' und dann nimmst du putty 
und schaust was im PC ankommt.

von Dirk (Gast)


Lesenswert?

Das sieht leider nicht danach aus!
nimm ein Oszi und miss nach!
Nimm mal ganz einfach ein Terminal-Programm
um das Senden zum µC zu überprüfen.
2. Baustellen sind immer Sch....
Du bist dir auf beiden Seiten nicht sicher was du machst.
Also nimm eine Baustelle weg..
Terminal-Prog und µC, bis µC das macht was du willst.
dann PC-Programm.
Oder Terminal-Programm und PC-Programm über null-modem Kabel koppeln und 
dann das PC-Programm programmieren.
(gibt auch SW-Nullmodemkabel!)

von Dirk (Gast)


Lesenswert?


von Peter II (Gast)


Lesenswert?

Dirk schrieb:
> http://sourceforge.net/projects/com0com/

hilft überhauptnicht weiter bei dem Problem. Denn Dort spielt die 
Baudrate keine rolle. Dort kann man auch mit 9600 senden und mit 14400 
empfangen.

von Dirk (Gast)


Lesenswert?

Stimmt zur Überprüfung der Baudrate, wenn du 2 mal das gleiche Programm 
startest.
Stellst du aber 9600 Baud bei Terminal-Programm ein, so sollten 9600 
Baud auch rauskommen, oder?
Dann kannst du dir sicher sein, wenn dein eigenes Programm dann mit dir 
(dem Terminal) spricht, das du da keinen Fehler mehr hast.
Wenn du dann das Terminal nutzt um mit dem µC zu reden (gleiche 
baudrate) dann solltest du auch die Übertragungsgeschwindigkeit prüfen 
können....
Oder habe ich da jetzt einen Denkfehler.

von Peter II (Gast)


Lesenswert?

Dirk schrieb:
> Oder habe ich da jetzt einen Denkfehler.

das macht einfach keinen sinn, er würde sich damit noch eine baustelle 
mehr schaffen.

Er soll einfach das ein paar zeichen (nicht immer das gleiche) vom µC 
zum PC senden und mit einen Programm was definitiv arbeitet (Putty) so 
lange rumspielen bis er alle Zeichen sauber sieht.

von Dirk (Gast)


Lesenswert?

Sag ich doch!
erst ein Programm in Ordnung bringen!
Entweder µC oder PC.
bloß für den PC braucht er ein Hilfsmittel um mittels Putty mit seinem 
Programm zu reden.
Kann man natürlich mit einem Nullmodemkabel machen, wenn man den noch 2 
RS232 hat....
Oder eben die Softwarelösung, die mich schon oft gerettet hat.
Als terminal Prog würde ich aber Hterm empfehlen, damit kannst du auch 
gleich die Zeichen in Hex sehen.
http://www.heise.de/download/hterm.html

von Peter II (Gast)


Lesenswert?

Dirk schrieb:
> Sag ich doch!
> erst ein Programm in Ordnung bringen!

nein putty ist in ordnung, das muss man nicht in Ordnung  bringen.

von Dirk (Gast)


Lesenswert?

LOL
Putty nehme ich auch, wenn ich mit einem fertigen System arbeite.
Zum Entwickeln unf finden von Com-Fehlern hat sich aber bei HTerm als 
sehr hilfreich herausgestellt. Gerade wenn du Baudratenprobleme hast, 
siehst du auch alle nicht darstellbare Zeichen schön im Hex-Dump.
Alternativ kannst du natürlich nach einem Hex-Font suchen und Putty so 
einstellen das er den nimmt (geht das überhaupt)

von Dell (Gast)


Lesenswert?

OK.

JETZT wirds peinlich:

Habe mir nochmal die Init-Sequenz angesehen. Dann kam ich darauf, dass 
ich evtl das URSEL-bit löschen sollte, bevor ich UBRRH schreibe.

Und jetzt kommts:
Wenn ich UCSRC schreibe, habe ich das URSEL-bit NICHT gesetzt. Fragt 
mich nicht, warum ich das jemals rausgenommen habe. Damit war das 
Frameformat natürlich doch falsch!! Anstatt 8-bit, 2Stopp-Bits zu 
schreiben, habe ich einen neuen Wert in UBRRH geladen, da sie sich eben 
den gleichen Adressbereich teilen und dies nur durch das URSEL-bit 
unterschieden wird.
Dementsprechend hat es auch zwischen 2 uCs geklappt, da sie somit im 
UCSRC den default-Wert beibehalten haben und beide 2x UBRRH geschrieben 
haben.

Alles funktioniert wie es soll.....

Hoffe ihr hattet im Nachhinein trotz der ganzen Mühe etwas zu lachen.
Vertraut mir nie wieder, wenn ich sage, dass ich den Standart-Code 
benutze.

Da ich die Header-Datei schon früher für Two-Way-UART genutzt habe, ist 
mir der Fehler nie aufgefallen.

Aber MUSSTE ja iwie am Frameformat liegen...

Gott, was bin ich erleichtert. 2 Tage den Fehler vollkommen falsch 
gesucht. Aber naja. Die Read-Befehle hatte ich ja vorher auch nicht 100% 
drauf.
Nur so lernt man etwas dazu :) Das wars mir Wert ;)

von Peter II (Gast)


Lesenswert?

Dell schrieb:
> JETZT wirds peinlich:

aber nett das du es uns wenigsten gesagt hast, schlimm sind dann die 
leute die sich einfach nicht mehr melden.

von Dell (Gast)


Lesenswert?

Peter II schrieb:
> Dell schrieb:
>> JETZT wirds peinlich:
>
> aber nett das du es uns wenigsten gesagt hast, schlimm sind dann die
> leute die sich einfach nicht mehr melden.

Hilft ja auch anderen weiter.
Ich hab mir ja auch unzählige Threads zu dem Thema durchgelesen.
Im Prinzip hat jemand, der jetzt einen Atmega32 und C# benutzt, sofort 
alle Codes zur Hand.
Schicke gleich nochmal den endgültigen Code, damit das Thema sauber 
abgeshclossen ist und es anderen WIRKLICH hilft. Immer so halb fertige 
Code-Stücke helfen einem Neuling auch nicht viel weiter. Habe ich aj 
selber gemerkt.

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.