Sitemap / Advertise

Introduction

While reading, use RFID tags as bookmarks to record your ratings. Then, inspect them on Qubitro to grasp and review chapters deliberately.


Tags

Share

IoT Bookmark and Reading (Book Ratings) Tracker w/ Qubitro

Advertisement:


read_later

Read Later



read_later

Read Later

Introduction

While reading, use RFID tags as bookmarks to record your ratings. Then, inspect them on Qubitro to grasp and review chapters deliberately.

Tags

Share





Advertisement

Advertisement




    Components :
  • [2]PCBWay Custom PCB
  • [1]Arduino Nano 33 IoT
  • [1]MFRC522 RFID Reader
  • [1]SH1106 OLED Display (128x64)
  • [1]5mm Green LED
  • [2]COM-09032 Analog Joystick
  • [4]Button (6x6)
  • [1]Creality CR-6 SE 3D Printer
  • [1]Power Jack
  • [1]External Battery
  • [1]Jumper Wires

Description

While reading books or comics, I am fond of recording my ratings on a daily basis to track any surge or plunge in my interest regarding each chapter. Also, I can review books effortlessly by scrutinizing my ratings and notes after completing reading them.

Since I have always logged my ratings on a notebook or a piece of paper, my home library has been deluged with unsolicited paper clusters. Therefore, I decided to create this IoT device to log and monitor my book ratings so as to obviate the need for handwriting.

After perusing book review and classification methods, I decided to employ this device to rate and record six different book characteristics which denote a book's quality and reliability:

For each characteristic above, I defined four different rating points to create a concise and coherent rating system with the collected data:

After defining my rating system, I decided to utilize RFID disk tags to identify books rather than scanning barcodes (ISBNs) with a barcode scanner since I wanted to design unique bookmarks with the RFID disk tags for each book. Therefore, I connected an MFRC522 RFID reader to the Arduino Nano 33 IoT so as to detect UIDs.

To display the rating settings menu, I connected an SH1106 OLED screen to the Nano 33 IoT. Then, I created a simple controller to adjust ratings for each characteristic with joysticks and buttons.

Instead of developing a web application from scratch to log and monitor the mentioned book ratings transferred by the Nano 33 IoT, I decided to utilize the Qubitro portal to build an IoT application. Since Qubitro supports various connectivity methods with different development boards and provides an easy-to-understand interface to visualize the received data packets on the cloud, I did not encounter any issues while building my IoT application for this project.

After completing wiring on a breadboard and testing the code for transferring data packets to the Qubitro application, I designed Batman-themed base and controller PCBs for this project. When I was watching the Batman: The Animated Series recently, I saw a bat-themed library in the Batcave. Since Batman is my favorite comic book character, I thought it would be interesting to design this device as if it is a part of that library in the Batcave.

Lastly, I also designed a complementary Batman-inspired book stand (3D printable) to insert the base and controller PCBs in order to create a robust and stylish device emphasizing the Batman theme gloriously :)

🎁🎨 Huge thanks to PCBWay for sponsoring this project.

🎁🎨 Also, huge thanks to Creality3D for sponsoring a Creality CR-6 SE 3D Printer.

🎁🎨 If you want to purchase some products from Creality3D, you can use my 10% discount coupon (Aktar10) even for their new and most popular printers: CR-10 Smart, CR-30 3DPrintMill, Ender-3 Pro, and Ender-3 V2. You can also use the coupon for Creality filaments.

project-image
Figure - 77.1


project-image
Figure - 77.2


project-image
Figure - 77.3

Step 1: Designing and soldering Batman-themed base and controller PCBs

Before prototyping my Batman-themed base and controller PCB designs, I tested all connections and wiring with the Arduino Nano 33 IoT and the MFRC522 RFID reader.

project-image
Figure - 77.4

Then, I designed the Batman-themed base and controller PCBs by utilizing KiCad - inspired by the legends of the Dark Knight :) I attached the Gerber files for both PCBs below. Therefore, if you want, you can order my PCB designs from PCBWay to create your RFID-enabled IoT bookmark and reading tracker so as to transfer your book ratings effortlessly to a Qubitro application.

Click here to inspect and order the base and controller PCBs directly on PCBWay.

project-image
Figure - 77.5


