📦 Archived documentation: r1 (committed 2026-07-24) View current documentation →

Serial Port: Encrypted Device-to-Device

Sends AES-256 encrypted, checksummed measurements between devices over RS-485: objects are serialised with string(), encrypted with bin.enc(), hex-encoded with bin.toHex() and framed with a carriage return; the receive callback reverses each step and validates the checksum.

let port = 1; // Available ports vary depending on the device. Refer to the serial.init documentation
let aesKey = bin.sha256("password");

function serialRxCallback(msg){
  print("Received Serial Msg");
  print("Port:", msg.port);              // port of incoming msg
  print("Overflowed:", msg.ovf);         // msg.ovf is boolean true / false
  print("Data:", bin.toHex(msg.data));

  if(msg.data.length && !msg.ovf){       // received a complete message
    let payload = bin.fromHex(msg.data); // convert the hex message back to binary

    let decrypted = bin.dec(payload, aesKey); // decrypt the encrypted message

    if(decrypted.valid){ // decryption successful and checksums valid
      // For binary payloads we could parse directly, e.g.:
      // decrypted.data.seek(0); let value = decrypted.data.read("F32ABCD");
      let decryptedObj = JSON.parse(decrypted.data);
      print(string(decryptedObj));
    } else {
      print("AES Decryption Failed.");
    }
  }
}

function transmitMeasurements(){
  let data = { message: "Hello World!", voltage: 13.45, ch1: 3.99 };
  let payload = string(data);            // convert the object to a string
  let encrypted = bin.enc(payload, aesKey); // encrypted data includes a 256-bit checksum
  let hex = bin.toHex(encrypted);        // hex-encode for transmission over serial

  serial.tx(port, hex + "\r");           // append a carriage return to the end
}

serial.init(port, 19200);
serial.listen(port, "\r", serialRxCallback); // buffer rx until a carriage return arrives

while(run()){
  transmitMeasurements();
  waitMS(1000);
}