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-10-01
- Revision:
- 9:d6e7981dfc89
- Parent:
- 8:fa2a2c3a16ce
- Child:
- 10:9da863a6da3e
File content as of revision 9:d6e7981dfc89:
#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; CircularBuffer<char, 16> serrxbuffer; 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.serIsActive=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; net1.connectCmd=false; /* 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; 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 (net2->devMsgOpenRx) { sport0.write(cbuf,clen); clen=0; } else if (clen>3) { for (cbc=0;cbc<clen-3;cbc++) { if (net2->serIsActive==true) { if ((cbuf[cbc]==0x4d) && (cbuf[cbc+1]==0x45) && (cbuf[cbc+2]==0x54)) { sport0.write(cbuf,clen); net2->devMsgOpenRx=true; net2->devMsgReq=0; clen=0; break; } if ((cbuf[cbc]==0x54) && (cbuf[cbc+1]==0x41) && (cbuf[cbc+2]==0x50)) { sport0.write(cbuf,clen); net2->devMsgOpenRx=true; net2->devMsgReq=0; clen=0; break; } if ((cbuf[cbc]==0x41) && (cbuf[cbc+1]==0x43) && (cbuf[cbc+2]==0x43)) { sport0.write(cbuf,clen); net2->devMsgPos=1; clen=0; break; } if (cbuf[cbc]==0x2a) { sport0.write(cbuf,clen); net2->devMsgPos=2; clen=0; break; } if ((cbuf[cbc]==0x3d) && (cbuf[cbc+1]==0x3e)) { sport0.write(cbuf,clen); net2->devMsgPos=4; clen=0; break; } if ((cbuf[cbc]==0x3d)) { sport0.write(cbuf,clen); net2->devMsgPos=0; clen=0; break; } } if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC0)) { sport0.write(cbuf,clen); net2->pollState=1; clen=0; break; } if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC1)) { sport0.write(cbuf,clen); if (vReg1.numAnalog!=cbuf[6]) { printf("\r\nAnalog Channel Count Off\r\n"); net2->pollState=0; clen=0; break; } if (vReg1.numDigital!=cbuf[8]) { printf("\r\nDigital Channel Count Off\r\n"); net2->pollState=0; clen=0; break; } char anum=16; char nxc; for (txc=0;txc<vReg1.numAnalog;txc++) { for (nxc=0;nxc<6;nxc++) { if(vReg1.analogs[txc].analogName[nxc]!=cbuf[anum+nxc]) { printf("\r\nPoint %d Failed\r\n",txc); break; } } anum = anum + 11; } net2->pollState=2; clen=0; break; } if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xD1)) { char anum=cbc+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("%.2f\r\n",vReg1.analogs[txc].analog1Value); } 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); } net2->connectCmd=true; ret = net2->srv_sock.connect(net2->srv_addr,net2->cltPort); if (ret==0) { net2->connectRetry = false; printf("Connected %d\r\n",ret); 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->connectCmd=false; 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); } net2->connectCmd=false; 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->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 rxindex=0; int rxc; bool crRx = false; int4byte cmdpack; while (1) { rxlen=sport0.readable(); if (rxlen>0) { for (rxc=0;rxc<rxlen;rxc++) { rxbuf[rxindex+rxc]=sport0.getc(); if (rxbuf[rxindex+rxc]=='\r') { crRx=true; } } rxindex=rxindex+rxlen; printf("%d\r\n",rxlen); printf("%d\r\n",rxindex); rxlen=0; if ((rxindex>2) && (crRx==true)) { crRx=false; for (rxc=0;rxc<=rxindex-3;rxc++) { cmdpack.bytes[3]=rxbuf[rxc]; cmdpack.bytes[2]=rxbuf[rxc+1]; cmdpack.bytes[1]=rxbuf[rxc+2]; cmdpack.bytes[0]=rxbuf[rxc+3]; printf("%08x\r\n",cmdpack.cmdint); if (cmdpack.cmdint==0x4d45544d) { printf("MIN MAX METERING\r\n"); net2->devMsgReq=1; net2->devMsgPos=2; rxindex=0; } if (cmdpack.cmdint==0x54415052) { printf("TAP REPORT\r\n"); net2->devMsgReq=2; net2->devMsgPos=2; rxindex=0; } } if (rxindex>0) { printf("Serial Command Not Found"); rxindex=0; } } } } } //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) { if ((net1.sendState==0)||(net1.sendState==5)) { if (net1.devMsgReq>0) { net1.serTimeoutCount=0; sendLength.push(serCmdSeq[2][net1.devMsgPos]); for (txc=0;txc<serCmdSeq[2][net1.devMsgPos];txc++) { sendBuffer.push(serCmd[serCmdSeq[net1.devMsgReq-1][net1.devMsgPos]][txc]); } if (net1.serIsActive==false) { net1.serIsActive=true; } } else { 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.serIsActive)) { 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; if (net1.serIsActive==false) { net1.cltCloseConnection=true; net1.sendState=0; } } if (net1.serIsActive) { net1.devMsgOpenRx=false; if ((net1.serTimeoutCount==sertimeoutperiods) || (net1.devMsgReq==0)) { net1.cltCloseConnection=true; net1.devMsgReq=0; net1.serIsActive=false; net1.sendState=0; } else { net1.pollTimeout=0; net1.serTimeoutCount++; printf("Serial Active Timeout Count: %d\r\n",net1.serTimeoutCount); } } } } 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) { 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; } } }