project-image
Figure - 77.6


project-image
Figure - 77.7


project-image
Figure - 77.8

First of all, by utilizing a soldering iron, I attached headers (female), COM-09032 analog joysticks, pushbuttons (6x6), a 5mm green LED, and a power jack to the base and controller PCBs.

📌 Component list on the base PCB:

A1 (Headers for Arduino Nano 33 IoT)

RFID1 (Headers for MFRC522 RFID Reader)

SH1106 (Headers for SH1106 OLED Display)

J1 (Headers for Controller PCB)

D1 (5mm Green LED)

J2 (Power Jack)

📌 Component list on the controller PCB:

J1 (Headers for Base PCB)

U1, U2 (COM-09032 Analog Joystick)

K1, K2, K3, K4 (6x6 Pushbutton)

project-image
Figure - 77.9


project-image
Figure - 77.10


project-image
Figure - 77.11

Step 1.1: Making connections and adjustments


// Connections
// Arduino Nano 33 IoT :  
//                                MFRC522
// D3  --------------------------- RST
// D4  --------------------------- SDA
// D11 --------------------------- MOSI
// D12 --------------------------- MISO
// D13 --------------------------- SCK
//                                SH1106 OLED Display (128x64)
// D6  --------------------------- SDA
// D5  --------------------------- SCK
// D7  --------------------------- RES
// D8  --------------------------- DC
// D9  --------------------------- CS
//                                JoyStick (R)
// A0  --------------------------- VRY
// A1  --------------------------- VRX
// A2  --------------------------- SW
//                                JoyStick (L)
// A3  --------------------------- VRY
// A4  --------------------------- VRX
// A5  --------------------------- SW
//                                Button (Up)
// A6  --------------------------- S
//                                Button (Right)
// A7  --------------------------- S
//                                Button (Left)
// D2  --------------------------- S
//                                Button (Down)
// D10 --------------------------- S
//                                5mm Green LED
// D0  --------------------------- +

After completing soldering, I attached all remaining components to the Batman-themed base and controller PCBs via headers - Arduino Nano 33 IoT, MFRC522 RFID reader, and SH1106 OLED screen.

Then, I connected the base PCB to the controller PCB by utilizing male jumper wires.

project-image
Figure - 77.12

Step 2: Designing and printing a Batman-inspired book stand

Since I wanted to apply the bat theme to create a device as if it is a part of the Batcave from the animated series, I decided to design a complementing book stand to display the books I am currently reading in my home library. To insert and attach the Batman-themed base and controller PCBs to the book stand effortlessly, I added slots and hooks. Also, I inscribed the prominent bat symbol on the book stand to emphasize the Batman theme gloriously :)

I designed the book stand in Autodesk Fusion 360. You can download its STL file below.

project-image
Figure - 77.13


project-image
Figure - 77.14

Then, I sliced my book stand 3D model (STL file) in Ultimaker Cura.

project-image
Figure - 77.15

Since I wanted to create a solid structure for the book stand and complement the Batman theme, I utilized this PLA filament:

Finally, I printed the book stand (model) with my Creality CR-6 SE 3D Printer. Although I am a novice in 3D printing, and it is my first FDM 3D printer, I got incredible results effortlessly with the CR-6 SE :)

project-image
Figure - 77.16

Step 2.1: Assembling the book stand and creating RFID bookmarks

After printing my book stand 3D model, I affixed the Batman-themed base and controller PCBs to the book stand. I placed the controller PCB via the hooks on the front. Then, I fastened the base PCB to its slot on the top via a hot glue gun and utilized a cable tie to make a rigid and stable connection.

project-image
Figure - 77.17


project-image
Figure - 77.18


project-image
Figure - 77.19


project-image
Figure - 77.20


project-image
Figure - 77.21


project-image
Figure - 77.22


project-image
Figure - 77.23

Since I decided to employ RFID disk tags to create unique bookmarks in order to identify books, I fastened the disk tags to my limited edition comic bookmarks I purchased from a comic book convention in my hometown.

project-image
Figure - 77.24


project-image
Figure - 77.25

Step 3: Setting up an IoT application on Qubitro

