Shawn - Fab Academy

13. Networking and communications

Group assignment:

Individual assignment:

Group Assignment

We chose to do Bluetooth communication for our group assignment, and we chose the HC-05 Bluetooth module for the task.

As it turns out, the HC-05 module itself has a serial interface that can be used to communicate with our Arduino boards. For simplicity, we just used Arduino Uno for the task.

Although the Arduino Uno has built-in Serial pins for doing Serial communication, that Serial port is taken for doing communication between itself and the computer. For this, we need to use a library called SoftwareSerial.

As its name suggests, it can take two pins on the Arduino board and make them emulate the same functionality as a Serial port, we can use it to send and receive data from the HC-05/

Another thing worth noting is that the data pin of the HC-05 has a logic level of 3.3v, so we need to put a voltage divider between the receiving side of the module, the Arduino can read 3.3v level as high voltage so the sending side can work without a voltage divider.

After we did the wiring correctly, we uploaded the following code to both of the Arduino boards. The program constantly reads the data sent from the computer and sends it through the Bluetooth module, as well as reads the data receiving from the module and outputs it to the computer.


#include <SoftwareSerial.h>

SoftwareSerial BTSerial(8, 9);   // RX | TX

void setup() {
  pinMode(7, OUTPUT);    /* this pin will pull the HC-05 pin 34 (KEY pin) HIGH to switch module to AT mode */
  digitalWrite(7, HIGH); 
  
  Serial.begin(38400);
  Serial.println("Enter AT Commands:");
  BTSerial.begin(38400);  // HC-05 default speed in AT command mode
}

void loop() {
  delay(1000);
  //BTSerial.write("HIHIHI");

  //The code below allows for commands and messages to be sent from COMPUTER (serial monitor) -> HC-05
  if (Serial.available())           // Keep reading from Arduino Serial Monitor 
    BTSerial.write(Serial.read());  // and send to HC-05

  //The code below allows for commands and messages to be sent from HC-05 -> COMPUTER (serial monitor)    
  if (BTSerial.available())         // Keep reading from HC-05 and send to Arduino 
    Serial.write(BTSerial.read());  // Serial Monitor
}
    

Individual Assignment

As my PCB design is a Xiao expansion board, I started researching what networking capability the Xiao board has, and I found that the XIAO ESP32C3 version has Bluetooth and WiFi capability.

Since we have a couple of these lying around in our workshop, I went on to try to experiment with them.

Installing

Because the esp32 board family is not officially included in the boards that are supported by the Arduino software, I have to install the board definition of the esp32 boards before I can program the Xiao esp32 board with Arduino IDE.

I followed the official guide from Espressif to install Esp32 boards for the Arduino software.

Trying WiFi

Now I can upload programs to the Xiao esp32, first I began studying some example programs that came with the esp32 platform. As I was trying with the SimpleWiFiServer example under the WiFi category, I went into researching how networking works between devices in general. As it turns out, this example uses the IP protocol - which is the shorthand for 'Internet Protocol', to let the board communicate with our computer.

The IP protocol, as stated in its name, is the protocol used to identify different devices throughout the network, making 'the Internet' possible. In the wifi server example, the board can connect to a WiFi network by its SSID and password. After connection, the board gets an IP address from the router, printed in the serial monitor and can be used to identify the board within the network.

According to the comments in the example, I can now control the LED connected to the board by opening the address in the browser.

And when I connected to the board from the browser, the board printed more stuff in the serial monitor.

After some more research, I learned that the browser displays the web page by making requests to the servers on the Internet, and showing the web page that it got back. During the process, they uses the HTTP protocol to exchange messages. And by looking at the code, I now know that the thing printed by the board is the HTTP message it got from the browser.

Communication between boards

After studying more examples, I also found out that the ESP32 board can become a wifi hotspot itself, just like our smartphones. So now I can have other boards connect to it and send messages over the wifi.

I came up with these programs by modifying the examples, one for the receiving board that changes the LED when receiving different messages and the other for connecting to the receiving board and sending messages over a certain period.


/* WiFi receiver
   Code for receiving message over wifi
   adaped from the WiFiAccessPoint example
*/

#include <WiFi.h>

int led = 5;                    // led on pin 5
const char* ssid = "receiver";  // wifi access point name

WiFiServer server(80);  // server for receving messages
WiFiClient client;      // the client that has connected
String message = "";    // message received from the client

void setup() {
  pinMode(led, OUTPUT);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // start an access point that has no password
  if (!WiFi.softAP(ssid)) {
    log_e("Soft AP creation failed.");
    while (1)
      ;
  }
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  server.begin();
  Serial.println("Server started");
}

void loop() {
  WiFiClient c = server.available();  // listen for incoming clients
  if (c) {
    Serial.println("New Client.");
    client = c;  // save the connected client
  }

  if (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.write(c);  // print what the client has send
      if (c == '\n') {
        // message ended
        if (message == "open") {
          // if we got a message says "open", turn on the led
          digitalWrite(led, HIGH);
          Serial.println("command open: LED ON");
        } else if (message == "close") {
          // if we got a message says "close". turn off the led
          digitalWrite(led, LOW);
          Serial.println("command close: LED OFF");
        } else {
          // print the unknown command
          Serial.print("Unknown command: ");
          Serial.println(message);
        }

        message = "";  // clear the message
      } else if (c != '\r') {
        // add the character to the message
        message += c;
      }
    }
  }
}
    

/* WiFi sender
   Code for sending message over wifi
   adaped from the WiFiClient example
*/

#include <WiFi.h>

const char* ssid = "receiver";          // the name of the access point
const char* http_host = "192.168.4.1";  // the ip address of the wifi access point defaults to 192.168.4.1
const int http_port = 80;               // the port of the receiving server
WiFiClient client;                      // the client to send the message

bool is_on = false;  // the LED is on or not

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("******************************************************");
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // connect to the receiving board
  WiFi.begin(ssid);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  if (!client.connected()) {
    // try to connect to the receving board
    if (!client.connect(http_host, http_port)) {
      Serial.println("Failed to connect");
      delay(2000);
      return;
    }
  }

  if (is_on) {
    // send close command if the led is on
    client.print("close\n");
    client.flush();
    is_on = false;
    Serial.println("sent command: close");
    delay(3000);
  } else {
    // send open command if the led is off
    client.print("open\n");
    client.flush();
    is_on = true;
    Serial.println("sent command: open");
    delay(3000);
  }
}
    

As shown in the video and the code, I have one board open a wifi access point and a LED connected, another board connects to the first board and send different commands over a period of 3 seconds. When the first board receives an 'open' command, it turns on the LED, and when receiving a 'close' command, it turns off the LED.