• I have started my first project, I am new to electronics but an old hand at coding.

    I have 5v regulated DC power connected to my circuit (not via the espruino 5v), espruno is powered via USB, I am running code via the API

    I am making a RGB LED strip change color depending on distance measured by ultrasonic echo.

    I am just experimenting with the sensor module:

    var sensor = require("HC-SR04").connect(A0,A2,functio­n(dist) {
      console.log("response "+Math.floor(dist)+" cm away");
    });
    

    Now this seems to continuously send output after loaded until you trigger it via:

    sensor.trigger();
    

    Does anyone know why this is?

    Also, I seem to be getting very random results that don't have anything to do with putting an object in front of the sensor when I use setInterval, I have wired it up as described here http://www.espruino.com/HC-SR04

    If anyone has experience with this sensor I would love some pointers.

  • further to this, now I have set it up to only trigger on button 1 press, each time it is pressed it returns several times:

    Code:

    var sensor = require("HC-SR04").connect(A2,A3,functio­n(dist) {
      console.log("response "+Math.floor(dist)+" cm away");
    });
    
    function runIt(){
      console.log("button pressed");
      sensor.trigger();
    }
    
    runIt();
    
    setWatch(runIt, BTN1, {repeat:true, edge:"rising"});
    
    

    Results:

    
    button pressed
    response 27015 cm away
    response 11 cm away
    response 13 cm away
    response 109 cm away
    

    I would expect one response per trigger, or am I missing something?

  • The code as presented does exactly one trigger... on upload, and then everytime you enter in the console sensor.trigger().

    If you see it constantly doing something, you may have a grounding issue from the fact that you power Espruino from USB and your distance sensor device from you 5V power supply.

    Did you make a connection from GND of the device to GND of Espruino?

    If you do not have that, both GNDs are dancing around by the noise, and the noise constantly but irregulaerly triggers the device, 1st, and 2nd, the readings are not reliable either... ;)

  • Brilliant! @allObjects that fixed it, thank you very much.

  • ;)

    Now I know that you later plan to run your stuff disconnected from USB, just off of your 5V power supply, correct?

    You can do that final configuration already now and still have only 4 connections between Espruibo and the distance sensor device 'exactly' as described on the HC-SR04 page (except that you use A2 rather A1 for capturing the Echo from the device).

    If you have an Espruino standard board, you connect your power supply to the white Battery connecter in the corner of the standard board next to B2 pin. Make sure that (-)GND of the power supply goes to (-)GND to (-)(GND) of the battery connector, and (+)5V to the (+) of the battery connector. 'NEVER' connect the power supply 5V(+) to the Bat pin of the board, even though there are situations with such a connection that do not lead to disaster (your power supply delivers 5V and that is more than what comes from 5V USB through the blocking diode - 4.7/4.3V, but when our power supply delivers less or has another issue, USB will try to feed it and that leads to all sorts of unesirable (final fatal) results, even though there is a 1000mA fuse in the circuit). With connecting to the Battery connector you can have safely run USB connected parallel to your power supply.

    If ou have an Espruino Pico - and I assume that's the case - you connect your power supply's (-)GND to the Pico GND pin between to the USB tab and VBat pin - the GND pin is the first pin on the right sight looking from top and USB tab, and you connect the power supply's (+)5V to the BAT_IN pin between the USB tab and pin B15 - the BAT_IN pin is the first pin next to the TAB opposite the GND pin. Again, do not connect the power supply 5V(+) to Pico's VBAT pin beteween GND and 3.3V pin, for the same reasons as describe for the standard board, with a small difference: there is no fuse that can prevent disaster, not even for a limited time...

    Now, connected to and run from your power supply, you add an onInit() as described below, then you upload the code, type save() into the console, and you are all set:

    Disconnecting USB, pulling the power supply from the wall socket (or what ever allows you to shut it off), and then repowering with the power supply will start run your code... ;)

    var intervalTimer = null;
    function onInit() {
      intervallTimer = setInterval(sensor.trigger,250);
    }
    

    Having added the variable to hold on to the intervalTimer returned by setInterval() allows you to stop the triggering by software:

    clearInterval(intervalTimer);
    

    and to restart it calling

    onInit();
    

    Since you are an old hand, you will say that you do not like to call onInit() for restarting the triggering at all, because in your final (SW) setup you will have other things in the onInit() which should be called only exactly once... Said so, you create two functions, start() and stop() - start setting the intervall, and stop clearing the interval - and invoke start() in the onInit(). To be on the defensive side your stop looks then like this:

    function stop() {
      if (intervalTimer) {
        clearInteval(intervalTimer);
        intervalTimer = null;
      }
    }
    

    If this is a waste of breath on you because you are already beond that, just ignore the code litany.... ;-)

  • @allObjects This is all very useful stuff, thanks for the detail. I am using the standard board, I am feeling my way through the world of electronics and loving how easy it is to get results (using espruino), I now have the led strip reacting to distance from the sensor.

    I will make sure to keep well clear of the batt connector until I am ready to go stand alone with my contraption.

    var distance = 0;
    var running;
    var sensor = require("HC-SR04").connect(A2,A3,functio­n(dist) {
      distance = dist;
    });
    
    SPI2.setup({baud:3200000, mosi:B15});
    
    function runIt(){
      sensor.trigger();
      console.log("response "+Math.floor(distance)+" cm away");
      if (distance < 10){
        SPI2.send4bit([255,255,255], 0b0001, 0b0011); // white
      }else if(distance <= 20){
        SPI2.send4bit([255,0,0], 0b0001, 0b0011); // red
      }else if(distance <= 30){
        SPI2.send4bit([0,255,0], 0b0001, 0b0011); // green
      }else if(distance <= 40){
        SPI2.send4bit([0,0,255], 0b0001, 0b0011); // blue
      }else{
        SPI2.send4bit([0,0,0], 0b0001, 0b0011); // black
      }
    }
    
    function stopIt(){
      console.log("button pressed");
      clearInterval(running);
    }
    
    running = setInterval(runIt, 100);
    
    setWatch(stopIt, BTN1, {repeat:true, edge:"rising"});
    
  • That was quick... did not want to pull the button for stop into play yet... But may be now is the time: since you have the standard board, you may take a look at the Software Buttons - Many buttons from just one hardware button. This gives you multiple functions by just one button (BTN1), by different sequences of short an long presses, just as Morse managed to convey text over a single wire in a human (easy) to create and interprete async communication. A asynch protocol that is not as time/baoud sensitive as the async serial communication... I used the software buttons to control running lights - ok, just the three leds on the board - my first 'project' a while ago...

    To keep you clear from the battery connector was not at all my intention... because if you stay clear until done and connect the LEDs to VBat of Espruino, you have to reduce the intensity for the LEDs, because they will pull your USB into the ground (use values lower than 255)... 10 RGB LEDs bright white pull 600mA... already beyond 500mA what a Computer Stanard USB can deliver... (MacBook Pro complains about pulling to much from the USB, shuts the USB down... but unfortunately looses with that also the keyboard until you restart your machine - other computers may do similar things if 'friendly').

    To be safe power your LEDs directly from your power supply (if they can handle the 5V)... either way - connected to battery connector or not. But again: have all GNDs tied together. Since you already have it for the sensor, you are just fine.

    Could you publish a short clip? ...a pic is more than 1000 words, and a clip is a multi-volume lexicon... (with that you notice I'm old fashioned... so more in the presence: ...a clip is a google result... ;)).

  • @allObjects I have my RGB strip powered off of 5VDC regulated which can supply up to 3amps which is plenty for this initial prototype (24 LED strip).

    That multiple button script will definitely come in handy. My next bit of research is going to be into getting a DMX protocol working so that I can power four emitters in a DMX chain. Does not look like there is too much out there in javascript (I saw something using node).

    I have a video which is being uploaded to youtube I will post it here when it has finished processing.

  • Excuse my shaky hands, first thing on a monday morning

    https://www.youtube.com/watch?v=INoPvwaM­0nk

  • I've no experience with DMX... I followed only some converation which made me conclude that non regular a/sync protocols need some special attention. I'm sure you already came across thesee posts. @alexanderbrevig is very active in the audio area, and I'm sure he has some thought's about getting such things mastered...

    Regarding the distance sensor for light control: are youo thinking of having touch less controls instead of the classical slider things? Nice Idea... the challenge is how can you keep a value 'set', because moving away just changes the setting again... May be you are not looking for that, but: A way to control/mix in multi-dimensional manner various lights dynamically, similar to sound mixing with Turntablism?

  • @allObjects the aim is for an on-street interactive lighting installation for our local council, so the sensors would be strategically placed to pick up people moving through the installation and affecting the lighting around them (the lights will go back to a default routine when no one is within range). We needed some pretty powerful emitters to put through fibre optic cables and the ones available need to be controlled via DMX, otherwise the prototype I have would almost be sufficient as is.

  • Yes, that shield would be fine, it's basically just a level converter to DMX levels - you just have to connect up RX and TX wires (and power/ground obviously). So are you planning on transmitting DMX rather than receiving it? If so I think it should be relatively easy to do with Espruino.

  • ...from managed inside space of managed buildings to managed outside space of managed communities.

  • @Gordon yes this is to send DMX signals, no need to receive. I was looking into the protocol, it seems to need a serial outpit and a set of data not dissimilar to what is sent to the RGB-LED's I have been playing with.

    I am not sure what could be used on the espruino to create a serial connection, plus the need for a three pin connector I figured a shield may be the way to go.

  • You can use any pin marked USARTx_TX, so you should be ok. I think DMX uses 12v voltage levels, so you need the level converter anyway (which will be on that shield).

    To send DMX, all you should need is:

    // if using USART1
    Serial1.setup(250000, { tx: DMXpin });
    var DMXdata = new Uint8Array(512);
    setInterval(function() {
      pinMode(DMXpin, "output");
      digitalPulse(DMXpin, 0, 0.1); // send 'break'
      pinMode(DMXpin, "af_output");
      Serial1.write(DMXdata);
    }, 50);
    

    I think you could increase the refresh rate if you needed, and you could make life easier for yourself by not sending all 512 bytes.

    I haven't tried that though, so I'm not 100% sure if it'd work.

  • Thanks @Gordon I will order that shield now and update when I have progress

  • Using 3 sensors, one for red, one for green, one for blue. Measuring up to 25 cm (full scale will be 2.55 meters) otherwise set levels to 0

    var distanceR = 0;
    var distanceG = 0;
    var distanceB = 0;
    
    var running;
    
    var sensorR = require("HC-SR04").connect(A0,A1,functio­n(dist) {
      distanceR = dist;
    });
    var sensorG = require("HC-SR04").connect(A2,A3,functio­n(dist) {
      distanceG = dist;
    });
    var sensorB = require("HC-SR04").connect(A4,A5,functio­n(dist) {
      distanceB = dist;
    });
    
    SPI2.setup({baud:3200000, mosi:B15});
    
    function runIt(){
      sensorR.trigger();
      sensorG.trigger();
      sensorB.trigger();
      console.log("RGB("+Math.floor(distanceR)­+","+Math.floor(distanceG)+","+Math.floo­r(distanceB)+")");
      
      if(distanceR > 25){distanceR = 0;} else {distanceR = distanceR*10;}
      if(distanceG > 25){distanceG = 0;} else {distanceG = distanceG*10;}
      if(distanceB > 25){distanceB = 0;} else {distanceB = distanceB*10;}
        SPI2.send4bit([distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB], 0b0001, 0b0011); // white
    
    }
    
    function stopIt(){
      console.log("button pressed");
      clearInterval(running);
    }
    
    running = setInterval(runIt, 100);
    
    setWatch(stopIt, BTN1, {repeat:true, edge:"rising"});
    
  • Nice! First time I've seen more than one of those sensors used :)

    Not sure, but it's possible you'll end up with one sensor receiving the signal from the other - if you get problems you might have to do something like:

    var c=0;
    setInterval(function() {
      if (c==0) sensorR.trigger();
      if (c==1) sensorG.trigger();
      if (c==2) {
        sensorB.trigger();
        sendToLeds();
        c=0;
      } else c++;
    }, 50);
    
  • @Gordon I have had that issue, that is a nice solution to it, though the crossover does produce a pretty lighting effect :)

    I think having each sensor with a 1 meter gap between should help with the issue also, for the end result three people moving through the installation should be able to produce any color / shade on the RGB scale, can't wait to go full scale.

  • Let each trigger run on a different interval... and also let the interval change... in other words, do not run interval, but timeout that starts a next timeout with either a 'wave' or random or even changing time patterns... that will provide even more (halloween) effects...

  • working with a greater distance, firing sensors individually, more stable output:

    var distanceR = 0;
    var distanceG = 0;
    var distanceB = 0;
    var running;
    var c=0;
    var sensorR = require("HC-SR04").connect(A0,A1,functio­n(dist) {
      if (dist < 300 && dist > 0) distanceR = dist;
    });
    var sensorG = require("HC-SR04").connect(A2,A3,functio­n(dist) {
      if (dist < 300 && dist > 0) distanceG = dist;
    });
    var sensorB = require("HC-SR04").connect(A4,A5,functio­n(dist) {
      if (dist < 300 && dist > 0) distanceB = dist;
    });
    SPI2.setup({baud:3200000, mosi:B15});
    function runIt(){
      if (c===0) sensorR.trigger();
      if (c===1) sensorG.trigger();
      if (c===2) {
        sensorB.trigger();
        sendToLeds();
        c=0;
      } else c++;
    }
    
    function sendToLeds(){
        
      //console.log("before("+Math.floor(dista­nceR)+","+Math.floor(distanceG)+","+Math­.floor(distanceB)+")");
      
      if(distanceR > 100 || distanceR === 0){distanceR = 0;} else {distanceR = 255-(distanceR/4)*10;}
      if(distanceG > 100 || distanceG === 0){distanceG = 0;} else {distanceG = 255-(distanceG/4)*10;}
      if(distanceB > 100 || distanceB === 0){distanceB = 0;} else {distanceB = 255-(distanceB/4)*10;}
      
    if(Math.floor(distanceR) > 0 || Math.floor(distanceG) > 0 || Math.floor(distanceB) > 0) console.log("RGB("+Math.floor(distanceR)­+","+Math.floor(distanceG)+","+Math.floo­r(distanceB)+")");
      SPI2.send4bit([distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB,distanceR,distanceG,dista­nceB,distanceR,distanceG,distanceB,dista­nceR,distanceG,distanceB,distanceR,dista­nceG,distanceB], 0b0001, 0b0011); // white
    }
    
    function stopIt(){
      console.log("button pressed");
      clearInterval(running);
    }
    
    running = setInterval(runIt, 100);
    
    setWatch(stopIt, BTN1, {repeat:true, edge:"rising"});
    
    
  • @Gordon @allObjects I was hoping to borrow some more of your knowledge.

    I have finally received my DMX shield, it got caught in customs it seems.

    I may need a push in the right direction on how to wire it up to my project. I have decided to use a pico instead now because of size in the enclosure I have (assuming it is up to the job).

    As far as I can see I should be able to use mostly the same pins on the pico as the full size espruino:

    For HC-SR04 Ultrasonic Sensor x3

    Espr --- Pico
    A0 ---> A0 (trig)
    A1 ---> A1 (echo)
    A2 ---> A2 (trig)
    A3 ---> A3 (echo)
    A4 ---> A4 (trig)
    A5 ---> A5 (echo)

    Now I need to replace the Serial port which I was using for the RGB strip with USART_RX & USART_TX:

    PICO
    B6 --- Transmit
    B7 --- Receive

    These need to be hooked up to the DMX shield, I assume like so:

    PICO --- DMX

    B6 --- RX 0
    B7 --- TX 1
    (assuming RX on PICO goes to TX on the shield and vice versa, or do I have that backwards)

    I then need to work out how to send the data as Uint8Array(512) instead of send4bit, I am not sure on this part.

    And then finally, there is the power. I have a 5v 3a power supply, I assume that this should be able to power the pico and the shield together (though I am unsure of the current pulled by the DMX shield). The shield has a 5v pin, so that should be easy, however I am not certain I can put 5v straight to the pico without blowing things up, am I save to plug 5v into the pico 3.3 pin or do I need to step it down first?

    Finally I can connect all of the grounds together and cross my fingers she works.

    Can one of you guys confirm I am on the right track, I appreciate your time.

    Summary:

    • Will A0 to A5 on pico work the same as A0 to A5 on Espruino?
    • Will RX on pico goes to TX on the shield, or does RX on pico go to RX on shield
    • How do I send Uint8Array(512) RGB data to a specific DMX channel
    • Can I safely put 5v 3a direct to pico?

    Reference:

    DMX Shield: https://www.tindie.com/products/Concepti­netics/dmx-shield-for-arduino-remote-dev­ice-management-capable/ - I cant seem to find any diagrams docs on the shiend
    PICO: http://www.espruino.com/Pico
    ESPRUINO: http://www.espruino.com/EspruinoBoard


    1 Attachment

    • project dmx.jpg
  • Will A0 to A5 on pico work the same as A0 to A5 on Espruino?

    Ya. The STM32 series is lovely like that - they keep a pretty standard pinout for each package, and they put the peripherals in the same places - like SPI2 is always on B13-B15, etc. In contrast, Atmel (the one who makes the uC's used in arduinos) chooses pin and peripheral assignments with a monkey and a dart board.

    Will RX on pico goes to TX on the shield, or does RX on pico go to RX on shield

    Depends which way around it's labeled. Things that are Arduino shields are often labeled with respect to the arduino pin function, not the shield pin function. Check the Uno pinout, and connect RX to the pin that would go to the RX pin on the Uno.

    Can I safely put 5v 3a direct to pico?

    Put the 5v power into BAT_IN (or VBat...), that will be regulated down to 3.3v to run the pico. Do not connect 5v to the pin labeled 3.3v.

  • Thank you @DrAzzy!

    I will Use the same pins on pico
    I will try RX to RX first
    I will use BAT_IN for pico power

    That just leaves:

    How do I send Uint8Array(512) RGB data to a specific DMX channel

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

Distance - Color RGBLED + Distance sensor HC-SR04 (having strange results)

Posted by Avatar for Rek @Rek

Actions