To log and monitor the book ratings transferred by the Nano 33 IoT, I decided to utilize the Qubitro portal to build an IoT application. Qubitro provides developer-friendly features and supports various connectivity methods such as a fully-featured MQTT broker and The Things Stack devices. Since Qubitro has easy-to-understand online examples with technical guides and allows the user to visualize the received data packets on the cloud with specialized widgets effortlessly, I highly recommend building IoT applications with Qubitro.

#ī¸âƒŖ First of all, go to the Qubitro portal and sign in.

project-image
Figure - 77.26

#ī¸âƒŖ Then, create a new project (IoT application) and define its name and description.

project-image
Figure - 77.27


project-image
Figure - 77.28

#ī¸âƒŖ To create a new Qubitro device under the application, choose a connectivity method depending on your project's requirements. Select the MQTT option to transfer data via the Qubitro MQTT broker to the given Qubitro device.

project-image
Figure - 77.29

#ī¸âƒŖ Define the device information and details.

project-image
Figure - 77.30

If required, you can also use the application's MQTT credentials to publish data via the Qubitro APIs.

project-image
Figure - 77.31

#ī¸âƒŖ After creating the Qubitro device successfully, open the device on the project dashboard and click Settings.

project-image
Figure - 77.32

#ī¸âƒŖ Then, copy the device ID and token to transfer data packets from the Nano 33 IoT to the Qubitro device via the MQTT broker.

project-image
Figure - 77.33

Step 3.1: Analyzing the collected data on Qubitro

After building my IoT application on Qubitro, I started to send data packets (book ratings) from the Nano 33 IoT to the Qubitro device under the application via the MQTT broker immediately.

To analyze the collected data, I utilized the built-in chart feature in the device interface.

You can inspect the code for transferring book ratings via the Qubitro MQTT broker in Step 4.

#ī¸âƒŖ After the Qubitro device receives data packets, open the device on the project dashboard and click Analytics.

project-image
Figure - 77.34


project-image
Figure - 77.35

#ī¸âƒŖ Then, create a chart with unique colors for each data element to scrutinize the collected data in a given period.

project-image
Figure - 77.36


project-image
Figure - 77.37

Step 3.2: Creating widgets to visualize the collected data on Qubitro

#ī¸âƒŖ First of all, on the project dashboard, go to Monitoring so as to create a new monitoring dashboard.

project-image
Figure - 77.38

#ī¸âƒŖ Then, click the Add widget button.

#ī¸âƒŖ Define the required information for the widget: title, project (IoT application) name, device name, and widget type (e.g., area chart).

project-image
Figure - 77.39


project-image
Figure - 77.40

#ī¸âƒŖ To customize the recently created widget, assign a data element (sensor value), select the widget color, and adjust the appearance settings.

project-image
Figure - 77.41

After creating widgets for each data element, the Qubitro portal should show a monitoring dashboard as follows.

project-image
Figure - 77.42

Step 4: Programming the Arduino Nano 33 IoT

First of all, I needed to install the SAMD21 core to set up the Arduino Nano 33 IoT on the Arduino IDE.

#ī¸âƒŖ On the Arduino IDE, navigate to Tools > Board > Boards Manager.

project-image
Figure - 77.43

#ī¸âƒŖ Then, search for the Arduino SAMD Boards (32-bits ARM Cortex-M0+) core and install it.

project-image
Figure - 77.44

#ī¸âƒŖ Go to Tools > Board > Arduino SAMD Boards (32-bits ARM Cortex-M0+) in order to select the Arduino Nano 33 IoT.

project-image
Figure - 77.45

#ī¸âƒŖ After setting up the Nano 33 IoT successfully, download the required libraries to transfer data packets via the Qubitro MQTT broker:

WiFiNINA | Download

mqtt-client-arduino | Download

#ī¸âƒŖ Then, download the required libraries for the MFRC522 RFID reader and the SH1106 OLED screen:

rfid | Download

Adafruit_SH110x | Download

Adafruit-GFX-Library | Download

⭐ Include the required libraries.


#include <QubitroMqttClient.h>
#include <WiFiNINA.h> 
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <MFRC522.h>

⭐ Initiate the Wi-Fi and Qubitro MQTT clients.

⭐ Define the Wi-Fi settings.

⭐ Define the Qubitro device settings and information (ID and token).


WiFiClient wifiClient;
QubitroMqttClient mqttClient(wifiClient);

