How can I make a MicroBit MakeCode mass code creator?

53 Views Asked by At

I am working on a project for my town's Maker Faire. What I'm trying to do is have a Micro:Bit send a message through radio, where another one would pick it up and send it through another channel. Then another Micro:Bit would pick that up and so on and so forth. I have the code for the starting micro:bit that sends the first message, and the second micro:bit that receives the first one's message and sends it out again. Each new Micro:Bit bumps up the radio channels by one. Is there any way to do this automatically without having to manually bump it up for each new Micro:bit?

This is my code for the second Micro:Bit:

radio.onReceivedString(function (receivedString) {
radio.setGroup(1)
basic.showString(receivedString)
radio.setGroup(2)
radio.sendString(receivedString) 
})

Thanks!

1

There are 1 best solutions below

1
Sam El-Husseini On

The challenge here is coming up with a way so that each micro:bit knows what its sequence number is on startup. If you're able to initialise each micro:bit with a unique sequence number (eg: 0, 1, 2, 3, 4, 5), then you can flash the same code on each micro:bit and just use the sequence number as an offset. ie: setGroup(sequenceNumber)... setGroup (sequenceNumber + 1). In the case of the first micro:bit that will be groups 0 and 1 respectively, in the case of the second micro:bit that will be groups 1 and 2 respectively, and so on.

I can think of a few ways of having each micro:bit have its own unique sequence number on startup. One way you can do that is have them all set to 0 on startup, and then use the buttons on each micro:bit to change the sequence number. Something like this:

let sequenceNumber = 0;

input.onButtonPressed(Button.A, function () {
    if (sequenceNumber > 0) sequenceNumber--;
})

input.onButtonPressed(Button.B, function () {
   sequenceNumber++; 
})

radio.onReceivedString(function (receivedString) {
    radio.setGroup(sequenceNumber)
    basic.showString(receivedString)
    radio.setGroup(sequenceNumber + 1)
    radio.sendString(receivedString)
})

The above strategy would require you to go around each micro:bit and manually set their sequence number after flashing it. If you flash it again, you'll have to repeat the process..

Another way to approach this is to have all micro:bits running the same program, except for one, which we'll refer to as the master. This master micro:bit will keep a list of all devices its seen (over radio on a preset group, eg: 0) and for every new micro:bit that requests a sequence number, it'll assign it a unique number and send it back. Each of the other micro:bits will startup in an initialization phase where it continuously requests a sequence number and polls until it's been assigned one by the master micro:bit.

Something like the following:

Master:


let masterGroupNumber = 0; // predetermined group number for master micro:bit

let currentSequenceNumber = 1;
let devices: { [key: string]: number } = {};

radio.setGroup(masterGroupNumber);
radio.onReceivedValue(function (name: string, value: number) {
    if (name === "uid") {
        // We're received a unique id. Assign it a sequence number
        // if it has not already been assigned
        let uid = value.toString();
        if (!devices[uid])
            devices[uid] = currentSequenceNumber++;

        radio.sendValue(uid, devices[uid]);
    }
})

All other micro:bits:


// Begin the program in the initialization phase,
// we're waiting to be assigned a sequence number

let masterGroupNumber = 0; // predetermined group number for master micro:bit

let sequenceNumber = 0;
let hasSequenceNumber = false;
radio.setGroup(masterGroupNumber);

let uniqueDeviceId = control.deviceSerialNumber();

radio.onReceivedValue(function (name: string, value: number) {
    if (name === uniqueDeviceId.toString()) {
        sequenceNumber = value;
        hasSequenceNumber = true;
    }
})

// Poll till we've received a sequence number
while (!hasSequenceNumber) {
    // Broadcast our unique device id. 
    radio.sendValue("uid", uniqueDeviceId);

    // Wait a litte
    basic.pause(500);
}

// We've established communication with the master micro:bit
// and have received a sequence number

radio.onReceivedString(function (receivedString) {
    radio.setGroup(sequenceNumber)
    basic.showString(receivedString)
    radio.setGroup(sequenceNumber + 1)
    radio.sendString(receivedString)
})

There's probably a few other ways you could go about doing this, but I hope this gives you some ideas.

ps: I did not have a chance to test if this code works. Let me know how it goes :)