This demonstrates the process of communicating through ethernet to a SEL-2431 Voltage Regulator Control Panel using SEL Fast Message. Basic device commands and data cna be requested and displayed over a connected serial port. This is a basic version and full testing and documentation has yet to be completed.
Dependencies: BufferedSerial analogAverager voltageRegulator netStatReg analogMinMax CounterMinMax
main.cpp
- Committer:
- masterkookus
- Date:
- 2019-09-26
- Revision:
- 8:fa2a2c3a16ce
- Parent:
- 7:be13a9037d41
- Child:
- 9:d6e7981dfc89
File content as of revision 8:fa2a2c3a16ce:
#if !FEATURE_LWIP #error [NOT_SUPPORTED] LWIP not supported for this target #endif #include "mbed.h" #include "EthernetInterface.h" #include "TCPServer.h" #include "TCPSocket.h" #include "BufferedSerial.h" #include "nettime.h" #include "netdevices.h" #include "mydevices.h" #include "platform/CircularBuffer.h" #include "netDataTypes.h" #include "selMsg.h" #include "string.h" Ticker nettimer; struct netsys net1; struct vRegData vReg1; bool polltick; BufferedSerial sport0(sport0tx, sport0rx, sport0buff, sport0mult); // UART2 CircularBuffer<char, 1024> receiveBuffer; CircularBuffer<char, 64> sendLength; CircularBuffer<char, 1024> sendBuffer; Thread conchkthread[2]; Thread rxtxdatathread[5]; unsigned int currenttime=0; nsapi_error_t ret; //Provides the deivce poll timing void heartbeat() { //polltick=true; setTick(true); } void confignetdevices(EthernetInterface *eth) { net1.cltPort=setclientport; net1.srv_addr=setclientaddress; net1.cltIsActive=false; net1.cltCloseConnection=false; net1.pollTime=0; net1.pollTimeout=0; net1.pollInterval=setpollinterval; net1.pollRequestSent=false; net1.pollResponseReceived=false; net1.srv_sock.set_blocking(true); net1.srv_sock.set_timeout(100); net1.aliveTimeout=setservertimeout; net1.srv.set_blocking(true); net1.srv.set_timeout(100); net1.pollEnabled=setpollenabled; net1.pollTimeoutCount=0; net1.pollState=0; net1.pollTimeoutCount=0; net1.sendRetryCount=0; net1.messageFailCount=0; net1.txMessageCount=0; net1.rxMessageCount=0; /* Open the server on ethernet stack */ net1.srv.open(eth); net1.srvIsActive=false; net1.srvCloseConnection=false; /* Bind port 23 to the server */ net1.srvPort=setserverport; net1.srv.bind(net1.srvPort); /* Can handle 5 simultaneous connections */ net1.srv.listen(5); sport0.baud(sport0baud); } void dataprocess(netsys *net2) { int txc; char cchar; char cbuf[256]; unsigned int clen=0; unsigned int cbc; int4byte cmdpack; float4byte valpack; short2byte timepack; while(1) { while (!receiveBuffer.empty()) { receiveBuffer.pop(cchar); cbuf[clen]=cchar; clen++; } if (net2->pollRequestSent) { if (clen>0) { net2->pollResponseReceived=true; } } if (clen>3) { for (cbc=0;cbc<clen-3;cbc++) { //printf("Length: %d\r\n",clen); //printf("%c%c%c%c\r\n",cbuf[cbc],cbuf[cbc+1],cbuf[cbc+2],cbuf[cbc+3]); if (net2->sendState==3) { cmdpack.bytes[3]=cbuf[cbc]; cmdpack.bytes[2]=cbuf[cbc+1]; cmdpack.bytes[1]=cbuf[cbc+2]; cmdpack.bytes[0]=0x00; //printf("%08x\r\n",cmdpack.cmdint); if (cmdpack.cmdint&0xF0000000) { printf("Telnet Command Received\r\n"); cbc=cbc+3; if (cbc>=clen) { clen=0; } } } else { //printf("%c%c%c%c\r\n",cbuf[cbc],cbuf[cbc+1],cbuf[cbc+2],cbuf[cbc+3]); cmdpack.bytes[3]=cbuf[cbc]; cmdpack.bytes[2]=cbuf[cbc+1]; cmdpack.bytes[1]=0x00; cmdpack.bytes[0]=0x00; if (cmdpack.cmdint==0xA5C00000) { sport0.write(cbuf,clen); /*sendLength.push(tstlen); for (txc=0;txc<2;txc++) { sendBuffer.push(tstcmd[txc]); }*/ net2->pollState=1; clen=0; break; } if (cmdpack.cmdint==0xA5C10000) { sport0.write(cbuf,clen); if (vReg1.numAnalog!=cbuf[6]) { printf("\r\nAnalog Channel Count Off\r\n"); net2->pollState=0; break; } if (vReg1.numDigital!=cbuf[8]) { printf("\r\nDigital Channel Count Off\r\n"); net2->pollState=0; break; } char anum=16; char nxc; for (txc=0;txc<vReg1.numAnalog;txc++) { for (nxc=0;nxc<6;nxc++) { //printf("%c %c",vReg1.analogs[txc].analogName[nxc],cbuf[anum+nxc]); if(vReg1.analogs[txc].analogName[nxc]!=cbuf[anum+nxc]) { printf("\r\nPoint %d Failed\r\n",txc); break; } } anum = anum + 11; //printf("\r\n"); } net2->pollState=2; clen=0; break; } if (cmdpack.cmdint==0xA5D10000) { char anum=4; for (txc=0;txc<vReg1.numAnalog;txc++) { valpack.bytes[3]=cbuf[anum]; valpack.bytes[2]=cbuf[anum+1]; valpack.bytes[1]=cbuf[anum+2]; valpack.bytes[0]=cbuf[anum+3]; vReg1.analogs[txc].analog1Value = valpack.cmdflt; anum = anum + 4; //printf("%02x, %02x %02x %02x\r\n",cbuf[anum],cbuf[anum+1],cbuf[anum+2],cbuf[anum+3]); //printf("%02x, %02x %02x %02x\r\n",valpack.bytes[3],valpack.bytes[2],valpack.bytes[1],valpack.bytes[0]); //printf("%f\r\n",valpack.cmdflt); printf("%.2f\r\n",vReg1.analogs[txc].analog1Value); } printf("%d\r\n",anum); vReg1.timeStamp.month=cbuf[anum]; vReg1.timeStamp.day=cbuf[anum+1]; vReg1.timeStamp.year=cbuf[anum+2]; vReg1.timeStamp.hour=cbuf[anum+3]; vReg1.timeStamp.min=cbuf[anum+4]; vReg1.timeStamp.sec=cbuf[anum+5]; timepack.bytes[1]=cbuf[anum+6]; timepack.bytes[0]=cbuf[anum+7]; vReg1.timeStamp.msec=timepack.cmdshort; printf("%d/%d/%d %d:%d:%d.%d\r\n",vReg1.timeStamp.month,vReg1.timeStamp.day,vReg1.timeStamp.year,vReg1.timeStamp.hour,vReg1.timeStamp.min,vReg1.timeStamp.sec,vReg1.timeStamp.msec); anum=anum+8; for (txc=0;txc<vReg1.numDigital;txc++) { vReg1.digitalTargets[txc]=cbuf[anum+txc]; } clen=0; break; } } } if (clen>0) { printf("Command not Received\r\n"); clen=0; } } } } //Ethernet to Ethernet Send Data void datantx(netsys *net2) { while(1) { if (net2->cltIsActive) { while (net2->sendState==3) { if (net2->connectRetry == true) { wait_ms(100); } ret = net2->srv_sock.connect(net2->srv_addr,net2->cltPort); if (ret==0) { net2->connectRetry = false; printf("Connected %d\r\n",ret); //net2->cltCloseConnection=true; net2->sendState=4; } else if (ret==-3015) { printf("May already be connected, attempting send.\r\n"); net2->connectRetry = false; net2->sendState=4; } else { net2->connectRetry = true; net2->sendRetryCount++; printf("Connect Attempt Failed, Code: %d\r\n",ret); if (net2->sendRetryCount>3) { printf("Communication Failed, Closing\r\n"); net2->connectRetry = false; net2->sendRetryCount = 0; net2->messageFailCount++; net2->cltCloseConnection=true; net2->sendState=0; net2->sendTime=0; } } } while (net2->sendState==4) { if (net2->sendRetry == true) { wait_ms(100); } ret = net2->srv_sock.send(net2->sendString,net2->sendLen); if (ret>=0) { printf("Send Result %d\r\n",ret); net2->sendRetry = false; net2->txMessageCount++; //net2->cltCloseConnection=true; net2->sendState=5; net2->sendTime=0; } else { net2->sendRetry = true; net2->sendRetryCount++; printf("Send Attempt Failed, Code: %d\r\n",ret); if (net2->sendRetryCount>3) { printf("Communication Failed, Closing\r\n"); net2->sendRetry = false; net2->sendRetryCount = 0; net2->messageFailCount++; net2->cltCloseConnection=true; net2->sendState=0; net2->sendTime=0; } } } } } } //Ethernet receive data and send to aux devices (serial, etc...) void datancrx(netsys *net2) { char rxbuf[256]; int rxlen=0; int rxc; while (1) { while (net2->cltIsActive) { rxlen=net2->srv_sock.recv(rxbuf, sizeof(rxbuf)); if (rxlen>0) { net2->aliveTime=0; for (rxc = 0;rxc<rxlen;rxc++) { receiveBuffer.push(rxbuf[rxc]); } printf("Client Received Data\r\n"); net2->rxMessageCount++; } } } } //Ethernet receive data and send to aux devices (serial, etc...) void datansrx(netsys *net2) { char rxbuf[256]; int rxlen=0; int rxc; while (1) { while (net2->srvIsActive) { rxlen=net2->clt_sock.recv(rxbuf, sizeof(rxbuf)); if (rxlen>0) { net2->aliveTime=0; for (rxc = 0;rxc<rxlen;rxc++) { receiveBuffer.push(rxbuf[rxc]); } printf("Server Received Data\r\n"); net2->rxMessageCount++; } } } } //Serial device to server void datasrx(netsys *net2) { char rxbuf[256]; int rxlen=0; int rxc; while (1) { while (net2->srvIsActive) { rxlen=sport0.readable(); if (rxlen>0) { for (rxc = 0;rxc<rxlen;rxc++) { rxbuf[rxc] = sport0.getc(); } net2->aliveTime=0; net2->clt_sock.send(rxbuf, rxlen); net2->txMessageCount++; } } } } //Checks for a Ethernet to Serial connection void conchk(netsys *net2) { TCPServer *server=&(net2->srv); TCPSocket *client_socket=&(net2->clt_sock); SocketAddress *client_address=&(net2->clt_addr); while(1) { while (server->accept(client_socket, client_address) < 0) { //printf("Connection Failed.\r\n"); } printf("Server Port %d\r\n", net2->srvPort); printf("accept %s:%d\r\n", client_address->get_ip_address(), client_address->get_port()); net2->aliveTime=0; net2->srvIsActive=true; } } int main() { EthernetInterface eth; eth.set_network(setseveraddress,setsevermask,setsevergateway); //Use these parameters for static IP eth.connect(); initVoltageRegulator(&vReg1); printf("The target IP address is '%s'\r\n", eth.get_ip_address()); printf("%s\r\n",vReg1.analogs[0].analogName); confignetdevices(ð); /* Setup Ethernet to Serial Connection Thread */ conchkthread[0].start(callback(conchk,&net1)); /* Setup polltick Ticker */ nettimer.attach_us(heartbeat,10000); /* Setup Ethernet to Serial transmit data Thread */ rxtxdatathread[0].start(callback(datansrx,&net1)); rxtxdatathread[1].start(callback(datancrx,&net1)); /* Setup Ethernet to Serial receive data Thread */ rxtxdatathread[2].start(callback(datasrx,&net1)); rxtxdatathread[3].start(callback(datantx,&net1)); rxtxdatathread[4].start(callback(dataprocess,&net1)); unsigned int txc; unsigned int sxc; while (true) { polltick=getTick(); if (polltick) { setTick(false); incTime(); currenttime=getTime(); net1.pollTime++; net1.sendTime++; if (net1.srvIsActive) { net1.aliveTime++; if (net1.aliveTime>net1.aliveTimeout) { printf("Closed\r\n"); net1.clt_sock.close(); net1.srvIsActive=false; net1.srvCloseConnection=false; } } if (net1.pollEnabled) { if (net1.pollTime >= net1.pollInterval) { sendLength.push(2); for (txc=0;txc<2;txc++) { sendBuffer.push(fmCmd[net1.pollState][txc]); } if (net1.sendState==0) { net1.sendState=1; net1.pollRequestSent=true; } net1.pollTime=0; } if (net1.sendState==5) { net1.pollTimeout++; if (net1.pollTimeout==setpolltimeout) { if (net1.pollRequestSent) { printf("Poll Request Sent\r\n"); if (net1.pollResponseReceived==false) { printf("Poll Response Not Received\r\n"); } else { printf("Poll Response Received\r\n"); } net1.pollRequestSent=false; net1.pollResponseReceived=false; net1.cltCloseConnection=true; net1.sendState=0; } } } else { net1.pollTimeout=0; } } if (net1.sendTime == 10) { switch (net1.sendState) { case 1: if (!sendLength.empty()) { sendLength.pop(net1.sendLen); for (sxc=0;sxc<net1.sendLen;sxc++) { sendBuffer.pop(net1.sendString[sxc]); } } else { net1.sendState=0; } ret=net1.srv_sock.open(ð); printf("Socket%d\r\n",ret); if (ret < 0) { if (ret==-3003) { printf("May already be attached, attempting connect.\r\n"); } else { net1.attachRetry = true; net1.sendRetryCount=0; net1.sendState=2; net1.sendTime=0; break; } } net1.sendState=3; net1.sendTime=11; net1.cltIsActive=true; break; case 2: ret=net1.srv_sock.open(ð); printf("Socket%d\r\n",ret); if (ret < 0) { net1.attachRetry = true; net1.sendRetryCount++; net1.sendTime=0; printf("Attach Attempt Failed, Code: %d\r\n",ret); if (net1.sendRetryCount>3) { printf("Communication Failed, Closing\r\n"); net1.attachRetry = false; net1.sendRetryCount = 0; net1.messageFailCount++; net1.sendState=0; net1.sendTime=0; } break; } net1.sendState=0; net1.attachRetry = false; net1.sendTime=11; net1.cltIsActive=true; break; default: net1.sendTime=0; if (!sendLength.empty()) { if (net1.sendState==5) { if (!sendLength.empty()) { sendLength.pop(net1.sendLen); for (sxc=0;sxc<net1.sendLen;sxc++) { sendBuffer.pop(net1.sendString[sxc]); } } net1.sendState=4; } else { net1.sendState=1; } } break; } } } if (net1.cltCloseConnection==true) { printf("Client Socket Closed\r\n"); net1.srv_sock.close(); net1.cltIsActive=false; net1.cltCloseConnection=false; net1.sendState=0; } } }