Avatar for jijidad

jijidad

Member since Jul 2018 • Last active Aug 2018
  • 2 conversations
  • 13 comments

Most recent activity

  • in Puck.js, Pixl.js and MDBT42
    Avatar for jijidad

    The API Ref page currently states:

    power - Transmit power. Accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm. Others will give an error code.

    But I tried to set my puck's TxPower to -30 and got this:

    >NRF.setTxPower(-30);
    Uncaught Error: Got BLE error 0x7 (INVALID_PARAM)
     at line 1 col 19
    NRF.setTxPower(-30);
    

    Digging into the code there is a comment indicating-30 is nRF51 only. Might be good to use the same (or similar) line on the API reference page:

    Accepted values are -40(nRF52 only), -30(nRF51 only), -20, -16, -12, -8, -4, 0, and 4 dBm. Others will give an error code.

    Also, I'm not even sure what is the difference between nRF52 and nRF51? Is nRF52 just newer firmware/hardware?

  • in ESP8266
    Avatar for jijidad

    I also had trouble flashing the ESP8266 from firmware "0018000902-AI03" to "0.25.0.0". I was using esptool on a mac, and it would look like it was working and get to "Uploading stub...", then it would fail with error "A fatal error occurred: Timed out waiting for packet header".

    I tried many things, and finally got it to work by decreasing the baud rate from 9600 down to 57600.

    For others experiencing this problem, the steps below worked for me:

    1) Pin connections:
    [ESP8266 ---> USB-TTL adaptor]
    GND --> GND
    UTXD --> RXD
    GPIO2 --> [none]
    CH_PD --> 3.3V
    GPIO0 --> GND
    VCC --> 3.3V
    URXD --> TXD

    2) Downloaded firmware ESP8266_AT25-SDK112-512k.bin into my Documents folder

    3) Downloaded and installed esptool.py using terminal:

    cd ~/Documents
    git clone https://github.com/themadinventor/esptoo­l.git
    cd esptool
    sudo python setup.py install

    4) In the terminal found my tty port using

    ls /dev/tty.*

    For me, I found it was /dev/tty.usbserial-AI06B7Y6

    5) I then ran the esptool from the terminal:

    python esptool/esptool.py -b 57600 -p /dev/tty.usbserial-AI06B7Y6 write_flash 0 ESP8266_AT25-SDK112-512k.bin

    It spit out a bunch of stuff and finally finished with:
    Hash of data verified.
    Leaving...
    Hard resetting via RTS pin...

    6) To verify, I followed the firmware test in Espruino IDE as described here, and it verified 0.25.0.0.

  • in General
    Avatar for jijidad

    I'm having success with my hardware SPI clock method. But I agree. It isn't spec friendly. I'll report back when I do larger scale testing in schools and let you know how it holds up to real world use.

  • in Puck.js, Pixl.js and MDBT42
    Avatar for jijidad

    I had a need to detect color. There are several boards available to detect color, but none of them work that great. I decided to see if the Puck's built-in red, green and blue LEDs (LED1, LED2, and LED3) could be used to detect color, and it works surprisingly well, so I wanted to share.

    Here is the simple approach I tested with:

    colors = {};
    
    function learnColor(colorName){
      var ledData = [analogRead(LED1),analogRead(LED2),analo­gRead(LED3)];
      colors[colorName] = ledData;
    }
    
    function whichColor(){
      var closestColor = null;
      var closestLQD = null;
      var ledData = [analogRead(LED1),analogRead(LED2),analo­gRead(LED3)];
      for(var colorName in colors){
        var colorLEDData = colors[colorName];
        var dr = ledData[0] - colorLEDData[0];
        var dg = ledData[1] - colorLEDData[1];
        var db = ledData[2] - colorLEDData[2];
        var leastSquares = dr*dr+dg*dg+db*db;
        if(closestLQD === null || leastSquares<closestLQD){
          closestColor = colorName;
          closestLQD = leastSquares;
        }
      }
      return closestColor;
    }
    

    There is a learnColor() function and a whichColor() function. Press the top of the puck against a color source and call learnColor(colorName) and pass in the name of that color. It works best with back illumination. I'm using my MacBook's screen with the following image:

    I went ahead and called learnColor("red") while holding the puck against the red, and then called learnColor("green") against the green, etc..

    Now when I hold the the puck against one of the four color patches at random and call whichColor(), it returns the correct color 100% of the time. Pretty cool!

    Now, this is VERY primitive at the moment. This is testing the exact same colors I trained on. But, with some additional work, I believe it would be possible to color balance and allow the training to generalize more. Also, currently, retraining on the same colorName will override the old data, but it's possible to average or otherwise accumulate the training data. Many more improvements can obviously be made.

    This is just a starting point, but it is already very useful. I'm using it as a UI input device where a young student can hold a puck against different patches on a screen to make different input choices. It's working great at the moment for this purpose.

    I should note that to get good readings, it's best to place the top face of the puck consistently flat against the display, and touching the display. I've tried it both with and without the white silicone case. It works better without the case.

  • in General
    Avatar for jijidad

    Aha! Got the inversion back after trying your technique with hardware SPI.

    I reset the board and tried with the following isolated test case:

    var spi = SPI1;
    spi.setup({miso:D15, mosi:D14, sck:LED1, baud: 1000000});
    
    function testMosi(){
     var finalClk = 0b10000000;
      var c = 0b10101010;
      var d = this.spi.send([c,c,c,c,c,c,finalClk]);
      print(d); 
    }
    
    setInterval(testMosi,1000);
    

    Gordon, can you try the above and take a look at D14 on your scope? Do you also see a normally high MOSI line? Please tell me I'm not crazy. Or, at least, show me what I'm doing wrong here...

  • in General
    Avatar for jijidad

    For what it's worth, here is the version of the module that I'm using. It's the most stable and precise of all the versions I've tested so far. It uses the SPI clock to send 24 ticks, and it uses hardware SPI1, which appears to be twice as fast as software SPI. It doesn't allow changing of the mode, as that requires a nonmultiple of 8 ticks. Here it is:

    /**
    Options should contain:
    {
      sck   : PD_SCK pin
      miso  : DOUT pin
      lsbGrams : grams per LSB
    */
    function HX711(options) {
      options = options||{};
      this.sck = options.sck;
      if (!this.sck) throw "Expecting sck";
      this.miso = options.miso;
      if (!this.miso) throw "Expecting miso";
      //this.mode = options.mode||"A128"; //changing the mode isn't supported yet
      this.lsbGrams = options.lsbGrams||1;
      /* The spec sheet specifies sending 24 ticks followed by 1-3 ticks for the gain.
         However, we are using the SPI clock which can only send multiples of 8 ticks.
         The HX711 seems to be fine with only getting 24 ticks.
      */
      this.spi = SPI1;//new SPI(); // use hardware SPI instead of software SPI
      this.spi.setup({miso:this.miso, sck:this.sck, baud: 1000000});
      //this.sck.write(0); // idle, but on
      this.zero = 0;
    }
    
    HX711.prototype.readRaw = function() {
        var d = this.spi.send([0,0,0]);
        var val = d[0]*65536 + d[1]*256 + d[2];
        return val;
    };
    /// Set the current reading to be the zero
    HX711.prototype.tare = function() {
      this.zero = this.readRaw();
    };
    /// Calibrate the lsbGrams value by putting a known weight on the scale
    /// then call this function passing in the grams of the known weight.
    HX711.prototype.calibrateLSBGrams = function( knownGrams ) {
      if(!this.zero){
        throw "Must call tare() with zero weight first before calibrating.";
      }
      if(!knownGrams){
        throw "Must supply a non-zero value for the known weight in grams.";
      }
      this.lsbGrams = knownGrams/this.readRaw();
    };
    /// Read the ADC and return the result in grams (based on options.lsbGrams)
    HX711.prototype.readGrams = function() {
      return (this.readRaw() - this.zero) * this.lsbGrams;
    };
    /// Is data ready for retrieval?
    HX711.prototype.isReady = function() {
      return !this.miso.read();
    };
    /// Set whether the ADC is in standby mode or not
    HX711.prototype.setStandby = function(isStandby) {
      this.sck.write(isStandby);
    };
    
    exports.connect = function(options) {
      return new HX711(options);
    };
    

    Below is an example of using it where I call tare() after 1 second and then spit out the weight measurement every second after that. Note that if you tare() too quickly, it'll not be accurate. Sometimes I need to tare again because the zero was off. This appears to be normal behavior since my kitchen scale is the same way (requiring multiple tares to get a stable zero). You can't do reads too close together in time or it'll introduce variability. This might be because the ADC needs to time out since I'm only sending 24 ticks or something... It appears that if you wait at least 30ms between reads, you'll be fine. Here I'm waiting 1000ms:

    //var HX711 = require(....)
    
    var h=HX711.connect({
      sck : D14,
      miso : D15,
      lsbGrams : 0.00103123388
    });
    
    setInterval(function() {
      if(!h.zero){
        print("tare");
        h.tare();
      }
      else{
        print(h.readGrams());
      }
    }, 1000);
    

    Here are some readings with nothing on the scale:

    -0.04949922623
    0.08559241203
    -0.04743675847
    0.01237480655
    0.00618740327
    -0.01753097595
    -0.04124935519
    -0.00206246775
    -0.03918688743
    0.025780847
    0.04743675847
    

    And here are some sample readings with a 33 gram weight:

    33.00773403103
    33.00464032939
    32.96854714359
    32.94998493375
    33.00876526491
    32.93039149003
    33.07167053159
    32.96339097419
    33.03248364415
    33.05620202339
    32.95926603867
    32.94895369987
    32.97060961135
    

    If you round to the nearest 0.1 gram, it's quite stable. Rounding to the nearest quarter gram is extremely stable. Since you can sample every 30ms, one could easily increase sampling rate and return an average over multiple reads to reduce noise even more. That's probably what I'll do for my current application.

    Hope this helps others who want to use an HX711.

    Gordon, I'm available to investigate things or do tests, or otherwise help in any way.

  • in General
    Avatar for jijidad

    Yes, I'm using MDBT42Q with 1v99 firmware. I'm using pins D14 and D15. Using D14 for the clock. I just restarted the board by disconnecting the battery and reconnecting. I'm now no longer getting the inverted mosi! I've tried for the last hour to reproduce getting that inversion back, but I haven't been successful yet. Any ideas on how it got into that state? Some internal pullup or something that didn't get reset? It probably would go unnoticed for most SPI situations since during the clock ticks, the voltage is correct. It's just in between the bytes that it goes high. But, after resetting, I'm not able to reproduce. Argh!! If you think that might be a bug somehow, I'm happy to try things that will help track this down if you want me to.

    With more testing, I did catch something that I didn't catch before which might be causing the variability in the readings. There appears to be an intermittent variability in the gaps between the mosi bytes. Normally, it's 30uS, but sometimes it's much higher. Here are a couple of examples:

    Notice that there can sometimes be over 100uS gaps. Have you run into this with software SPI? These longer gaps seem relatively infrequent. I'm wondering if this is causing the variability in the weight readings due to the ADC timing out or something. I haven't yet been able to correlate these two things though.

    Sorry. I feel like this is muddying the water instead of adding clarity.

Actions