Skip to content

Embedded device

System Requirements

This is what my system requirements look like:

Requirement ID# Requirement MoSCoW Compliant
EMBRQ#01 Embedded device sends measured sensordata to the application backend over http or https. MUST YES
EMBRQ#02 Embedded device receives or retrieves status messages from the application backend over http or https. MUST YES
EMBRQ#03 The embedded device contains at least two input sensors (e.g. LDR, buttons, joystick, capacitive touch, etc.). MUST YES
EMBRQ#04 The embedded device contains at least two visual and/or sensory outputs (e.g. LED, LED Matrix, 7-segement display, motor, servo, actuator,LCD-screen, etc.). MUST YES
EMBRQ#05 The embedded device uses the wifi manager for configuration of SSID, User ID (UID) en Password (PWD) for connecting to the network. MUST YES

EMBRQ#01

My embedded device sends the measured data to the backend of the application via http. I can then see the results of the numbers on my frontend web page. It sends it to dice type 6 and dice type 9. Dice type “D06” will only generate numbers from 1 to 6. And dice type “D09” will generate numbers from 0 to 9.

  WiFiClient client;                               // Get current wifi connection
  HTTPClient httpClient;                           // Client HTTP request
  DynamicJsonDocument jsonBuffer(JSON_NUMBER);
  jsonBuffer["JSON_NUMBER"] = currentNumber;

    if (currentNumber > 6 ) {
      jsonBuffer["dice_type"] = "DICE_TYPE_6";
    } else {
      jsonBuffer["dice_type"] = "DICE_TYPE_9";
    }


  String jsonString;
  serializeJson(jsonBuffer, jsonString);
  Serial.println(jsonString);

  httpClient.begin(client, URL);
  httpClient.addHeader(CONTENT_TYPE, APPLICATION_JSON);


  int httpResponseCode = httpClient.POST(jsonString);  // Send post request

EMBRQ#02

My device is able to read if message has been successfully received or not and writes a reply.

if (httpResponseCode == HTTP_CODE_OK) {
    String response = httpClient.getString();
    Serial.println(response);

    // Parse the JSON response and retrieve the "message" field
    DynamicJsonDocument jsonResult(JSON_NUMBER);
    deserializeJson(jsonResult, response);
    String message = jsonResult["message"];
    Serial.println("Response message: " + message);
  } else {
    Serial.println("Failed to retrieve message from API.");
  }

EMBRQ#03

Two Input Buttons. One button (push_button_1) generates numbers from 1 to 6. And the other button (push_button_2) generates numbers from 0 to 9. And I also have a IR Remote controller with IR Receiver as input.

Code reading buttons:

void loop()
  int push_button_1 = digitalRead(lowButton);
  int push_button_2 = digitalRead(highButton);
  // If either push button is pressed, generate a new random number and display the corresponding LED pattern
  if (push_button_1 == LOW) {
    random_int = random(1, 7); // Generate a random number between 1 and 6
// Wait for 2 seconds before allowing another roll
    sendNumb(random_int);
    displayLED(random_int);
  }

  if (push_button_2 == LOW)
  {
    random_int = random(1, 10); // Generate a random number between 1 and 9
    sendNumb(random_int);
    displayLED(random_int);
  }

Code reading IR Receiver:

IRrecv receiver(irPin);

decode_results results;

void setup()
  Serial.begin(SERIAL_RECEIVER);
  irrecv.enableIRIn(); // Start the receiver

  void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(DELAY);
}

EMBRQ#04

Only one 7 segment display, displaying the random number. I use the buzzer as another output.

Code reading Buzzer:

void buzzerSound(){
  tone(buzzer, TONEBUZER); // Send 1KHz sound signal...
  delay(BUZERDELAY);        // ...for 1 sec
  noTone(buzzer);     // Stop sound...
}

Code reading 7 segment display number zero:

switch (num)
    case 0:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(E, HIGH);
      digitalWrite(F, HIGH);
      break;

EMBRQ#05

The embedded device is used by the wifi manager to authenticate and connect to the network via http. That’s why I use the Wemos D1 mini with my Arduino Uno.

WiFiManager wm;
bool res;
res = wm.autoConnect("GeacubeAP", "password"); //password protected ap

Program Code

Below is the code for my Wemos D1 mini and Arduino. ⬇️

