PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kommunikation zwischen Arduino und Matlab



BraucheHilfe
09.06.2016, 12:50
Hallo zusammen,

ich bin neu auf dem Gebiet, was die Kommunikation zwischen Arduino und Matlab bzw. das Auslesen einer seriellen Schnittstelle angeht. Auch meine Programmierkenntnisse sind auf keinem hohen Stand. Deswegen hoffe ich, dass ihr mir weiter helfen könnt =)
Folgendes Problem. Ich messe mit dem Arduino Mega board die Spannung über einen Widerstand. In Reihe zu dem Widerstand befindet sich ein Plattenkondensator. Über die gemessene Spannung möchte ich dann den Strom und folglich die Ladung berchnen die auf den Plattenkondensator fließt.

Der Code auf dem Arduino:


const float sensorVoltage=A0;
void setup() {
Serial.begin(115200); // opens serial port, sets data rate to 9600 bps
}
void loop() {
float inputVoltage2=analogRead(sensorVoltage); // Spannungswert im bereich zw 0-1023
float voltage2=5*inputVoltage2/1024; // Skalierung auf 0-5V
Serial.println(voltage2);
}

Hier bekomme ich schon das erste Problem. Wenn ich in die Console schaue werden vor der ersten Zahl teilweise Leerzeichen gesendet? Wie kann ich das umgehen, weil ich ich denke das wird bei der Datenerfassung in Matlab Probleme verursachen? Mir ist klar, dass ich dabei sehr sehr viele Spannungswerte aufnehme.
Es schaut beispielweise so aus:


0.5
0.5
0.5
0.5
0.5


In Matlab möchte ich die verschiedenen Spannungswerte als Funktion plotten und dann darüber integrieren, sodass ich berechnen kann wie viel Strom auf die Platten geflossen ist. Dabei schreibe ich alle Messwerte die vom Arduino gesendet werden in einen array voltage[]. In xaxis[] steht dann die Anzahl an Messwerten, sodass ich mit plot(voltage,xaxis) meine Funktion bekomme.

Mein Matlab code:


close all;
clc;
delete(instrfind({'Port'},{'COM5'}));
serialport=serial('COM5');
serialport.BaudRate=115200; %abgleichen der BaudRate
warning('off','MATLAB:serial:fscanF:unsuccessfulRe ad');
fopen(serialport);

int x = 1000; %passe ich je nachdem wie ich es brauche an
int i = 1;
voltage=[]; %hier kann ich natürlich die Größe 'x' anpassen
xaxis=[]; %hier kann ich natürlich die Größe 'x' anpassen

while i<=x
voltage1(i)=fscanf(serialport,'%f');
xaxis(i)=i;
i=i+1;
end


Als Fehler kommt:
bei
voltage1(i)=fscanf(serialport,'%f');
Subscripted assignment dimension mismatch.

Wäre sehr nett, wenn ihr mir weiterhelfen könntet.
Viele Grüße!

Ceos
09.06.2016, 13:06
eine reine Vermutung wäre hier dass du oben println benutz, was immer ein \n hinterhersendet und dein fscanf damit nciht klarkommt

BraucheHilfe
09.06.2016, 13:11
Danke, das hat aber leider auch nicht geholfen

Ceos
09.06.2016, 14:05
Entschuldige, meine Aussage war eventuell nicht kräftig genug
wenn du Zahlen ala print(zahl) schreibst sieht das so aus
Biepsiel Zahlen 2,1 - 2,2 - 4,1
"2,12,24,1" und dein fscanf rastet aus weil es anfang und ende nicht findet

es wäre zumindest sinnvoll immer print(zahl) gefolgt von print(" ") zu verwenden oder du musst in deinem scanf " %f" verwenden, also mit einem leerzeichen davor ... eventuell dahinter statt davor

wichtig ist nur dass du ein trennzeichen einfügst ... statt einem leerzeichen ginge auch print(zahl);print(":"); und im scanf dann "%f:"

vielleicht gibt es ja auch ein fundamentaleres problem und du solltest erstmal anfangen deine empfangenen zeichen auszuwerten ;)

eine noch bessere version in meinen augen zumindest

immer erst ein readline in einen string machen und dann mit scanf arbeiten

