IoT Devices or Things

A microcontroller is a SoC that provides data processing and storage capabilities. Microcontrollers contain a processor core (or cores), memory (RAM), and erasable programmable read-only memory (EPROM) for storing the custom programs that run on the microcontroller. Microcontroller development boards are PCBs with additional circuitry to support the microcontroller to make it more convenient to prototype with and program the chip.

Sensors and actuators connect to the microcontroller through digital or analog General Purpose Input/Output (GPIO) pins or through a hardware bus. Standard communication protocols like I2C and SPI are used for intra-device communication with the components that are connected with the bus. Adopting standards makes it easier to add or swap out components that are connected with the bus.

Arduino development board

Arduino is an open source device platform, with an active community who are creating compatible development boards and tooling. Device capabilities vary across the official Arduino models, and also between the dozens of third-party compatible boards. All of the devices in are Arduino-compatible microcontrollers, including Arduino Uno, which includes an integrated cellular modem, and Espressif Systems’ ESP8266.

ESP8266-microcontroller family and ESP32 family like ESP32 WROOM, Arduino 33 IoT Board and Arduino MKR WiFi 1010 board include integrated wifi and Bluetooth modules.

All Arduino family development boards have an active community of adopters. Notable development boards that are based around the ESP8266, include NodeMCU, WeMos D1, and AdaFruit’s Feather Huzzah. A number of alternative firmware options for ESP8266-based boards have been developed by the open source and maker community, enabling IoT developers to program for these boards using Lua, Python, and JavaScript, and to support over-the-air (OTA) updates.

The standard approach for developing the software to run on Arduino-compatible microcontrollers is to use C or C++ and the Arduino IDE. Arduino-compatible boards that share common pin layouts are able to be expanded by using optional third-party shields, for example, to add an Ethernet port or Bluetooth to an Arduino Uno. Arduino is the most widely adopted hobbyist microcontroller development environment. Python is supported for boards like MicroPython’s PyBoard and by WeIO.

Selecting an Arduino-compatible microcontroller makes it easier to port programs that are developed using the cross-platform Arduino libraries and Arduino IDE to run on other Arduino-compatible devices. Working through and around subtle difference is still required.

For example, the Arduino Uno uses 5V logic on digital I/O pins (where 0 volts equals LOW or OFF and 5 volts equals HIGH or ON), but the ESP8266 boards use 3.3V logic (HIGH is 3.3V). This might affect your choice of sensor or actuator components, as some components only work with one or the other.

Swapping sensors that are designed for 5V to 3.3V logic might result in unpredictable results and possibly damage the pins that are intolerant to higher voltages, and so you’d need to add a logic-level converter to make this work. When you get down to implementing low-level hardware features like enabling deep sleep mode or reading from connected sensors by using specific protocols, you’ll likely need to rely on device or component-specific libraries that will make your code less portable.

Arduino ESP32 coding example

In this section we will check how to get the MAC address of the WiFi station interface of the ESP32, using the Arduino core, how to connect MySQL server and how to insert data to a database.

To be able to make code you need to learn some C and C++ programming languages. There is plenty of reference material and code examples for these on the internet.

Get WiFi station interface MAC address

Although we don’t need to connect the ESP32 to a WiFi network before we get the MAC address, we will need to initialize the WiFi interface first. We will do this by explicitly setting the WiFi mode, which will initialize the interface under the hood.

The code

The code will be very simple. We will start by including the WiFi.h library, so we have access to the WiFi extern variable, which exposes the method we need to obtain the MAC address of the station interface.

#include "WiFi.h"

Next we will declare two global variables to hold our WiFi network credentials, more precisely the network name (SSID) and the password. This way, we can easily access and modify these variables. Note that you need to change the values to the ones that apply to your network.

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

Now we will move on to the Arduino setup function, where we will run all the remaining code. Since this is more of a network configuration tutorial, we will not have to use the main loop.

Moving on to the setup function, we will start by initializing the serial interface, so we can later output the obtained MAC address.

Serial.begin(115200);

Then we need to call the mode method on our WiFi variable. This method receives as input a value of the enum type wifi_mode_t and sets the WiFi mode of the ESP32. In our case, since we want the ESP32 station interface MAC, we will pass as input the value WIFI_MODE_STA. Note that, if we analyze the implementation of the mode method, we can confirm that it will initialize the WiFi interface in case it hasn’t been done yet. So, the esp_wifi_init will be called under the hood to perform this initialization.

WiFi.mode(WIFI_MODE_STA);