// Define the Wi-Fi settings.
char ssid[] = "<_SSID_>";   
char pass[] = "<_PASSWORD_>";

// Define the Qubitro device settings and information.
char deviceID[] = "<_DEVICE_ID_>";
char deviceToken[] = "<_DEVICE_TOKEN_>";
char host[] = "broker.qubitro.com";
int port = 1883;

⭐ Define the SH1106 OLED screen settings.


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_MOSI     6
#define OLED_CLK      5
#define OLED_DC       8
#define OLED_CS       9
#define OLED_RST      7

// Create the SH1106 OLED screen.
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RST, OLED_CS);

⭐ Create the MFRC522 instance and define the MFRC522 module key input.


#define RST_PIN   3
#define SS_PIN    4
MFRC522 mfrc522(SS_PIN, RST_PIN);

// Define the MFRC522 module key input.
MFRC522::MIFARE_Key key;

⭐ Initialize the SH1106 OLED screen.


  display.begin(0, true);
  display.display();
  delay(1000);

  display.clearDisplay();   
  display.setTextSize(2); 
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
  display.setCursor(0,0);
  display.println("IoT");
  display.println("Bookmark");
  display.display();
  delay(1000);

⭐ Connect to the given Wi-Fi network.


  Serial.println("Connecting to the Wi-Fi network...");
  while(WiFi.begin(ssid, pass) != WL_CONNECTED){
    Serial.print(".");
    delay(1000);
  }
  Serial.println("Connected to the Wi-Fi network!");

⭐ Set the Qubitro device ID and token for authentication.

⭐ Connect to the Qubitro device via the Qubitro MQTT broker.


  mqttClient.setId(deviceID); 
  mqttClient.setDeviceIdToken(deviceID, deviceToken);
  Serial.println("Connecting to the Qubitro device...");

  // Connect to the Qubitro device via the Qubitro MQTT broker.
  if(!mqttClient.connect(host, port)){
    Serial.println("Qubitro: Connection failed! Error code => ");
    Serial.println(mqttClient.connectError());
    while(1);
  }
  Serial.println("Connected to the Qubitro device!"); 

⭐ Activate the two-way communication with the Qubitro device to get informed of the server responses (received messages).


  mqttClient.onMessage(receivedMessage);                                       
  mqttClient.subscribe(deviceID);

⭐ Initialize the MFRC522 RFID reader (hardware).


  SPI.begin();          
  mfrc522.PCD_Init();
  Serial.println("\n----------------------------------\nApproximate a New Card or Key Tag : \n----------------------------------\n");

⭐ In the read_UID function, detect a new RFID card or tag UID.

⭐ Then, copy the detected UID to the lastRead string, process the lastRead string, and print it on the serial monitor.


int read_UID() {
  // Detect the new card or tag UID. 
  if ( ! mfrc522.PICC_IsNewCardPresent()) { 
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return 0;
  }

  // Display the detected UID on the serial monitor.
  Serial.print("\n----------------------------------\nNew Card or Key Tag UID : ");
  for (int i = 0; i < mfrc522.uid.size; i++) {
    lastRead += mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ";
    lastRead += String(mfrc522.uid.uidByte[i], HEX);
  }
  lastRead.trim();
  lastRead.toUpperCase();
  Serial.print(lastRead);
  Serial.print("\n----------------------------------\n\n");
  mfrc522.PICC_HaltA();
  return 1;
}

⭐ Maintain the MQTT connection with the Qubitro broker.


mqttClient.poll(); 

⭐ If an RFID card or tag UID is detected and stored, initiate the rating settings menu:

⭐ Display the detected UID and the current book ratings on the SH1106 OLED screen.

⭐ Then, adjust book ratings by utilizing joystick (first and second) movements and control buttons (up, right, left, and down).

⭐ If the second joystick's switch is pressed, create a string in the JSON format to transfer the detected UID and the adjusted book ratings to the Qubitro device:

⭐ Then, send the given data packet to the Qubitro device via the Qubitro MQTT broker.

⭐ Finally, return to the home screen and clear the lastRead string (detected UID).

