DEV Community

Cover image for Save Data to Kintone with an ESP8266
sean-kintone for Kintone Developer Program

Posted on • Updated on • Originally published at kintone.dev

Save Data to Kintone with an ESP8266

Overview

This article introduces how to save data to a Kintone App using a NodeMCU ESP8266 device.

While the device used in this tutorial is an ESP8266, the concepts apply to most if not all Arduino devices with Wi-Fi capabilities. And similarly, while the Web Database used in this tutorial is Kintone, changing the contents of the HTTP Request allows for any REST API based web database to be used.

Video available as well:

General Flow

The general flow of this tutorial is as follows:

  1. Connect and Test the ESP8266
  2. Create a Kintone App to store data
  3. Write and upload a program or "sketch" to the device that will access Kintone's REST API

Initial Setup

First connect the ESP8266 to your computer via USB cable. Note that the quality of cable matters, and a high quality USB cable should be used, or else the cable will only provide power and will fail to transfer data.

Image description

Download and install the Arduino IDE. After installation, open the IDE to the first sketch.

Image description

Open the settings menu, and in the Additional Boards Manager URLs option, add the following open source ESP8266 repository URL: https://arduino.esp8266.com/stable/package_esp8266com_index.json

Image description

This will allow support for various Arduino and other micro-controller devices based on the ESP8266 chip to be downloaded.

Next, open the library tab on the left side of the IDE, and search for ESP8266. Install the latest version.

Image description

Next, ensure that the ESP8266 is connected via USB cable, and in the top menu, select the ESP8266 model to use. If it is not displayed automatically, click on the Select Other Board and Port menu item.

Image description

Search for ESP8266, and select the model that is being used. In this example, a LoLin board based on NodeMCU is used. This will vary depending on the development board used. Select the port the ESP8266 is connected to.

Image description

Common port names are usbserial, usbmodem, COM3, or other names that end with (USB), but will depend on the operating system, drivers, and firmware of the development environment.

Connecting via a faulty or weak USB cable is the most common reason for failure to connect. Refer to the official Arduino Help Article for more troubleshooting.

After confirming the board is connected, the ESP8266 is ready for development.

Create a Kintone App

Set up the Fields

For this example, a simple App with a single Radio button field will be used.
Create a new App with the following field settings.

Field Type Field Name Field Code Remarks
Radio button Favorite Color color Options: Red, Blue, Green, Yellow

Additional fields will not significantly increase the complexity of this tutorial, and only require the JSON object sent via the ESP8266 be modified accordingly (with some exceptions, such as Attachment fields and Tables.)

Create an API Token

Create an API Token with View records and Add records permissions.
Refer to the Generating API Tokens article on the Kintone Help site for more information on API Tokens.

Information For Later

The following information will be used to test the POST request from the ESP8266.

  1. API Token
  2. Subdomain (for example.kintone.com, the subdomain is example)
  3. App ID

The App ID can be found in the URL of the App.
For example, if the URL of the App is https://example.kintone.com/k/23/, the App ID is 23.

Program a POST request in the ESP8266

The ESP8266 is a popular choice for low-cost IOT, as it has Wi-Fi capabilities, and is able to connect to and broadcast Wi-Fi networks. The code in this example has three main goals:

  1. Connect to a Wi-Fi network, and start a server on the local network.
  2. Create HTML routes and a form
  3. Pass the information from the form to a REST API request to Kintone.

This tutorial can be downloaded from the Kintone Workshop repository.
In this example the user needs only to edit the code regarding Wi-Fi credentials on lines 8 and 9, before compiling and uploading the code to the ESP8266.

Complete Code Example

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>

// Your WIFI information. You must be connected to the same WIFI network to connect via localhost.
const char* ssid = "MY_WIFI_SSID";
const char* password = "MY_WIFI_PASSWORD";
// A JSON Class to handle JSON data.
DynamicJsonDocument doc(1024);
// The ESP8266 server class.
ESP8266WebServer server(80);
// A variable for tracking a valid HTTP response or not.
bool result = false;

// The setup function is special, and runs only once.
void setup() {
  // The BAUD rate for the serial monitor.
  Serial.begin(9600);
  delay(100);
  Serial.println("Connecting to ");
  Serial.println(ssid);

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");
  Serial.println(WiFi.localIP());

  // The HTTP server class let's developers create routes, that run specific functions on access.
  // Here, we designate the root route, the /post route, and a 404 route.
  server.on("/", handle_OnConnect);
  server.on("/post", handlePost);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("HTTP server started");
}

// The loop function. This will run continuously, and let our server class handle incoming requests.
void loop() {
  server.handleClient();
}

// This function runs when users access the root route.
void handle_OnConnect() {
  Serial.println("Welcome. Enter your App ID, API Key, and Subdomain to post some data.");
  // This function sends a 200 on successful connection, and then runs the SendHTML() function.
  server.send(200, "text/html", SendHTML());
}