Finally, to obtain the MAC address of the station interface, we simply need to call the macAddress() method of the WiFi variable. This method takes no arguments and returns the MAC as a string.

It’s important to take in consideration that, in its implementation, the macAddress() method calls the esp_wifi_get_mac() function. As can be seen if it is called without a previous call to the esp_wifi_init() function, then it will return an error.

This is why, as already mentioned, we need to call the mode method before we try to get the MAC, so the WiFi interface is previously initialized.

Otherwise, we would obtain an empty string.

Serial.println(WiFi.macAddress());

The final code can be seen below.

#include "WiFi.h"

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPassword"


void scanNetworks() {

  int numberOfNetworks = WiFi.scanNetworks();

  Serial.print("Number of networks found: ");
  Serial.println(numberOfNetworks);

  for (int i = 0; i < numberOfNetworks; i++) {

    Serial.print("Network name: ");
    Serial.println(WiFi.SSID(i));

    Serial.print("Signal strength: ");
    Serial.println(WiFi.RSSI(i));

    Serial.print("MAC address: ");
    Serial.println(WiFi.BSSIDstr(i));

  }
}

void connectToNetwork() {
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Establishing connection to WiFi..");
  }

  Serial.println("Connected to network");

}


void setup(){
  Serial.begin(115200);

  WiFi.mode(WIFI_MODE_STA);
  scanNetworks();
  connectToNetwork();

  Serial.println(WiFi.macAddress());
  Serial.println(WiFi.localIP());

  WiFi.disconnect(true);

}

void loop(){}

MAC Address

A MAC address is given to a network adapter when it is manufactured. It is hardwired or hard-coded onto your computer's network interface card (NIC) and is unique to it. Something called the ARP (Address Resolution Protocol) translates an IP address into a MAC address. The ARP is like a passport that takes data from an IP address through an actual piece of computer hardware.

Once again, that's hardware and software working together, IP addresses and MAC addresses working together.