⭐ If the first joystick's switch is pressed, return to the home screen and clear the lastRead string (detected UID) without sending the data packet.


  if(lastRead != ""){
    uid_activated = true; 
    // If an RFID card or tag is detected, open the rating settings menu.
    while(uid_activated){
      read_controls();
      mqttClient.poll(); 
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(SH110X_WHITE);
      display.setCursor(0,5);
      display.print("UID: "); display.println(lastRead);
      display.print("Plot :        "); display.println(options[0]);
      display.print("Delineation : "); display.println(options[1]);
      display.print("Immersion :   "); display.println(options[2]);
      display.print("Prolixity :   "); display.println(options[3]);
      display.print("Characters :  "); display.println(options[4]);
      display.print("Editing :     "); display.println(options[5]);
      display.display();
      delay(150);
      // Adjust book ratings by utilizing joysticks and control buttons:
      if(joystick_x_1 >= 850){ if(!up) options[0] = 1; if(!right) options[0] = 2; if(!left) options[0] = 3; if(!down) options[0] = 4; }
      if(joystick_x_1 <= 150){ if(!up) options[1] = 1; if(!right) options[1] = 2; if(!left) options[1] = 3; if(!down) options[1] = 4; }
      if(joystick_y_1 >= 850){ if(!up) options[2] = 1; if(!right) options[2] = 2; if(!left) options[2] = 3; if(!down) options[2] = 4; }
      if(joystick_x_2 >= 850){ if(!up) options[3] = 1; if(!right) options[3] = 2; if(!left) options[3] = 3; if(!down) options[3] = 4; }
      if(joystick_x_2 <= 150){ if(!up) options[4] = 1; if(!right) options[4] = 2; if(!left) options[4] = 3; if(!down) options[4] = 4; }
      if(joystick_y_2 >= 850){ if(!up) options[5] = 1; if(!right) options[5] = 2; if(!left) options[5] = 3; if(!down) options[5] = 4; }
      // Send the given book ratings to the Qubitro device via the Qubitro MQTT broker.
      if(!joystick_sw_2){
       digitalWrite(control_led, HIGH);
       mqttClient.beginMessage(deviceID);   
       // Create a string in the JSON format to transfer data to the Qubitro device successfully.
       mqttClient.print("{\"UID\":\"" + lastRead + "\",\"plot\":" + String(options[0]) + ",\"delineation\":" + String(options[1]) + ",\"immersion\":" + String(options[2]) + ",\"prolixity\":" + String(options[3]) + ",\"characters\":" + String(options[4]) + ",\"editing\":" + String(options[5]) + "}");
       mqttClient.endMessage();             
       delay(3000); 
       Serial.println("Message Sent!");
       // Exit and clear:
       lastRead = "";
       display.clearDisplay();   
       display.setTextSize(2); 
       display.setTextColor(SH110X_BLACK, SH110X_WHITE);
       display.setCursor(0,0);
       display.println("IoT");
       display.println("Bookmark");
       display.display();
       digitalWrite(control_led, LOW);
       uid_activated = false;
      }

      // Exit and clear:
      if(!joystick_sw_1){
          lastRead = "";
          display.clearDisplay();   
          display.setTextSize(2); 
          display.setTextColor(SH110X_BLACK, SH110X_WHITE);
          display.setCursor(0,0);
          display.println("IoT");
          display.println("Bookmark");
          display.display();
          uid_activated = false;
      }
    }
  }

project-image
Figure - 77.46


project-image
Figure - 77.47


project-image
Figure - 77.48


project-image
Figure - 77.49


project-image
Figure - 77.50


project-image
Figure - 77.51

Modes and Features

đŸĻ‡đŸ“— First of all, the device attempts to connect to the given Wi-Fi network and the Qubitro device via the Qubitro MQTT broker.

đŸĻ‡đŸ“— Then, the device displays the home screen.

project-image
Figure - 77.52


project-image
Figure - 77.53

đŸĻ‡đŸ“— If the device detects an RFID card or tag UID, it initiates the rating settings menu and shows the detected UID and the current book ratings:

project-image
Figure - 77.54

đŸĻ‡đŸ“— On the rating settings menu, the device allows the user to adjust the book ratings by utilizing joystick movements and control buttons:

🕹ī¸ To adjust the Plot rating:

🕹ī¸ To adjust the Delineation rating:

