AnsweredHot!HTTP Net Dynamic Variables

Author
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
2018/05/11 11:25:31 (permalink)
0

HTTP Net Dynamic Variables

Background: MPLAB X IDE v4.15, XC32 v2.05, Harmony v2.05, PIC32MZ2048EFH100
 
Cutting right to the chase: how does one process an array of integers (from C) in javascript? I've been able to transfer the data using this code, which is treated as a string by the web browser, because I'm simply inserting ~tester~ into my web pages. Is there some sort of memcpy in javascript?
 
I could solve this problem by using sprintf, using a comma separated list of integers, but this would be ugly and I'm concerned that multiple calls to sprintf in a loop or one call with a bunch of arguments would be slow.
 
How do you guys transfer and process large blocks of data from the server (PIC application) to the client (web page javascript)?
 

TCPIP_HTTP_DYN_PRINT_RES TCPIP_HTTP_Print_tester(TCPIP_HTTP_NET_CONN_HANDLE connHandle, const TCPIP_HTTP_DYN_VAR_DCPT *vDcpt)
{
    HTTP_APP_DYNVAR_BUFFER *pDynBuffer = HTTP_APP_GetDynamicBuffer();
    uint16_t arr[10];
    if(pDynBuffer == 0)
    {   // failed to get a buffer; retry
        return TCPIP_HTTP_DYN_PRINT_RES_AGAIN;
    }

    ReadModbusRegisters(arr, 0, 10);
    memcpy(pDynBuffer->data, arr, sizeof(arr));
    TCPIP_HTTP_NET_DynamicWrite(vDcpt, pDynBuffer->data, sizeof(arr), true);
    return TCPIP_HTTP_DYN_PRINT_RES_DONE;
}

#1
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/11 11:41:43 (permalink)
0
Is this a "one" time write of the data or will ajax be used for updates ?
#2
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/11 12:04:54 (permalink)
0
I use AJAX and the xml files to update everything once every 500 ms, same as the example webpages.
#3
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/11 12:10:04 (permalink) ☄ Helpfulby bblessing 2018/05/11 13:51:17
5 (1)
I found with many variables going into tables I could make use of
 "<pre>" 
and pre formatting the data using sprintf, rather than labeling each variable in the table, ie: I built the table in the PIC.
I json encoded the data for use in the java ajax code for dynamic updates.
javascript knows how to deal with the json strings as arrays.
#4
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/11 13:55:04 (permalink)
0
I'll have to look into this, but I was under the impression that it was better to offload processing onto the web browser (within reason).
 
Either way I'll have to look into using the "ugly", my words, comma-separated list of integers or your method, both of which use sprintf. Looking at the timing of my old code ported over it's slow, ostensibly because I'm getting values one integer at a time as opposed to a whole block, which is what was done with the old web server.
#5
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/12 06:27:10 (permalink) ☼ Best Answerby bblessing 2018/05/14 12:42:28
5 (1)
In my Modbus interface I scan Modbus looking for changes.
When I detect a change I store it in an array in the PIC.
For the response to the Ajax request I output a json encoded string from the array with the changed keys, values.
If it has been a while since any changes I output all the array values.
The ajax web page code parses the json string to a javascript array and updates the fields.
The data is passed as a "block" ( one string ) from the PIC to the web page.
The key is used to index into the web page "id" to update the values.
#6
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/14 12:42:24 (permalink)
0
No question about it: a comma separated block is WAY faster. @Jim, I am taking your advice with the key/value pairs. That is very clever and my hat goes off to you for it. Thank you!
#7
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/15 06:32:39 (permalink)
0
bblessing,
You are welcome.
This method has served me well for some time.
#8
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/16 15:52:25 (permalink)
0
While I have your ear, Jim, could you answer another question for me? One of the things that is nice with most modbus serial applications is the ability to display a certain number of registers from a given offset. Passing arguments to dynamic variables, a la ~myVariable(2,6)~ for example, would seem to do the trick. However, this only applies to the initial loading of a webpage. If you want to periodically update the dynamic variables you'll have to use AJAX and an xml file.
 
The problem is that the xml files are sort of hardcoded. Look at the examples with led0,led1,led2,etc. Suppose that I wanted to have a single field to update, mb_read for example. The xml entry would be something like this:
 
<mb_read0>~mb_read(0)~</mb_read0>
 
The argument sent down to TCPIP_HTTP_Print_mb_read would be 0. However, it doesn't seem possible to make the argument "dynamic". In other words I can't say ~mb_read(x)~ where x is a value input from, say, a textbox. At least I don't think I can do that.
 
The fix for now is to send down the offset through a post message and just not send down arguments. I'm positive this will work, but it feels "kludgey".
 
Any thoughts?
#9
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/17 06:35:57 (permalink)
0
To get feedback from the web page from the user the mla demonstrates responding to a user click on index.htm and using forms in forms.htm
#10
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/17 07:54:53 (permalink)
0
JANickerson
To get feedback from the web page from the user the mla demonstrates responding to a user click on index.htm and using forms in forms.htm