Read more about MAC Address here: (https://whatismyipaddress.com/mac-address)

WiFi

More functions that we use can be found here: (https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/network/esp_wifi.html#_CPPv216esp_wifi_get_mac16wifi_interface_tA6_7uint8_t).

ESP32 Libraries

arduino-esp32 includes libraries for Arduino compatibility along with some object wrappers around hardware specific devices. Examples are included in the examples folder under each library folder. https://github.com/espressif/arduino-esp32/tree/master/libraries

MySQL Connector

Using MySQL_Connector class, you can connect your Arduino project directly to a MySQL server without using an intermediate computer or a web- or cloud-based service. Having direct access to a database server means you can store data acquired from your project as well as check values stored in tables on the server.

Example code below demonstrates how to connect to a MySQL server from an Arduino using an Arduino-compatible Wifi shield.

INSTRUCTIONS FOR USE

  1. Change the address of the server to the IP address of the MySQL server
  2. Change the user and password to a valid MySQL user and password
  3. Change the SSID and pass to match your WiFi network
  4. Connect a USB cable to your Arduino
  5. Select the correct board and port (Esp32 dev Module)
  6. Compile and upload the sketch to your Arduino
  7. Once uploaded, open Serial Monitor (use 115200 speed) and observe

If you do not see messages indicating you have a connection, refer to the manual for troubleshooting tips. The most common issues are the server is not accessible from the network or the user name and password is incorrect.

//#include <ESP8266WiFi.h> // Use this library instead of WiFi.h when development board is ESP8266 model type.
#include <WiFi.h>
//If there are problems connecting to network change using WiFi.h
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
//#include <Dns.h>

IPAddress server_addr(xxx,xxx,xxx,xxx);  // IP of the MySQL *server* here
//IPAddress server_addr(xx,xx,xx,xx);  // the internal network IP of the MySQL *server* here - it means that all devices are same internal network ip address space
//char hostname [] = "dns.server.xxx"; //use this when using dns server
char user[] = "SomeStudent";              // MySQL user login username
char password[] = "superSecretPassword";        // MySQL user login password

// Sample query
//char INSERT_SQL[] = "INSERT INTO SomeStudent.sensors (temperature) VALUES (12)";

char INSERT_DATA[] = "INSERT INTO SomeStudent.sensors (room, sensor_num, value) VALUES ('%s',%d,'%s')";
char query[128];
char temperature[10];

// WiFi card example
char ssid[] = "yourhomessid";
char pass[] =  "yourhomenetworkpassword";
//char ssid[] = "SuperSecretSSID";         // Wlan SSID
//char pass[] = "verySuperSecretPassword;     //  Password

WiFiClient client;                 // Use this for WiFi instead of EthernetClient
MySQL_Connection conn(&client);
MySQL_Cursor* cursor;

//IPAddress server_ip;
//DNSClient dns;

void setup()
{
  Serial.begin(115200);
  while (!Serial); // wait for serial port to connect.

  // Begin WiFi section
  Serial.print("\nConnecting to %s", ssid);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // print out info about the connection:

  Serial.println("\nConnected to network");
  Serial.print("My IP address is: ");
  Serial.println(WiFi.localIP());

  Serial.print("Connecting to SQL...  ");
  if (conn.connect(server_addr, 3306, user, password)) //Port number 3306 is default port where SQL server listen to the incomming connections.

    Serial.println("OK.");
  else
    Serial.println("FAILED.");
  // Initiate the query class instance
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  // Save
  dtostrf(50.125, 1, 1, temperature);
  sprintf(query, INSERT_DATA, "kitchen", 24, temperature);
  // Execute the query
  cur_mem->execute(query);
  // Note: since there are no results, we do not need to read any data
  // Deleting the cursor also frees up memory used
  delete cur_mem;

  // create MySQL cursor object
  cursor = new MySQL_Cursor(&conn);
}

void loop()
{
 // data is to read every 5 second
  delay(5000);
}

Complex Insert

The most frequent use of the connector is recording data collected by the Arduino. This could be a sensor such as temperature, button pressed, etc.

Notice we have three variables here. The first, a message, is just a string (room). The second is the sensor number. The last is a floating-point number. While we use a %s to signify a string and a %d to signify the integer for substitution, we have another string %s for the floating-point value. This is because the Arduino library does not support converting floating-point numbers in sprintf() function. Thus, we must use the dtostrf() method as illustrated in the code snippet below.

char INSERT_DATA[] = "INSERT INTO SomeStudent.sensors (room, sensor_num, value) VALUES ('%s',%d,%s)";

Here we are converting the floating point value 50.125 to a string and storing it a variable named temperature, which we later use in the sprintf() call along with our message we pass to the char INSERT_DATA[] = "INSERT INTO SomeStudent.sensors (room, sensor_num, value) VALUES ('%s',%d,'%s')"; clause.

// Initiate the query class instance
MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
// Save
dtostrf(50.125, 1, 1, temperature);
sprintf(query, INSERT_DATA, "kitchen", 24, temperature);
// Execute the query
cur_mem->execute(query);

For more information and zip-file for Arduino library - https://github.com/ChuckBell/MySQL_Connector_Arduino

Arduino TinkerCad

Tinkercad is a free online collection of software tools that help people all over the world think, create and make and demonstrate circuit and code.

Here you can found several Youtube videos how to use Tinkercad:

Video 1: https://youtu.be/3kDMYomFw5o

Video 2. https://youtu.be/m0Np5J6MMl0

Video 3. https://youtu.be/7Zs6fsMg9K8

Video 4. https://youtu.be/sjFsRCiA92k

Raspberry Pi Single board computers

Single board computers (SBCs) are a step up from microcontrollers. They allow you to attach peripheral devices like keyboards, mice, and screens, as well as offering more memory and processing power (for example, a 1.2 GHz 32-bit ARM microprocessor compared to an 16 MHz 8-bit AVR microcontroller).

Table 2 lists technical specifications for three SBCs, the Raspberry Pi 4, BeagleBone Black and DragonBoard 410c.

As with microcontrollers, SBC device capabilities can be expanded through the addition of stackable expansion boards known as hats on Raspberry Pi and capes on BeagleBone Black, and through the addition of external modules, such as motor controllers or analog-to-digital converters, to mitigate limitations with the built-in device capabilities.

Many SBC devices are more like a mini-PC, and run an embedded operating system, typically a streamlined Linux distribution. As a result, there are many more development tools and language choices that are available for developing embedded applications that work with the attached sensors and actuators on these devices than on microcontroller boards. However, SBCs are more complex to set up, larger, more power hungry, and more prone to problems like corruption of the SD card or flash memory where applications are stored.

The attached "know_raspberrypi" pdf document contains all the essentials that should be mastered when using the Raspberry Pi in application development.

know_raspberrypi

Fully updated for Raspberry Pi 4 and latest software, including Scratch 3, this 252-page official Raspberry Pi book found here: https://magpi.raspberrypi.org/books/beginners-guide-3rd-ed