The index in to the payload.bytes, i, is on 17 by the time you get to pulling the SDS011 data which, as you surmise is absent. It doesn’t explode but it doesn’t give you anything useful.
This is my JS PF Tester setup for your decoder. Copy n paste in to a text file ending .html
and then open in your browser.
<!DOCTYPE html>
<html>
<head>
<title>Payload formatter tester</title>
</head>
<body>
<h1>Payload formatter tester</h2>
<h2>Input</h2>
<pre id="positions"></pre>
<pre id="payloadAsHex"></pre>
<p>Port: <span id="port"></span>
<p>Size: <span id="size"></span>
<h2>Result</h2>
<pre id="result"></pre>
<script>
// #### Your stuff here ####
const payloadFromConsole = "000300062C2020322E332C2020302E36";
const fPort = 1;
function decodeUplink(input) {
var data = {};
if (input.fPort === 1) {
var i = 0;
if (input.bytes.length >= 2) {
data.wifi = (input.bytes[i++] << 8) | input.bytes[i++];
}
if (input.bytes.length === 4 || input.bytes.length > 15) {
data.ble = (input.bytes[i++] << 8) | input.bytes[i++];
}
if (input.bytes.length > 4) {
data.latitude = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.longitude = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.sats = input.bytes[i++];
data.hdop = (input.bytes[i++] << 8) | (input.bytes[i++]);
data.altitude = ((input.bytes[i++] << 8) | (input.bytes[i++]));
}
// Add after the "if (bytes.length > 4)" block
if (input.bytes.length >= 15) {
// data.sds011 = String.fromCharCode.apply(null, input.bytes[I]);
data.sds011 = String.fromCharCode(input.bytes[I]);
i+=11;
}
data.pax = 0;
if ('wifi' in data) {
data.pax += data.wifi;
}
if ('ble' in data) {
data.pax += data.ble;
}
}
if (input.fPort === 2) {
var i = 0;
data.voltage = ((input.bytes[i++] << 8) | input.bytes[i++]);
data.uptime = ((input.bytes[i++] << 56) | (input.bytes[i++] << 48) | (input.bytes[i++] << 40) | (input.bytes[i++] << 32) | (input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.cputemp = input.bytes[i++];
data.memory = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.reset0 = input.bytes[i++];
data.restarts = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
}
if (input.fPort === 4) {
var i = 0;
data.latitude = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.longitude = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.sats = input.bytes[i++];
data.hdop = (input.bytes[i++] << 8) | (input.bytes[i++]);
data.altitude = ((input.bytes[i++] << 8) | (input.bytes[i++]));
}
if (input.fPort === 5) {
var i = 0;
data.button = input.bytes[i++];
}
if (input.fPort === 7) {
var i = 0;
data.temperature = ((input.bytes[i++] << 8) | input.bytes[i++]);
data.pressure = ((input.bytes[i++] << 8) | input.bytes[i++]);
data.humidity = ((input.bytes[i++] << 8) | input.bytes[i++]);
data.air = ((input.bytes[i++] << 8) | input.bytes[i++]);
}
if (input.fPort === 8) {
var i = 0;
if (input.bytes.length >= 2) {
data.voltage = (input.bytes[i++] << 8) | input.bytes[i++];
}
}
if (input.fPort === 9) {
// timesync request
if (input.bytes.length === 1) {
data.timesync_seqno = input.bytes[0];
}
// epoch time answer
if (input.bytes.length === 5) {
var i = 0;
data.time = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
data.timestatus = input.bytes[i++];
}
}
if (data.hdop) {
data.hdop /= 100;
data.latitude /= 1000000;
data.longitude /= 1000000;
}
data.bytes = input.bytes; // comment out if you do not want to include the original payload
data.port = input.fPort; // comment out if you do not want to include the port
return {
data: data,
warnings: [],
errors: []
};
}
// JS Payload support stuff - do NOT put this in to the TTS console
const toHexCount = byteArray => 'Position: ' + byteArray.map((x, i) => ('0' + i).slice(-2) ).join(' ');
const toHexStringX = byteArray => 'Payload: 0x' + Array.from(byteArray, byte => ('0' + byte.toString(16)).slice(-2)).join(' 0x')
function hexToBytes(hex) { let bytes = []; for (let c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16)); return bytes; }
var payload = {}
payload.bytes = hexToBytes(payloadFromConsole);
payload.fPort = fPort;
result = decodeUplink(payload);
console.log("data", result.data);
document.getElementById("positions").innerHTML = toHexCount(payload.bytes); //payload.bytes.map((x, i) => ('0' + i).slice(-2) ).join(' ');
document.getElementById("payloadAsHex").innerHTML = toHexStringX(payload.bytes);
document.getElementById("port").innerHTML = payload.fPort;
document.getElementById("size").innerHTML = payload.bytes.length;
document.getElementById("result").innerHTML = JSON.stringify(result, null, 4);
</script>
</body>
</html>
Ideally you have the browser developer tools console open (right click, inspect element will do that for you) so you can see the JS errors or how it’s being processed.
You can add console.log();
in get the Arduino Serial.println();
effect in to the decoder but best to remove them before applying them to the console. You can put any variables or messages in to the console log to see ‘stuff’
More after Strictly.