Nov 19, 2019 at 10:33am UTC
Error: 'tm' is not a member of 'std'. from /usr/include/time.h:39:0
//Dies ist die zu verwendende Funktion
ModbusRTU::ModbusRTU(uint8_t id): _DO(20), _AO(10), _DI(20), _AI(20) { // inicializamos a cero los vectores digitales y analogicos
_id = id;
for(unsigned i = 0; i < _DO.size(); i += 2){
_DO[i] = true;
}
for(unsigned i = 0; i < _AO.size(); i++){
_AO[i] = i * 4;
}
//
for(unsigned i = 14; i < _AI.size(); i +=2){
_AI[i] = 1111;
actualizaAI();
}
}
Mensaje ModbusRTU::peticion(Mensaje recibido){
_petRecibidas ++;
_byteRecibidos += recibido.size()-2;
actualizaAI();
Mensaje respuesta;
std::cerr << "Recibido mensaje" << recibido.toString() << std::endl;
uint8_t id = recibido[0];
uint8_t funcion = recibido[1];
}
std::cerr << "El mensaje es de tamaño " << (int)id
<< " y la funcion es la numero " << (int)funcion << std::endl;
uint16_t crc = recibido[recibido.size()-2];
crc = (crc >> 8);
crc = crc | recibido[recibido.size()-1];
switch(funcion) {
case 3:
respuesta = atiende03(recibido);
break;
case 1:
respuesta = atiende01(recibido);
break;
case 5:
respuesta = atiende05(recibido);
break;
case 15:
respuesta = atiende15(recibido);
break;
case 6:
respuesta = atiende06(recibido);
break;
case 16:
respuesta = atiende16(recibido);
break;
case 2:
respuesta = atiende02(recibido);
break;
case 4:
respuesta = atiende04(recibido);
break;
default:
std::cerr << "Funcion aun no implementada" << std::endl;
uint8_t error = 1;
respuesta.push_back(id);
respuesta.push_back(funcion | (1 << 7));
respuesta.push_back(error);
respuesta.aniadeCRC();
return respuesta;
actualizaAI();
break;
}
_byteEnviados += respuesta.size() - 2;
actualizaAI();
return respuesta;
}
Mensaje ModbusRTU::atiende03(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende03 con mensaje "
<< recibido.toString() << std::endl;
respuesta.push_back(recibido[0]);
respuesta.push_back(recibido[1]);
uint16_t offset = recibido.getWordAt(2);
uint16_t numPos = recibido.getWordAt(4);
respuesta.push_back((2 * numPos));
for(unsigned i = offset; i < (offset + numPos); i++) {
std::cerr << "Accediendo AO[" << i << "]: " << _AO[i] << std::endl;
respuesta.pushWord_back(_AO[i]);
}
respuesta.aniadeCRC();
return respuesta;
}
Mensaje ModbusRTU::atiende01(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende01 con mensaje "
<< recibido.toString() << std::endl;
respuesta.push_back(recibido[0]);
respuesta.push_back(recibido[1]);
uint16_t offset = recibido.getWordAt(2);
uint16_t numPos = recibido.getWordAt(4);
unsigned numBytes = ((numPos - 1) / 8) + 1;
respuesta.push_back(numBytes);
unsigned posBit = 0;
uint8_t dato = 0;
for(unsigned p = offset; p < (offset + numPos); p++) {
std::cerr << "Accediendo DO[" << p << "]: " << _DO[p] << std::endl;
if (_DO[p] ) {
dato = dato | (1 << posBit);
}
posBit++;
if(posBit == 8){
respuesta.push_back(dato);
dato = 0;
posBit = 0;
}
}
if(posBit > 0) {
respuesta.push_back(dato);
}
respuesta.aniadeCRC();
return respuesta;
}
Mensaje ModbusRTU::atiende05(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende05 con mensaje "
<< recibido.toString() << std::endl;
uint8_t id = recibido[0];
uint8_t funcion = recibido[1];
uint16_t offset = recibido.getWordAt(2);
if( (recibido[4] == 0xFF) && (recibido[5] == 0x00) ) {
std::cerr << "Ponemos a 1 la DO" << offset << "]: "
<< _DO[offset] << std::endl;
_DO[offset] = true;
} else if( (recibido[4] == 0x00) && (recibido[5] == 0x00) ) {
std::cerr << "Ponemos a 0 la DO" << offset << "]: "
<< _DO[offset] << std::endl;
_DO[offset] = false;
}
return recibido;
}
Mensaje ModbusRTU::atiende06(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende06 con mensaje "
<< recibido.toString() << std::endl;
uint16_t offset = recibido.getWordAt(2);
offset +=2;
uint16_t valor = recibido.getWordAt(4);
_AO[offset] = valor;
respuesta.push_back(recibido[0]); // id
respuesta.push_back(recibido[1]); // funcion
respuesta.pushWord_back(recibido.getWordAt(2));
respuesta.pushWord_back(recibido.getWordAt(4));
respuesta.aniadeCRC();
return recibido;
}
Mensaje ModbusRTU::atiende15(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende15 con mensaje "
<< recibido.toString() << std::endl;
uint16_t offset = recibido.getWordAt(2);
uint16_t numPos = recibido.getWordAt(4);
respuesta.push_back(recibido[0]); // id
respuesta.push_back(recibido[1]); // funcion
Mensaje datos;
uint16_t numDatos = recibido[6];
int datInicial = 7;
for(unsigned i = 1; i < numDatos; i++){
datos.push_back(datInicial);
datInicial++;
}
int numByte = 0;
int numBit = 0;
for(unsigned p = offset; p < (offset + numPos); p++) {
if(datos[numByte] & (1 << numBit)){
_DO[p] = true;
}else {
_DO[p] = false;
}
numBit++;
if(numBit > 7){
numByte++;
numBit = 0;
}
}
respuesta.aniadeCRC();
return respuesta;
}
Mensaje ModbusRTU::atiende16(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende16 con mensaje "
<< recibido.toString() << std::endl;
//Sacamos el offset y numPos del mensaje
uint16_t offset = recibido.getWordAt(2);
uint16_t numPos = recibido.getWordAt(4);
respuesta.push_back(recibido[0]); // id
respuesta.push_back(recibido[1]); // funcion
respuesta.pushWord_back(recibido.getWordAt(2));
respuesta.pushWord_back(recibido.getWordAt(4));
uint16_t numReg = recibido.getWordAt(4);
uint16_t datoNuevo = 0;
int cambioDobleBit = 7;
for(unsigned i = offset; i < (offset + numReg); i++) {
datoNuevo = recibido.getWordAt(cambioDobleBit);
_AO[i] = datoNuevo;
cambioDobleBit += 2;
}
respuesta.aniadeCRC();
return respuesta;
}
void ModbusRTU::actualizaAI() {
unsigned ra = 0;
// Datos de peticiones recibidas, bytes enviados y recibidos
_AI[ra++] = _petRecibidas;
_AI[ra++] = _byteRecibidos;
_AI[ra++] = _byteEnviados;
// Datos de fecha
std::time_t now_time = std::time(nullptr);
std::tm* now = std::localtime(& now_time);
_AI[ra++] = now -> tm_year + 1900;
_AI[ra++] = now -> tm_mon + 1;
_AI[ra++] = now -> tm_mday;
_AI[ra++] = now -> tm_hour;
_AI[ra++] = now -> tm_min;
_AI[ra++] = now -> tm_sec;
// Datos del proceso UID, GID, PID, PPID
_AI[ra++] = getuid();
_AI[ra++] = getgid();
_AI[ra++] = getpid();
_AI[ra++] = getppid();
for(unsigned i = 0; i < 15; i++) {
if(_AI[i] % 2 == 0){
_DI[i] = false;
} else {
_DI[i] = true;
}
}
}
Mensaje ModbusRTU::atiende02(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende02 con mensaje "
<< recibido.toString() << std::endl;
uint16_t offset = recibido.getWordAt(2);
uint16_t numPos = recibido.getWordAt(4);
respuesta.push_back(id);
respuesta.push_back(funcion);
if((numPos % 8 == 0)) {
respuesta.push_back((numPos/8));
} else {
respuesta.push_back((numPos/8) + 1);
}
unsigned posBit = 0;
uint8_t dato = 0;
for(unsigned i = offset; i < (offset + numPos); i++) {
std::cerr << "Accediendo DI[" << i << "]: " << _DI[i] << std::endl;
if (_DI[i] ) {
dato = dato | (1 << posBit);
}
posBit++;
if(posBit == 8){
respuesta.push_back(dato);
dato = 0;
posBit = 0;
}
}
if(posBit > 0) {
respuesta.push_back(dato);
}
respuesta.aniadeCRC();
return respuesta;
}
Mensaje ModbusRTU::atiende04(Mensaje recibido) {
Mensaje respuesta;
std::cerr << "Entramos en método atiende02 con mensaje "
<< recibido.toString() << std::endl;
uint16_t offset = recibido.getWordAt(2);
uint16_t numPos = recibido.getWordAt(4);
respuesta.push_back(id);
respuesta.push_back(funcion);
respuesta.push_back(numPos * 2);
for(unsigned i = offset; i < (offset + numPos); i++) {
std::cerr << "Accediendo al elemento " << i << " que vale: ["
<< _AI[i] << "]" << std::endl;
respuesta.pushWord_back(_AI[i]);
}
respuesta.aniadeCRC();
return respuesta;
}
Last edited on Nov 19, 2019 at 10:41am UTC
Nov 19, 2019 at 11:09am UTC
In order to use the std:: variant you need to #include <ctime> not time.h.