BraucheHilfe
09.06.2016, 14:24
okay vestehe, es kann also nicht unterschieden werden. Habe jetzt den serial.print(":") eingefügt. Hat soweit erstmal leider auch nichts geholfen.
Ich habe jetzt mal debugged. Die Variable a (siehe code) kann er noch einlesen. Das wirklich komische ist aber, dass im workspace für a ein leerer Array steht also []. Dann ist auch versändlich, dass
Matlab in der nächste Zeile streikt bei voltage1(i)=a; da er ja an die Stelle i keinen Array schreiben kann. Daher kommt der 'dimension mismatch'.



while i<=Zeit
a=fscanf(serialport,'%f:');
voltage1(i)= a;
time(i)=i;
i=i+1;
end


Die Ausgabe in der Arduino Konsole schaut nun so aus:


0.00:0.00:0.00:0.00:...

Also wieder Leerzeichen die am Anfang stehen. Da stellt sich mir jetzt die Frage, ob das Board die Leerzeichen am Anfang an Matlab sendet und daher als Wert von a ein leeres array schreibt?

Ceos
09.06.2016, 14:31
dann versuch es nochmal mit println OHNE :
und statt fscanf mit readline (das ließt immer bis zum nächsten \n) und dann sscanf auf den gelesenen String ... ich glaube diesmal hab ich es richtig geschrieben XD

dann kannst du das gelesene auch besser debuggen, also ob evtl. müll empfangen wurde

BraucheHilfe
10.06.2016, 11:02
Also das mit readline geht ja glaub ich nur wenn ich eine Datai einlese oder? Ich möchte es aber direkt vom Serialport einlesen.
Ich habe nochmal was neues probiert.

Arduino code:



const float sensorVoltage=A0;
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
int inputVoltage2=analogRead(sensorVoltage); // Spannungswert im bereich zw 0-1023
float voltage2=5*inputVoltage2/1024; // Skalierung auf 0-5V
Serial.println(voltage2);

}


und der Matlab code:


delete(instrfind({'Port'},{'COM5'}));
s = serial('COM5', 'BaudRate', 9600);
fopen(s);
a=fscanf(s,'%f');
disp(a)


Im workspace erhalte ich :
Wert: Value:
a 1x7 char

aber wenn ich a öffne oder ausgebe (disp(a)) steht dort lediglich: ÿ0.00
Warum wird es mir in char gespeicht? Der hintere Wert 0.00 passt aber. Er erstellt einen char array und setzt mir komische Zeichen davor... Wieso?
Gruß

Ceos
10.06.2016, 11:13
das "ÿ" steht für 255, also ist dein Serialport nicht ganz sauber oder produziert im ersten Moment Müll, hier sollte man einen anderen Ansatz versuchen!

Aber nochmal zum readline ... readline wartet immer bis zum Empfang eines newline oder kurz "\n" befor es von der Ausführung zurückkommt, genauso wie dein fscanf versucht erst den angegebenen Wert zu interpretieren

fscanf das f vorne steht übrigens für file, ein serialstream ist das gleiche wie ein filestream die sind identisch bis auf dass die Datei bis zum EOF schon da ist, während der serialstream quasi erst über den input aufgebaut wird :)

Für den veränderten Ansatz und um das überschüssige 0xFF loszuwerden könntest du mal über ein Handshake nachdenken, bei dem du erst ein Zeichen von Arduion bekommst, dann ein Zeichen zum Synchronisieren schickst, dass der Arduino mit einer passende Antwort bestätigen muss ... danach kannst du davon ausgehen immer die Zeichen in der gleichen Reihenfolge zu Empfangen .... oder du machst die Lösung mit dem ":" nochmal und machst einfach solange read() auf deinen stream biss du ein ":" erhälst und beginnst danach erst mit fscanf, also das ":" zum synchronisieren

uart am PC ist invertiert, solang dein Controller also keinen Pegel auf die Leitung legt, denkt dein Computer du sendest nur 1en, bricht dann nach einem internen timeout ab verwirft den fehler dass er kein stopbit erhalten hat und speichert eben 0xff/255/0b11111111 im stream ... und darüber stolpert dein fscanf

BraucheHilfe
13.06.2016, 11:11
Vielen Dank ,
habe es mit dem ":" auf die Reihe bekommen =)
Gruß