Closed emnik closed 9 years ago
the code I use is:
var SerialPort = require('serialport').SerialPort;
var xbee_api = require('xbee-api');
var util = require('util');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('./sensor-data.sqlite');
function readRemoteTemp(callback)
{
var xbeeAPI = new xbee_api.XBeeAPI({
api_mode: 1, //ATAP1 -without escape characters
module: "802.15.4"
});
var serialport = new SerialPort("/dev/ttyAMA0", {
baudrate: 9600,
parser: xbeeAPI.rawParser()
});
xbeeAPI.on("frame_object", function(frame) {
console.log('hello from frame_object');
if (frame.remote16 === '0002') // this is the address of the remote Xbee
{
var buf = frame.data;
var value = buf.readFloatLE(0);
//console.log(value);
var data = {
temperature_record:[{
unix_time: Date.now(),
celsius: Math.round(value * 10) / 10 //round temperature to 1 decimal digit
}]};
// console.log(data);
if (data.temperature_record[0].celsius!=""){
callback(data);
}
}
})
}
// Write a single temperature record in JSON format to database table.
function insertRemoteTemp(data){
//var db = new sqlite3.Database('./sensor-data.sqlite');
// data is a javascript object
var statement = db.prepare("INSERT INTO sensor_data (timestamp, sensor_id, value) VALUES (?, 2, ?)");
// Insert values into prepared statement
statement.run(data.temperature_record[0].unix_time, data.temperature_record[0].celsius, function(error){
if (error){
console.log("SQL error from xbee module: ");
console.log(error);
}
});
// Execute the statement
statement.finalize();
//db.close();
}
function logRemoteTemp(){
readRemoteTemp(insertRemoteTemp);
}
module.exports.logRemoteTemp = logRemoteTemp;
Hey man, sorry you're having these problems. Could you log all the bytes received from the serial port to a file? (writing buffer[i] at the beginning of the for loop in parseRaw)
Ok, lets see: In
XBeeAPI.prototype.parseRaw = function(buffer) {
var S = this.parseState;
for(var i = 0; i < buffer.length; i++) {
I added:
console.log('logging buffer['+i+']: '+buffer[i]);
if (i==buffer.length-1) console.log('-----------------------');
and when I use the module I also added a consoloe.log(frame)
xbeeAPI.on("frame_object", function(frame) {
console.log(frame);
You can see the normal log at http://pastebin.com/jvfaKZ2P and the error log at http://pastebin.com/6FreaQ7i
if (S.length > 0 && S.offset === S.length + 4) {
...
this.emit("frame_object", frame);
...
is never true in that case. I saw that in the frames of the first message (http://pastebin.com/LSeRbJQm) I posted above...
I'll remind you that the error happens only the first time running the app after boot.
I think it is connected to all those zeros leaking in from the serial port, even once the xbee starts talking (see those extra zeros in between the message, line 19 to 32 in error.log?). I'm not sure if I should "fix" this on the xbee-api side, since this is clearly caused by the raspi...
It seems like the zeros stop leaking in after some time. Maybe you can work around that on your end? wait for xbee-api to be (re-)initialized?
OK... Any idea how to do this? I have tried catching the RangeError and I didn't succeed. At first I tried with try / catch and it didn't work because of the async nature of node... Then I read about domains and I tried them:
var d = require('domain').create();
d.on('error', function(err){
// handle the error safely
console.log('error caugth in domain...');
console.log(err);
//trying to re-initialize xbee-api:
ds1820_xbee.logRemoteTemp(); //the code is shown in my second message above...
});
d.run(function(){
process.nextTick(function(){
ds1820_xbee.logRemoteTemp(); //the code is shown in my second message above...
})
});
but again it doesn't catch the RangeError... and crashes. I even used try/catch with domains together as I've read somewhere but that also didn't caught the error. If you have any better idea I'd be happy to learn from you :-)
So, I kind of solved (more of a hack really) my problem by encapsulating the for loop of the ParseRaw function in an:
if (buffer.length<=8) {
the for loop...
}
I added this, as I noticed that on normal operation the buffer length is 8+5 (the for loop runs twice for every frame - Can you please explain to me why?), while when the error arrises, the buffer length at first is 16 (not ok) then 9 + 5 (not ok) and after that 8 + 5 / 8 + 5 / 8 + 5 /... that seems ok. Now I don't know why is this happening but for me seems to be working. Also I don't know if the values 8 followed by 5 for the buffer size, is specific to the data I am sending over RF (I send a float representing a thermal value) or not...
I'd like your opinion on this...
Yes, the 8+5 is specific to your data. Other messages will have other sizes. Also, the messages may come in chunks from the serial port (4 bytes, 2 bytes 10 bytes 1 byte) (and inside the for loop, we deal with each individual byte of that chunk). So the for loop may run for a single message several times (for the first 4 bytes, then for 5 more bytes, etc.)...
I can't test this fix, but maybe this could also work for you: #34
Sorry for the bad title but... I am developing a smart thermostat using node.js on raspberry pi with Xbee Series 1. The following is happening only with xbee-api in node.js (in python code I don't have such a problem) so it must be a bug. The first time after booting RPi, on every Xbee frame I receive when I added console.log(util.inspect(S)); in xbee-api.js (~line 187) I get: MULTIPLE frames (every time much more than the previous) with wrong offset, length etc: To be more specific: I receive data from a remote Xbee every 30sec:
On the first data I get 16 TIMES:
On the second data I get 11 TIMES:
with offset values ranging from 1 to 14 every time...
On the third data I get 13 TIMES:
with offset values ranging from 5 to 27 every time...
... this keeps growing and when the offset becomes = 128 it crashes:
SEE HERE: http://pastebin.com/LSeRbJQm
Now, if I restart the app everything works just fine: Every 30 seconds I get a frame such: