Skip to content

13. Networking and Communications

Group assignment:

  • Send a message between two projects

  • Document your work to the group work page and reflect on your individual page what you learned

Individual assignment:

  • design, build and connect wired or wireless node(s) with network or bus addresses and a local interface

Download Design Files

Click here to download my design files folder

Group Work Reflection

This week’s group work was actually very fun! Landon Broadwell and I did some very confusing but cool networking between our individual work’s networking projects. As stated in our group work documentation, “To connect Landon’s ATtiny1614 and its BNO-055 sensor with Alana’s Xiao RP2040-nRF52840, we hooked up the SDA and SCL lines of each sensor and to the BNO-055 sensor and asked GPT 4.0 to modify Alana’s code so that it could read and take a value from Landon’s code.” This whole process described here was so confusing to me but it was also confusing to Landon, meaning we had to figure it out and I learned a whole lot from it!

Link to Group Work Page

Seeed XIAO-nRF52840

With Collin Kanofsky’s wonderful recommendation, I decided to use the Seeed XIAO-nRF52840 to do bluetooth connection and network. Seeed Studio’s Seeed Wiki was absolutely indispensable for my easy success with this week! I highly recommend reading through and following their steps for setting up and networking with the XIAO-nRF52840.

Hardware

I used a Seeed XIAO-nRF52840, my computer, my phone (needs to be able to do bluetooth), and a PCB that I designed.

The XIAO-nRF52940:

Seeed XIAO-nRF52940 pinout (from Seeed Wiki):

From the Seeed Wiki, I got the footprint for the Seeed XIAO-nRF52840 from the download [LBR] Seeed Studio XIAO nRF52840 Eagle footprint.

My board:

  • Collin Kanofsky and I had to make this board jointly because of the limited resources of bluetooth capable XIAO chips.

Software

To set up the software for the XIAO-nRF52840, I connected the XIAO-nRF52840 to my computer and then did the following steps (all of which can primarily be found through the Seeed Wiki).

First, I opened/launched Arduino IDE.

Then, I went to File > Preferences > Additional Boards Manager URLs. From their I entered the url https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json into the Boards Manager, clicked “ok,” and clicked “ok” again. It then popped up that it was installing the board.

Once it finished installing, I went to Tools > Board > Boards Manager and entered “seeed nrf52” into the search box. From there, I installed both “Seeed nRF52 Boards” by Seeed Studio and “Seeed nRF52 mbed-enabled Boards” by Seeed Studio.

Next, I selected my port (this was COM35 for me) and my board (Seeed XIAO nRF53840).

Programming

To ensure everything was working, I first ran an example Blink code. I went to File > Examples > 01.Basics > Blink and clicked to open the code. I then clicked “Upload” and, voila! it worked! The XIAO-nRF52840 LED started blinking red every ~1 seconds.

The Blink Code:

