BBC Micro:bit and MySensors - a great match!


  • Plugin Developer

    The BBC Micro:bit is a small NRF52 based board that is designed for use in education (similar to the Raspberry Pi).

    Micro:bit features

    It comes with a lot of onboard things:

    • NRF51 chip
    • Micro USB port. A second chip allows the Micro:bit to show up as a USB drive once you plug it into your computer. You can place a hex file on there, and it will be loaded when you reboot it. Or you can program the board directly, like a normal Arduino.
    • A 3 axis accelerometer
    • A 5x5 red LED matrix
    • Digital compass / magnet sensor
    • 2 buttons
    • A PH battery connector (but no charging circuitry). Idle it uses 5.38 mw.

    BUYING
    The cheapest Micro-bit I've found is $18 on Aliexpress.

    There are LOTS of expansion boards available. Some nice ones:

    GETTING STARTED

    USAGE
    I plan to first use it for home security, as a battery powered..

    • Motion sensor on doors.
    • Window opening detector using the magnet sensor.

    OPPORTUNITIES
    The MySensors community could create some tutorials for children. Perhaps a teacher or instructor could set-up a gateway, and then children could get long-term data on all sorts of things. Do some citizen science.. learn about privacy issues 🙂


  • Hardware Contributor

    It's an NRF51 not 52 unfortunately.


  • Plugin Developer

    Here's a quick motion detection sketch.

    I don't know how an I2C interrupt device can trigger an interupt (to save battery). Is that even possible?

    And do I need to do something to make it go into even deeper sleep?

    Any recommendation for what to use as the motion intensity message? Currently it sends it as a light level. I could use S_Custom, but not a lot of controllers support that.

    /*
     * 
     * This is a motion sensor.
     * 
     * It uses a BBC Micro:bit.
     * 
     * You need to install the required libraries. In the Arduino program click on "sketch" -> "include library" -> "manage libaries". 
     * For each of the library names below enter their name into the search field, and when it pops up select "install".
     * 
     * MySensors                  This is to create a wireless network between your devices.
     * MMA8653                    Thsis library must be installed manually. Download it from https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip
     * 
     * 
     * You can look through the code below and tweak other things if you like.
     * 
     */
    
    //
    // SETTINGS
    //
    
    // Enable and select the attached radio type
    //#define MY_RADIO_RF24                             // This is a common and simple radio used with MySensors. Downside is that it uses the same frequency space as WiFi.
    #define MY_RADIO_NRF5_ESB                           // This is a new type of device that is arduino and radio all in one. Currently not suitable for beginners yet.
    //#define MY_RADIO_RFM69                            // This is an open source radio on the 433mhz frequency. Great range and built-in encryption, but more expensive and little more difficult to connect.
    //#define MY_RADIO_RFM95                            // This is a LoRaWan radio, which can have a range of 10km.
    
    // MySensors: Choose your desired radio power level. High power can cause issues on cheap Chinese NRF24 radio's.
    //#define MY_RF24_PA_LEVEL RF24_PA_MIN
    //#define MY_RF24_PA_LEVEL RF24_PA_LOW
    //#define MY_RF24_PA_LEVEL RF24_PA_HIGH
    //#define MY_RF24_PA_LEVEL RF24_PA_MAX
    
    // Mysensors security
    //#define MY_ENCRYPTION_SIMPLE_PASSWD "changeme"    // Be aware, the length of the password has an effect on memory use.
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN A7         // Setting a pin to pickup random electromagnetic noise helps make encryption more secure.
    
    // Mysensors advanced settings
    #define MY_TRANSPORT_WAIT_READY_MS 10000            // Try connecting for 10 seconds. Otherwise just continue.
    //#define MY_RF24_CHANNEL 100                       // In EU the default channel 76 overlaps with wifi, so you could try using channel 100. But you will have to set this up on every device, and also on the controller.
    //#define MY_RF24_DATARATE RF24_1MBPS               // Slower datarate makes the network more stable?
    //#define MY_NODE_ID 10                             // Giving a node a manual ID can in rare cases fix connection issues.
    //#define MY_PARENT_NODE_ID 0                       // Fixating the ID of the gatewaynode can in rare cases fix connection issues.
    //#define MY_PARENT_NODE_IS_STATIC                  // Used together with setting the parent node ID. Daking the controller ID static can in rare cases fix connection issues.
    #define MY_SPLASH_SCREEN_DISABLED                   // Saves a little memory.
    //#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE      // Saves a little memory.
    
    // Enable MySensors debug output to the serial monitor, so you can check if the radio is working ok.
    //#define MY_DEBUG 
    
    // MySensors devices form a mesh network by passing along messages for each other. Do you want this node to also be a repeater?
    //#define MY_REPEATER_FEATURE                       // Add or remove the two slashes at the beginning of this line to select if you want this sensor to act as a repeater for other sensors. If this node is on battery power, you probably shouldn't enable this.
    
    // LIBRARIES (in the Arduino IDE go to Sketch -> Include Library -> Manage Libraries to add these if you don't have them installed yet.)
    #include <MySensors.h>                              // MySensors library                  
    #include "Wire.h"
    #include "MMA8653.h"
    
    // accelerometer
    
    MMA8653 accel;
    
    // Mysensors settings
    const byte RF_DELAY = 100;                          // A few milliseconds delay between sending makes the radio happy.
    #define CHILD_ID_ACCEL 0                            // The child ID of the sensor that will be presented to the controller.
    #define CHILD_ID_ACCEL2 1                           // The child ID of the sensor that will be presented to the controller.
    
    MyMessage msgAccel(CHILD_ID_ACCEL, V_LIGHT_LEVEL);  // Sets up the message format that we'l be sending to the MySensors gateway later.
    MyMessage msgAccel2(CHILD_ID_ACCEL2, V_TRIPPED);    // Sets up the message format that we'l be sending to the MySensors gateway later.
    
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(F("motion sensor"), F("1.4"));
      
      // Register all sensors to gateway (they will be created as child devices): 
      present(CHILD_ID_ACCEL, S_LIGHT_LEVEL); sleep(RF_DELAY);
      present(CHILD_ID_ACCEL2, S_MOTION); sleep(RF_DELAY);
    }
    
    
    void setup() {
      Serial.begin(115200);
      while (!Serial) {}
      
      Serial.println(F("I am a movement sensor"));
    
      accel.begin(false, 2);                            // 8-bit mode, 2g range. The library doesn't support more precision.
    
    }
    
    void loop() {
    
      // variables to store the old measurements in
      static float oldX = 0;
      static float oldY = 0;
      static float oldZ = 0;
      static boolean motionDetected = 0;
    
      // Request the latest data from the accelerometer.
      accel.update();
    
      // Calculate the latest measurements.
      float newX = (float)accel.getX() * 0.0156;
      float newY = (float)accel.getY() * 0.0156;
      float newZ = (float)accel.getZ() * 0.0156;
    
      // Calculate the difference in position from the previous measurements.
      float difX = abs(newX - oldX);
      float difY = abs(newY - oldY);
      float difZ = abs(newZ - oldZ); 
    
      // Calculate the total amount of movement on all three axis.
      int changePercentage = (int)((difX + difY + difZ) * 30); // Theoretical maximum = 1+1+1 * 30 = 90%
      Serial.println(changePercentage);
    
      // Store the old values for comparison in the next round.
      oldX = newX;
      oldY = newY;
      oldZ = newZ;
        
    
      // Don't go to sleep for too long if there is movement detected.
      if(changePercentage > 3){                         // Very small movements are ignored.
        Serial.println(F("movement"));
        send(msgAccel.set(changePercentage,0));         // send the data
        if(motionDetected == false){
          motionDetected = true;
          sleep(RF_DELAY);                              // Avoid sending data too quickly one afte the other.
          send(msgAccel2.set(true));
        }
        sleep(10000);                                   // If movement has been detected, send a signal for 10 seconds. This way the controller interface can update to show the movement.
      }else{
        if(motionDetected == true){
          Serial.println(F("movement stopped"));
          motionDetected = false;
          send(msgAccel2.set(false));
          changePercentage = 0;
          send(msgAccel.set(changePercentage,0));
        }
        sleep(2500);
      }
    }
    
    
    /* 
     * This code makes use of the MySensors library:
     * 
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     */
    ```

  • Hardware Contributor

    @alowhum said in BBC Micro:bit and MySensors - a great match!:

    I don't know how an I2C interrupt device can trigger an interupt (to save battery). Is that even possible?

    No it's not, accelerometers (and other sensors that need to generate interrupts) have interrupt pins that you can connect to digital input(s).
    It's on P0.28 (INT 1) and P0.27 (INT 2) for accelerometer (see page 5) :
    https://github.com/bbcmicrobit/hardware/blob/master/SCH_BBC-Microbit_V1.3B.pdf


  • Plugin Developer

    I've spent 2 hours trying to learn about interupts, connecting P0.28 to a norma pin name, etc. It's too complex for me I'm afraid.

    I now have things in my code like:

    #define INT_ASLP 1
    #define INT_FF_MT 1
    //#define INT_DRDY 1
    
    static const uint8_t P0.27 = 46;
    
    // MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0); 
    // MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c); 
     //accel.setPeriod(250);
    
      accel.begin(false, 2);                            // 8-bit mode, 2g range. The library doesn't support more precision.
      accel.initMotion();
    //  
    
    
      //accel.setInterrupt(movement, 27, 1); 
      //pinMode(P0_27, INPUT_PULLUP);
      //pinMode(P0.28, INPUT_PULLUP);
      attachInterrupt(MMA8653FC_INT1, motionInterupt, CHANGE);
      attachInterrupt(47, motionInterupt, CHANGE);
    
    void motionInterupt()
    {
      interupted = true;
      Serial.println("x");
    }
    
    

    I have no idea what I'm doing 🙂

    Can I use the MyBoardNRF5.cpp thing, or does that risk damaging the MicroBit?


  • Hero Member

    @alowhum I'm sure you could use the MyBoardNRF thing to write to it. In doing so whether you lose the bootloader that came with the microbit, I couldn't say. Anyone know? Having a usb/serial bootloader is worth something.


  • Plugin Developer

    The AAA batteries that came with it were empty in a day..


  • Hero Member

    It would be safe if you used the usb/serial bootloader to upload your program made by the MyBoardNRF though. I just meant that it may not be safe if you were to use a programmer and the SWD pins, because then you might (?) lose the bootloader that's on your BBC micro bit.


  • Hardware Contributor

    @alowhum it could be different reasons:

    • the battery was old
    • in MySensors nrf5, if I remember well, sleep function is not optimized yet
    • sensors not in sleep mode
    • others parts of your board are maybe draining current. I've not looked at sch of this board, so I can be wrong.

  • Hero Member

    @alowhum Were you able to get the OTA upload to work?

    I received a BBC Micro:bit today and just now tried it. I successfully paired with it from my android phone. I attempted to upload the MicroPython "Hello World" sketch to it OTA from the phone. Fist it rebooted the MicroBit. Then it uploaded the sketch. According to the microbit app on my phone, the upload was successful. However, the MicroBit was hung, and resetting didn't revive it. No Hello World. 😞

    So, I reinstalled the factory firmware over USB, and I tried it again, with the same result. 😞

    Kinda pathetic. Are you having better luck with it than me?

    I will note that if I upload the micropython "Hello World" sketch over USB, then it does work. However, it appears that the OTA upload feature does not work. I'm frankly surprised. I thought by now the microbit would have had its bugs fixed.

    Hmm... Maybe I need to update the firmware: https://support.microbit.org/support/solutions/articles/19000019131-how-to-upgrade-the-firmware-on-the-micro-bit

    I'll try that. [Edit: Nope. No difference. That "firmware" is really just for managing USB communications.]

    [Well, it doesn't explain the hang, but apparently Micropython disables the bluetooth update capability: https://support.microbit.org/support/solutions/articles/19000026073-how-to-re-instate-bluetooth-after-previously-using-micropython.

    Still, I would have expected it to work for one shot at least. Maybe it only works with Javascript blocks...]

    [Edit: So, it appears Micropython simply won't work OTA with the micro:bit, not even once. Despite ambiguous outward appearances, no support for it is being claimed.

    I did manage to geta Blocks "Hello World" to upload to the Micro:bit, though it required resetting the micro:bit before it would run.

    There apparently is C/C++ support available through mbed, and I get the impression that may offer OTA uploads, though I haven't yet looked into it. ]


  • Plugin Developer

    @neverdie @neverdie I never tried to get OTA to work, no. Glad to see you diving in though!


Log in to reply
 

Suggested Topics

  • 87
  • 7
  • 8
  • 7
  • 5
  • 2

53
Online

11.4k
Users

11.1k
Topics

112.7k
Posts