Agreed, but I was just curious if I was missing something regarding AJAX. In the example above, let's suppose that I have a function call, TCPIP_HTTP_Print_raw_registers, that gets a TCPIP_HTTP_DYN_ARG_TYPE_INT32 argument. This argument is simply the offset into a modbus register array. The function would then send back a comma-separated list of 10 registers starting at the offset passed in. This is all well and good.
 
Unfortunately, from an AJAX point of view, I'm stuck with the following problem. The user would want to change the offset on the fly, via a textbox input for example, so the javascript would look something like this:
 
str = getXMLValue(xmlData, 'raw_registers' + offset.toString());
arr = str.split(",");
 
The problem is that the xml file would look horrible as I'd have to have something like this:
 
<raw_registers0>~raw_registers(0)~</raw_registers0>
<raw_registers1>~raw_registers(1)~</raw_registers1>
...
<raw_registers1000>~raw_registers(1000)~</raw_registers1000>
 
This would be a hideous waste of resources, as I essentially need to have as many calls as there could be possibilities for an offset argument. If I'm off base, please set me straight.
 
As you've pointed out, using post (get may be better here), does get around this. However, if this is the ONLY way to do it, it makes the idea of sending down inputs to dynamic variables A LOT less useful. Regardless, thank you for helping out!!!
#11
malaugh
Super Member
  • Total Posts : 338
  • Reward points : 0
  • Joined: 2011/03/31 14:04:42
  • Location: San Diego
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/17 08:44:15 (permalink)
5 (1)
Have you looked into JSON?  The way we handle this is to send the data as a JSON string to the browser.  A JSON array looks like
 
{ "MyArray":[1,2,3,4] }
 
Which on the embedded side is fairy easy to construct
 

char Buffer[MAX_SIZE];
char *BufferPtr = Buffer;
char Preamble[] = "{ \"MyArray\":[");
char Postamble[] = "]}";
 
BufferPtr += sprintf(BufferPtr, "%s",  Preamble);
for(i = 0; i < Array_Length; i++)
{
        BufferPtr += sprintf(BufferPtr, "%d",  ArrayValue[i]);   
}
BufferPtr += sprintf(BufferPtr - 1, "%s",  Postamble);

 
The reason for doing this is because it makes it much easier on the browser side.  JSON is easily converted into a Javascript object, the equivalent of a C structure.  I simple example of the Javascript code to send a JSON message, get the JSON response, change that into a Javascript object, and print the result on the browser is:
 

function FlashLights()
{
    var args = {};
    args.OnOff = parseInt(document.getElementById("GroupOrTheme").value);
    var jsonString = JSON.stringify(args);
    
    SendRequest("FlashLights.json", jsonString, StatusResponse);
}


function SendRequest(RequestUrl, jsonString, ResponseFunction)
{     
    if(NoWait == 0)
    {
        document.getElementById("Status").value = "Wait"
    }
    ajaxReq = new XMLHttpRequest();
    ajaxReq.onreadystatechange=ResponseFunction;
    ajaxReq.open("POST", RequestUrl, true);
    ajaxReq.send(jsonString);
}


function StatusResponse()
{     
    if (ajaxReq.readyState==4 && ajaxReq.status==200)
    {
        rsp = JSON.parse(ajaxReq.responseText)
        if(parseInt(rsp.Status) == 0)
        {
            document.getElementById("Status").value = "OK"
        }
        else
        {
            document.getElementById("Status").value = "Fail"
        }
    }
}

 
This assumes you have a text box called "Status" in the HTML, something like
 

<input id="Status" name="Status" style="width: 40px">

 
 
 
#12
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/17 08:48:34 (permalink)
0
malaugh,
I agree ( as I stated above in post 6 ).
You did go the extra mile and provide an example....
#13
bblessing
Super Member
  • Total Posts : 690
  • Reward points : 0
  • Joined: 2008/12/04 06:44:21
  • Location: Cincinnati, OH
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/17 10:59:47 (permalink)
0
I may need to take a step back and look into this further. It seems that looking at the code that you don't even bother with a lot of Microchip's sample code: mchp.js, status.xml, etc. Is this case? If so, I would think that it also means you guys also wrote your own versions of custom_http_net_app.c and the like. If this is the case then I have A LOT of reading and research to do. I'm simply working from Harmony's stock HTTP NET driver.
 
Edit: Are there any sources (literature, etc) that you recommend for this sort of thing?
post edited by bblessing - 2018/05/17 11:03:30
#14
Jim Nickerson
User 452 _
  • Total Posts : 5109
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: HTTP Net Dynamic Variables 2018/05/17 11:04:21 (permalink)
0
bblessing
you guys also wrote your own versions of custom_http_net_app.c and the like.
 

I used the stock custom_http and modified it for my own use.
I note I am using the MLA and not Harmony...
 
#15
Jump to:
© 2018 APG vNext Commercial Version 4.5