read() method of Pin class resets the pin's state? #438
Replies: 15 comments
-
Posted at 2014-03-01 by @gfwilliams Hi Maik, yes that is expected. Not like Arduino but I think it is more obvious for beginners. It you want to 'lock' the pin mode, use pinMode and then read/set/reset/write won't change the pin state |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-05 by Rollo Oh dear I find it so confusing :) Reading a pin is not a read-only operation. So I check if LED1 is on and it returns 1 meaning yes. Except it's not any more, LED1 is off now. Reading pinMode documentation with its eight possible values is a bit rough. Do I have to know pullup, opendrain and the difference between "output" and "af_output" just to play around with LED1 like in op example? I really admire Espruino's API and find it superior to other things I've tried, but this one seems like NaN in JS - weird. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-05 by DrAzzy Yeah, this is pretty bizzare. Does digitalRead() do that too? (I can't remember if I've run into this - but I almost always do pinmode) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-05 by Rollo @drazzy yes it does the same thing. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-05 by @gfwilliams
Yes, it does - pretty much all the IO functions do it.
Sure, it's that in Arduino, you have to know what to do with If you say For instance you'd write As I'm trying to be easy to use for beginners, if nobody specifies
Yes, thanks for letting me know - I've put that on my to-do list and I'll try and improve it. I'll make sure
Yes and no. If you want to set LED1, you use The reason is that digitalRead is probably not doing what you expect. The actual GPIO is like in the circuit below. It's a bit overcomplicated, but basically the input value doesn't come from the same register as the output value - it's actually reading the voltage on the output pin. So if you have a capacitor (for instance) connected to the pin, and you do:
You'd expect that it would just print a bunch of 1s - But it almost certainly won't. It'll actually print 0 until the capacitor charges up, and then 1. Now maybe that's not a huge issue, but what if you were trying to pulse-width modulate the capacitor's voltage to 3.3v/2 by simply toggling the output high and low the way you'd think would work fine:
and now it's going to do something really different from what you expect. Instead of a nice quick square wave it's actually going to wait until the capacitor has charged before discharging, and vice versa It would be totally possible to add a Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-05 by Rollo Thank you @gordon for such detailed explanation. I have used the LED example but in fact my use case is a bit different. So I have a bunch of things toggling a relay from a number of places in the code. Then there is other things logic depending on relay's state, so I want to check if it's on or off. Now I could simply use a variable just like you suggested but it adds this overhead of keeping it in sync with a real state - as I said in multiple places of the code. I just feel more confident when operating directly on a given pin with Pin.write and - I wish - Pin.read. I hope you will change your mind and see some value in adding something like readOutputValue :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by @gfwilliams In that case I'd really consider adding functions like While it does add some overhead, it could well be worth it for flexibility/readability (for instance what happens if you change to use a relay module that turns on when 0v is applied). To be honest your relay case is probably a pretty good example of why a What does everyone else think about |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by Rollo You are right. I will have to delegate it to some utility classes. This project is mostly in my head at this time so you probably saved me some trouble later on. I also realized that using pinMode is a good idea, wasn't even aware of it. Am I right thinking that onInit is a good place for pin mode configuration? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by DrAzzy That's where I always put my pinMode() calls. I'd very much like a pin.mode() - Gordon indicated a willingness to implement this... I oppose pin.readOutputValue(). Set the pin mode properly in the first place and use pin.read(), or remember what you've set the pin to. Unless we're interested in cases where the output value is not the same as the logical value on the pin because you're trying to draw so much current that the chip can't drive it hard enough. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by Rollo
I suppose it all comes down to documentation so I'll make a PR and we're good ;) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by Rollo Ehh say what you want but for me (that is a beginner with no understanding of Figure 16) this whole thing is getting hairy. After reading example codes I assumed that Yes you said charging capacitors and square waves, but I say toggling is more likely a beginner's thing. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by DrAzzy
What?! pin.write(!pin.read()); should absolutely toggle the pin, unless you did pinMode(pin,'input') or something which would prevent it from writing the pin... That's wacky if it's not... The only way I can see that not working is if the relay draws so much current that even when the chip is trying to drive the pin high, the voltage isn't high enough to be a logical 1. Relays often draw more current that a microcontroller is designed to supply; if such a relay was connected directly, the 'high' output voltage (if it's active high) wouldn't be able to get up to 3.3v; the pico can only supply 20mA max, and I think at 20mA, it's significantly below Vcc - and if it was drooping low enough, it would be seen by pin.read() as a 0, not a 1. What's the voltage on the pin when you drive it high with the relay module connected? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by Rollo @drazzy I will try to get hold of a multimeter tomorrow and answer your question. For now I can only say that it's a one channel Arduino relay module connected with Espruino Board with shared GND, IN to C9 and VCC to VBat. I should also clarify that it fails when no explicit pin mode specified by me, but works when I set pin mode to "output" beforehand. And don't get me wrong guys, I'm not claiming that there is no good explanation for this behaviour. All I'm saying is that it has nothing to do with beginners friendliness :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-06 by DrAzzy Oh, if it works with pinMode() set to output, but not with pinMode() not set, it's not what I thought it was. I think I see what's happening.... I'll bet it sets it to input to read it, but because there's a load on the pin, the voltage is dropping as soon as it's no longer an output - so fast that by the time it reads it, it's no longer high anymore... Yeah, this behavior is kinda ugly. I always explicitly set pinMode() so I don't run into this sort of behavior. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-08-07 by @gfwilliams When I said about For one of those relay modules with the drive electronics, something like:
Will probably work fine. I still wouldn't recommend it though :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2014-03-01 by user6579
I did some experiments with setting and reading LEDs using firmware 1v52:
The set() method lights up LED1 and the read() returns the right state. In addition, read() switches off the LED, so the next call returns false. Is this expected behaviour?
Best,
Maik
Beta Was this translation helpful? Give feedback.
All reactions