Espruino Bluetooth devices like Puck.js and Pixl.js contain a programmable NFC tag.
In most cases you'd program them using NRF.nfcURL
to make a URL available,
and then a user can scan the device to go to that URL.
However, two way communications are possible by emulating an NFC tag on Puck.js.
To make a complete system, we'll write code for Puck.js that emulates a tag, and will then send text to it from a Web Page with Web NFC.
Note: More information is available on the Espruino NFC Tag Module page and the NRF NFC documentation.
Upload the following code to Puck.js:
var data = new Uint8Array(10+64);
var header = NRF.nfcStart();
var written = false;
data.set(header,0); // NFC device header
data.set([0,0,0xE1,0x10,(data.length-10)/8,0,0,3,0,0xFe], 0x0A); // NDEF tag header
// 0,0,e1
NRF.on('NFCrx', function(rx) {
var idx = rx[1]*4;
switch(rx[0]) {
case 0x30: //command: READ
NRF.nfcSend(new Uint8Array(data.buffer, idx, 16));
break;
case 0xa2: //command: WRITE
written = true;
if(idx > data.length) {
NRF.nfcSend(0x0);
} else {
data.set(new Uint8Array(rx, 2, 4), idx);
NRF.nfcSend(0xA);
}
break;
default: //just, re-enable rx
NRF.nfcSend();
break;
}
});
NRF.on("NFCoff",function() {
if (written)
onWritten(E.toString(new Uint8Array(data.buffer,26,data[21]-3)));
written = false;
});
function onWritten(data) {
console.log("NFC written", data);
var colors = {
red : 1,
green : 2,
blue : 4,
};
// Only light LEDs if we actually have 3 LEDs! Allows Pixl.js upload
if (colors[data] && global.LED1 && global.LED2 && global.LED3) {
digitalWrite([LED3,LED2,LED1], colors[data]);
setTimeout(function() {
digitalWrite([LED3,LED2,LED1], 0);
},1000);
}
}
This will create a simple 64 byte NFC tag, and when the NFC writer is removed
from within range of the Espruino device, Espruino will call onWritten
with the new tag information if the tag had been modified.
On Puck.js this'll light up the red, green or blue LEDs, but on Pixl.js it'll just display the text that was written.
First, check out this page for instructions on enabling Web NFC in your browser.
Then you can click the 'try now' link at the bottom of the page below to try it out:
<html>
<body>
<script>
if (typeof NDEFReader==="undefined") {
document.write("NDEFReader is not supported on this browser<br/>");
}
const ndef = new NDEFReader();
ndef.onreading = event => {
console.log("NFC", event);
};
function start() {
/* Starting a scan stops Android from
moving away from the Chrome window when a tag is found*/
ndef.scan().then(_ => {
// hide 'start' button
document.querySelector("#startButton").style.display = "none";
document.querySelector("#buttons").style.display = "block";
});
}
// If we already have permission, start right up!
// Otherwise we need the user to press a button
navigator.permissions.query({ name: "nfc" }).then(p => {
if (p.state === "granted") start();
});
function send(msg) {
ndef.write(msg).then(_=>console.log("Written ",msg));
}
</script>
<button id="startButton" onclick="start()">Start!</button>
<div id="buttons" style="display:none">
<button onclick="send('red')">Red</button>
<button onclick="send('green')">Green</button>
<button onclick="send('blue')">Blue</button>
</div>
</body>
</html>
Simply click one of the buttons while in NFC range of the Puck.js (eg your phone buzzes), and when you exit NFC range of the device the relevant LED will light.
Note: Old versions of Web NFC used NDEFWriter
. If you get a
ndef.write is not a function
error, you'll need to update your browser.
NXP TagWriter
for AndroidWrite Tags
New Dataset
Plain text
Enter text
type red
(lowercase)Save
- if you can't see the button because it's under the keyboard,
choose About
from the top right, then press the Back
button and you
should be able to see Save
again.Ok
Write Tags
againMy Datasets
red
Confirm overwrite
Write
, move the phone near Puck.js and the app should make
a noise to show the content has been written.green
and blue
, or could update the Puck.js code above.This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.