A WIFI Datalogger for Espruino PICO

Posted on
  • A WIFI Datalogger for Espruino PICO

    Github

    What it does:

    1. Connects to a Wifi router

    2. Sends a Dweet containing the local IP address

    Dweet

    1. Sets the PICO RTC to the time returned by the Dweet Service

    2. DIsconnects and reconnects to the Wifi router

    3. Serves a Web page that allows the client to enter the filename to assign to downloaded data.

    4. Send the collected data in comma separated format CSV with a MIME header that opens an Excel spreadsheet.

    5. Collects the data at specified intervals and stores it in ring buffers in RAM.

    The Hardware

    1. Espruino PICO board running Espruino 1v95 or later software, and an ESP8266 mounted on a shim.

    PICO wifi shim

    1. A pushbutton switch wired from pin B3 to ground. (Digital Read)

    2. A 10k potentiometer or series of 10k resistors wired to vary the Voltage on pin B1 in a range of 0.0 to 3.0 Volts. (Analog Read)

    3. (for one program) A DHT22 Relative Humidity and Temperature sensor with the power leads appropriately connected to ground and the 3.3 Volt busses and the output pin with a pullup resistor connected to PICO pin A7.

    DHT22

    Items to edit in order to run the examples:

    1. Local Modules

    In the upper right of the WebIDE is a 'gear' looking icon, hover the cursor over the icon and the word settings will appear. Click on the settings icon and then select Project. Use the "Select Directory for the Sandbox " to select or even create a sanbox directory. For example I create a sandbox named EspruinoModules. It has a number of sub-directories. We are interested in the one called \modules.

    "C:\Users\jj\Documents\EspruinoModules\m­odules"

    Copy the attached modules files to the folder:

    "C:\Users\jj\Documents\EspruinoModules\m­odules\PICOwifi.js"

    and

    "C:\Users\jj\Documents\EspruinoModules\m­odules\ringMod.js"

    1. Editing the Programs to run the Demos


    "C:\Users\jj\Documents\PICOwifi\logger\R­ing\Post19Feb2018\PICOwifi-Dweet-Log-Tes­t.js"

    "C:\Users\jj\Documents\PICOwifi\logger\R­ing\Post19Feb2018\PICOwifi-Dweet-Log-DHT­22.js"

    a. ssid - wifi name

    b. key - wifi password

    c. DweetID make up a name unique to you

    d. timezone (-6 is for CST)

    // things to configure
    var ssid="myssid";
    var key="mykey";
    //set DweetID to a unique value
    var DweetID="mydweetname";
    // https://dweet.io/get/latest/dweet/for/my­dweetname
    var verbose; //module is quiet
    //var verbose=1; // module console.logs
    var timezone=-6;
    var dsize=432;//144;
    var loginterval=1000;
    

    The verbose refers to console output in the PICOwif module.
    dsize it the length of the rung buffer used to store data.

    loginterval is the number of milliseconds between data samples.

    The WebIDE output:

     1v95 Copyright 2017 G.Williams
    >Start connection process
    =undefined
    null
    IP=  192.168.1.11
    null
    Mytask 1
    Sun Feb 18 2018 20:22:25 GMT-0600
    Start connection process
    null
    IP=  192.168.1.11
    null
    Mytask 2
    dl
    rend1
    dl
    rend1
    dl
    rend2
    rend2
    rend2
    rend2
    rend2
    rend2
    rend2
    rend1
    

    The Dweet Page

    From a browser enter the IP address
    (substitute mysweet name)

    https://dweet.io/get/latest/dweet/for/my­dweetname

    The output displayed on the web page will be

    {"this":"succeeded","by":"getting","the"­:"dweets","with":[{"thing":"lovelyDay823­","created":"2018-02-19T02:22:25.410Z","­content":{"IP":"192.168.1.11"}}]}
    

    The Download Page

    Using a browser enter the IP address of the PICO

    For example:

    http://192.168.1.11:8080/

    To Download data from lovelyDay871 
    Name the .CSV file name where you want to save the data 
     Click to download 
    

    For now just click. Later try changing the filename before clicking download. Try xxy.csv, xxx , and xx.txt.

    For xxx.csv my Windows10 system displays a message at the bottom of the page that says:

    What do you want to do with xxx.csv?
    From 192.168.1.11
    Open, Save Cancel
    

    The file is opened with Excel.

    Example xxx.csv downloaded (see attached file):

    Station Name	lovelyDay871	 					
    Download Time	Sun Feb 18 2018 16:59:12 GMT-0600	 	 	 			
    							
    N	Date	Temp F	Temp C	Flow l/s	Pump	dhtTemp C	dhtRH %
    0	Sun Feb 18 2018 16:55:18 GMT-0600	79.07	25.7	0.67	1	21.6	40.1
    1	Sun Feb 18 2018 16:55:19 GMT-0600	79.65	26.35	0.66	1	21.6	40.4
    2	Sun Feb 18 2018 16:55:20 GMT-0600	80.02	26.15	0.67	1	21.6	40.2
    3	Sun Feb 18 2018 16:55:21 GMT-0600	80.24	27.01	0.67	1	21.6	40.2
    

    6 Attachments

  • Using the ringMod.js Module

    Assuming that the ringMod.js module is located in th emodules folder of the WEBide sandbox.

    Require the module in your code and for convience use a variable to specify the length of the rinf buffers.

    var R=require('ringMod');
    var dsize=432;
    

    Declare an array of pointers to instances of ringMOD and then create the instances

    For example:

    var data=[];
    data.push(new R("Date",dsize,Array,1,1,0,gettime,null,­datestring,0));
    data.push(new R("Temp F",dsize,Int16Array,100,9/5,32,E.getTemp­erature,null,tofixed,2));
    data.push(new R("Temp C",dsize,Int16Array,100,1,0,E.getTempera­ture,null));
    data.push(new R("Flow l/s",dsize,Int16Array,4096,1,0,analogRea­d,pinB1,tofixed,2));
    data.push(new R("Pump",dsize,Int8Array,1,1,0,digitalRe­ad,pinB3,tofixed,0));
    data.push(new R("dhtTemp C",dsize,Int16Array,100,1,0,getTemp,null­));
    data.push(new R("dhtRH %",dsize,Int16Array,100,1,0,getRH,null))­;
    

    The fields used when creating instances of ringMOD

    ring(hname,size,type,mult,slope,intercep­t,logfunc,lfargs,format,fargs){
    
    1. hname - a string that is used for the column title in the final spreadsheet
    2. size - the length of the ring buffer
    3. type - the data type used to store the data. Examples Int16Array, Int8Array etv
    4. mult - multiplies the raw data before storage, divides the stored value before using
    5. slope - the linear regression slope used to scale raw values into engineering units (non-zero) If in doubt use 1.0
    6. intercept - the linear regression intercept used to scale raw values into engineering units (try 0.0)
    7. logfunc - name the function or helper function used to obtain the raw data. Examples:

      function gettime(a){
      return clk.getDate();
      }
      
    8. lfargs - any argument needed to complte the logfunc. Example logfunc= "analogRead" and lgargs= B7, if not needed use null

    9. format - name of helper function used to format the data Examples:

      function datestring(a){
      //  console.log(a);
      return Date(a).toString();
      }
      
      function tofixed(a,b){
      return(a.toFixed(b));
      }
      
    10. fargs - argument used with the format function: For example format =tofixed and fargs=2

    Inserting the data

    Note the logflag used to suspend logging until the clock etc are ready to log.

    function log() {
     var i;
     if(logflag>0){
      for(i=0;i<data.length;i++)data[i].insert­();
       digitalWrite(LED1,l=!l);
     }
    }
    

    Logging the data

    The DHT22 returns data in a callback so call it first and in the callback save the DHT data and do the log()

    // Do the logging at loginterval in ms
    setInterval(function(){
    dht.read(function (a){
     DHTt= a.temp;
     DHTrh= a.rh;
    //  console.log("Temp is ",getTemp());
    //  console.log("RH is ",getRH());
     log();
    });
    },loginterval);
    

    The DHT temporary storage variables and the logfunct helper functions

    var DHTt,DHTrh;
    function getTemp(){return DHTt;}
    function getRH(){return DHTrh;}
    

    Creating the CSV data from the data array

    The process.memoy() commands fix a bug that the cutting edge version of Espruino has fixed.

    Send 10 lines at a time in the drain function to keep from using too much memory at a time.

    function onPageRequest(req, res) { 
        var i=0;
        var ii=0;
        var j=0;
        var sss="";
      var a = url.parse(req.url, true);
    if (a.pathname.substr(-1)=="/") { // a slash at the end
        res.writeHead(200, {'Content-Type': 'text/html'});
    // substitute your own html here
    // maybe a button to clear or reset the data log on the Pico
        res.write(page1+DweetID+page2);
    process.memory(); 
        res.end();                                
    }else{ //filename.csv after the URL slash to do csv files
    process.memory(); 
    console.log("dl");
        res.writeHead(200, {'Content-Type': 'text/csv'});
    //write csv file header
         res.write("Station Name,"+DweetID+"\r");
         res.write("Download Time,"+clk.getDate().toString()+"\r");
         res.write("\r");
    //write the column headers for the csv file
      for(j=0;j<data.length;j++)sss+=data[j].h­name+",";
      sss=sss.slice(0,sss.length-1)+'\r';
    //  console.log("N,",sss);
      res.write("N,"+sss);
      i=0;j=0;
    // send the data
      res.on('drain',function(){
    process.memory(); ////////////////////////////////////////­/
        if(j>=data[0].cnt){ //logdata.length){ 
        console.log("rend1");
        res.end();
       }else{
      for(i=j;i<j+10;i++){
        if(i<data[0].cnt){ 
      sss="";
         for(ii=0;ii<data.length;ii++)
          sss=sss+data[ii].getDatum(i)+",";
         sss=sss.slice(0,sss.length-1)+'\r';
         res.write(i.toString()+","+sss);
         }else{
    process.memory(); ////////////////////////////////////////­/
          console.log("rend2");
          if(j){
            res.end();
            j=0;
          }//end if j  
         }
        }//next i
        j+=10;
       }//end else
      });//end on drain
    }//end else
     res.on('close', function() {});//console.log("t2close");  });
     req.on('data',function(data){});//,data)­;});
     req.on('error',function(){});//console.l­og("reqerr");});
     req.on('close',function(){});//console.l­og("reqcls");});
    }//end onPagerequest
    
  • Using the PICOwifi.js Module

    Require and create an instance of PICOwifi

    var X=require('PICOwifi');
    var Y=new X();
    
    

    Setup some variables

    // things to configure
    var ssid="your network name";
    var key="your network password";
    
    // used by PICOwifi module
    var Startagain=0;
    var myinterval;
    var verbose; //module is quiet
    //var verbose=1; // module console.logs
    

    Create a task or a series of tasks

    For example:

    var page1 = "<!DOCTYPE html>\r\n<html>\r\n<body>\r\n\r\n<h1>My First Web Page</h1>\r\n<p>My first paragraph.\r\n</body>\</html>";
    
    function mytask(){
     console.log("Mytask");
    //// Various user code can go here a simple hello page server
    //// is given as an example
    var http=require('http').createServer(functi­on (req, res) {
    res.writeHead(200);
     console.log("hello");
     res.write(page1);
     res.end();
     res.on('close', function() {});//console.log("t2close");  });
     req.on('data',function(data){});//,data)­;});
     req.on('error',function(){});//console.l­og("reqerr");});
     req.on('close',function(){});//console.l­og("reqcls");});
    }).listen(8080); //end server
    //// end user code  
    }//end my task
    
    

    Setup function to start the wifi and check it periodically

    function test(){
        Y.connect(ssid,key,mytask);
    }//end test
    
    myinterval=setInterval(function () {
    //  console.log("Test for error");
      if(Startagain){
       Startagain=0;
       test();
      }//end of Startagain
    }, 2000);
    
    test();
    

    The Startagain variable can be used in the task code to cause the WIFI to restart. A tasknumber could be used in Mytask to take the tasks through a series of tasks


    1 Attachment

    • xxx.jpg
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

A WIFI Datalogger for Espruino PICO

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions