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.
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:
(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.
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.
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:
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 |
Links¶
The Useful Web. The Useful Web. The Wiring Diagram. The Scheme Common Cathode.