Forum: Mikrocontroller und Digitale Elektronik Serielle Verbindung Arduino und Processing


von Jibonacci (Gast)


Lesenswert?

Hey Leute, ich habe ein kleines Problem.

Ich würde gerne über die Serielle Schnittstelle Befehle an den Arduino 
senden via Processing. Als Test habe ich ein Programm, dass bei 
gedrückter Maustaste eine '1' schickt und sonst eine '0'.

Das Programm auf dem Arduino gibt ein Signal an den digitalen Pin 2, 
falls es eine '1' über den seriellen Port bekommt. Wenn ich Processing 
starte, funktioniert das Programm, da im Serial Moninitor der 
entsprechende Text beim betätigen und lösen der Maustaste angezeigt 
wird.

Das Programm im Arduino funktioniert theoretisch auch. Lass ich den Teil 
mit read.serial weg, leuchtet meine LED ordnungsgemäß auf. füge ich eine 
if-Anweisung mit ein, funktioniert das Programm nicht mehr.

Der Arduino Mega läuft über COM3, die Baudrate ist auf 9600 einestellt. 
Die Werte habe ich natürlich auch entsprechend in Processing und im 
Arduino Code angegeben.

Stecke ich die LED ein, tut sich einfach nichts, auch wenn ich den Port 
ändere. Stecke ich die LED in zwischen GND und Pin 13, leuchtet sie die 
ganze Zeit.

Hat Jemand eine Idee was falsch laufen könnte? Im folgenden der Code:

Arduino :
-----------------------
1
 char val; 
2
 int ledPin = 2; 
3
4
 void setup() 
5
{
6
   pinMode(ledPin, OUTPUT); 
7
   Serial.begin(9600);
8
 }
9
 void loop() {
10
   
11
     if (Serial.available()) 
12
   { 
13
     val = Serial.read(); 
14
   }
15
   if (val == '1') 
16
   { 
17
     digitalWrite(ledPin, HIGH); 
18
   } 
19
else 
20
{
21
     digitalWrite(ledPin, LOW); 
22
   }
23
   delay(10); 
24
}

Processing:
-----------------------
1
import processing.serial.*;
2
3
Serial port;  
4
5
void setup() 
6
{
7
  size(200,200); 
8
  port = new Serial(this, "COM3", 9600);}
9
void draw() {
10
  if (mousePressed == true) 
11
  {                           
12
   myPort.write('1');         
13
   println("Maus gedrückt");   
14
  } else 
15
  {                           
16
  myPort.write('0');          
17
  println("Maus nicht gedrückt");
18
  }   
19
}

: Bearbeitet durch User
von STK500-Besitzer (Gast)


Lesenswert?

1
void loop() {
2
3
     if (Serial.available())
4
     {
5
       val = Serial.read();
6
       if (val == '1')
7
       {
8
         digitalWrite(ledPin, HIGH);
9
       }
10
       else
11
       {
12
         digitalWrite(ledPin, LOW);
13
       }
14
}

Die Abfrage von "val" muss ja nur dann durchgeführt werden, wenn auch 
ein Zeichen empfangen wurde.

von STK500-Besitzer (Gast)


Lesenswert?

die fehlende Klammer musst du selber finden ;)

von Jibonacci (Gast)


Lesenswert?

In diesem Fall möchte ich ja, das die LED nur aufleuchtet, wenn eine 
Maustaste betätigt wurde. Ohne die Anfrage funktioniert es. Aber ich 
möchte, dass der Arduino auf die '1' von processing wartet.

Und ja, sorry ich hatte die klammer vom loop vergessen, aber in meinem 
Programm ist die glaube ich vorhanden, oder denkst du das es daran lag.

von STK500-Besitzer (Gast)


Lesenswert?

Jibonacci schrieb:
> Und ja, sorry ich hatte die klammer vom loop vergessen, aber in meinem
> Programm ist die glaube ich vorhanden, oder denkst du das es daran lag.

es war meine.

Probier doch einfach mal ein anderes Terminalprogramm aus. z.B. hterm 
(nicht zu verwechseln mit Hyperterm von MS)

von Jibonacci (Gast)


Lesenswert?

@STK500

Danke für deine Antwort.
Ich habe jetzt einmal ein anderes Terminal Programm ausprobiert. In 
diesem Fall "Realtearm". Dabei wurde der entsprechende Port "COM3" und 
Baud Rate ausgewählt. Wenn ich nun eine '1' sende, blinkt die LED auf. 
Das bedeutet, dass die serielle Kommunikation zwischen meinem PC und dem 
Arduino funktioniert. Eigentlich kann man davon schon ausgehen, da es 
ansonsten nicht möglich wäre den Sketch, über die Schnittstelle, auf das 
Board zu laden.

Daraus schlussfolgere ich, dass Processing keine Verbindung aufbaut. Das 
kann aber aus zwei Gründen nicht sein. Zum einen ist der Port beim 
starten des Processing sketches belegt und zum anderen blinkt die 
receive LED vom Arduino beim senden von Processing auf. Das heißt, dass 
Board erhält die Daten über die Schnittstelle und auch in dem Moment.

Die Frage ist jetzt nur welche Zeichen. Ich vermute, dass ein falsches 
Zeichen gesendet wird. Leider fällt mir gerade kein Weg heraus, dass 
heraus zu finden. Dafür müsste der Arduino die Zeichen von Processing 
speichern und mir im späteren Verlauf wieder ausgeben.

von Bastello (Gast)


Lesenswert?

Versuch mal, ob es beim Senden von "1\r\n" bzw "0\r\n" klappt.
Manche Libs für die serielle Schnittstelle erwarten einen Return als 
Signal, dass die Übertragung abgeschlossen ist und die Daten aus dem 
Buffer übernommen werden können. Ob das beim Arduino so ist, weiss ich 
nicht.

