Merge branch 'main' of gitlab.fdmci.hva.nl:propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-3/qaajeeqiinii59
This commit is contained in:
@@ -9,6 +9,7 @@ nav:
|
||||
- 🎮 Arduino documentation:
|
||||
- I2C: arduino-documentation/i2c-ESP32
|
||||
- TFT screen : node-documentation/TFT-screen
|
||||
- Classes : arduino-documentation/classes
|
||||
- 🍓 RPi Documentation:
|
||||
- Raspberry pi: Sp1SchetsProject/InfrastructuurDocumentatie/raspberryPi
|
||||
- MariaDB: rpi-documentation/mariadb-installation
|
||||
@@ -24,5 +25,5 @@ nav:
|
||||
- Taskflow: brainstorm/Taskflow
|
||||
- Design: Sp1SchetsProject/FirstDesign
|
||||
- 🖨️ Software:
|
||||
- Dev page: brainstrom/SotwareDocumentatie/Dev_page
|
||||
- Dev page: brainstorm/SoftwareDocumentatie/Dev_page
|
||||
|
73
docs/arduino-documentation/classes.md
Normal file
73
docs/arduino-documentation/classes.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Arduino classes
|
||||
|
||||
|
||||
## How do I make a class?
|
||||
|
||||
First you need to start out with a header file. This file will contain the class definition. And which functions of the class are public and which are private.
|
||||
|
||||
```cpp
|
||||
#ifndef DISPLAYTEXT_H
|
||||
#define DISPLAYTEXT_H
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
#include "Adafruit_ST7796S_kbv.h"
|
||||
|
||||
class DisplayText {
|
||||
private:
|
||||
Adafruit_ST7796S_kbv& tft;
|
||||
int centerText(char* text);
|
||||
int bottomText(char* text);
|
||||
void printWordsFull(char* text);
|
||||
|
||||
public:
|
||||
DisplayText(Adafruit_ST7796S_kbv& tftDisplay);
|
||||
void writeText(char* text, int size, int posX, int posY, int screenTime, bool center, bool bottom);
|
||||
};
|
||||
|
||||
#endif
|
||||
```
|
||||
```#ifndef``` DISPLAYTEXT_H is a preprocessor directive that checks if DISPLAYTEXT_H is defined. If it is not defined, the code between #ifndef and #endif will be included in the compilation. If it is defined, the code will be excluded from the compilation. This is to prevent the same code from being included multiple times in the same file.
|
||||
|
||||
|
||||
To start out with a class you need a constructor. This is a function that is called when the class is created. This function is used to initialize the class.
|
||||
```cpp
|
||||
DisplayText::DisplayText(Adafruit_ST7796S_kbv& tftDisplay) : tft(tftDisplay) {
|
||||
tft.fillScreen(0x0000);
|
||||
}
|
||||
```
|
||||
The library gets passed to tftdisplay. And the tft gets initialized with the tftdisplay.
|
||||
|
||||
|
||||
|
||||
## How do I create a function in a class?
|
||||
```cpp
|
||||
void DisplayText::centerText() {
|
||||
//insert code here
|
||||
}
|
||||
```
|
||||
This is a example of a function in a class. The function is called centerText and it is a private function. This means that it can only be called from within the class.
|
||||
|
||||
|
||||
When creating a class you also need to reference it in the header file like this
|
||||
|
||||
```cpp
|
||||
#include "DisplayText.h"
|
||||
|
||||
class DisplayText {
|
||||
private:
|
||||
int centerText();
|
||||
//other functions
|
||||
|
||||
public:
|
||||
//other functions
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
# Sources
|
||||
* https://www.circuitbasics.com/programming-with-classes-and-objects-on-the-arduino/
|
||||
|
||||
|
||||
|
@@ -2,15 +2,17 @@
|
||||
|
||||
### parsing JSON
|
||||
|
||||
The data that is send by the nodes is send in json data. We chose this becouse we can easily use the data within javascript, this is called parsing. We use the parced data and send that in to the next function to make the data more acceseble to use in further instences.
|
||||
|
||||
```js
|
||||
const jsonData = JSON.parse(event.data);
|
||||
// Use the parsed JSON data as needed
|
||||
handleIncomingData(jsonData);
|
||||
```
|
||||
|
||||
### Pro
|
||||
|
||||
Here is the function that receves the parced JSON data and set it into variables. So that it can be more easlily used in the next function with is the processNodeData, witch is setting the data in to the right array.
|
||||
|
||||
```js
|
||||
function handleIncomingData(data) {
|
||||
nodeNumber = data.node;
|
||||
temperature = data.Temp;
|
||||
@@ -20,13 +22,20 @@ function handleIncomingData(data) {
|
||||
|
||||
processNodeData(nodeNumber, temperature, humidity, CO2, TVOC);
|
||||
}
|
||||
```
|
||||
|
||||
function processNodeData(nodeNumber, temperature, humidity, CO2, TVOC) {
|
||||
In the function processNodeData we first check if there is a array for the node that is sending the data, this is done becouse if we want to seperate the data in to show witch node is sending what data. So if the nodeNumber plus sensorData (the name of the array) not already there the array is made.
|
||||
|
||||
```js
|
||||
// Initialize the array for this node if it doesn't exist yet
|
||||
if (!sensorData[nodeNumber]) {
|
||||
sensorData[nodeNumber] = [];
|
||||
}
|
||||
```
|
||||
|
||||
For the actual data put in to array function is there a simple array.push for the data that is send allong from when the function is called.
|
||||
|
||||
```js
|
||||
// Push the new data onto the array for this node
|
||||
sensorData[nodeNumber].push({
|
||||
'node': nodeNumber,
|
||||
@@ -35,106 +44,22 @@ function processNodeData(nodeNumber, temperature, humidity, CO2, TVOC) {
|
||||
'CO2': CO2,
|
||||
'TVOC': TVOC,
|
||||
});
|
||||
```
|
||||
|
||||
// updateNodeData(node, temperature, humidity, lightIntensity)
|
||||
updateNodeData(nodeNumber, temperature, humidity, CO2, TVOC);
|
||||
|
||||
// Log the array for this node
|
||||
console.log(sensorData[nodeNumber]);
|
||||
We want only use the last 10 readings from the nodes so there is a check for if the array is longer than 10 the first (or the oldest reading), if that is so there is a .shift executed. This is done to be later used in the graph function. Than there is a call for the next function, that is the updateNodeData and that will acctually find the right html id coresponding with the right reading to update that.
|
||||
|
||||
```js
|
||||
// If the array for this node has more than 10 elements, remove the oldest one
|
||||
if (sensorData[nodeNumber].length >= 10) {
|
||||
sensorData[nodeNumber].shift();
|
||||
}
|
||||
}
|
||||
|
||||
function createNodeData(node) {
|
||||
// Create main div
|
||||
var nodeData = document.createElement("div");
|
||||
nodeData.className = "nodeData";
|
||||
updateNodeData(nodeNumber, temperature, humidity, CO2, TVOC);
|
||||
```
|
||||
|
||||
// Create flex-NodeData div
|
||||
var flexNodeData = document.createElement("div");
|
||||
flexNodeData.clsName = "flex-NodeData";
|
||||
|
||||
// Create p element
|
||||
var pNode = document.createElement("p");
|
||||
pNode.textContent = "Node " + node;
|
||||
|
||||
// Append p to flex-NodeData
|
||||
flexNodeData.appendChild(pNode);
|
||||
|
||||
// Create flex-LiveData div
|
||||
var flexLiveData = document.createElement("div");
|
||||
flexLiveData.className = "flex-LiveData";
|
||||
|
||||
// Create data divs (Temperature, Humidity, Light Intensity)
|
||||
var dataTypes = ["Temperatuur", "Luchtvochtigheid", "CO2", "TVOC"];
|
||||
var ids = ["temperature", "humidity", "CO2", "TVOC"];
|
||||
var statusIds = ["tempStatus", "humidStatus", "CO2Status", "TVOCStatus"];
|
||||
|
||||
for (var i = 0; i < dataTypes.length; i++) {
|
||||
var dataDiv = document.createElement("div");
|
||||
|
||||
var dataTypeDiv = document.createElement("div");
|
||||
dataTypeDiv.textContent = dataTypes[i] + ": ";
|
||||
|
||||
var pElement = document.createElement("p");
|
||||
pElement.id = ids[i] + node;
|
||||
pElement.textContent = "Not connected";
|
||||
|
||||
dataTypeDiv.appendChild(pElement);
|
||||
dataDiv.appendChild(dataTypeDiv);
|
||||
|
||||
var statusElement = document.createElement("div");
|
||||
statusElement.className = "statusElement";
|
||||
|
||||
var statusText = document.createElement("p");
|
||||
statusText.className = "statusText";
|
||||
statusText.id = statusIds[i];
|
||||
statusText.textContent = "Not connected";
|
||||
|
||||
statusElement.appendChild(statusText);
|
||||
dataDiv.appendChild(statusElement);
|
||||
|
||||
flexLiveData.appendChild(dataDiv);
|
||||
}
|
||||
|
||||
// Append flex-LiveData to flex-NodeData
|
||||
flexNodeData.appendChild(flexLiveData);
|
||||
|
||||
// Create flex-graph div
|
||||
var flexGraph = document.createElement("div");
|
||||
flexGraph.className = "flex-graph";
|
||||
|
||||
var graphDiv = document.createElement("div");
|
||||
|
||||
var graphP = document.createElement("p");
|
||||
graphP.textContent = "Live graph:";
|
||||
|
||||
var liveGraph = document.createElement("div");
|
||||
liveGraph.id = "liveGraph";
|
||||
|
||||
graphDiv.appendChild(graphP);
|
||||
graphDiv.appendChild(liveGraph);
|
||||
flexGraph.appendChild(graphDiv);
|
||||
|
||||
// Append flex-graph to flex-NodeData
|
||||
flexNodeData.appendChild(flexGraph);
|
||||
|
||||
// Append flex-NodeData to main div
|
||||
nodeData.appendChild(flexNodeData);
|
||||
|
||||
// Check if nodeDataLocation element exists
|
||||
var nodeDataLocation = document.getElementById("nodeDataLocation");
|
||||
if (nodeDataLocation) {
|
||||
// Append main div to nodeDataLocation
|
||||
nodeDataLocation.appendChild(nodeData);
|
||||
} else {
|
||||
console.error("Element with ID 'nodeDataLocation' does not exist.");
|
||||
}
|
||||
}
|
||||
In the last function there are 2 updates the first is to actually update the text to the right value that we are getting from the node, and the connection checker.
|
||||
|
||||
```js
|
||||
function updateNodeData(node, temperature, humidity, eCO2, TVOC) {
|
||||
// Update the temperature, humidity and light intensity values
|
||||
document.getElementById("temperature" + node).textContent = temperature;
|
||||
@@ -148,4 +73,4 @@ function updateNodeData(node, temperature, humidity, eCO2, TVOC) {
|
||||
document.getElementById("CO2Status").textContent = "Connected";
|
||||
document.getElementById("TVOCStatus").textContent = "Connected";
|
||||
}
|
||||
|
||||
```
|
56
docs/brainstorm/SoftwareDocumentatie/graph_classes.md
Normal file
56
docs/brainstorm/SoftwareDocumentatie/graph_classes.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Graphs
|
||||
|
||||
## Introduction
|
||||
|
||||
The graphs are used to display the data from the sensors. The data is collected by the raspberry pi and then displayed on the graphs. The graphs are made using the [plotly library](https://plotly.com/javascript/) .
|
||||
|
||||
## Requirements
|
||||
|
||||
### Live graphs
|
||||
- Every node has to have a live graph
|
||||
- The graphs has to be updated every 5 seconds
|
||||
- All the data from one node has to fit in one graph
|
||||
|
||||
|
||||
## Class diagrams
|
||||
|
||||
### Live graphs
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class liveGraph {
|
||||
+nodeId
|
||||
+cnt
|
||||
+timeArray
|
||||
+tempArray
|
||||
+humiArray
|
||||
+eco2Array
|
||||
+tvocArray
|
||||
makeGraph()
|
||||
updateGraph()
|
||||
updateData()
|
||||
}
|
||||
```
|
||||
|
||||
## Order of operations
|
||||
|
||||
### Live graphs
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Node
|
||||
participant Raspberry pi
|
||||
participant Website
|
||||
|
||||
Node->>Raspberry pi: sensordata via websocket every 5 seconds
|
||||
Raspberry pi->>Website: Node data via websocket if new data is received from the node
|
||||
Website->>Website: updateGraph()
|
||||
Website->>Website: updateData()
|
||||
```
|
||||
|
||||
1. Every node sends its data to the raspberry pi via websocket every 5 seconds
|
||||
2. The raspberry pi sends the data to the website via websocket if new data is received from the node
|
||||
3. The website updates the data coming from the raspberry pi on its own variables and arrays
|
||||
4. The website updates the live graphs every time new data is received from the websocket
|
||||
|
||||
|
Reference in New Issue
Block a user