Page 1 of 1

Advice on a ESP8266 data logger/recorder/AP

Posted: Fri Feb 19, 2021 1:13 am
by Zim
This is cicciocb's post.


Zim,
in the demo programs package delivered with the toolkit (in the files data-min.zip or data-full.zip), there are some examples of graph.
The example graph4.bas shows how interact with several javascript libraries (this demo handle with 4 different).

In particular there is the javascript xy.min.js that is probably what you are looking for.
This is the screenshot of demo4.bas running.
The xy can be easily configured using its documentation available here https://web.archive.org/web/20200917120 ... der9/xy.js


image.png

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Fri Feb 19, 2021 1:20 am
by Zim
Hi Zim,
I "played" a little bit with the graph as I think that could be nice to show how Annex can do in few lines of code
Adding a little bit of javascript code, is possible to refresh a graph in a single shot.
In particular the line jscall |traceme(1, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24");|
shows what must be sent: the first argument is the trace (0 or 1) and the second is a string of space separated values.
This example simply refresh random data coming from the basic each 500 msec.
The result can be seen in this little video

""

Code: [Local Link Removed for Guests]

''''' Animated Graph Demo '''''''''
' by cicciocb 2020
' draw 2 sets of random data refreshed
' alternatively each second
'''''''''''''''''''''''''''''''''''
cls
' loads the library
jsexternal "/xy.min.js"
cnt = 0

a$ = ""
a$ = a$ + |<p>Temperature Graph</p><canvas id="canvas1" width="600" height="300"></canvas>|
html a$
pause 1000

' define che datasets 
A$ = ""
A$ = A$ + |var datasets = [|
A$ = A$ + |  {|
A$ = A$ + |    lineColor : 'rgba(220,0,0,1)',|
A$ = A$ + |    pointColor : 'rgba(220,220,220,1)',|
A$ = A$ + |    pointStrokeColor : '#fff',|
A$ = A$ + |    data : []|
A$ = A$ + |  },|
A$ = A$ + |  {|
A$ = A$ + |    lineColor : 'rgba(151,187,205,1)',|
A$ = A$ + |    pointColor : 'rgba(151,187,205,1)',|
A$ = A$ + |    pointStrokeColor : '#fff',|
A$ = A$ + |    data : []|
A$ = A$ + |  }|
A$ = A$ + |];|

A$ = A$ + |var ctx2 = document.getElementById('canvas1').getContext('2d');|
A$ = A$ + ||
A$ = A$ + |var xy = new Xy(ctx2, {rangeX:[0,24], rangeY:[-50,50], smooth:0.1, pointCircleRadius:4, pointStrokeWidth:2 });|
A$ = A$ + ||

A$ = A$ + |function traceme(set, data){|
A$ = A$ + |  var s = data.split(" ");|
A$ = A$ + |  for (var i=0; i<s.length; i++) {|
A$ = A$ + |    datasets[set].data[i] = [i, s[i]];|
A$ = A$ + |  }|
A$ = A$ + |  xy.draw(datasets);|
A$ = A$ + |}|

jscript a$
A$ = "" ' clean memory

'create a "test set"
jscall |traceme(1, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24");|

timer0 500, counter
wait

counter:
  v$ = ""
  for z=0 to 24
     v$ = v$ + str$(rnd(100) - 50) + " "
  next z
  if (cnt and 1) then
    jscall |traceme(0,"| + v$ + |");|
  else
    jscall |traceme(1,"| + v$ + |");|
  end if
  
  cnt = (cnt + 1) mod 100
return


as a second example, I simply modified the previous one showing how is possible to create scrolling data always coming from the basic.
The result can be seen in this little video

""

Code: [Local Link Removed for Guests]



''''' Animated Graph Demo '''''''''
' by cicciocb 2020
' draw 2 sets of random data scrolled
' alternatively each second
'''''''''''''''''''''''''''''''''''
cls

' loads the library
jsexternal "/xy.min.js"
cnt = 0

a$ = ""
a$ = a$ + |<p>Temperature Graph</p><canvas id="canvas1" width="600" height="300"></canvas>|
html a$
pause 1000


A$ = ""
A$ = A$ + |var datasets = [|
A$ = A$ + |  {|
A$ = A$ + |    lineColor : 'rgba(220,0,0,1)',|
A$ = A$ + |    pointColor : 'rgba(220,220,220,1)',|
A$ = A$ + |    pointStrokeColor : '#fff',|
A$ = A$ + |    data : []|
A$ = A$ + |  },|
A$ = A$ + |  {|
A$ = A$ + |    lineColor : 'rgba(151,187,205,1)',|
A$ = A$ + |    pointColor : 'rgba(151,187,205,1)',|
A$ = A$ + |    pointStrokeColor : '#fff',|
A$ = A$ + |    data : []|
A$ = A$ + |  }|
A$ = A$ + |];|

A$ = A$ + |var ctx2 = document.getElementById('canvas1').getContext('2d');|
A$ = A$ + ||
A$ = A$ + |var xy = new Xy(ctx2, {rangeX:[0,24], rangeY:[-50,50], smooth:0.1, pointCircleRadius:4, pointStrokeWidth:2 });|
A$ = A$ + ||

A$ = A$ + |function traceme(set, data){|
A$ = A$ + |  var s = data.split(" ");|
A$ = A$ + |  for (var i=0; i<s.length; i++) {|
A$ = A$ + |    datasets[set].data[i] = [i, s[i]];|
A$ = A$ + |  }|
A$ = A$ + |  xy.draw(datasets);|
A$ = A$ + |}|

jscript a$
A$ = ""

'create 2 random series
v1$ = ""
v2$ = ""
  for z=0 to 24
     v1$ = v1$ + str$(rnd(100) - 50) + " "
     v2$ = v2$ + str$(rnd(100) - 50) + " "
  next z
v1$ = trim$(v1$)
v2$ = trim$(v2$)



timer0 500, counter
wait

counter:
  if (cnt and 1) then
    ' insert at the beginning and remove from the end
    v1$ = str$(rnd(100) - 50) + " " + v1$
    p = instr(-1, v1$, " ")
    v1$ = left$(v1$, p -1)
    jscall |traceme(0,"| + v1$ + |");|
  else
    ' insert at the beginning and remove from the end
    v2$ = str$(rnd(100) - 50) + " " + v2$
    p = instr(-1, v2$, " ")
    v2$ = left$(v2$, p -1)  
    jscall |traceme(1,"| + v2$ + |");|
  end if
  
  cnt = (cnt + 1) mod 100
return



The number of points can be increased (I tried up to 96 points who correspond at a point each 15 minutes and it works without any issue) but always consider that the ESP8266 has few memory.

Obviously the same program works for the ESP32 too.

cicciocb

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Mon Jan 30, 2023 3:09 pm
by oldbiddy
hi the link for the documentation for the xy.min.js sems to be broken can a copy be put some where on the forum

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Mon Jan 30, 2023 7:35 pm
by cicciocb
[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Mon Jan 30, 2023 3:09 pm hi the link for the documentation for the xy.min.js sems to be broken can a copy be put some where on the forum
Please find the file here :
xy.min.js.gz
Just for info, that file can be found inside the zip files delivered with the AnnexToolkit (That I suppose you already downloaded :D )

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Mon Jan 30, 2023 8:01 pm
by bugs
I have been using the xy.min for some time but have never found out what exactly it can do.go
The start of the xy.min.js file has this address referenced but it gives a 404 error :- https://github.com/thunder9/xy.js

Does anyone have another URL - or any info on how to make it do variations on the above examples.
I have tried to make it auto-range (in the Y axis) but with 20 points plotted it does not always work for some reason.

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Tue Jan 31, 2023 3:26 pm
by cicciocb
[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Mon Jan 30, 2023 8:01 pm I have been using the xy.min for some time but have never found out what exactly it can do.go
The start of the xy.min.js file has this address referenced but it gives a 404 error :- https://github.com/thunder9/xy.js

Does anyone have another URL - or any info on how to make it do variations on the above examples.
I have tried to make it auto-range (in the Y axis) but with 20 points plotted it does not always work for some reason.
Apparently this library disappeared from github, probably the author decided to remove it.

Edit :
With a little bit of research, I've been able to find it on the web historical archive

https://web.archive.org/web/20200917120 ... der9/xy.js

However, the best is to move toward chart.js https://www.chartjs.org/docs/latest/

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Tue Jan 31, 2023 6:06 pm
by bugs
Wow! Thank you for the research - I spent a long time looking on google without success. It will take me a while to digest the details as I struggle with the modern coding methods (I am however fluent in MC6809 machine code :) )
I think chart.js is one step too far.

Thanks (as always) for the superb support. :D :D

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Tue Jun 06, 2023 9:41 am
by BeanieBots
Any chance of a simple example using chart.js ?
As always, I can get an example working in the likes of jsfiddle, but fail to make it work from Annex.

working html example:

Code: [Local Link Removed for Guests]

<div>
  <canvas id="myChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>
  const ctx = document.getElementById('myChart');

  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
</script>
Any help would be much appreciated.

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Wed Jun 07, 2023 2:31 pm
by cicciocb
You could simply copy/paste the content of your web page and save it as, for example, /mytest.html

Then you can simply open this page with http://your_ip_address/mytest.html
In fact, the module hosts a web server which can be used to display static pages; you can put as many pages as you want.
But this is only for static pages.
If you want to transfer content between basic and html, you have to write some code relying on XMLhttpRequest command in javascript and OnUrlMessage in basic.
I give an example below on how to do it (html and basic):

Code: [Local Link Removed for Guests]

<div>
  <canvas id="myChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>
  const ctx = document.getElementById('myChart');

  mychart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
  
  setInterval(function() {
    xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", "msg?a=10&b=20&c=30"); // send this message to the basic (onUrlMessage)
    xmlHttp.addEventListener('load', function(e) {
      console.log(xmlHttp.response);
      if (xmlHttp.response != "STOPPED") {  // receive the message from the basic
         mychart.data.datasets[0].data = xmlHttp.response.split(",");  //convert from comma separated value (text) to array
         mychart.update();
      }
    });
    xmlHttp.send(null);

  }, 1000);  // each 1000msec
  
</script>

Code: [Local Link Removed for Guests]

'very minimalist example of transfer 
'between the html and the basic using static files
onUrlMessage message
wait

message:
  wlog "Received from the html : " + UrlMsgGet$()
  j$ = ""
  for w = 0 to 5
    if (w > 0) then j$ = j$ + ","
    j$ = j$ + str$(rnd(100) ) ' generate random values 
  next w
  UrlMsgReturn j$ ' send the values to the javascript
return
Now, there is a much simpler way to do that using the OUTPUT page.
In fact this page already contains a lot of javascript code that simplify the transfer of the variables.
As this page works in a special mode, it requires a little bit of work to split the javascript and the html code into separated parts.
The big advantage of this method is that you can continue to use the TEXTBOX$, BUTTON$, .... at the same time and the transfer of the variables is done under the hood.

Try this example:

Code: [Local Link Removed for Guests]

'Example of transfer of variables from basic to javascript object
jsexternal "https://cdn.jsdelivr.net/npm/chart.js"
pause 500 'wait a little bit the time required to load the library
cls
A$ = ||
A$ = A$ + |<div>|
A$ = A$ + |  <canvas id="myChart"></canvas>|
A$ = A$ + |</div>|
html a$

A$ = ||
A$ = A$ + |ctx = document.getElementById('myChart');|
A$ = A$ + ||
A$ = A$ + |   mychart = new Chart(ctx, {|
A$ = A$ + |    type: 'bar',|
A$ = A$ + |    data: {|
A$ = A$ + |      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],|
A$ = A$ + |      datasets: [{|
A$ = A$ + |        label: '# of Votes',|
A$ = A$ + |        data: [12, 19, 3, 5, 2, 3],|
A$ = A$ + |        borderWidth: 1|
A$ = A$ + |      }]|
A$ = A$ + |    },|
A$ = A$ + |    options: {|
A$ = A$ + |      scales: {|
A$ = A$ + |        y: {|
A$ = A$ + |          beginAtZero: true|
A$ = A$ + |        }|
A$ = A$ + |      }|
A$ = A$ + |    }|
A$ = A$ + |  });|
A$ = A$ + |  js_var = 123456;| 'local javascript variable
jscript a$

bas_var = 0 ' default value at 0
while 1
  j$ = ""
  for w = 0 to 5
    if (w > 0) then j$ = j$ + ","
    j$ = j$ + str$(rnd(100) )
  next w
  jscall "mychart.data.datasets[0].data = [" + j$ + "]; mychart.update();"
  jscall |connection.send("cmd:setvars" + "bas_var=" + js_var)| 'transfers js_var(javascript) in the variable bas_var (basic)
  pause 1000
  wlog bas_var 'print the content of the variable coming from the javascript
wend 
   
As you can see, JSCALL send commands in the javascript side enabling to send and receive variables easily.
With a little bit of exercise any javascript object / library can be included with this method

cicciocb

Re: Advice on a ESP8266 data logger/recorder/AP

Posted: Thu Jun 08, 2023 5:36 pm
by BeanieBots
Thank you so much for the worked example and more importantly the explanation of what and why.
The examples work really well, now I can fiddle and get it working the way I want.