-
-
Without cutting the traces, they may ripp off the board on the 'inner'-side of the breaking. But I think the good news of the thickness of the board is that keeping two break off spots at the USB end should be strong enough to hold on to the PICO - for placement and soldering. Milling first the two long edges incl the USB sides, and then the USB tip, then drilling the holes in the breakout parts at the left and right side of USB tip... No problem w/ Jaltek the specialists, but listen to ideas never hurts... it's difficult though ;-)
-
...not because I say it, it is because you @Gordon made it so! - Credit where - to whom - credit is due!
-
The issue with break out is the thickness of the board. Did you ever think of doing it differently, suchas making a thinner board and snapping something on to create the thickness? It may also have an inpact on the cost of the overall bard.
As I understand from this process is, that after the Picos have been tested, the milling will happen to cut off the utility connections - is that correct?
-
@Gordon, didn't you recently add .bind()? Would that now be even a better option - resource-wise - and for sure from a point of avoiding globals...?
I guess the code would then look like this:
Wheel.prototype.spin = function(stopt) // stopt = stoptime { this.vel = (2 + Math.random() * 5) / 40; // give the wheel a velocity setTimeout(this.stop.bind(this), stopt); // tell it when to stop };
Adding this .bind() was a great move! Still have to get used to it having started JS with 1.3...
-
-
-
-
When you save, timers should be stopped. Usually on upload, stuff starts to run and timers are on the go and state of variables are saved as well. I see that you have some reset() and other things going on. To have reset() redefined in your code may be an issue. Reset is a built-in function... Quick+Start. I do not know what redefining it in your code does to the system: override, not override,...
-
The system report just reads what the underlaying unix shows in the 'file' system (/dev). And it looks like @tony1tf's OS X version is not picking up the plugging in and does not connect on the hardware level and create this device entry. May be the sensing of the plugging in on an electro mechanical / electronic signal level does not make it. @Gordon, what is the USB compatibility? 1, 2, 3, 3 fast,...? Using a USB A/Male-A /Femal Extension Cable to connect Pico with the Mac would be my last resort worth a shot.
-
You need an onInit() in which you stat the timers... save() is also saving the state of the machine, but only the 'static' (code and settings) part, but not the timer things. in the onInit() you put the init(). I did not fully analyze and understand your code, but with timings/timers that's usually the issue.
-
@tony1tf, I'm sure you have checked this conversation about Mac Web IDE problems. So it is the OS X version that messes with you... (according to my post there, I had already moved on... and it is about the time when I started to do Espruino 7/2014).
I know that there are other ways to talk to (standard) Espruino (board) than USB... don't know about Pico.
-
Interesting... (I'm sorry for not having gotten it)
(C0rrected: stated earlier: Even without Espruino connected, I get the following list... and that is incorrect... only when OS X detects Espruino, it creates the device).
I'm using OS X 10.9.5 on MacBook Pro - I hope it is not the 10.9.5 which makes the difference... (I cannot remember when I moved on from Snow Leopard...).
allO:dev allO$ ls -l | grep usb crw-rw-rw- 1 root wheel 33, 27 Apr 25 23:11 cu.usbmodem411 crw-rw-rw- 1 root wheel 33, 26 Apr 26 00:29 tty.usbmodem411 allO:dev allO$
-
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... ;(
-
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.
-
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.
-
-
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.
-
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();
-
Did you install and start the Espruino Web IDE in Chrome?
In the IDE in top left corner, you see a yellow/kaki Connect icon. Clicking/tapping it shows you the list of USB ports, from which you pick the one that obviously got successfully installed.
The Connect icon will turn green, and in the console, Espruino will print a banner including the installed firmware.
Espruino is now at you service!
PS: This button press on or briefly after plugging in/powering on is only for reset or flash. You do not need that to just get Espruino connected and talking to the IDE.
-
For Espruino module, that is what you get: a
The module is at http://www.espruino.com/modules/GPS.js .
I list it in this thrad for discussion purpose. This source is what I cloned and enhanced for my purposes. You can to that easily for yourself as well.
This are the steps:
- In Web IDE go to Setting (Cogwheel) - Projects
- Select a Directory (you made on your system) for Sandbox
- Copy the module code into the IDE editor (right side pane)
- Save the moduel under GPS_JB.js in the folder /modules
- Load your application code into the IDE editor
- Change the Require to to "GPS_JB.js"
- When you got it running to the point it runs now, you are ready to modify the moduel - either in the IDE editor - or what ever multi-document editor you are used to.
- Everytime you upload your application code to the board, it does not find
the module in the official place (or you are not connected), it goes after your sandbox module folder and tries to load / loads it from there - For now disable minification - because if you do iteratively - you may get flagged by the free Google closure compiler service that's invoked every time you upload and you are stuck until you change to no minification or the 'flag wears down' (may be that is not the case anymore... I do not have latest status from @Gorden about built in minifier / closure compiler / etc. But it does not hurt you yet, since you do not have much code with memory nor performance challenges).
Now to the module code:
/* Copyright (c) 2013 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. */ /* Module for interfacing with serial (NMEA) GPS devices Serial4.setup(9600,{tx:C10,rx:C11}); var gps = connect(Serial4, function(data) { console.log(data); }); */ function handleGPSLine(line, callback) { var tag = line.substr(3,3); if (tag=="GGA") { var d = line.split(","); var dlat = d[2].indexOf("."); var dlon = d[4].indexOf("."); callback( { time: d[1].substr(0,2) + ":"+d[1].substr(2,2)+":" + d[1].substr(4,2) , lat: (parseInt(d[2].substr(0,dlat-2),10) + parseFloat(d[2].substr(dlat-2))/60)*(d[3]=="S"?-1:1) , lon: (parseInt(d[4].substr(0,dlon-2),10) + parseFloat(d[4].substr(dlon-2))/60)*(d[5]=="W"?-1:1) , fix: parseInt(d[6],10) , satellites: parseInt(d[7],10) , altitude: parseFloat(d[9]) }); } } exports.connect = function(serial, callback) { var gps = {line:""}; serial.on('data', function(data) { gps.line += data; var idx = gps.line.indexOf("\n"); while (idx>=0) { var line = gps.line.substr(0, idx); gps.line = gps.line.substr(idx+1); handleGPSLine(line, callback); idx = gps.line.indexOf("\n"); } if (gps.line.length > 80) gps.line = gps.line.substr(-80); }); return gps; }
When you say
require("GPS")
in your code, you get an object back that understands.connect()
, where you pass the serial and your application function. The application function has to accept a prameter object, which is the object crated from the GPS data in the GPS module by the module only line handler in lines 18 through 26.Unfortunately the way the module is built and without changing it/that, it does you not give access to change this handler with something of your's that would be more powerful. The only thing accessible to you in the object reteurned from .connect() is an object with one property, and that is the data recieved but not processed yet by the handler.
When the moudule is changed so that the module's integrated handler is put into thet returned gps object as a "handler:" property (in line 31) and then referenced in line 38, you could put just any other linehandler in there right afert connect.
You have serveral options of remedy:
First option:
in your cloned GPS_JB module:
- make line 31:
var gps = {line:"", handle:handleGPSLine}
- make line 38: ```gps.handle(line,callback);
- make line 31:
in your application:
Serial1.setup(9600, {tx: B6, rx: B7}); var gps = require('GPS_JB').connect(Serial1, function(data){ console.log(data); }); gps.handle = function(line,callback) { // your line handler processing creating data object var data = { ... }; callback(data); };
Second (preferred option) {
in your cloned GPS_JB module:
make line 30:
2. make line 31:
var gps = {line:"", handle:(handle) ? handle : handleGPSLine }```
make line 38:
- in your appliacation:
Serial1.setup(9600, {tx: B6, rx: B7});
var gps = require('GPS_JB').connect( Serial1,
function(data){console.log(data);
},
function(line,callback){// your line handler processing creating data object var data = { ... }; callback(data);
} );
For the (anonymously) provided handle *function(line,callback)* you can do something like that:
function(line,callback){
// your line handler processing create data object var tag = line.substr(3,3), data; switch (tag) { case "GGA": data = {.... }; break; case "XYZ": data = {.... }; break; } if {data) {callback(data); }
}
```Make sure your line handler as well as your applicaiton callback processing happens within the timeframe the next data come...
- In Web IDE go to Setting (Cogwheel) - Projects
-
The F401 chip in the Pico also has much better clock control - the CPU can slow itself down from 84Mhz, saving a lot of power. That's something I plan on adding soon too
How slower can it be clocked? ...down to static? (like some CMOS uCs that were/are sent to space? ...down to single steppinh the clock? (Of course, that would disable wake ups, etc.).
It is for sure an interesting feature...
missing the first byte or so You can do setWatch on the serial signal, but by the time the Pico has woken up you'll have missed the first character or so of the data
How fast is the thing moving that you track? ...and what is the resolution you expect? This may together with sending GPS to standby/sleep may give you various types of relieves:
- larger intervals than 2 seconds
- if delta from last position is less than your resolution (and of course the gps resolution), you drop / do not keep the tracking point
- not the gps is the clocking thing but Espruino. In other words Espruino timer wakes Espruino up, wakes up GPS and goes to sleep for the time GPS is waking up, comes out of sleep and is ready when GPS is sending data. Some GPS can send data 10 lines / s, so Espruino does not need to hangout awake too long in case it misses, it just has to stay up until it gets a complete set of data. Afer that it puts GPS to 'sleep', and goes to sleep itself as well.
- larger intervals than 2 seconds
-
This would be your get going sequence:
- wire all up including pico to your pc
- open ide
- connect to espruino
- paste your code into the edit / right hand pane
- upload to the board
- wait
- wait
- wait
- watch console where the default handler's decoded line will show.
It takes some time for the module to actually provide a line that the line handler can process...
Before useful data shows through the default handler, the gps (hardware) module receives already lines and sends them to the (js) module, but they are not yet the lines the default handler looks for. That's why I added an enhanced handler that gives more information back then the default handler built into the Espruino module.
When I built it, I was not familiar with the module build/update process... but now I could make a pull request and have other's benefit automatically from the get going.
- wire all up including pico to your pc
Theremin is the term and instrument I had in mind... just could not recall the details right away...
@alexanderbrevig - you may like this... one person - one organ pipe of variable tuning!