/*
Blink

Turns an LED on for one second, then off for one second, repeatedly.

Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your Arduino
model, check the Technical Specs of your board at:
https://www.arduino.cc/en/Main/Products

modified 8 May 2014
by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
modified 8 Sep 2016
by Colby Newman

This example code is in the public domain.

https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
delay(1000);                      // wait for a second
digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
delay(1000);                      // wait for a second
}

PC Keyboard to my Phone

Again, largely due to the help of Seeed Wiki, I was able to wirelessly connect a PC keyboard to my mobile phone.

I followed the same general setup as detailed earlier, but this time I went to File > Examples > Adafruit Bluefruit nRF52 libraries > Peripheral > blehid_keyboard and clicked to open the code:

/*********************************************************************
This is an example for our nRF52 based Bluefruit LE modules

Pick one up today in the adafruit shop!

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

MIT license, check LICENSE for more information
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/



#include <bluefruit.h>      // includes the Bluefruit library, providing functions and classes to use Adafruit's Bluetooth modules
BLEDis bledis;          // creates an instance of BLE Device Information service
BLEHidAdafruit blehid;          // creates an instance of the BLE HID (Human Interface Device) service

bool hasKeyPressed = false;         // a boolean flag to track if a key has been pressed

void setup()  
{

Serial.begin(115200);           // Initializes serial communication at 115200 baud rate  
while ( !Serial ) delay(10);            // waits for the serial communication to be established; for nrf52840 with native usb

// multiple "Serial.println"  statements print messages to the serial monitor to guide the user

Serial.println("Bluefruit52 HID Keyboard Example");
Serial.println("--------------------------------\n");

Serial.println();           
Serial.println("Go to your phone's Bluetooth settings to pair your device");
Serial.println("then open an application that accepts keyboard input");

Serial.println();
Serial.println("Enter the character(s) to send:");
Serial.println();

Bluefruit.begin();          // Initializes the Bluefruit module
Bluefruit.setTxPower(4);    // Sets the transmission power of the Bluefruit module; Check bluefruit.h for supported values

// Configure and Start Device Information Service
bledis.setManufacturer("Adafruit Industries");
bledis.setModel("Bluefruit Feather 52");
bledis.begin();

/* Start BLE HID
* Note: Apple requires BLE device must have min connection interval >= 20m
* ( The smaller the connection interval the faster we could send data).
* However for HID and MIDI device, Apple could accept min connection interval 
* up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
* connection interval to 11.25  ms and 15 ms respectively for best performance.
*/
blehid.begin();

// Set callback for set LED from central
blehid.setKeyboardLedCallback(set_keyboard_led);

/* Set connection interval (min, max) to your perferred value.
* Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
* min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms 
*/
/* Bluefruit.Periph.setConnInterval(9, 12); */

// Set up and start advertising
startAdv();
}




void startAdv(void)
{  
// Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD);


Bluefruit.Advertising.addService(blehid);               // Include BLE HID service

Bluefruit.Advertising.addName();            // adds the device name to the advertising packet

/* Start Advertising
* - Enable auto advertising if disconnected
* - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
* - Timeout for fast mode is 30 seconds
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
* 
* For recommended advertising interval
* https://developer.apple.com/library/content/qa/qa1931/_index.html   
*/
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds
}

void loop() 
{
// Only send KeyRelease if previously pressed to avoid sending
// multiple keyRelease reports (that consume memory and bandwidth)
if ( hasKeyPressed )
{
    hasKeyPressed = false;
    blehid.keyRelease();

    // Delay a bit after a report
    delay(5);
}

if (Serial.available())
{
    char ch = (char) Serial.read();

    // echo
    Serial.write(ch);

    blehid.keyPress(ch);
    hasKeyPressed = true;

    // Delay a bit after a report
    delay(5);
}
}

/**
* Callback invoked when received Set LED from central.
* Must be set previously with setKeyboardLedCallback()
*
* The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
*    Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
*/
void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap)
{
(void) conn_handle;

// light up Red Led if any bits is set
if ( led_bitmap )
{
    ledOn( LED_RED );
}
else
{
    ledOff( LED_RED );
}
}
  • Note: According to IDBLUE, “Human Interface Device Profile (HID) – The IDBLUE device is configured using the Bluetooth HID driver as an input device that can only send specific tag information of the first successful tag scanned as text output when the Action Button is pressed.”

Next, I clicked “upload” and opened the serial monitor (found in the upper right corner of the Arduino IDE).

I then downloaded the LightBlue app on my phone (the nRF Connect for Mobile app also works).

Notes on the LightBlue app:

