Arduino Parts

Posted on
  • Hey,

    I'm about to finally start a project with my Espruino chip, but had a question regarding parts. I wanted to add a pH probe but all I could find are ones that are Arduino Library ready.

    Will this pH probe work my Espruino chip? If not, where can I buy the Espruino specialty parts?

    Thanks!

  • Presently, nobody's written an Espruino driver for a PH meter.

    Someone will need to write the code to interface with it (hopefully as a module) - that could be you (I wrote a few of the modules, some of them only shortly after discovering microcontrollers in general - it's not particularly hard or anything, at least for cooperative hardware).

    Read the datasheets/specs for the modules to see how you have to interface with them - this gives you an idea of how easy it would be to write that module. If it's just an analog output, it's trivial - all you need to do is whatever mathematical manipulations the datasheet/specs tell you to. If it's I2C, the module will probably be straightforward to write. SPI is a bit harder to work with, but nothing too awful. Things that use custom digital protocols (like the DHT11) are not as agreeable.

    Also, things that have arduino libraries are much easier to write drivers for, because you have working driver code to crib from. Some of the modules were clearly the result of copy-pasting arduino code (probably using an editor with JS highlighting) and converting that way, rather than writing code from scratch.

    For what it's worth, the first result I saw on ebay ( http://www.ebay.com/itm/Analog-PH-Probe-­Sensor-Shield-and-PH-Probe-Kit-For-Ardui­no-Compatible-/181341515761?pt=LH_Defaul­tDomain_0&hash=item2a38cbeff1 ) has analog output and the measuring process looks trivial.

  • Hi,

    So I just received my pH Meter and shield from df, however, I am running into a little trouble converting the library to JS. I have taken the Arduino code from here[http://www.dfrobot.com/wiki/index.php/PH­_meter(SKU:_SEN0161)], but I can't seem to find an equivalent to "millis();". Is there a way around this? Am I even going in the right direction?

    Thanks.

    
    function SEN0161(pin) {
      this.pin = pin;
    }
    
    SEN0161.prototype.getScale = function () {
      pin = this.pin;
      var val = digitalRead(pin);
      
      var Offset = 0.00;
      var LED = 13;
      var samplingInterval = 20;
      var printInterval = 800;
      var ArrayLength = 40;
      
      var pHArray = [ArrayLength];
      var pHArrayIndex = 0;
      var samplingTime = '';
      
      var printTime = Date.now();
      var pHValue,voltage;
      
      //console.log(Date.now());
      //console.log(digitalPulse(this.pin,1,5)­);
    
      if(Date.now() - samplingTime > samplingInterval) {
          pHArray[pHArrayIndex++] = analogRead(this.pin);
        
          if(pHArrayIndex == ArrayLenth)pHArrayIndex=0;
        
          voltage = this.averageArray(pHArray, ArrayLength) * 5.0 / 1024;
          pHValue = 3.5 * voltage + Offset;
          samplingTime = Date.now();
      }
      if(Date.now() - printTime > printInterval) {
            console.log("Voltage:");
            console.log(voltage,2);
            console.log("    pH value: ");
            console.log(pHValue,2);
            digitalWrite(LED,digitalRead(LED)^1);
            printTime = Date.now();
      }
    };
    
    SEN0161.prototype.averageArray = function (arr, number) {
      var i;
      var max,min;
      var avg;
      var amount=0;
    
      if(number <= 0){
        console.log("Error number for the array to avraging!/n");
        return 0;
      }
      if(number < 5) {   //less than 5, calculated directly statistics
        for(i=0; i < number; i++) {
          amount += arr[i];
        }
        avg = amount/number;
        return avg;
      } else {
        console.log(arr);
        if(arr[0] < arr[1]) {
          min = arr[0]; max=arr[1];
        } else {
          min=arr[1];
          max=arr[0];
        }
        console.log(min);
        console.log(max);
        for(i=2; i < number; i++) {
          if(arr[i] < min) {
            amount += min;        //arr<min
            min = arr[i];
          } else {
            if(arr[i] > max) {
              amount += max;    //arr>max
              max = arr[i];
            } else {
              amount += arr[i]; //min<=arr<=max
            }
          }
        }
        avg = amount/(number-2);
      }
      return avg;
    };
    
    exports.connect = function (pin) {
      return new SEN0161(pin);
    };
    
    //exports.connect();
    
    
    var sensor = exports.connect(A1);
    console.log(sensor);
    //console.log(sensor.getScale());
    setInterval('sensor.getScale()', 1000);
    
  • Hi - there is getTime() which is like millis() except that it returns seconds (but as a fractional number).

    However the Arduino code keeps going around the loop and grabbing values every samplingInterval. In Espruino it probably makes more sense to use setInterval to run your code exactly every samplingInterval (whenever you need a value), and to then to use a callback whenever you have the result...

    So for example you could try (untested!):

    SEN0161.prototype.getScale = function (callback) {
      var sensor = this;
      var Offset = 0.00;
    
      var readings = [];
      var interval = setInterval(function() {
       readings.push(analogRead(sensor.pin));
       if (readings.length>=5) {
        var voltage = E.getAnalogVRef()*E.sum(readings)/readin­gs.length;
        var pHValue = 3.5 * voltage + Offset;
        clearInterval(interval);
        callback({pHValue:pHValue,voltage:voltag­e});
       }
      , 20/*samplingInterval*/);
    };
    
    // ...
    sensor.getScale(function(d) {
      console.log("    Voltage: "+d.voltage.toFixed(2));
      console.log("    pH value: "+d.pHValue.toFixed(2));
    });
    

    So whenever you want a value, that'll go away and will get 5 values (meanwhile other code can be doing other things), and it will then average them and return the result.

    A few things I noticed that might help:

    • analogRead in Espruino returns a floating point value between 0 and 1, rather than an integer between 0 and 1023
    • Espruino is 3.3v, so you have to multiply by 3.3 rather than 5 for the voltage. In the code above I'm using E.getAnalogVRef() though, which actually measures the voltage based on an internal voltage reference.
    • If you want to output a value to 2 decimal places, just use value.toFixed(2) - console.log(x,2) will just return the value of x, and then 2
    • There's some really odd-looking filtering being done on the data that's received. I've just replaced it with an average using E.sum (which is fast, and looks tidier) which should at least give you a value to work with.
  • @badxhabit I have had a bit of experience using ph sensors with the Espruino; however, I do not have any example code at the moment. I have used the ph sensor from http://www.atlas-scientific.com and I recently just purchased the LeoPhi from http://www.sparkyswidgets.com. The PH sensor from sparkyswidgets is on backorder so I haven't received it yet. Also, the ph sensor from sparkyswidgets is opensource and openhardware. I tend to navigate more towards opensource/hardware to support the the opensource movement. I will get back to you with my findings on the LeoPhi once I receive it.

    I would recommend that you hook up a temperature sensor to get a temperature compensated ph results. Temperature compensated ph results give more of an "accurate" reading than just a ph reading. I use the analog temp sensor from atlas-scientific with success. I also posted my temp sensor code in the forum which can be found here: http://forum.espruino.com/conversations/­1572/#comment29544

    When you have the time can you respond back letting us know how you like the PH sensor that you purchased?

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

Arduino Parts

Posted by Avatar for badxhabit @badxhabit

Actions