Hallo zusammen,
ich bin immernoch dabei zu versuchen eine kommunikation mit einem MM4005 der Firma Newport über die Serielle Schnittstelle von einem Linux PC aus zu aufzubauen.
Laufen soll das ganze unter:
KDE Version 3.5.5
Linux version 2.6.24.3
Debian 4.1.1-21
Machine: i686
Ich benutze dabei hauptsächlich KDE.
Wie sende ich nun Befehle an das Gerät?
In dessen Anleitung steht: Command Syntax:
yy::xxAAnn
yy - Controller address, in RS-232-C addressable mode
xx - Optional or required preceding
AA - Common mode
nn - some parameter
Mein Programm sieht so aus:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <iostream>
#include <time.h>
using namespace std;
char *buffer;
char* szData;
int write_size=0,read_size=0;
int main()
{
int rs232ali=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (rs232ali == -1 ) { perror("open_port: Unable to open /dev/ttyS0"); }
else { printf("Port RS232 has been sucessfully opened and %d is the value of open()\n",rs232ali); }
szData="MR\n";
cout<<"folgender Befehl wird gesendet: "<<szData<<endl;
write_size=write( rs232ali, szData, sizeof(szData));
if(write_size==-1) { printf( "Error writing: %s\n", strerror( errno ) );}
else { cout<<"Bytes written: write_size="<<write_size<<endl;}
for(int e=0;e<1e7;e++){} //wait some time
cout << "rs232ali = "<<rs232ali << endl;
//read_size=read("/dev/ttyS0",buffer,10);
read_size=read(rs232ali,buffer,10);
if(read_size==-1) { printf( "Error reading: %s\nBuffer= %s\n", strerror( errno ),buffer);}
else {cout<<"Bytes read: read_size="<<read_size<<endl;printf("Position Achse1 = %d\n",buffer);}
close(rs232ali);
}
Alles anzeigen
Die Ausgabe im Terminal lautet:
ZitatPort RS232 has been sucessfully opened and 3 is the value of open()
folgender Befehl wird gesendet: MRBytes written: write_size=4
rs232ali = 3
Error reading: Resource temporarily unavailable
Buffer= (null)
Es kommen auf jeden Fall Daten aus der Schnittstelle (hab ich mit Oszi getestet). Allerdings kann ich mit dem Code auch nichts lesen, wenn ich Pin 2 und 3 miteinander verbinde (sende und empfangsleitung). Irgendwas ist also faul.
Ich habe im Internet etwas recherchiert und bin in einem Forum auf einen Code gestoßen, den ich modifiziert habe und mit dem nun das Senden und Empfangen klappt, wenn Pin 2 und 3 verbunden sind. Bei Anschluss des MM4005 klappt die Kommunikation immernoch nicht. Der Code lautet:
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
int writeport(int rs232, char *chars);
int readport(int rs232, char *result);
int getbaud(int rs232);
int initport(int rs232);
int rs232;
int wtm=900000; //set wait time between write and read
int main(int argc, char **argv) {
rs232 = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (rs232 == -1) {
perror("open_port: Unable to open /dev/ttyS0: ");
return 1;
} else {
perror("Open Port /dev/ttyS0: ");
// fcntl(rs232, F_SETFL, 0);
}
int old_baud=getbaud(rs232);
initport(rs232);
printf("baud=%d\n", old_baud);
if(getbaud(rs232)==old_baud){}
else printf("new baud=%d\n", getbaud(rs232));
char sCmd[254];
for(int i=0;i<254;i++){sCmd[i]=0x00;}
/* sCmd[0] = 0x4D;
sCmd[1] = 0x52;
sCmd[2] = 0x3B;
sCmd[3] = 0x4D;
sCmd[4] = 0x4F;
sCmd[5] = 0x3B;*/
sCmd[0] = 0x31;
sCmd[1] = 0x54;
sCmd[2] = 0x50;
if (!writeport(rs232, sCmd)) {
printf("write failed!\n");
close(rs232);
return 1;
}
printf("written: %s\n", sCmd);
printf("wait %i ms\n",wtm/1000);
usleep(wtm);
char sResult[254];
fcntl(rs232, F_SETFL, FNDELAY); // don't block serial read
if (!readport(rs232,sResult)) {
printf("READING of SERIAL PORT FAILED\n");
close(rs232);
return 1;
}
printf("readport = %s\n", sResult);
close(rs232);
return 0;
}
int initport(int rs232) {
struct termios options;
// Get the current options for the port...
tcgetattr(rs232, &options);
// Set the baud rates to 19200...
cfsetispeed(&options, B19200); /*sets the input baud rate stored in the structure pointed to by termios_p to speed.*/
cfsetospeed(&options, B19200); /*shall set the output baud rate stored in the structure pointed to by termios_p to speed.*/
// Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD); /* Enable receiver, set local */
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_cflag &= ~CSTOPB; /*That clears the bits which cause a 2 bit wide stop bit.*/
options.c_cflag &= ~CSIZE; /*This clears all of the bits which determine data length. */
options.c_cflag |= CS7; /*This sets bits to enable 7 bit data. */
// Set the new options for the port...
tcsetattr(rs232, TCSANOW, &options); /*TCSANOW: sets terminal attributes immediately.*/
return 1;
}
int writeport(int rs232, char *chars) {
int len = strlen(chars); //len is the length of the string chars.
chars[len] = 0x0D; // stick a <CR> after the command
chars[len+1] = 0x00; // terminate the string properly
int n = write(rs232, chars, strlen(chars));
if (n < 0) {
return 0;
}
return 1;
}
int readport(int rs232, char *result) {
int bytes_read = read(rs232, result, 254);
result[bytes_read-1] = 0x00;
if (bytes_read == -1) {
/*if (errno == EAGAIN) {
printf("SERIAL EAGAIN ERROR\n");
return 0;
} else {*/
printf("FATAL READ ERROR Nr. %d: %s\n", errno, strerror(errno));
return 0;
}
//}
return 1;
}
int getbaud(int rs232) {
struct termios termAttr;
int inputSpeed = -1;
speed_t baudRate;
tcgetattr(rs232, &termAttr);
/* Get the input speed. */
baudRate = cfgetispeed(&termAttr);
switch (baudRate) {
case B0: inputSpeed = 0; break;
case B50: inputSpeed = 50; break;
case B110: inputSpeed = 110; break;
case B134: inputSpeed = 134; break;
case B150: inputSpeed = 150; break;
case B200: inputSpeed = 200; break;
case B300: inputSpeed = 300; break;
case B600: inputSpeed = 600; break;
case B1200: inputSpeed = 1200; break;
case B1800: inputSpeed = 1800; break;
case B2400: inputSpeed = 2400; break;
case B4800: inputSpeed = 4800; break;
case B9600: inputSpeed = 9600; break;
case B19200: inputSpeed = 19200; break;
case B38400: inputSpeed = 38400; break;
case B57600: inputSpeed = 57600; break;
}
return inputSpeed;
}
Alles anzeigen
Die Ausgabe im Terminal ist die folgende:
ZitatOpen Port /dev/ttyS0: : Success
baud=19200
written: 1TP
wait 900 ms
FATAL READ ERROR Nr. 11: Resource temporarily unavailable
READING of SERIAL PORT FAILED
Hat jemand eine Idee, wie ich da weiter vorgehen kann, bzw. woran es scheitert?