-
https://www.espruino.com/Data+Collection
This is where I learnt how to leverage the puck and web bluetooth to do data collection. In addition to that I added a nodejs process that takes the data from the custom downloading site in that article and puts into a file in my computer for convenience. I found that the best way to actually get the data in a practical way.
I understand that you are not computer literate and that maybe you already saw that article but if you are feeling brave and wanna dive deeper I am here to help :)
-
-
-
@allObjects is right! I want to make me like a portable web browser with a physical interface all run by puck
-
-
What I meant was maybe a bit far fetched. But id like to build an app with a la Electron but then I want to be able to run that app in the puck and interact with it with buttons and pots and things from the physical world. I understand that I could have a site and talk to it through Web Bluetooth, but I was wondering if I could use puck as a computer running a browser hehe.
Maybe this is more suitable for a RPi?
-
-
-
-
Hej @Gordon @Robin @AkosLukacs and @maze1980, thanks for taking the time to review my code and also for helping me improving it. I took the time to edit my code and include the suggestions, feel free to double check.
This should store up to 2000 readings of the high accuracy TI TMP117 sensor into an array.
const i2c = new I2C(); const tmp117Address = 0x48; const temperatureAddress = 0x00; const timePeriod = 30 * 1000; // every 30 secs const log = new Float32Array(2000); // our logged data let logIndex = 0; // index of last logged data item let lastReadingTime; // time of last reading // Store data into RAM const storeMyData = (data) => { logIndex++; if (logIndex >= log.length) logIndex = 0; log[logIndex] = data; }; // Get Data and store it in RAM const getData = () => { i2c.writeTo({address: tmp117Address, stop: false}, temperatureAddress); setTimeout(() => { let reading = i2c.readFrom(tmp117Address, 2); let dataBytes = ((reading[0] << 8) | reading[1]); let dataCentigrades = dataBytes * 0.0078125; storeMyData(dataCentigrades); console.log(dataCentigrades); lastReadingTime = Date.now(); }, 500); }; // Dump our data in a human-readable format const exportData = () => { for (let i = 1; i <= log.length; i++) { let time = new Date(lastReadingTime - (log.length - i) * timePeriod); let data = log[(i + logIndex) % log.length]; console.log(Math.floor(time / 1000) + ' ' + data); } }; const startLight = () => { digitalWrite(LED2, 1); setTimeout(() => { digitalWrite(LED2, 0); }, 1000); }; const stopLight = () => { digitalWrite(LED1, 1); setTimeout(() => { digitalWrite(LED1, 0); }, 1000); }; i2c.setup({ scl : D31, sda: D30 }); let recording = true; let interval = setInterval(getData, timePeriod); setWatch(() => { console.log("Pressed"); if (recording) { recording = false; clearInterval(interval); stopLight(); } else { recording = true; interval = setInterval(getData, timePeriod); startLight(); } }, BTN, {edge:"rising", debounce: 50, repeat: true});
Then you can download this data from the puck using a site with this code
<html> <head> </head> <body> <script src="https://www.puck-js.com/puck.js"></script> <button id="myButton">On!</button> <script type="text/javascript"> // Create WebSocket connection. const socket = new WebSocket('ws://localhost:8080'); const button = document.getElementById("myButton"); function onLine(data) { // CSV data is received here socket.send(data); console.log(data); } var connection; button.addEventListener("click", function() { if (connection) { connection.close(); connection = undefined; } Puck.connect(function(c) { if (!c) { alert("Couldn't connect!"); return; } connection = c; // Handle the data we get back, and call 'onLine' // whenever we get a line var buf = ""; connection.on("data", function(d) { buf += d; var i = buf.indexOf("\n"); while (i>=0) { onLine(buf.substr(0,i)); buf = buf.substr(i+1); i = buf.indexOf("\n"); } }); // Request data from Puck.js connection.write("\x10exportData()\n"); }); }); </script> </body> </html>
but before make sure you are running a node process with this code, it will listen to socket data and use Winston to dump it into the file system.
const winston = require('winston'); const logger = winston.createLogger({ transports: [ new winston.transports.Console(), new winston.transports.File({ filename: `${new Date().toISOString()}.txt` }) ] }); const WebSocket = require('ws') const wss = new WebSocket.Server({ port: 8080 }) wss.on('connection', ws => { ws.on('message', message => { const msg = message.trim(); const timestamp = msg.split(" ")[0]; const temp = msg.split(" ")[1]; logger.info(`${timestamp} ${temp}`); }) ws.send('Server ready') })
-
As I said in my previous post. I managed to fix it by changing line 8 in which I write 1 to instead write 0, this seems to clear the previous measurement or something in the TMP117 and then the next reading works flawless.
I adaparted the Espruino Data Collection example to store the temp measurement of the TMP117 and the magnetometer of the puck.js board every 30seconds in memory and then export it out via bluetooth using a site to connect and download the logs.
var i2c = new I2C(); i2c.setup({ scl : D31, sda: D30 }); const TMP117_Address = '0x48'; const Temp_Reg = '0x00'; var log = new Float32Array(2000); // our logged data var magLog = new Float32Array(2000); // our logged data var logIndex = 0; // index of last logged data item var magLogIndex = 0; // index of last logged data item var timePeriod = 30*1000; // every 30 secs var lastReadingTime; // time of last reading // Store data into RAM function storeMyData(data) { logIndex++; if (logIndex>=log.length) logIndex=0; log[logIndex] = data; let mag = Puck.mag(); magLogIndex++; if (magLogIndex>=magLog.length) magLogIndex=0; magLog[magLogIndex] = data; } // Get Data and store it in RAM function getData() { i2c.writeTo(TMP117_Address, Temp_Reg); let a = i2c.writeTo(TMP117_Address, 0); setTimeout(() => { let b = i2c.readFrom(TMP117_Address, 2); let datac = ((b[0] << 8) | b[1]); let temp = datac*0.0078125; console.log(temp); storeMyData(temp); lastReadingTime = Date.now(); }, 500); } // Dump our data in a human-readable format function exportData() { for (var i=1;i<=log.length;i++) { var time = new Date(lastReadingTime - (log.length-i)*timePeriod); var data = log[(i+logIndex)%log.length]; console.log(Math.floor(time/1000)+" "+data); } for (var y=1;y<=magLog.length;y++) { var time2 = new Date(lastReadingTime - (magLog.length-y)*timePeriod); var data2 = magLog[(y+magLogIndex)%magLog.length]; console.log(Math.floor(time2/1000)+" "+data2); } } function startLight () { digitalWrite(LED2,1); setTimeout(() => { digitalWrite(LED2,0); }, 1000); } function stopLight () { digitalWrite(LED1,1); setTimeout(() => { digitalWrite(LED1,0); }, 1000); } var recording = true; var interval = setInterval(getData, timePeriod); setWatch(function() { console.log("Pressed"); if (recording) { recording = false; clearInterval(interval); stopLight(); } else { recording = true; interval = setInterval(getData, timePeriod); startLight(); } }, BTN, {edge:"rising", debounce:50, repeat:true}); */
sorry for variable names :/
I also added a start green led and stop red led if you press the button to start and stop recording temps -
Thanks for your input I will next time do all this checklist you suggest because it all makes sense to try, specially the analyzer and decoder thing. !!!
I figured it out by bruteforcing trial and error attempts. In the end I had to change the 1 in line 8 for a 0. Doing that did the trick. I have no clue why!
-
I am trying to read from a i2c connect sensor. I managed to get my schematic and code working for arduino leonardo but not when I interface with the puck. I suck at bytes and low level stuff, so I am wondering if I understand what I am doing.
var i2c = new I2C(); i2c.setup({ scl : D31, sda: D30 }); const TMP117_Address = '0x48'; const Temp_Reg = '0x00'; setInterval(() => { i2c.writeTo(TMP117_Address, Temp_Reg); let a = i2c.writeTo(TMP117_Address, 1); setTimeout(() => { let b = i2c.readFrom(TMP117_Address, 2); console.log(b); let datac = ((b[0] << 8) | b[1]); console.log(datac*0.0078125); }, 500); }, 2000);
trying to imitate this:
/*********************** Read Temperature Sensor Function **************************/ double ReadTempSensor(void){ // Data array to store 2-bytes from I2C line uint8_t data[2]; // Combination of 2-byte data into 16-bit data int16_t datac; // Points to device & begins transmission Wire.beginTransmission(TMP117_Address); // Points to temperature register to read/write data Wire.write(Temp_Reg); // Ends data transfer and transmits data from register Wire.endTransmission(); // Delay to allow sufficient conversion time delay(10); // Requests 2-byte temperature data from device Wire.requestFrom(TMP117_Address,2); // Checks if data received matches the requested 2-bytes if(Wire.available() <= 2){ // Stores each byte of data from temperature register data[0] = Wire.read(); data[1] = Wire.read(); // Combines data to make 16-bit binary number datac = ((data[0] << 8) | data[1]); // Convert to Celcius (7.8125 mC resolution) and return return datac*0.0078125; } }
i am getting a senseless value, i wonder what am I doing wrong? I find it hard to understand how to map these i2c operations to the pucks i2c api.
Thanks for the info! Ill read up, i suck at basic physics