Key features:

  • Scan and discover Bluetooth peripherals in the vicinity

  • See basic device info (UUID, RSSI)

  • Browse services and characteristics

  • Register for notifications and indications

  • Send data from notifications and indications to AWS loT or Adafruit 10 via our Cloud Connect feature

  • Read values from characteristics

  • Write to characteristics in Hex, Oct, Bin, Decimal or ASCII

  • Clone peripheral profiles

  • Choose from an array of common, preconfigured peripheral profiles

  • Advertise as a peripheral using custom profiles

  • Thoroughly log and share BLE events

  • Custom UI and extended support for connecting to Microchip AVR-BLE and PIC-BLE development boards

Notes on the nRF Connect for Mobile app:

Key Features:

  • Supports DFU on all Nordic Semiconductor-powered devices.

  • Supports Nordic Thingy™ from Nordic Semiconductor.

  • Scan and discover nearby Bluetooth LE peripherals.

  • Filter Scanned Peripherals by Name, Manufacturer, Services (Advertised & Connected) and RSSI Level.

  • Parsing Multiple Formats of Bluetooth LE Advertisement Data.

  • Live RSSI Chart of Scanned Bluetooth LE Peripherals.

  • Complete iPad Support, including Multi-Tasking and Mouse Support as of 13.4.

  • Logs: Including BLE Function calls, and Export Function as CV and Text.

  • Privacy-Oriented: Full-Disclosure of Scanned Data, Advertised Data, and User-Performed Actions held by nRF Connect.

  • Connecting to Any Connectable Bluetooth LE Smart Device.

  • Discovery of Services, Characteristics and Descriptors.

  • Read and Write Characteristics and Descriptors.

  • Enable and Disable Notifications and Indications.

  • Advertising as a Bluetooth LE Peripheral.

  • Setting up a Bluetooth LE (Peripheral) Server and Notifying/Indicating back to connected Central(s).

  • Low-Fat: RF Connect for iOS is Very Small, so You Can Always Keep Us With You!

I opened the app and then looked for the device called “XIAO nRF52840” and clicked it. It then connected to my phone and I was able to communicate between the PC keyboard and my phone wirelessly.

In the video below you can see me type “open” into the serial monitor and press “enter.” When I do this, my phone turns on and opens to the lock screen!

the letters “open” + pressing the “enter” button specifically open/turn on my phone. If I wanted to unlock it, I would have to click the space bar and enter the numbers/letters corresponding to my password. Additionally, if I open a notes document, text message, or any other writing space on my phone I can type just like I could with my phone keyboard using the PC keyboard.

For Fun: Shutter images

I saw that Collin had made it so the Seeed XIAO-nRF52840 would record video of him. I thought it would be fun to try out so I uploaded his code to the XIAO-nRF52840 and, although it didn’t work perfectly, it was still super cool to see it work! (It kinda freaked me out though so I stopped here… felt a bit too ‘watched’ 🫣)

/*********************************************************************
This is an example for our nRF52 based Bluefruit LE modules

Pick one up today in the adafruit shop!

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

MIT license, check LICENSE for more information
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/

/*
* This sketch uses the HID Consumer Key API to send the Volume Down
* key when pinShutter is grounded. This will cause your mobile device
* to capture a photo when you are in the camera app.
*/

#include <bluefruit.h>

BLEDis bledis;

BLEHidAdafruit blehid;

// Use on-board button if available, else use A0 pin

#ifdef PIN_BUTTON1

uint8_t pinShutter = PIN_BUTTON1;

#else

uint8_t pinShutter = A0;

#endif


// Circuit Play Bluefruit has button active state = high

#ifdef ARDUINO_NRF52840_CIRCUITPLAY

#define BTN_ACTIVE HIGH

#else

#define BTN_ACTIVE LOW

#endif

void setup()

