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.