Wemos D1 mini code

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <WiFiManager.h>
#include <ArduinoJson.h>
#define BAUD 115200
#define DELAY 1000
#define CONTENT_TYPE "Content-Type"
#define APPLICATION_JSON "application/json"
#define DICE_TYPE_6 "D06"
#define DICE_TYPE_9 "D09"
#define RESPONSE "response"
#define JSON_NUMBER "1024"
#define CONNECTED "connected"
#define ZERO 0
#define NUMBER 6

/**
 * This C++ script builts the DigitalDice.
 * @author Lucie Banszelova
 * @license MIT License
 *
 */


int currentNumber = 0;
String URL = "http://banszel.loca.lt/dice.php";  // API endpoint URL


void setup() {
  const char* ssid = "Your_SSID";  // Change to your Wi-Fi network SSID
  const char* password = "Your_Password";        // Change to your Wi-Fi network password

  WiFi.begin(ssid, password);
  Serial.begin(BAUD);

  // Wait until the board is connected to the Wi-Fi network
  while (WiFi.status() != WL_CONNECTED) {
    delay(DELAY);
    Serial.println("Connecting to Wi-Fi...");
  }
  Serial.println("Connected to Wi-Fi.");
}

void loop() {

  currentNumber = Serial.parseInt();  // reads number from arduino
  if (currentNumber > ZERO)              //when the number is more than zero
  {
    addRoll(currentNumber);
  }
}

void addRoll(int currentNumber) {
  WiFiClient client;                               // Get current wifi connection
  HTTPClient httpClient;                           // Client HTTP request
  DynamicJsonDocument jsonBuffer(JSON_NUMBER);
  jsonBuffer[JSON_NUMBER] = currentNumber;

    if (currentNumber > NUMBER ) {
      jsonBuffer["dice_type"] = "DICE_TYPE_6";
    } else {
      jsonBuffer["dice_type"] = "DICE_TYPE_9";
    }

  String jsonString;
  serializeJson(jsonBuffer, jsonString);
  Serial.println(jsonString);

  httpClient.begin(client, URL);
  httpClient.addHeader(CONTENT_TYPE, APPLICATION_JSON);


  int httpResponseCode = httpClient.POST(jsonString);  // Send post request
  Serial.println(RESPONSE);
  Serial.println(httpResponseCode);
  if (httpResponseCode == HTTP_CODE_OK) {
    String response = httpClient.getString();
    Serial.println(RESPONSE);

    // Parse the JSON response and retrieve the "message" field
    DynamicJsonDocument jsonResult(JSON_NUMBER);
    deserializeJson(jsonResult, response);
    String message = jsonResult["message"];
    Serial.println("Response message: " + message);
  } else {
    Serial.println("Failed to retrieve message from API.");
  }
  httpClient.end();
}


void setup() {
   WiFiManager wm;
   bool res;
   res = wm.autoConnect("GeacubeAP", "password"); //password protected ap
   Serial.begin(BAUD);

   if (!res) {
  Serial.println("Failed to connect");
   //ESP.restart();
   }
   else {
      //if you get here you have a connected to the WiFi
  Serial.println(CONNECTED)
}
}

Arduino Uno code

#include <IRremote.h>
#define SERIAL 115200
#define RIGHTBUTTONONE 1
#define RIGHTBUTTONTWO 7
#define LEFTTBUTTONONE 1
#define LEFTTBUTTONTWO 10
#define BUTTONDELAY 200
#define TONEBUZER 980
#define BUZERDELAY 1000
#define APPLICATIONJS "application/json"
#define DICETYPE6 "D06"
#define DICETYPE9 "D09"
#define RESPONSE "response"
#define SERIAL_RECEIVER 9600
#define DELAY 100
#define NUMBER_ONE 1
#define NUMBER_SEVEN 7
#define NUMBER_TEN 10

/**
 * This C++ script builts the DigitalDice.
 * @author Lucie Banszelova
 * @license MIT License
 *
 */


const int A = 2;
const int B = 3;
const int C = 4;
const int D = 7;
const int E = 8;
const int F = 12;
const int G = 13;

const int lowButton = 6;
const int highButton = 9;

const int buzzer = 11; //buzzer to arduino pin 15
const int irPin = 10;
int random_int = 0;
IRrecv receiver(irPin);