von Jibonacci (Gast)


Angehängte Dateien:

Lesenswert?

So, ich habe das ganze noch einmal mit einem sniffer überprüft und mit 
die RAW Daten ausgeben lassen (siehe Anhang). Die Hälfte der Pakete 
wurde mit dem Serial Monitor von der Arduino Software gesendet. Die 
andere Hälfte mit Processing. Es ist kein Unterschied zu erkennen, nur 
das im einen Fall die LED leuchetet und im anderen Fall nicht ...

von Jibonacci (Gast)


Lesenswert?

@Bastello

Ok, ich probiere es mal.

von Bastello (Gast)


Lesenswert?

was mir gerade auffällt:
In der setup-Routine definierst du die Variable port und in der 
draw-Routine greifst du auf myPort zu, was aber nirgends 
deklariert/definiert ist.
Warscheinlich nur ein Tippfehler hier im Forum, weil es sonst ja auch 
eine Fehlermeldung gegeben haben müsste, aber überprüf es mal.

von Jibonacci (Gast)


Lesenswert?

Ich habe zuvor schon in einigen Code Beispielen gesehen, dass noch ein 
"\n" seperat übermittelt wurde. Ich habe jetzt alle Kombinationen 
ausprobiert, leider klappt es nicht.

An meinem Screenshot sieht man auch, dass beide scheinbar das gleiche 
senden. Also hätte der Serial Monitor noch ein \n hinter jedes Paket 
oder Zeichen angehängt, dass wäre das sicher angezeigt worden. Aber 
eigentlich ist es doch nicht möglich, dass wenn auf dem Gleichen Port 
und mit der Gleichen Rate, dass gleiche Zeichen übermittelt wird, dass 
Board einmal korrekt reagiert und im anderen Fall, der eigentlich genau 
dem gleichen entspricht, nicht ... confused

von Jibonacci (Gast)


Lesenswert?

Danke für den Hinweis. Ich sollte mir echt mal einen Account machen um 
solche Fehler zu korrigieren. Ich habe es gerade noch einmal überprüft 
und dort steht auch ordnungsgemäß Serial myPort, auch wenn es in meinem 
vorherigen nur port steht :)

von Jibonacci (Gast)


Lesenswert?

Ok, ich habe den Fehler gefunden, es lag am Processing Code. Ich muss 
noch genau analysieren woran es lang, aber ich habe gerade folgenden 
Code einmal ausprobiert :
1
import processing.serial.*;
2
import processing.serial.*;
3
Serial comPort;
4
boolean ledState=false; //LED is off
5
6
void setup(){
7
 //Open COM Port for Communication
8
 comPort = new Serial(this, Serial.list()[1], 9600);
9
 background(255,0,0); //Start with a Red background
10
}
11
12
void draw(){
13
}
14
15
16
void mousePressed() {
17
 //Toggle led ON and OFF
18
 ledState=!ledState;
19
 
20
 //If ledState is True - then send a value=1 (ON) to Arduino
21
 if(ledState){
22
 background(0,255,0); //Change the background to green
23
 
24
 /*When the background is green, transmit
25
 a value=1 to the Arduino to turn ON LED */
26
 comPort.write('1');
27
 }else{
28
 background(255,0,0); //Change background to red
29
 comPort.write('0'); //Send "0" to turn OFF LED.
30
 }
31
}
Quelle:
http://sites.prenninger.com/arduino-uno-r3/processing/arduino-processing

: Bearbeitet durch User
von Bastello (Gast)


Lesenswert?

Muss wohl irgendwie an dieser Zeile liegen:
Jibonacci schrieb:
> comPort = new Serial(this, Serial.list()[1], 9600);

Serial.list() wird alle verfügbaren COM-Ports beinhalten.
Mit Serial.list()[1] greifst du also auf den zweiten verfügbaren 
COM-Port zu.

Lass dir doch mal ausgeben, was Serial.list()[1] genau für einen Wert 
hat. Es scheint ja nicht "COM3" zu sein, sonst wäre es ja das gleiche 
wie oben.

von Jibonacci (Gast)


Lesenswert?

Den Gedanken hatte ich auch. Wenn ich mir die Liste ausgebe, steht dort 
entsprechen "COM1" oder "COM3".
Ich hatte vorher den Port auch manuell eingegeben, sprich statt

new Serial(this, Serial.list()[1], 9600);

new Serial(this, "COM3", 9600);

Das hat auch funktioniert. Mich macht diese Funktion "void 
MousePressed()" stutzig. Ersten wird sie in Draw(), nicht aufgerufen. 
Was sie wohl auch nicht muss, da alles auf dieser Serial Ebene abläuft. 
Aber die Funktion welchselt einfach nur die Zustände der Variable 
ledState und schreibt dann mit comPort.write('1'); eine 1.
Also im Prinzip genau das selbe.

Lasse ich die Schleifen weg und schreibe lediglich

comPort.write('1');
delay(100);

Tut sich nichts, dann funktiniert es nicht mehr. Sehr merkwürdig oder 
nicht?

von Bastello (Gast)


Lesenswert?

MousePressed ist der Eventhandler, der beim drücken einer Maustaste 
aufgerufen wird.
Dort wird dann ledState getoggelt und je nach Wert '1' oder '0' auf der 
Seriellen Schnittstelle ausgegeben.
Das sollte auch im Draw-Loop funktionieren.

Gibt Serial.list() denn wirklich einen StringArray zurück oder 
vielleicht einen Array eines anderen Objekttyps, welcher nur den 
Bezeichner COM1 usw hat?

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.