Thus we are going to change the protocol so we are sending each Data item one-by-one.
Get Last Data Block Number
If we send "GET0", we receive N = <Data Block Number>.<Data Block Number>
is unsigned 32 bit integer ranging from "N = 1" to "N = 4294967295"Of course it doesn't get that big.
In the source code from Data Log Code posting, SD_BASE_BLOCK (1024) is equal to 0.
Get Data Block
If we send "GETn", we receive
- N = <Data Block Number>
- T = <time stamp>
- D = <data>
<time stamp> uses sec part from POSIX time_t.
Because we don't use the millisecond part, we need to *1000.
"T = 4294967295". Of course it will be hard to see this number in your lifetime.
<data> has +dd.ddd format.
- "D=+12.345"
- "D=": when there is no data
- "D=-99.999": termination. Data Block has finished.
Original Protocol
Digital Out
- Turning On: "DOn=ON"
- Turning Off: "DOn=OFF"
n is equal to Channel number which is between 0 and 7, and there is no reply.
Digital In
When you send "DI" it replies with "bbbbbbbb". b is equal to each input channel and it is either '0' or '1'.
Analog In
When you send "AIn" it replies with "+dd.ddd". n is equal to channel number which is between 0 and 7, and "+dd.ddd" ranges from -10.000 to +10.000.
Below I am only excerpting codes related to uploading. Refer to the link at the bottom for entire code.
// -------------------------------- Data Uploading Function void upload_lastBlockNo(void); void upload_DataBlock(uint32_t reqBlock); byte *setTerminator(byte *pD); /* ---------------------------------------------------------- D A T A U P L O A D I N G Function ---------------------------------------------------------- */ /* 0 1 012345678901 last data block number 12 bytes send N=4294967295 0 1 012345678901 time stamp 12 bytes send T=4294967295 012345678 Data 9 bytes send D=+99.999 D= empty D=-99.999 terminator */ void xsfBlockNo(uint32_t block) { ltoa(block - SD_BASE_BLOCK, printLn + 2, 10); printLn[0] = 'N'; printLn[1] = '='; WSsend(printLn, strlen(printLn)); } void upload_loastBlockNo(void) { xsfBlockNo(currBlock - 1); } void upload_DataBlock(uint32_t reqBlock) { byte *pS; int cnt; float data, *pF; // Store the currently logging Block into SD. // We might lose packets that ADAM-4017 is receiving. sdCard.writeBlock(currBlock, sdBuffer); printLn[1] = '='; if(sdCard.readBlock(reqBlock, sdBuffer)) { pS = sdBuffer; if(*((uint32_t*)pS) == USED_MARK) { pS += 4; // block number xsfBlockNo(reqBlock); // time stamp (milliseconds) ltoa(*((uint32_t*)pS), printLn + 2, 10); printLn[0] = 'T'; WSsend(printLn, strlen(printLn)); pS += 4; // data printLn[0] = 'D'; pF = (float*)pS; cnt = 120; while(cnt--) { data = *pF++ / 10.0; if(data != -99.999) dtostrf(data, 7, 3, printLn + 2); else printLn[2] = 0x00; WSsend(printLn, strlen(printLn)); } } printLn[0] = 'D'; setTerminator((byte*)(printLn + 2)); WSsend(printLn, strlen(printLn)); } // Reload the block that we have stored. sdCard.readBlock(currBlock, sdBuffer); } //--------------------------------------------------------- byte *setTerminator(byte *pD) { *pD++ = '-'; *pD++ = '9'; *pD++ = '9'; *pD++ = '.'; *pD++ = '9'; *pD++ = '9'; *pD++ = '9'; *pD++ = 0x00; return pD; } /* --------------------------------------------------------- W E B S O C K E T h a n d l e r --------------------------------------------------------- */ void onData(WebSocket &socket, char* rxLn, byte rxSz) { uint32_t block; if((rxLn[0] == 'G') && (rxLn[1] == 'E') && (rxLn[2] == 'T')) { *(rxLn + rxSz) = 0x00; block = atol(rxLn + 3); if(block) upload_DataBlock(block + SD_BASE_BLOCK); else upload_lastBlockNo(); } }
HTML/JS code for Upload Testing
<!DOCTYPE html> <html> <head> <title>WebLogger 5.0</title> <script type="text/javascript" src="jquery-2.0.3.min.js"></script> <script> var ws; var rcvCnt; $(document).ready(function() { WebSocketConnect(); }); function WebSocketConnect() { var ar = new Array(); var arSz, i; try { ws = new WebSocket('ws://192.168.219.16:80/'); ws.onopen = function() { status('Connected...'); } ws.onclose = function() { status('Closed...'); } ws.onerror = function(evt) { status('Error ' + evt.data); } ws.onmessage = function(evt) { ar = evt.data.split('='); // receive Last Data Block Number if (ar[0] == 'N') { $("#lastBlockNo").empty(); $("#lastBlockNo").append('Last Block Number:' + ar[1]); } // receive Time Stamp if (ar[0] == 'T') { $("#timestamp").empty(); $("#timestamp").append('TimeStamp(milliseconds):' + ar[1]); } // receive Data Block if (ar[0] == 'D') { $("#RcvLn").append('<p>' + ar[1] + '<p>'); if (ar[1] == '-99.999') { $("#recordCnt").empty(); $("#recordCnt").append('Record Count:' + rcvCnt); } rcvCnt++; } } } catch (exception) { status('Exception' + exception); } } function upload_lastBlockNo() { ws.send("GET0"); } function upload_DataBlock() { var recNo = document.getElementById("getRecordNo").value; ws.send("GET" + recNo); rcvCnt = 0; $("#timestamp").empty(); $("#recordCnt").empty(); $("#RcvLn").empty(); } function status(str) { $("#status").empty(); $("#status").append(str); } </script> </head> <body> <p id="status"></p> <button type="button" onclick="upload_lastBlockNo()">Get Last Data Block Number</button> <br /> <input type="text" id="getRecordNo" value="1"> <button type="button" onclick="upload_DataBlock()">Get Data Block</button> <p id="lastBlockNo"></p> <p id="timestamp"></p> <p id="recordCnt"></p> <p id="RcvLn"></p> </body> </html>
Full codes can be found in following links
- WSAdam.ino:
https://github.com/michelleseo/Arduino_Web/blob/master/WSAdam/WSAdam4/WSAdam4.ino - WSAdam5_0.html:
https://github.com/michelleseo/Arduino_Web/blob/master/WSAdam/WSAdam5_0.html
No comments:
Post a Comment