The Internet of Things (IoT) generally refers to devices capable of collecting data and communicating that data to servers and other devices over the Internet without human intervention. Every “thing” does something unique, like sensing the temperature of the environment, or monitoring the foods you take out of your fridge. IoT devices perform limited functions; therefore, they require far fewer resources as compared to regular computers like phones and laptops. They are implemented with microcontrollers which are extremely small computers that have limited computing resources (in order to reduce price and power consumption). Microcontrollers also have peripherals that allow them to interact with the physical world through sensors (e.g. temperature sensors) and actuators (e.g. motors).
This post focuses on implementing IoT with the Arduino microcontroller because it is a popular platform with an active community and tons of resources. Of course IoT devices must be able to connect to the Internet, and this post will show how to do that with an ESP8266 Wi-Fi module.
List of Items
- Arduino Uno
- Breadboard
- ESP8266 Wi-Fi module
- Jumper wires
Getting Sensor Data
In this post, we will be implementing a mini weather station that measures the temperature of a room and sends that to a server. We can measure temperature with an Arduino using the LM35 temperature sensor. To use it, connect the ground pin to ground the VCC pin to 5V on the Arduino, the ground pin to ground, and the output pin to analog pin 0.
Copy and paste the following code into your Arduino IDE and upload it onto your board.
/* Program to get data from lm35 temperature sensor on analog pin * by: Stephan Ofosuhene */ int tempSensor = A0; void setup() { // open serial port Serial.begin(9600); } void loop() { // print sensor readings to the serial output Serial.println(get_temp(tempSensor)); analogReference(INTERNAL); } float get_temp(int sensorPin){ float temp = analogRead(sensorPin); temp = (temp*5000.0)/1024; return temp; }
You should now be able to see the temperature readings from the LM35 in your serial monitor. Note that the Arduino reads analog input from 0V to 5V in 1024 quantized levels. The formula for converting the analog readings to temperature in degrees Celsius can be found in the get_temp function.
Sending Sensor Data over the Internet
The next step is to upload the following code onto the Wi-Fi module using the instructions in this post
// Relays sensor readings from arduino to an IoT server // by: Stephan Ofosuhene // ======= flush the serial before sending data to remove old data ============== #includeconst char* ssid = "Mans not hot"; const char* password = "spacebar"; const char* host = " "; String temperature; void setup() { Serial.begin(9600); delay(100); // We start by connecting to a WiFi network Serial.println(); Serial.println(); Serial.print("esp -> Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.println("esp -> "); Serial.println("esp -> WiFi connected"); Serial.println("esp -> IP address: "); Serial.println(WiFi.localIP()); Serial.println("ready"); } void loop() { WiFiClient client; const int httpPort = 8000; if (!client.connect(host, httpPort)) { Serial.println("esp -> connection failed"); return; } String url = "/data"; // read the data from serial for (int i = 0; i < 4; i++){ read_serial_data(); } clear_serial_line(); String data = "temperature=" + temperature; Serial.print("esp -> Requesting POST: "); // Send request to the server: client.println("POST " + url + " HTTP/1.1"); client.println("Host: " + String(host)); client.println("Accept: */*"); client.println("Content-Type: application/x-www-form-urlencoded"); client.print("Content-Length: "); client.println(data.length()); client.println(); client.print(data); delay(500); // Can be changed if (client.connected()) { client.stop(); // DISCONNECT FROM THE SERVER } Serial.println("esp -> "); Serial.println("esp -> closing connection"); delay(5000); } void read_serial_data(){ String var = Serial.readStringUntil('='); String value = Serial.readStringUntil('\t'); if (var == "TEMP"){ temperature = value; } } void clear_serial_line(){ // clear remnant of current data line Serial.readStringUntil('\n'); }
The code allows the module to connect to an existing Wi-Fi network and relay data received from the Arduino over serial communication to a server on the Internet or a local network.
Next, upload the following code onto the Arduino board to enable communication between the Wi-Fi module and the Arduino.
/* Wifi enabled temperature monitor * by: Stephan Ofosuhene */ #includeSoftwareSerial espSerial(10, 9); // RX, TX // Sensor pins int temp_sensor = A0; // Sensor values float temperature = 0; // lm35 temperature readings // serial data String esp_output; //============================================================== void setup() { // Start the serial port Serial.begin(115200); espSerial.begin(9600); } void loop() { // Check sensor readings every second if (millis()%1000 == 0){ temperature = get_temp(temp_sensor); esp_output = espSerial.readStringUntil('\n'); // print debugging output debugging_output(); // send data to the wifi module to be relayed to the internet send_data(); // print output from wifi module Serial.println(esp_output); } } //============================================================== void debugging_output(){ Serial.print("TEMP="); Serial.print(temperature); Serial.print('\t'); } void send_data(){ // send data to the cloud espSerial.print("TEMP="); espSerial.print(temperature); espSerial.print('\t'); } float get_temp(int sensorPin){ float temp = analogRead(sensorPin); temp = (temp*5000.0)/1024; return temp; }
Finally, connect the Wi-Fi module to the Arduino (as shown below) to establish serial communication through software serial. Software serial allows us to use PWM on the Arduino pins as serial pins. Next, connect the Wi-Fi module (as shown in the diagram below) and paste the code above into your Arduino IDE.
After performing these steps, we can now see the new IoT device in action. You can set up a server on the same network as my IoT device so I can see the readings being received.