Messaging
A program running on the brick can exchange short messages with your computer through mailboxes. This is the way to combine fast on-brick control loops with high-level decisions on the computer.
- The computer writes into inboxes 1–10 of the brick (
Mailbox::M1…Mailbox::M10). - The on-brick program answers through response outboxes, one per inbox (numbered 11–20 in NXC). The computer collects replies from there.
- A message is at most 58 bytes.
nxt_rs::doc_example_with(|brick, sim| async move {
use nxt_rs::protocol::{Mailbox, Message};
use std::time::Duration;
let messages = brick.messages();
messages.send(Mailbox::M1, "forward").await?;
sim.push_outbox(Mailbox::M1, Message::new("ok")?);
if let Some(reply) = messages.recv(Mailbox::M1).await? {
println!("robot says {:?}", reply.as_str());
}
// or wait for one, polling every 50 ms
sim.push_outbox(Mailbox::M1, Message::new("done")?);
let reply = messages.wait(Mailbox::M1, Duration::from_millis(50)).await?;
Ok(()) });
| Method | Does |
|---|---|
send(mailbox, data) | Puts text or bytes into the brick’s inbox |
recv(mailbox) | Takes the next reply from the response outbox, or None |
peek(mailbox) | Like recv, without removing the message |
wait(mailbox, interval) | Polls recv until a reply arrives |
recv_from(remote, remove) | Reads any mailbox, including the brick’s inboxes |
The brick can’t push messages to the computer: the computer has to poll. Each mailbox only holds a handful of messages, so poll regularly.
The on-brick side
In NXC, read the computer’s messages with ReceiveRemoteString and answer
with SendResponseString. Mailbox constants are zero-based: NXC’s
MAILBOX1 is Mailbox::M1.
task main() {
string cmd;
while (true) {
if (ReceiveRemoteString(MAILBOX1, true, cmd) == NO_ERR) {
if (cmd == "forward") OnFwd(OUT_BC, 75);
if (cmd == "stop") Off(OUT_BC);
SendResponseString(MAILBOX1, "ok");
}
Wait(10);
}
}
NXC also has ReceiveRemoteNumber/SendResponseNumber (numbers sent as
text) and ReceiveRemoteBool/SendResponseBool. On the Rust side, these
are ordinary messages:
nxt_rs::doc_example_with(|brick, sim| async move {
use nxt_rs::protocol::{Mailbox, Message};
brick.messages().send(Mailbox::M2, 42.to_string()).await?;
sim.push_outbox(Mailbox::M2, Message::new("17")?);
let number: i32 = brick.messages().recv(Mailbox::M2).await?
.and_then(|m| m.as_str()?.parse().ok())
.unwrap_or_default();
Ok(()) });
See the remote control recipe for a complete example.