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
.png)
No comments:
Post a Comment