🕹ī¸ To adjust the Immersion rating:

🕹ī¸ To adjust the Prolixity rating:

🕹ī¸ To adjust the Characters rating:

🕹ī¸ To adjust the Editing rating:

🎮 Rating points by control buttons:

project-image
Figure - 77.55


project-image
Figure - 77.56

đŸĻ‡đŸ“— If the second joystick's switch is pressed, the device sends the data packet (the detected UID and the adjusted book ratings) to the Qubitro device via the Qubitro MQTT broker.

đŸĻ‡đŸ“— Then, the device blinks the 5mm green LED if the Qubitro device receives the transferred data packet successfully.

project-image
Figure - 77.57


project-image
Figure - 77.58

đŸĻ‡đŸ“— After sending the data packet, the device returns to the home screen.

đŸĻ‡đŸ“— If the first joystick's switch is pressed, the device also returns to the home screen without transferring the data packet.

project-image
Figure - 77.59

đŸĻ‡đŸ“— The device stores the adjusted book ratings and shows them on the rating settings menu when being activated so as to remind the user of the previously assigned book ratings.

project-image
Figure - 77.60

đŸĻ‡đŸ“— If the Nano 33 IoT throws an error while operating, the device prints the error code and details on the serial monitor.

project-image
Figure - 77.61

đŸĻ‡đŸ“— Also, the device prints notifications and UID readings on the serial monitor for debugging.

project-image
Figure - 77.62

đŸĻ‡đŸ“— After transferring data packets to the Qubitro device, the Qubitro portal lets the user visualize the book ratings on the monitoring dashboard, as explained in Step 3.2.

project-image
Figure - 77.63

Videos and Conclusion

As far as my experiments go, the device works impeccably while adjusting the book ratings and transferring data packets to the Qubitro device via the Qubitro MQTT broker :)

project-image
Figure - 77.64

Code

IoT_Bookmark.ino

Download



         /////////////////////////////////////////////  
        // IoT Bookmark and Reading (Book Ratings) //
       //          Tracker w/ Qubitro             //
      //             ---------------             //
     //          (Arduino Nano 33 IoT)          //           
    //             by Kutluhan Aktar           // 
   //                                         //
  /////////////////////////////////////////////

//
// While reading, use RFID tags as bookmarks to record your ratings. Then, inspect them on Qubitro to grasp and review chapters deliberately.
//
// For more information:
// https://www.theamplituhedron.com/projects/IoT_Bookmark_and_Reading_Tracker_w_Qubitro
//
//
// Connections
// Arduino Nano 33 IoT :  
//                                MFRC522
// D3  --------------------------- RST
// D4  --------------------------- SDA
// D11 --------------------------- MOSI
// D12 --------------------------- MISO
// D13 --------------------------- SCK
//                                SH1106 OLED Display (128x64)
// D6  --------------------------- SDA
// D5  --------------------------- SCK
// D7  --------------------------- RES
// D8  --------------------------- DC
// D9  --------------------------- CS
//                                JoyStick (R)
// A0  --------------------------- VRY
// A1  --------------------------- VRX
// A2  --------------------------- SW
//                                JoyStick (L)
// A3  --------------------------- VRY
// A4  --------------------------- VRX
// A5  --------------------------- SW
//                                Button (Up)
// A6  --------------------------- S
//                                Button (Right)
// A7  --------------------------- S
//                                Button (Left)
// D2  --------------------------- S
//                                Button (Down)
// D10 --------------------------- S
//                                5mm Green LED
// D0  --------------------------- +


// Include the required libraries:
#include <QubitroMqttClient.h>
#include <WiFiNINA.h> 
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <MFRC522.h>

// Initiate the Wi-Fi and MQTT clients.
WiFiClient wifiClient;
QubitroMqttClient mqttClient(wifiClient);

// Define the Wi-Fi settings.
char ssid[] = "<_SSID_>";   
char pass[] = "<_PASSWORD_>";

// Define the Qubitro device settings and information.
char deviceID[] = "<_DEVICE_ID_>";
char deviceToken[] = "<_DEVICE_TOKEN_>";
char host[] = "broker.qubitro.com";
int port = 1883;

// Define the SH1106 screen settings:
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_MOSI     6
#define OLED_CLK      5
#define OLED_DC       8
#define OLED_CS       9
#define OLED_RST      7

