"read" LED state

Posted on
  • While I can maintain the state of the LED in the JS impl - I would like to be able to just read the register for the digital pin connected to an LED

    Arduino seems to support reading from and OUT pin

    But this does not work the same/expected way in Espruino:

    pinMode(5, 'output')

    I can sort of get what I want by using pin auto mode and making sure that every read writes back itself like this:

    var x;
    x = digitalRead(5); digitalWrite(5,x)

    But I was thinking there should be a way I should just be able to read the state?

    I'm guessing I could use peek* functions to get at the register directly? But that seems very un-espruino like from a dev-ux POV

    Any ideas on the right solution here?

  • Espruino has a nice feature on pins: it has a configuration - called auto - where it configures itself as input or output depending on the read or write operation...

    This nice feature plays now dirty tricks on you.... ;)

    When you define the pin as output, you will be able to read from the pin and you get the output register, because the driver of pin stays on (not three-state) and drives the input driver. ...and you get what you are looking for: status of the pin / LED... to be more precise: the output register... (if you short cut your pin, I bet you get the either rail... close to 0 or 3.3, I expect... I did not tell you to try... that's why I just guess. (Tried to find details about the inner circuitry to confirm, but could not find it).

    Give it a try...

    EDIT: just validated (on Espruino Wifi, expect Puck not to be different, but I may be mistaken... :( ...) ...in the console (on Espruino-Wifi, LED / LED1 - red LED - is on B2, therefore, B2 and LED and LED1 are interchangeable...):

    >getPinMode(LED1); // asking pin mode on LED / LED1 / B2 pin
    >pinMode(B2,"output"); // setting pin mode on LED / LED1 /B2 pin to plain ouput
    >getPinMode(LED1); //  asking again, and it shows set mode
    >digitalRead(LED1); // reading, 0 expected, because of wiring and LED is off
    >LED1.set(); // turning LED / LED1 / B2 pin on
    >digitalRead(LED1);  // reading, 1 expected, because of wiring and LED is on

    As noticed, pin mode (of B2, LED, LED1 on Espruino) is by default "analog" mode (Espuio-Wifi after reset / power-on / connect with 'factory' setup - no saved code of mine running on start up).

    Analog mode may have another twist: since it can be PWM and not really analog, reading may be fickle... If you for straight, plain "output", it just works...

    Without setting the pin mode, but turning the LED on, what happens when you read? ...I expect the LED turns of... (so is behavior of Espruino-Wifi):

    >pinMode(B2,"auto"); // set outo
    >getPinMode(B2); // returns what it was from before... 
    >B2.set(); // turns LED on
    >digitalRead(B2); // switches to input, but on 1st read I get 1 because it reads so fast and 'sensitively' that the voltage has not yet collapsed... very interesting - BUT LED EVENTUALLY TURNS OFF
    >digitalRead(B2); // 2nd time I get 0... as expected... because all the electrons have left the scene / left the building...

    (...my little Christmas present to you - Merry Christmas!)

  • It seems that nrf52 gpio input registers can't be read if gpio is set as output. Anyway, for a LED, which does have the exact logic level you previously imposed to it ( which may not be the case if output is open drain and used for communication such as I2C) , you should be able to get the current status of the LED by using the peek() method on the OUTPUT register, because digitalRead() won't work as it may poll INPUT register only.

  • @Jean-Philippe_Rey and @ptone, so I'm mistaken... I kind of knew that it could be different... should have tried it on Puck as well... :(((> --- good to know, that may change some application code to become used on either devices.

  • Thank you both - I tried to look at the nrf52 datasheet which has register tables, and the scant examples of the peek API - but I wasn't able to get them put together. How does one sort out what peek address to use for a given output pin?

    And FWIW - my approach of using auto [x = digitalRead(5); digitalWrite(5,x)]seems to "work" without any visible blink in the LED - not sure what is actually happening at the microsecond or less level. Wonder if espruino is somehow doing both in essentially one step?

  • Espruino won't be doing it in 2 steps, but chances are it's fast enough that you won't notice the LED going out for a fraction of a second and then going back on - however doing read then write isn't guaranteed to give you the results you want (if you do it on an IO pin that's shorted to ground you'll always get 0 returned).

    Honestly, I would do it in software. However if you're just wanting to play around with hardware, you're after the OUT register under GPIO in http://infocenter.nordicsemi.com/pdf/nRF­52832_PS_v1.0.pdf

    That's at address 0x50000504, so you just do peek32(0x50000504) and you'll get a number representing the output state of all pins.

    On Puck.js it looks like you're using pin D5 - so it's the 5th bit (counting from 0), so to get the value you want something like (peek32(0x50000504)>>5)&1.

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

"read" LED state

Posted by Avatar for ptone @ptone