• Nudging conversation about LED1 not working in Bangle.js emulator - and the fact that every IoT device must be able to blink to have its 'Hello World!' as first example - made me create this conversation.

    In deed, Bangle.js has no LED , or LED1. On the Espruino boards with LEDs, LEDs reference just particular pins of which each is connected to an on-board LED that turns on / off when pin is set or reset or written to - digitally (or analog or pwm if pin can do analog / pwm). For example: LED1.set(); , LED1.reset(); , LED1.write(true) , digitalWrite(LED1,1) , digitalWrite(B2,1) , B2.set(); - B2 is pin connected to red LED1 on Esrpruino PICO.

    BUT: Bangle.js has a graphic display... accessible as g with the function set of Espruino's Graphics object that can do way more than just turn on and off an LED of a fixed color. If you want to make the examples work that use LEDs, for example, for blinking, you can code a Software LED, or actually as many as you want, in the color you want, and the size you want... and the LED can even change the color as you go.

    For how you get what you see in still and video clip as attached - blinking small red, large green and yellow triangle LED, see next post - post #2.

    For other hints working with bangle.js and especially bangle.js emulator, see Some hints when starting with the Web IDE Emulator for Bangle.js.


    2 Attachments

  • Below is the (minimal) code to define an LED that just lets you use LED (or LED1 ) as is - which is a red round LED with size of 10 pixels in diameter in the left top corner of the display:

    let LED = // LED as minimal and only definition (as instance / singleton)
    { isOn: false // status on / off, not needed if you don't need to ask for it
    , set: function(v) { // turn on w/ no arg or truey, else off
       g.setColor((this.isOn=(v===undefined||!!­v))?1:0,0,0).fillCircle(4,4,5); }
    , reset: function() { this.set(false); } // turn off
    , write: function(v) { this.set(v); }  // turn on w/ no arg or truey, else off
    , toggle: function() { this.set( ! this.isOn); } // toggle the LED
    }, LED1 = LED; // LED1 as 'synonym' for LED 
    

    This snipped shows the classical blink:

    var ledIsOn = false;
    setInterval(()=>{ if ((ledIsOn=!ledIsOn)) LED.reset(); else LED.set();},500); 
    

    Since the LED1 is smart and knows to toggle, for blink you get a way with this:

    setInterval(()=>LED.toggle(),500);
    

    Another option is to use LED's status yourself:

    setInterval(()=>LED.set( ! LED.isOn),500);
    

    If you need the LED to show some where else on Bangle.js' screen, just change the coordinates in line 4. Same goes for color and shape. Just lookup (Bangle.js') Graphics reference or Espruino's Graphics reference ( Note the difference: Because Bangle.js has a particular display with its own driver setup, .setColor(..) is unique ). For example you want to have a yellow triangle shaped LED blinking next to BTN3, use below lines for line 4 in definition.

       var c=(this.isOn=(v===undefined||!!v))?[1,1,­0]:[0,0,0];
       g.setColor(c[0],c[1],c[2]).fillPoly([229­,196,238,204,220,204],1); }
    

    If you have to set the LED's status based on a variable, for example, whether the button BTN1 is pressed or not, you can use this condition digitalRead(BTN1) in the classical blink code. Checking the button only twice a second - every 500 milliseconds (ms) - is not not that suitable anymore. Increasing the frequency - lowering the timeout to 20ms - would make the LED more responsive but starts to eat away compute cycles and with that power. To avoid that, Espruino provides the global function setWatch(...). As the name says, it can watch something and act on changes of the watched thing, such as the event of a buttons press status change:

    setWatch((e)=>LED.set(e.state), BTN1, { repeat:true, edge:"both" });
    

    In other words: every time BTN1 changes its press status, LED reflects that (edge property in the watch options object can be omitted since true is default ).
    or as a constructor to create just any LED anywhere on the display of any color and any size.

    One single LED with a fixed color, shape and size is a bit limited. Therefore you like to go with the definition of LEDs as a class / template / prototype - as used in object-oriented programming terms - with which you can define as many LEDs as you like.

    // --- LED as constructor to create any number, colored, sized LEDs
    let LED = function(x,y,s,c,f) { // constructor
      this.isOn = false;  // LED on / off
      this.x = x || 0; // left of LED bounding box
      this.y = y || 0; // top of LED bounding box
      this.s = s || 10; // size (diameter) };
      this.c = c || [1,0,0]; //  color as RGB array with values 0..1
      this.f = f || function(_) {
          g.fillCircle(_.x+_.s/2,_.y+_.s/2,_.s/2);­ }; }; // fill shape
    LED.prototype.set = function(v) { // set method
      v = ((this.isOn = (v === undefined || !!v))
          ?g.setColor(this.c[0],this.c[1],this.c[2­]):g.setColor(0,0,0));
      this.f(this); }; // execute the function that fills the (default) shape
    LED.prototype.reset = function() { this.set(false); }; // reset method
    LED.prototype.write = function(v) { this.set(v); }; // like set method
    LED.prototype.toggle = function() { this.set( ! this.isOn); };
    

    If you want to use both definition methods simultaneously in your application, then you have to add this code for LED as singleton:

    // --- LED definition as instance / singleton (alternative or in combo)
    // var LED ={}: // uncomment this if you use this def without class above
    LED.isOn = false; // status on / off, not needed if you don't need to ask for it
    LED.set = function(v) { // turn on w/ no arg or truey, else off
       g.setColor((this.isOn=(v===undefined||!!­v))?1:0,0,0).fillCircle(4,4,5); };
    LED.reset = function() { this.set(false); }; // turn off
    LED.write = function(v) { this.set(v); }; // like set method
    LED.toggle = function() { this.set( ! this.isOn); }; // toggle the LED
    LED1 = LED; // LED1 as 'synonym' for LED 
    

    ** Use of LED in both ways:** (includes both definitions for easy, single copy / paste into Espruino Web (Bangle emulator) IDE code pane -on the right):

    // LEDs in Bangle.js context - by allObjects:
    
    // --- LED as constructor to create any number, colored, sized LEDs
    let LED = function(x,y,s,c,f) { // constructor
      this.isOn = false;  // LED on / off
      this.x = x || 0; // left of LED bounding box
      this.y = y || 0; // top of LED bounding box
      this.s = s || 10; // size (diameter) };
      this.c = c || [1,0,0]; //  color as RGB array with values 0..1
      this.f = f || function(_) {
          g.fillCircle(_.x+_.s/2,_.y+_.s/2,_.s/2);­ }; }; // fill shape
    LED.prototype.set = function(v) { // set method
      v = ((this.isOn = (v === undefined || !!v))
          ?g.setColor(this.c[0],this.c[1],this.c[2­]):g.setColor(0,0,0));
      this.f(this); }; // execute the function that fills the (default) shape
    LED.prototype.reset = function() { this.set(false); }; // reset method
    LED.prototype.write = function(v) { this.set(v); }; // like set method
    LED.prototype.toggle = function() { this.set( ! this.isOn); };
    
    // --- LED definition as instance / singleton (alternative or in combo)
    // var LED ={}: // uncomment this if you use this def without class above
    LED.isOn = false; // status on / off, not needed if you don't need to ask for it
    LED.set = function(v) { // turn on w/ no arg or truey, else off
       g.setColor((this.isOn=(v===undefined||!!­v))?1:0,0,0).fillCircle(4,4,5); };
    LED.reset = function() { this.set(false); }; // turn off
    LED.write = function(v) { this.set(v); }; // like set
    LED.toggle = function() { this.set( ! this.isOn); }; // toggle the LED
    LED1 = LED; // LED1 as 'synonym' for LED 
    
    // Use of both LED definitions / both ways
    var redOn        // status of red round LED
         , redIId    // interval id for red LED
         , greenLED  // green large LED
         , greenIId  // interval id for green LED
         , triangle  // fill triangle function
         , yellowLED // yellow triangle LED
         , yellowIId // interval id for yellow LED
         ;
    function onInit() {
      redOn = false;
      redIId = setInterval(function(){ // use of LED as is and
          LED.set(redOn=!redOn);       // toggle every 333 milliseconds
        }, 333);                       // (flash 3 times in 2 secs)
      greenLED = new LED(15,0,30,[0,1,0]); // Use LED as contructor
      greenIId = setInterval(function(){   // to create a green LED and
          greenLED.set(!greenLED.isOn);       // at 15//0 of size 30 and
        },500);                            // flash once a second
      triangle = function(_) { // fill triangle in x,y,x+s,y+s bounding box
        g.fillPoly([_.x+_.s/2,_.y,_.x+_.s,_.y+_.­s,_.x,_.y+_.s],1); };
      yellowLED = new LED(221,190,19,[1,1,0],triangle); // next BTN3
      yellowIId = setInterval(() => yellowLED.toggle(),1000);
    }
    
    setTimeout(onInit,999); // while dev'ing; remove before upload for save()
    

    An example of a big, fat, color changing LED code you find in the 'nudging' conversation post #7 - screen shot a clip attached here as well.


    2 Attachments

  • Hey, what about a leds widget ?

  • Realistically probably doing what @JumJum has done and adding a LED object with write/etc commands to the firmware would be a good bet.

    ... however I have just changed the emulator to give a more interesting bit of start code when using Bangle.js :)

  • Can digitalWrite/Read/analogRead/Write accept a JS object? Then complete emulation can be done.

  • They can :) Although not analogRead/Write

  • Thanks! I have just added a slightly tweaked version of this to Bangle.js so when the emulator is updated, examples using LED/LED1/LED2 should now work

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

Bangle.js (and emulator), where did you leave my LED, LED1, LEDX?

Posted by Avatar for allObjects @allObjects

Actions