// Create the SH1106 OLED screen.
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RST, OLED_CS);

// Create the MFRC522 instance.
#define RST_PIN   3
#define SS_PIN    4
MFRC522 mfrc522(SS_PIN, RST_PIN);

// Define the MFRC522 module key input.
MFRC522::MIFARE_Key key;

// Define joystick pins:
#define VRY_1     A0
#define VRX_1     A1
#define SW_1      A2
#define VRY_2     A3
#define VRX_2     A4
#define SW_2      A5

// Define control buttons:
#define b_up      A6
#define b_right   A7
#define b_left    2
#define b_down    10

#define control_led 0

// Define the data holders:
volatile boolean uid_activated = false;
String lastRead = "";
int options[8] = {0, 0, 0, 0, 0, 0};
int joystick_x_1, joystick_x_2, joystick_y_1, joystick_y_2, joystick_sw_1, joystick_sw_2, up, right, left, down;


void setup() {
  // Initialize the serial communication:
  Serial.begin(9600);
  
  pinMode(b_up, INPUT_PULLUP);
  pinMode(b_right, INPUT_PULLUP);
  pinMode(b_left, INPUT_PULLUP);
  pinMode(b_down, INPUT_PULLUP);
  pinMode(SW_1, INPUT);
  pinMode(SW_2, INPUT);
  digitalWrite(SW_1, HIGH);
  digitalWrite(SW_2, HIGH);
  pinMode(control_led, HIGH);
  
  // Initialize the SH1106 screen:
  display.begin(0, true);
  display.display();
  delay(1000);

  display.clearDisplay();   
  display.setTextSize(2); 
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
  display.setCursor(0,0);
  display.println("IoT");
  display.println("Bookmark");
  display.display();
  delay(1000);

  // Connect to the given Wi-Fi network.
  Serial.println("Connecting to the Wi-Fi network...");
  while(WiFi.begin(ssid, pass) != WL_CONNECTED){
    Serial.print(".");
    delay(1000);
  }
  Serial.println("Connected to the Wi-Fi network!");

  // Set the Qubitro device ID and token for authentication.
  mqttClient.setId(deviceID); 
  mqttClient.setDeviceIdToken(deviceID, deviceToken);
  Serial.println("Connecting to the Qubitro device...");

  // Connect to the Qubitro device via the Qubitro MQTT broker.
  if(!mqttClient.connect(host, port)){
    Serial.println("Qubitro: Connection failed! Error code => ");
    Serial.println(mqttClient.connectError());
    while(1);
  }
  Serial.println("Connected to the Qubitro device!"); 

  // Activate the two-way communication with the Qubitro device.
  mqttClient.onMessage(receivedMessage);                                       
  mqttClient.subscribe(deviceID);

  // Initialize the MFRC522 hardware:
  SPI.begin();          
  mfrc522.PCD_Init();
  Serial.println("\n----------------------------------\nApproximate a New Card or Key Tag : \n----------------------------------\n");
  delay(3000);
}

