Simple IoT Server + Client

In this HowTo I will show you how to store a value counter
in memory in a running server, and display the value on a tiny OLED screen.
Table of Contents
Intro
Below are the things you will need to build your own tiny IoT test setup:
- A server. Written in Java using Spring Boot
- An embedded device with a tiny screen. I usualy use the Wemos D1 mini. See my other posts/projects for details.
The boilerplate of the Java code was generated with https://start.spring.io/.
You can find the entire code of this HowTo here: https://github.com/pauls-3d-things/micro-counter.
Once you cloned the repo you can build and run it with
gradle build
java -jar build/lib/micro-counter.jar
The Backend
The backend is a Java application, that comes with an embedded Tomcat Server to host either static content, or usually a REST endpoint (whis is what we want).
All the starting and stopping is done by magic called Spring Boot, in the form of Java annotations (the stuff starting with an @
):
package de.uvwxy.microcounter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // <-- magic
public class MicroCounterApplication {
public static void main(String[] args) {
// activate magic:
SpringApplication.run(MicroCounterApplication.class, args);
}
}
If you don’t want to configure anything else, there is nothing to add to this class.
Now, the next step is to create an endpoint, i.e. a URL that does something, to store/load/manipulate data.
Endpoints are discovered automatically at application startup, by spring-boot, by looking for classes that have the @Controller
annotation.
As a result every such class will be scanned for methods that have a @RequestMapping
annotation.
This makes it really ease to add more functionality to your server without configuring anything (like the good old Application Server times ;)).
In the example below, we create a URL http://localhost:1234/counter
that increments the counter by one and returns the counter value.
package de.uvwxy.microcounter;
// I hate it if tutorials skip this part:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MicroCounterController {
private static long counter = 0;
// more magic:
@RequestMapping(value = "/counter", produces = { "application/json" }, consumes = {"*/*" }, method = RequestMethod.GET)
public ResponseEntity<Long> getCounter() {
// the _actual_ stuff we want to do..
counter++;
// .. wrapped in magic
return new ResponseEntity<>(new Long(counter), HttpStatus.OK);
}
}
If you want to add more endpoints, you need to change the value = "/counter"
part in the @RequestMapping
annotation.
The Client
The client is written in C++ using the Arduino Framework.
The snippet to fetch a value from the server is
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
HTTPClient http;
http.begin("http://:1234/counter/value");
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
Serial.println(payload);
}
http.end();
The snippet to attach a specific 128x32 pixel oled, and print stuff is:
#include <Wire.h>
#include <U8g2lib.h>
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
void setup() {
u8g2.begin();
u8g2.setContrast(0);
}
void loop() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_profont12_tf);
u8g2.drawStr(0, 8, "http://:1234/");
u8g2.drawStr(0, 31, "by @pauls_3d_things");
u8g2.drawStr(0, 20, String("Visits: " + payload).c_str());
u8g2.sendBuffer();
}
Now, to put everything into one application, look here: arduino-micro-counter-client.ino
Don’t forget to replace the SSID/PASS at the top of the file, to connect to your wifi.