Czesć,
Chcę oprogramować sobie komunikację z czujnikiem podłączonym do komputera przez zewnętrzny konwerter na RS485. Napisałem sobie krótki program w C++ którym chcę odczytać jego status, aczkolwiek nie odbieram żadnych danych
main.cpp
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#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
#include "umb-comm-linux.h"
UmbCommLinux cUmb;
int main () {
struct termios tty;
int serial = open("/dev/ttyS0", O_RDWR | O_NONBLOCK);
tcgetattr(serial, &tty);
cUmb.SerialPortDescriptor = serial;
cUmb.SensorID = 1;
// if (serial != 0)
// return -1;
cfmakeraw(&tty);
tty.c_cflag &= ~(CSIZE | PARENB);
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50; // timeout
tty.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
tty.c_oflag = 0;
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
tcflush(serial, TCIFLUSH);
tcsetattr(serial, TCSANOW, &tty);
cfsetospeed(&tty, (speed_t)B19200);
cfsetispeed(&tty, (speed_t)B19200);
cUmb.UmbGetStatus();
close(serial);
return 0;
}
umb-comm-linux.cpp
#include "umb-comm-linux.h"
unsigned short UmbCommLinux::CheckCRC(char* pInputData) {
char ii,i = 0;
unsigned short crc = 0xFFFF;
ii = pInputData[6] + 12;
for (i = 0; i < ii - 3; i++)
crc = UmbCommLinux::calc_crc(crc, pInputData[i]);
if ( (pInputData[ii - 2] == ( (crc & 0xFF00) >> 8) ) && ( pInputData[ii - 3] == (crc & 0xFF) ) )
return 0;
else
return -1;
}
unsigned short UmbCommLinux::calc_crc(unsigned short crc_buff, unsigned char input) {
unsigned char i;
unsigned short x16;
// well use this to hold the XOR mask
for (i=0; i<8; i++)
{
// XOR current D0 and next input bit to determine x16 value
if ( (crc_buff & 0x0001) ^ (input & 0x01) )
x16 = 0x8408;
else
x16 = 0x0000;
// shift crc buffer
crc_buff = crc_buff >> 1;
// XOR in the x16 value
crc_buff ^= x16;
// shift input for next iteration
input = input >> 1;
}
return (crc_buff);
}
short UmbCommLinux::UmbGetStatus(void) {
char* tBuffer = this->tCommBuffer, i, n;
bool isCRCCorrect = 0;
unsigned short crc = 0xFFFF;
/* Bezczynnosc */
memset(tBuffer, 0x00, BUFFER_LN);
tBuffer[0] = SOH;
tBuffer[1] = V10;
tBuffer[2] = this->SensorID & 0xFF;
tBuffer[3] = 0x08 << 4;
tBuffer[4] = MASTER_ID;
tBuffer[5] = 0xF0;
tBuffer[6] = 0x02;
tBuffer[7] = STX;
tBuffer[8] = 0x26;
tBuffer[9] = V10;
tBuffer[10] = ETX;
for( i = 0; i <= 10; i++)
crc = this->calc_crc(crc, tBuffer[i]);
tBuffer[11] = crc & 0xFF;
tBuffer[12] = ((crc & 0xFF00) >> 8);
tBuffer[13] = EOT;
// for (i = 0; i <= 13; i++)
write(this->SerialPortDescriptor, &tBuffer, 14);
memset(tBuffer, 0x00, BUFFER_LN);
n = read(this->SerialPortDescriptor, &tBuffer, 10);
// isCRCCorrect = checkCRC(sRecvData);
if (isCRCCorrect == 0);
// return sRecvData[11];
else {
UmbStatus |= 0x02;
return -11;
}
}
UmbCommLinux::UmbCommLinux() {
this->tCommBuffer = new char[BUFFER_LN];
}
UmbCommLinux::~UmbCommLinux() {
delete this->tCommBuffer;
}
oraz umb-comm-linux.h
#ifndef __UMB_COMM_LINUX
#define __UMB_COMM_LINUX
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#define BUFFER_LN 512
#define SOH 0x01
#define STX 0x02
#define ETX 0x03
#define EOT 0x04
#define V10 0x10
#define MASTER_ID 0x01
#define UNSIGNED_CHAR 0x10
#define SIGNED_CHAR 0x11
#define UNSIGNED_SHORT 0x12
#define SIGNED_SHORT 0x13
#define UNSIGNED_LONG 0x14
#define SIGNED_LONG 0x15
#define FLOAT 0x16
#define DOUBLE 0x17
typedef enum ChannelID{
ACT_TEMP = 100,
TEMP_AVG = 160,
ABS_PRESSURE = 365,
AVG_WINDSPEED = 460,
MAX_WINDSPEED = 440,
AVG_WINDDIR = 580,
NNULL = 0
}ChannelID;
typedef enum TransmissionState{
DISABLED,
COMM_IDLE,
RXING,
RXING_DONE,
TXING,
TXING_DONE,
TIMEOUT
}TransmissionState;
class UmbCommLinux {
private:
char* tCommBuffer; // bufor RS232
TransmissionState eState;
ChannelID eCurrentChannel;
int UmbStatus;
int UmbLastNonZeroSensorStatus;
static unsigned short UmbGlobalCRCErrors ;
unsigned short UmbCRCErrorsDuringSComm;
int SrlTXQueueLen;
int SrlRXBytesNum;
int SrlTRXDataCounter;
bool SrlTXing;
bool SrlRXing;
public:
unsigned char SensorID;
int SerialPortDescriptor;
unsigned short CheckCRC(char* pInputData);
unsigned short calc_crc(unsigned short crc_buff, unsigned char input);
short UmbGetStatus(void);
void UmbGetChannelValue(void);
UmbCommLinux();
~UmbCommLinux();
};
#endif
Problem polega na tym, że pomimo tego, iż metoda UmbGetStatus "przelatuje" przez wywołanie funkcji Read nie otrzymuje przy tym żadnych danych i bufor pozostaje pusty. Co robię źle? Użytkownik na którym debuguję tę aplikacje jest dodany do grupy dialout i ma dostęp do portu szeregowego