decode_results results;


void setup() {
  Serial.begin(SERIAL);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH); // Turn off built-in LED
  pinMode(lowButton, INPUT_PULLUP);
  pinMode(highButton, INPUT_PULLUP);
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(E, OUTPUT);
  pinMode(F, OUTPUT);
  pinMode(G, OUTPUT);

  pinMode(buzzer, OUTPUT); // Set buzzer as an output
  receiver.enableIRIn();
  // Wait until the board is connected to the Wi-Fi network
}

void loop() {
  int push_button_1 = digitalRead(lowButton);
  int push_button_2 = digitalRead(highButton);
  // If either push button is pressed, generate a new random number and display the corresponding LED pattern
  if (push_button_1 == LOW) {
    random_int = random(NUMBER_ONE, NUMBER_SEVEN); // Generate a random number between 1 and 6
// Wait for 2 seconds before allowing another roll
    sendNumb(random_int);
    displayLED(random_int);
  }

  if (push_button_2 == LOW)
  {
    random_int = random(NUMBER_ONE, NUMBER_TEN); // Generate a random number between 1 and 9
    sendNumb(random_int);
    displayLED(random_int);
  }

  // If neither push button is pressed, display the last generated random number
  else {
    Serial.write(random_int);
  }
  delay(BUTTONDELAY);
}
void buzzerSound(){
  tone(buzzer, TONEBUZER); // Send 1KHz sound signal...
  delay(BUZERDELAY);        // ...for 1 sec
  noTone(buzzer);     // Stop sound...
}

void sendNumb(int random)
{
    Serial.write(random); //send numbers to Wemos
    Serial.println();
    buzzerSound(); // make sound to wemos
}

void setup()
  Serial.begin(SERIAL_RECEIVER);
  irrecv.enableIRIn(); // Start the receiver

  void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(DELAY);
}


