Forum: PC-Programmierung Datenaustausch mit einem Mikrocontroller


von Dennis W. (dennis2008)


Lesenswert?

Hallo,

ich möchte mit meinem Mikrocontrollerboard (Arduino) zwei Variablen an 
meinen PC senden via serielle Schnittstelle. Diese werden dann dort 
verarbeitet und der Rückgabewert soll dann wieder auf der seriellen 
Schnittstelle landen und vom Mikrocontrollerboard empfangen werden. 
Hinter dem ganzen Programm steckt ein Fuzzy-Regler, welcher auf Windows 
läuft und die Parameter vom Board bekommt. Dann berechnet der Regler die 
Stellgröße und schreibt diese wieder auf die serielle Schnittstelle. 
Dort ließt das Board diese dann und sendet sie zum Ausgang.

Den Code für mein MC-Board habe ich schon fertig:
1
float ergebnis; 
2
//float ergebnis = 0.0; 
3
int wert1;                      //Regeldifferenz, ist e ein Integerwert oder float? 
4
int wert2;                      //Regelldifferenz über die Zeit 
5
  
6
void setup() {                  //SETUP 
7
  
8
  Serial.begin(9600); 
9
 // pinMode(ledPin, OUTPUT); 
10
  
11
} 
12
    
13
void loop() {                   //Programmschleife 
14
  
15
  Serial.print('@');            // sende Startzeichen           
16
  Serial.print(",");            // sende Zeichen Feldtrennung 
17
  Serial.print(wert1); 
18
  Serial.print(",");            
19
  Serial.print(wert2); 
20
  Serial.print(",\n");          // neue Zeile, Ende Uebertragung 
21
  Serial.flush();               // wartet bis alles uebertragen ist! 
22
  
23
  if (Serial.available() > 0)   //wenn sich Daten auf der seriellen Schnittstelle befinden 
24
  { 
25
    float ergebnis = Serial1.parseFloat(); //suche nächsten Float-Wert 
26
    delay(1000);                // warte 1 Sek. 
27
    Serial.write(ergebnis);     //schreibe den empfangenen Wert wieder auf die Schnittstelle 
28
    lcd.print(ergebnis);        //schreibe den empfangenen ergebnis auf das LCD Display 
29
  } 
30
}

Die passende Windows.exe dazu möchte ich mit DevCpp erstellen. Doch wie 
sieht der passende Code dazu aus, um die beiden Integer-Variablen von 
der seriellen Schnittstelle auszulesen und das Ergebnis dort wieder 
hinzuschreiben?
Den Code für die Verarbeitung der beiden Werte habe ich bereits 
erfolgreich in mein DevCpp Projekt eingebunden und getestet.

Ich habe den Windows Code mal hier hochgeladen:
http://www.file-upload.net/download-9509213/fuzzy0.zip.html

In der Konsole passt der Wert, doch auf der seriellen Schnittstelle sagt 
er immer dieser sei 0.0000:
1
long stell; 
2
DOUBLE **outputMatrix; 
3
  
4
PRINTF("Stellwert = %.12f", stell);  //das funktioniert, hier wird der richtige Wert angezeigt 
5
  
6
file = fopen("COM4:","w"); 
7
fprintf(file,"%.12f", stell); //hier wird nur 0.000000000 angezeigt 
8
fprintf(file,"\nDaten erfolgreich gesendet..."); //das funktioniert 
9
fclose(file);

Ich habe es schon mit %d, %i und sprintf probiert. Aber er zeigt mir 
einfach den Wert nicht an. Woran mag das liegen?

LG

von Lenny D. (le-do)


Lesenswert?

Wie meinst du "auf der Schnittstelle", protokollierst du die irgendwie 
mit oder meinst du das was der Arduino dir zurücksendet?

Meine Vermutung zu deinem Problem: Wenn ich den Code soweit richtig 
interpretiere, versucht der Arduino bei Empfang das float zu parsen und 
es dann zurückzuschicken, zur Kontrolle. Dabei kommt aber immer 0.000 
raus, das sollte auch auf dem Display dann erscheinen oder?
Ich vermute also er scheitert an der Konvertierung und gibt daher einen 
leeren Wert zurück. Die Windows-Routine sollte schon das richtige 
Absenden. Baue testweise einfach ein echo ein, also direkt die empfangen 
Daten ohne Konvertiereng wieder ausgeben.
Serial.Available() > 0 ist auch schon bei 1 byte erfüllt, aber 1 Ziffer 
reicht nicht um den ganzen Float darzustelle. macht Arduino das dann 
selbst auf alle nötigen Zeichen zu warten?

Ein paar Anmerkungen zum Code uC:
- loop wird so oft durchlaufen wie der Arduino kann wenn ich richtig 
liege, d.h. du solltest ein Delay() einbauen um das moderater zu machen.
- das Delay() in der if-Abfrage wird nur bei Datenempfang ausgeführt, 
ich sehe da nicht welchen Zweck das haben soll
- durch float ergebnis in der Abfrage deklarierst du es neu, damit wird 
das globale ergebnis glaube ich abgeschattet

-achja und in deinem Windows-Code steht long statt float, sicher dass 
das kappt?

*meine Kommentare gelten auf jeden Fall für standard C, mit Arduino 
kenne ich mich aber leider gar nciht aus daher ist vielleicht manches 
nicht korrekt hier

: Bearbeitet durch User
von Amateur (Gast)


Lesenswert?

Ist das Ganze Objekt-Orientiert?

Wenn nicht:
Serial.print(",");            // Gibt einen "lesbaren" Wert aus
Serial.print(wert2);          // Versucht binären Wert auszugeben

ent- oder weder.

von Karl H. (kbuchegg)


Lesenswert?

Kannst du das bischen Source Code (oder das Zip File) nicht hier im 
Forum anhängen? Ich hab ehrlich gesagt wirklich keine Lust mich durch 
Unmengen von Werbepopups und/oder sonstigen Schnickschnack der diversen 
Fremdhoster durchzuklicken (und dabei immer auf der Hut zu sein, welche 
Toolbar die mir diesmal wieder unterjubeln wollen), bis ich dann endlich 
mal einen Blick auf den Windows Code werfen kann.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Amateur schrieb:
> Ist das Ganze Objekt-Orientiert?
>
> Wenn nicht:
> Serial.print(",");            // Gibt einen "lesbaren" Wert aus
> Serial.print(wert2);          // Versucht binären Wert auszugeben
>
> ent- oder weder.

Sowohl, als auch.
Ein Arduino wird in C++ programmiert. Auch wenn viele Arduino 
Programmierer das nicht wissen und fälschlicherweise von C ausgehen.
Und ja. Das ist objektorientiert, wie man schon an der Syntax des 
Funktionsaufrufes sieht. Objekt.Methode_des_Objectes( Argumente )

: Bearbeitet durch User
von Lenny D. (le-do)


Lesenswert?

Die Funktion is eine Arduino-Definition, daher passt das schon, docu 
sagt die interpretiert den Typ und gibt passende ASCII Zeichen aus. Was 
du meintest ist Serial.write()

: Bearbeitet durch User
von Dennis W. (dennis2008)


Angehängte Dateien:

Lesenswert?

Anbei die gewünschte Datei...

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.