-
• #2
Added your code... into context.
SPI1.setup({ sck:B3, mosi:B5 }); var VPIN = A5; // divider resistor 1 in ohms var divr1 = 10000; var divr2 = 1000; function onInit() { var g = require("PCD8544").connect(SPI1,B6,B7,B10, function() { function updateVolts() { var aread = 0; var numReads = 5; for(var i = 0; i < numReads; i++) { aread += analogRead(VPIN); } aread /= numReads; var pinvolts = 3.3 * aread; var powervolts = (pinvolts / divr2) * (divr1 + divr2); g.clear(); g.setContrast(0.45); g.setFontVector(12); g.drawString("ADC: " + aread,0,0); g.drawString("Volts: "+ powervolts,0,16); g.flip(); } updateVolts(); setInterval(updateVolts, 500); }); // handle backlight (function() { var backlight = B1; var backlightSleep = false; setWatch(function(e) { // clear any old timeouts so that if we have a misspress the screen will // stay on during the subsequent presses if (backlightSleep) { clearTimeout(backlightSleep); backlightSleep = false; } // if button down if (e.state) { // turn backlight on digitalWrite(backlight, true); } else { // turn backlight back off after a few seconds backlightSleep = setTimeout(function() { digitalWrite(backlight, false); backlightSleep = false; }, 2000); } }, BTN, { repeat: true }); })(); } //onInit(); save();
-
• #3
I do not know exactly what is going wrong here, but I never placed save() into the uploaded code...
I also wonder why you put all code into the onInit(), because this defeats the purpose and benefit of save() to some extent.
The good part though is that the timers (and the watches) ar in the onInit(): You want them in there because all things have start up after a reset or re-power.
Reshuffle the code so that the onInit includes only the minimum, and everything else is already there. For example:
...delayed.
-
• #4
Hey +allObjects thanks for the reply.
I had
save()
in there like that so I could just plug the board in to the laptop, upload the latest change and disconnect immediately (i.e not having to manually typesave()
before switching over to in situ mode).Dropping the
save()
and typing that manually does seem to have brought everything back to working (i.e I can reupload that code and board detects the right voltage with the divider in place again).So that at least means I haven't totally nuked the board, thanks :)
I'm still a little concerned about why it worked previously with a
save()
during the upload and why it still works with the other two boards I have - it suggests something funky has gone awry at the hardware layer.P.s Your example code seems to have gone missing.
-
• #5
...yeah, 'got stuck' on the backlight. I like your approach to avoid globals, and the technique of (function(){})(); works nice for that... just a bit too much anonymity and loss of control.
-
• #6
Backlight management is quite a nifty thing depending on the requirements. I assume, you require:
- light goes on on button down.
- the timeout for light to go off starts on button up.
- existing timout is cleared on button down.
In other words, light is on when button is down and stays on for another 2 seconds after button has gone up.
- light goes on on button down.
-
• #7
The backlight stuff was just tinkering about trying to make it "feel" right - i.e you hit the button and it comes on, stays on for a while after but if you hit it a few times it stays on until a while after the last press (hence
var
ing the timeout).The
(function(){...})();
is just a closure, common in the web world (the background I come from, I'm new to electronics).This wasn't by any means final code I was just worried I'd broken the board by putting 2.9V in to A5 - FWIW after getting the code to run on the board again, it still freaks out (crashes and I have to reload an empty environment) when I put 2.9V to A5 from the Lab PSU, so there's definitely something bad going on.
For now I've added another 10K resistor on the
divr1
side (makingdivr1
ESR of 20K)... it seems to function fine with this, so there's definitely something about ~2.9V on that pin that's breaking things. -
• #8
More modern JS world likes the closures... and it is a neat thing, though not really new: Smalltalk had it already in the 70'... and Java tried to make it to really be forgotten... Anyway, took this light timing thing for some brain training... and that is what I came up with: not just one but two versions.
The first version is more familiar to me. In a nutshell: it does not use the e(vent) and starts the timer immediately, and therefore, it can be started multiple times to just to be killed without timing out. Worst case could be that the light may not go on because there is some time between the event capture that triggers the function call and the checking of the button state by reading the button again... which may (theoretically) be different. There is though no harm, beause the code is 'self healing'.
var backlight = LED; var backlightTimeout; pinMode(backlight,"output"); var backlightOn = function(e) { if (backlightTimeout) { clearTimeout(backlightTimeout); } backlight.set(); console.log("Time : " + getTime()); backlightTimeout = setTimeout(function(){ backlightTimeout = undefined; if (digitalRead(BTN)) { backlightOn(); } else { backlight.reset(); console.log("Timeout: " + getTime()); } },2000); }; setWatch(backlightOn, BTN, { repeat: true, debouce:50 });
And version 1 related console output:
Time...: 9395.98322296142```
Timeout: 9398.59645748138```
The second version is inspired by you using the e(vent), which creates only timeout when needed and is really taking the value - e(vent).state (Button press/signal change from -state to state) exactly when it happend. What I did not know until now, that there is always an event, but the timeout does not have a state information! This is trigger for further study of the e(vent) objecgt...
var backlight = LED; var backlightTimeout; pinMode(backlight,"output"); backlight.reset(); var backlightSwitch = function(e) { if (backlightTimeout) { clearTimeout(backlightTimeout); backlightTimeout = undefined; if (e.state === undefined) { // was timeout backlight.reset(); console.log("Timeout: " + getTime()); } } else { if (e.state) { backlight.set(); } else { backlightTimeout = setTimeout(backlightSwitch,2000); console.log("Time : " + getTime()); } } }; setWatch(backlightSwitch, BTN, { repeat: true, debouce:50 });
And version 2 related console output:
Timeout: 10316.78362751007```
Version 2 creates only one timeout, no matter how long the button is held down.
-
• #9
And here the delayed code. In mycrocontroller world things are bot a dynamic as in a client (browser) or server (node.s) of the Web world. Dedicatedness trumps flexibility and dynamics. Things get setup and there they are... Due to the memory constraints, the 'spaghetti' is limited... ;-) I still though apply good practices (best ... is just an excuse and justification of not having stepped between the boxes...
SPI1.setup({ sck:B3, mosi:B5 }); var VPIN = A5; // divider resistor 1 in ohms var divr1 = 10000; var divr2 = 1000; var numReads = 5; var g; var updateVolts = function updateVolts() { var aread = 0; for (var i = 0; i < numReads; i++) { aread += analogRead(VPIN); } aread /= numReads; var pinvolts = 3.3 * aread; var powervolts = (pinvolts / divr2) * (divr1 + divr2); g.clear(); g.setContrast(0.45); g.setFontVector(12); g.drawString("ADC: " + aread,0,0); g.drawString("Volts: "+ powervolts,0,16); g.flip(); } // backlight stays 2 more seconds on after releasing button var backlight = B1; var backlightTimeout; pinMode(backlight,"output"); var backlightOn = function(e) { if (backlightTimeout) { clearTimeout(backlightTimeout); } backlight.set(); backlightTimeout = setTimeout(function(){ backlightTimeout = undefined; if (digitalRead(BTN)) { backlightOn(); } else { backlight.reset(); } },2000); }; setWatch(backlightOn, BTN, { repeat: true, debouce:50 }); function onInit() { g = require("PCD8544").connect(SPI1,B6,B7,B10, function() { setInterval(updateVolts, 500); }); }
A more object-oriented aproach could have bin teaken... with two inline defined singletons - voltmeter and backlight, and make some start (and stop) methods... but that's overshooting again... ;(
-
• #10
I'm still not worried about the code conventions at this point and more that something is going wrong at the hardware level...
I appreciate the concern about the specific code, but it's kinda missing the point that I'm looking at some hardware problem and would really like to focus on that.
-
• #11
That is a strange one. I'll try on Monday and see if I can cause problems by putting 2.9v or more on A5. The chip should be fine up to 3.3v though - in fact I think even ADC inputs are 5v tolerant on these chips (maybe don't try it until I checked that though!)
By the way, if you do save something that breaks the chip, check out: http://www.espruino.com/Troubleshooting
It shows you how to boot up without loading the saved code.
-
• #12
Thanks for confirming it should be right to go to at least 3.3V +Gordon.
The troubleshooting page is where I figured out how to reflash and boot to an empty program from.
I'm going to stick with a much bigger voltage divider gap (and less accuracy in the range I care about for now).
I'm also getting a more accurate multimeter on the off chance that's the issue :)
-
• #13
I just checked this (more or less) and it works for me - I changed your code to use the LCD in the 'hello world' LCD position, and used A4 (with 3.3v on it). I also stripped out the LCD code and just printed to the console and used A5 (also with 3.3v on it), and both work.
What happens if you disconnect your voltage divider and connect the 3.3v pin in Espruino directly to A5? That should ensure that you have over 2.9v on A5, while not running the risk that you're over-volting it?
Depending what you're connecting to, it's possible that you're actually measuring something with an AC component? If so the volt meter may well read less than the actual peak voltage.
-
• #14
What happens if you disconnect your voltage divider and connect the 3.3v pin in Espruino directly to A5? That should ensure that you have over 2.9v on A5, while not running the risk that you're over-volting it?
This works fine :/ and now that you ask, I remember this was actually the first test I ran (i.e a wire straight from 3.3 -> A5, as a quick way to see what
analogRead(...)
gave).Depending what you're connecting to, it's possible that you're actually measuring something with an AC component? If so the volt meter may well read less than the actual peak voltage.
I think you're probably right and you've given me a couple of good things to try out.
I'm trying to switch a couple of devices based on the voltage in a 24V (nominally 24, in the real world 22-32V) offgrid solar system - to try to do that I'm currently testing with a cheapie Lab PSU in that range (I'm pretty sure the DC signal on this is ok) and supplying power to the Pico through a regulated buck converter circuit (this looks identical to the one using http://www.ebay.com.au/itm/181409861491) set to 5V and supplying the 5V via the USB plug. When I actually tested I was very slowly ramping up volts on the PSU (started at about 7V).
All GNDs are common.
I suspect if there's an AC signal getting in it might be the switching noise from the buck converter regulator.
I'll see if I can get some time with an Oscilloscope to see if I can find any fluctuations that shouldn't be there.
Cheers,
Daveedit: many many typos.
I have just been playing with my picos for a couple of days, but the main one I've been using is now returning:
when I try to upload code that uploads just fine to another pico. It fails when none of the pins on the pico are connected to anything else too.
Once this happens the board becomes unresponsive in the IDE and I have to reboot it hitting the button after the first LED flash to skip loading saved code.
I've tried reflashing it to see if that helps and the same thing happens when I reupload code.
I seem to be able to upload some simple code but for the longer code I'm running (attached) I get the
"ho" not found!
error repeatedly.The code was basically just to take a voltage divider reading and display it on a PCD8544 display.
At the time it first failed I had the voltage divider configured like so:
I had a multimeter on A5 and GND to make sure A5 never saw too high a voltage and only took the PSU up to 3V at the A5 pin, but at just under the 3V (IIUC I can take the pin to VCC or 3.3V?) point the display corrupted. I turned off the PSU and switched back to powering off the laptop and found the pico was mostly non-responsive at this point.
... so now for the actual questions:
Is there anything else I can try to recover the board?
What might I have missed that's caused the problem in the first place?
1 Attachment