{

pinMode(pinShutter, INPUT_PULLUP);

Serial.begin(115200);

#if CFG_DEBUG       // Blocking wait for connection when debug mode is enabled via IDE

while ( !Serial ) delay(10);   // for nrf52840 with native usb

#endif

Serial.println("Bluefruit52 HID Camera Shutter Example");

Serial.println("--------------------------------------\n");

Serial.println();

Serial.println("Go to your phone's Bluetooth settings to pair your device");

Serial.println("then open the camera application");

Serial.println();

Serial.printf("Set pin %d to GND to capture a photo\n", pinShutter);

Serial.println();

Bluefruit.begin();

Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values


bledis.setManufacturer("Adafruit Industries");     // Configure and start DIS (Device Information Service)

bledis.setModel("Bluefruit Feather 52");

bledis.begin();

/* Start BLE HID
* Note: Apple requires BLE devices to have a min connection interval >= 20m
* (The smaller the connection interval the faster we can send data).
* However, for HID and MIDI device Apple will accept a min connection
* interval as low as 11.25 ms. Therefore BLEHidAdafruit::begin() will try to
* set the min and max connection interval to 11.25 ms and 15 ms respectively
* for the best performance.
*/

blehid.begin();

/* Set connection interval (min, max) to your perferred value.
* Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
* min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
*/
/* Bluefruit.Periph.setConnInterval(9, 12); */

startAdv();     // Set up and start advertising

}

void startAdv(void)

{

Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);     // Advertising packet

Bluefruit.Advertising.addTxPower();

Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD);

// Include BLE HID service
Bluefruit.Advertising.addService(blehid);


Bluefruit.Advertising.addName();    // There is enough room for the dev name in the advertising packet

/* Start Advertising
* - Enable auto advertising if disconnected
* - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
* - Timeout for fast mode is 30 seconds
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
* 
* For recommended advertising interval
* https://developer.apple.com/library/content/qa/qa1931/_index.html   
*/

Bluefruit.Advertising.restartOnDisconnect(true);

Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms

Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode

Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds

}

void loop()

{

if ( digitalRead(pinShutter) != BTN_ACTIVE ) return;        // Skip if shutter pin is not Ground


for (uint16_t conn_hdl=0; conn_hdl < BLE_MAX_CONNECTION; conn_hdl++)   // Make sure we are connected and bonded/paired

{
    BLEConnection* connection = Bluefruit.Connection(conn_hdl);

    if ( connection && connection->connected() && connection->secured() )

    {

    digitalWrite(LED_RED, 1);        // Turn on red LED when we start sending data

    blehid.consumerKeyPress(conn_hdl, HID_USAGE_CONSUMER_VOLUME_DECREMENT);        // Send the 'volume down' key press to the peer

    delay(10);        // Delay a bit between reports

    blehid.consumerKeyRelease(conn_hdl);`     // Send key release`

    delay(10000); // RECORDING FOR 10 SECONDS

    blehid.consumerKeyPress(conn_hdl, HID_USAGE_CONSUMER_VOLUME_DECREMENT);

    delay(10);     // Delay a bit between reports

    blehid.consumerKeyRelease(conn_hdl);     // Send key release

    digitalWrite(LED_RED, 0);        // Turn off the red LED

    }

}

delay(250);     // Delay to avoid constant capturing

}

  • Note: I did not change any of these codes. The only thing I did change was the length of the recording delay(10000); // RECORDING FOR 10 SECONDS in the shutter code as I was trying to get the code to actually take a video instead of shuttering images. I decided not to spend too much time trying to get a longer video, though, as I had done enough for the week and was on a time crunch to finish Fab Academy and all of my school work.

Reflection

From this week I really learned the value in not only relying on and taking the advice of your instructors, but also your classmates. Collin’s advice helped me so much in this week whereas I was struggling with the networking suggestions of my instructors. I think this helped remind me to take everything with a grain of salt; everyone’s different and everything varies in difficult/ease for people. It’s all about perspective 🫶

References

https://wiki.seeedstudio.com/XIAO_BLE/

https://fabacademy.org/2024/labs/charlotte/students/collin-kanofsky/Week%2013/

http://fabacademy.org/2020/labs/leon/students/adrian-torres/week14.html#hello_serial_bus


Last update: September 6, 2024