void displayLED(int num) {
  // Turn off all LEDs
    digitalWrite(A, LOW);
  digitalWrite(B, LOW);
  digitalWrite(C, LOW);
  digitalWrite(D, LOW);
  digitalWrite(E, LOW);
  digitalWrite(F, LOW);
  digitalWrite(G, LOW);
  // Display the corresponding LED pattern for the given number
  switch (num) {
    case 0:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(E, HIGH);
      digitalWrite(F, HIGH);
      break;
    case 1:
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      break;
    case 2:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(E, HIGH);
      digitalWrite(G, HIGH);
      break;
    case 3:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(G, HIGH);
      break;
    case 4:
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(F, HIGH);
      digitalWrite(G, HIGH);
      break;
    case 5:
      digitalWrite(A, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(F, HIGH);
      digitalWrite(G, HIGH);
      break;
    case 6:
      digitalWrite(A, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(E, HIGH);
      digitalWrite(F, HIGH);
      digitalWrite(G, HIGH);
      break;
      case 7:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      break;
    case 8:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(E, HIGH);
      digitalWrite(F, HIGH);
      digitalWrite(G, HIGH);
      break;
      case 9:
      digitalWrite(A, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(F, HIGH);
      digitalWrite(G, HIGH);
      break;
  }
}

Hardware overview

Here you can see a common cathode diagram:

Alternative text

(Scheme from Microsoft Excel)

If the user presses the first green button on the right, the numbers from 1 to 6 should be displayed. When the user presses the second green button on the left, the numbers from 0 to 9 should be displayed. As an additional input I added ir remote and ir receiver. If the button on the ir remote is pressed, the number is also displayed. Every time a number appears, the cube should make a sound. That’s why the buzzer is added as an output.

Alternative text

The picture shows a random number after pressing the button.To make the cube work, you need to connect two USB C cables to the Wemos D1 mini and Arduino uno. I decided to use both because I didn’t have enough pins on the Wemos D1 mini. For better cable management I will be using a USB hub.

Alternative text

Wiring diagram

I tried really hard to design a circuit to display the dice values on a 7segment display using WeMos D1 mini (pro), Arduino Uno with other important components like: Arduino Logic Level Converter, Breadboard prototype and lots of connectors for cables and other…I had to use Arduino uno because of the missing pins. And I have to use Wemos D1 mini, because of the requirement to have Wi-Fi. The circuit diagram is shown in the picture below:

Alternative text

WiringDiagram

The Fritzing Program.

Bill of Materials

To create my first digital 7-segment dice project, I will need the following components:

Part# Manufacturer Description Quantity Price (incl VAT) Subtotal (incl VAT) Example url
003910 Lolin Wemos D1 Mini V4 - ESP8266 - CH340 1 EUR 7,00 EUR 7,00 https://www.tinytronics.nl/shop/en/development-boards/microcontroller-boards/with-wi-fi/wemos-d1-mini-v4-esp8266-ch340
000539 DuPont DuPont Jumper wire Female-Female 10cm 10 wires 2 EUR 0,50 EUR 1,00 https://www.tinytronics.nl/shop/en/cables-and-connectors/cables-and-adapters/prototyping-wires/dupont-compatible-and-jumper/dupont-jumper-wire-female-female-10cm-10-wires
LS-00019 OSEPP Electronics LTD BREADBOARD - 830 TIE POINTS 1 EUR 7,00 EUR 7,00 https://www.digikey.com/en/products/detail/osepp-electronics-ltd/LS-00019/11198542
LTS-4802BJR-H1 Lite-On Inc. DISPLAY 7SEG 0.39” SGL RED 10DIP 1 EUR 1,75 EUR 2,00 https://www.digikey.com/en/products/detail/liteon/LTS-4802BJR-H1/408200
RESISTORSET2W - 110Ω Vishay 10Ω-1MΩ Resistor Set - 2 Watt 1 EUR 7,00 EUR 7,00 https://www.tinytronics.nl/shop/en/components/resistors/resistors/10%CF%89-1m%CF%89-resistor-set-2-watt
RESISTORSET2W - 110Ω Vishay 10Ω-1MΩ Resistor Set - 2 Watt 1 EUR 7,00 EUR 7,00 https://www.tinytronics.nl/shop/en/components/resistors/resistors/10%CF%89-1m%CF%89-resistor-set-2-watt
RESISTORSET2W - 120Ω Vishay 10Ω-1MΩ Resistor Set - 2 Watt 1 EUR 7,00 EUR 7,00 https://www.tinytronics.nl/shop/en/components/resistors/resistors/10%CF%89-1m%CF%89-resistor-set-2-watt
TC-R13-23A-05DGN TRU COMPONENTS TRU COMPONENTS TC-R13-23A-05DGN Druktoets 250 V/AC 1.5 A 1x uit/(aan) Moment 1 stuk(s) 2 EUR 1,64 EUR 3,28 https://www.conrad.nl/nl/p/tru-components-tc-r13-23a-05dgn-druktoets-250-v-ac-1-5-a-1x-uit-aan-moment-1-stuk-s-1587866.html
238-038 RS PRO RS PRO 83dB Through Hole Continuous Internal Piezo Buzzer, 24 (Dia.) x 17.5mm, 3V dc Min, 20V dc Max 1 EUR 4,84 EUR 4,84 https://nl.rs-online.com/web/p/piezo-buzzers/0238038?cm_mmc=NL-PLA-DS3A-
A000066 Arduino Arduino UNO REV.3 1 EUR 38,99 EUR 39,00 https://www.allekabels.nl/arduino/11445/1267313/arduino-uno-rev.3.html?gclid=CjwKCAjw__ihBhADEiwAXEazJv66m8XevktafIX3iA6tu0jbzx4luHQijtDj_1x5qq9QOQTVffYGWxoCMpMQAvD_BwE
ELC3008 Adafruit 8 Channel Bi-directional Logic Level Converter Module Pro 1 EUR 1,40 EUR 2,00 https://thinkrobotics.com/products/i2c-3-3v-to-5v-level-shifter-8-channel
000111 Vishay IR sensor module with remote and battery 1 EUR 3,50 EUR 4,00 https://www.tinytronics.nl/shop/en/communication-and-signals/wireless/infrared/ir-sensor-module-with-remote-and-battery
8016 Vector Electronics BREADBOARD GENERAL PURPOSE PTH 1 EUR 17,00 EUR 17,00 https://www.digikey.com/en/products/detail/vector-electronics/8016/416000

The Useful Web. The Useful Web. The Wiring Diagram. The Scheme Common Cathode.


Last update: April 24, 2023