// This function runs after clicking the Post to Kintone button, and the users accesses the /post route.
void handlePost() {
  // A new HTTP Client.
  WiFiClientSecure client;
  HTTPClient http;
  client.setInsecure();
  Serial.println("Attempting to Save to Kintone...");
  // The variables passed to this route via Form Action. The user's subdomain, appID, API Token, and favorite color.
  String subdomain = server.arg("subdomain");
  String appID = server.arg("appID");
  String token = server.arg("API");
  String color = server.arg("color");
  // The URL for our HTTP Request.
  String URL = "https://" + subdomain + ".kintone.com/k/v1/record.json?app=" + appID;
  Serial.print("info:");
  Serial.println(URL);
  http.begin(client, URL);
  // Formatting the POST Request JSON Object.
  doc["app"] = appID;
  JsonObject recordObject = doc.createNestedObject("record");
  recordObject["color"]["value"] = color;
  String json;
  serializeJson(doc, json);
  // End of JSON formatting. The JSON string is saved to the json variable.

  // Response Code variable for our HTTP request.
  int responseCode = 0;
  // Adding request headers via the http class.
  http.addHeader("X-Cybozu-API-Token", token);
  http.addHeader("Content-type", "application/json");
  // Making the POST request, and saving the result to responseCode
  responseCode = http.POST(json);
  Serial.printf("http Response Code = %d \n", responseCode);
  String payload = http.getString();
  Serial.println(payload);

  // Using an IF statement we can choose which HTML to send for each response code. Details are logged to the serial monitor.
  if (responseCode > 0) {
    Serial.print("HTTP Response code: ");
    Serial.println(responseCode);
    String payload = http.getString();
    Serial.println(payload);
    result = true;
  } else if (responseCode == 400) {
    Serial.print("Error code: ");
    Serial.println(responseCode);
    result = false;
  }
  else {
    Serial.print("Error code: ");
    Serial.println(responseCode);
    result = false;
  }
  // Ending the HTTP request, and passing the result variable to the PostResult function.
  http.end();
  server.send(200, "text/html", PostResult(result));
}

// A function to handle all 404 routes.
void handle_NotFound() {
  server.send(404, "text/plain", "Not found");
}

// A Function which returns an html string. This is the HTML which gets displayed on each route. SendHTML for the root route.
// Note that quotation marks (" ") within HTML must be escaped with a forward slash ( \ ).
String SendHTML() {
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr += "<title>Kintone and IOT!</title>\n";
  ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr += ".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr += "</style>\n";
  ptr += "</head>\n";
  ptr += "<body>\n";
  ptr += "<h1>ESP8266 Web Server</h1>\n";
  ptr += "<p>Enter your subdomain, appID, and API Token!</p>";
  ptr += "<form action=\"/post\">";
  ptr += "<label for=\"subdomain\">Subdomain:</label><input type=\"text\" id=\"subdomain\" name=\"subdomain\" value=\"example\">";
  ptr += "<label for=\"appID\">App ID:</label><input type=\"text\" id=\"appID\" name=\"appID\" value=\"1\"/>";
  ptr += "<label for=\"API\">API Token:</label><input type=\"text\" id=\"API\" name=\"API\" value=\"1J22qNAR54I4eiMcd0JmfDAavJNfNJDVaqt34X9A\"/><br>";
  ptr += "<label for=\"color\">Pick your favorite Color:</label><br>";
  ptr += "<label for=\"red\">Red</label>";
  ptr += "<input type=\"radio\" id=\"red\" name=\"color\" value=\"Red\" checked /><br>";
  ptr += "<label for=\"blue\">Blue</label>";
  ptr += "<input type=\"radio\" id=\"blue\" name=\"color\" value=\"Blue\" /><br>";
  ptr += "<label for=\"green\">Green</label>";
  ptr += "<input type=\"radio\" id=\"green\" name=\"color\" value=\"Green\" /><br>";
  ptr += "<label for=\"yellow\">Yellow</label>";
  ptr += "<input type=\"radio\" id=\"yellow\" name=\"color\" value=\"Yellow\" /><br>";
  ptr += "<input type=\"submit\" value=\"Post to Kintone!\">";
  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}

// This function displays the HTML for the /post route. It takes a boolean variable, which can be used to alter the HTML displayed.
String PostResult(uint8_t result) {
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr += "<title>Kintone and IOT!</title>\n";
  ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr += ".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr += "</style>\n";
  ptr += "</head>\n";
  ptr += "<body>\n";
  ptr += "<h1>ESP8266 Web Server</h1>\n";
  ptr += "<p>Post page</p>";
  if (result) {
    ptr += "<p>Success!</p>";
  } else {
    ptr += "<p>Error Posting Check your JSON, API Token, and field codes!</p>";
  }
  ptr += "<a href='/'> Go Back </a>";
  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}
Enter fullscreen mode Exit fullscreen mode

Compile and Upload the code

After copying and pasting the code example into the Arduino IDE, the validity of the code can be checked via the Verify button.

Image description

Any errors will be output in the output console in the bottom of the editor.

Image description

If the code is technically sound, it can then be uploaded to the ESP8266.
Ensure that the ESP8266 is still connected via USB, and click on the Upload button in the top menu.

Image description

Upload progress and any errors can be confirmed in the output console in the bottom tab of the Arduino IDE.

Image description

Test the Sample Code

Once the code is uploaded, information on how to connect to the ESP8266 will be displayed in the serial monitor.

Displaying the Serial Monitor

The serial monitor is a fundamental concept of micro-controller development. For more information, refer to the Using the Serial Monitor tool article in the Arduino documentation.

In this example, the serial monitor is used in the code via Serial.println() statements. Those familiar with web development will find it similar to the JavaScript console.log() function. The Serial Monitor can be displayed in the bottom on the Arduino IDE.

Image description

Developers may noticed erroneous characters appearing in the Serial Monitor. When starting transmissions, a display of a few garbled characters is common and not a cause for concern. If no characters are displayed in the serial monitor, ensure that the baud rate matches the baud rate specified in the code.

Image description

The IP address on the local network is displayed in the serial monitor.

Ensure that the ESP8266, and the computer that will display the ESP8266 web page are connected to the same Wi-Fi network.

Image description

Accessing the IP Address of the ESP8266 will lead to the root route being executed in code, and displaying the following HTML:

Image description

Enter the data specified in this article's Information For Later section, choose a color, and click on the Post to Kintone! button.
Check the Kintone App to see if a new record has been successfully posted.

Image description

Top comments (0)