void loop(){
  read_UID();
  // Maintain the MQTT connection with the Qubitro broker.
  mqttClient.poll(); 
  
  if(lastRead != ""){
    uid_activated = true; 
    // If an RFID card or tag is detected, open the rating settings menu.
    while(uid_activated){
      read_controls();
      mqttClient.poll(); 
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(SH110X_WHITE);
      display.setCursor(0,5);
      display.print("UID: "); display.println(lastRead);
      display.print("Plot :        "); display.println(options[0]);
      display.print("Delineation : "); display.println(options[1]);
      display.print("Immersion :   "); display.println(options[2]);
      display.print("Prolixity :   "); display.println(options[3]);
      display.print("Characters :  "); display.println(options[4]);
      display.print("Editing :     "); display.println(options[5]);
      display.display();
      delay(150);
      // Adjust book ratings by utilizing joysticks and control buttons:
      if(joystick_x_1 >= 850){ if(!up) options[0] = 1; if(!right) options[0] = 2; if(!left) options[0] = 3; if(!down) options[0] = 4; }
      if(joystick_x_1 <= 150){ if(!up) options[1] = 1; if(!right) options[1] = 2; if(!left) options[1] = 3; if(!down) options[1] = 4; }
      if(joystick_y_1 >= 850){ if(!up) options[2] = 1; if(!right) options[2] = 2; if(!left) options[2] = 3; if(!down) options[2] = 4; }
      if(joystick_x_2 >= 850){ if(!up) options[3] = 1; if(!right) options[3] = 2; if(!left) options[3] = 3; if(!down) options[3] = 4; }
      if(joystick_x_2 <= 150){ if(!up) options[4] = 1; if(!right) options[4] = 2; if(!left) options[4] = 3; if(!down) options[4] = 4; }
      if(joystick_y_2 >= 850){ if(!up) options[5] = 1; if(!right) options[5] = 2; if(!left) options[5] = 3; if(!down) options[5] = 4; }
      // Send the given book ratings to the Qubitro device via the Qubitro MQTT broker.
      if(!joystick_sw_2){
       digitalWrite(control_led, HIGH);
       mqttClient.beginMessage(deviceID);   
       // Create a string in the JSON format to transfer data to the Qubitro device successfully.
       mqttClient.print("{\"UID\":\"" + lastRead + "\",\"plot\":" + String(options[0]) + ",\"delineation\":" + String(options[1]) + ",\"immersion\":" + String(options[2]) + ",\"prolixity\":" + String(options[3]) + ",\"characters\":" + String(options[4]) + ",\"editing\":" + String(options[5]) + "}");
       mqttClient.endMessage();             
       delay(3000); 
       Serial.println("Message Sent!");
       // Exit and clear:
       lastRead = "";
       display.clearDisplay();   
       display.setTextSize(2); 
       display.setTextColor(SH110X_BLACK, SH110X_WHITE);
       display.setCursor(0,0);
       display.println("IoT");
       display.println("Bookmark");
       display.display();
       digitalWrite(control_led, LOW);
       uid_activated = false;
      }

      // Exit and clear:
      if(!joystick_sw_1){
          lastRead = "";
          display.clearDisplay();   
          display.setTextSize(2); 
          display.setTextColor(SH110X_BLACK, SH110X_WHITE);
          display.setCursor(0,0);
          display.println("IoT");
          display.println("Bookmark");
          display.display();
          uid_activated = false;
      }
    }
  }
}

int read_UID() {
  // Detect the new card or tag UID. 
  if ( ! mfrc522.PICC_IsNewCardPresent()) { 
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return 0;
  }

  // Display the detected UID on the serial monitor.
  Serial.print("\n----------------------------------\nNew Card or Key Tag UID : ");
  for (int i = 0; i < mfrc522.uid.size; i++) {
    lastRead += mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ";
    lastRead += String(mfrc522.uid.uidByte[i], HEX);
  }
  lastRead.trim();
  lastRead.toUpperCase();
  Serial.print(lastRead);
  Serial.print("\n----------------------------------\n\n");
  mfrc522.PICC_HaltA();
  return 1;
}

void read_controls(){
  // Joysticks:
  joystick_x_1 = analogRead(VRX_1);
  joystick_y_1 = analogRead(VRY_1);
  joystick_sw_1 = digitalRead(SW_1);
  joystick_x_2 = analogRead(VRX_2);
  joystick_y_2 = analogRead(VRY_2);
  joystick_sw_2 = digitalRead(SW_2);
  // Buttons:
  up = digitalRead(b_up);
  right = digitalRead(b_right);
  left = digitalRead(b_left);
  down = digitalRead(b_down);
}

void receivedMessage(int messageSize){ Serial.print("Qubitro: A new message is received!\n\n"); }


Schematics

project-image
Schematic - 77.1


project-image
Schematic - 77.2


project-image
Schematic - 77.3


project-image
Schematic - 77.4


project-image
Schematic - 77.5


project-image
Schematic - 77.6


project-image
Schematic - 77.7


project-image
Schematic - 77.8


project-image
Schematic - 77.9


project-image
Schematic - 77.10


project-image
Schematic - 77.11


project-image
Schematic - 77.12


project-image
Schematic - 77.13

Downloads

IoT_Bookmark_Case_v1.stl

Download


Gerber Files (Base)

Download


Fabrication Files (Base)

Download


Gerber Files (Controller)

Download


Fabrication Files (Controller)

Download