diff --git a/arduino/node-code/node-code-1,3.ino b/arduino/node-code/node-code-1,3.ino index 6da239c..bf81745 100644 --- a/arduino/node-code/node-code-1,3.ino +++ b/arduino/node-code/node-code-1,3.ino @@ -1,3 +1,6 @@ +// Dano Bosch +// 14/2/2024 + #include #include #include diff --git a/arduino/node-code/node-code-final.ino b/arduino/node-code/node-code-final.ino index ecaa647..c8d1174 100644 --- a/arduino/node-code/node-code-final.ino +++ b/arduino/node-code/node-code-final.ino @@ -1,5 +1,5 @@ -// Sietse Jonker -// 09/02/2024 +// Sietse Jonker & Dano Bosch +// 13/02/2024 #include #include @@ -21,15 +21,16 @@ DHT dht(DHTPIN, DHTTYPE); Adafruit_SGP30 sgp; uint16_t TVOC_base, eCO2_base; -int counter = 0; +uint16_t counter = 0; float temperature = 0; float humidity = 0; -int eCO2 = 0; -int TVOC = 0; +uint16_t eCO2 = 0; +uint16_t TVOC = 0; bool noise = false; void resetValues() { - TVOC_base, eCO2_base; + TVOC_base; + eCO2_base; counter = 0; temperature = 0; humidity = 0; diff --git a/docs/Sp1SchetsProject/FirstDesign.md b/docs/Sp1SchetsProject/FirstDesign.md index 77a9c22..e2a7ff3 100644 --- a/docs/Sp1SchetsProject/FirstDesign.md +++ b/docs/Sp1SchetsProject/FirstDesign.md @@ -1,9 +1,9 @@ -## The First Designs -The first designs are made using a pencil and paper, because we want a clear view of the direction we want to go in. The Design of the nodes that are being put around school, wil have a compact and simple look. -![The First Node Sketch](../assets/ImagesSp1/sp1NodeSketch.jpg) +## The First Designs(led By Bram) +The first designs are made using a pencil and paper, because we want a clear view of the direction we want to go in. The design of the nodes that are being put around school, wil have a compact and simple look. +![The First Node Sketch(Bram)](../assets/ImagesSp1/sp1NodeSketch.jpg) On the top of this, page the front of the node is visable. This front shows a screen , a bar with led's ( wich is used to show how much sound is picked up on the node.), and a hexagon grid where the sensors are located behind. -This way we can have enough airflow and more senso pickups. +This way we can have enough airflow and more sensor pickups. On top of the node there are two lights. These indicate if the air is too warm for comfort, so the cleaners are aware of the the current studying climate. @@ -13,7 +13,7 @@ The nodes will be powerd by batteries and wil be mounted on walls around eye hei Next up is the central node that has a questionaire built into it. -![The First Questionaire Node Sketch](../assets/ImagesSp1/Sp1questionBoxNode.jpg) +![The First Questionaire Node Sketch(Bram)](../assets/ImagesSp1/Sp1questionBoxNode.jpg) On the top Of the page The front of the node is drawn. The node has two screens to show both the statistics and the questionaire. On the node, three Buttons are show wich the user can press in order to take the questionaire. @@ -22,4 +22,20 @@ This node still has all the sensors like all of the others, except this one has The locations for the nodes are still unsure but what is certain is that the questionaire node will be placed besides the water fountain and cofemachines. This location is frequently visited and is a wel known spot. -The people going for a cup of coffee often have to wait for it to be finished, so we can take advantage of that time by giving them a short questionaire that they can comforably fil in while their cofee is being made. \ No newline at end of file +The people going for a cup of coffee often have to wait for it to be finished, so we can take advantage of that time by giving them a short questionaire that they can comforably fil in while their cofee is being made. + +### Feedback + +As for feedback, we got a lot of positives, but also a few critic points. +`the LED's could be seen as distracting. + +That is why we decided to remove them intirely. THis wat the lights can't be distracting and the focus can remain on the statistics. + +`The whole ventilation look is a bit too crowded and messy. + +That is why we will shrink down the size of the hexagons and make them less obvious. + +We also redesignd the shell shape. it now curves inward in order to lock the statistics screen in place. + +Here is an updated version ready to be printed. +![3D design by Sietse](../assets/ImagesSp1/Sp13DDesignUpdated.png) \ No newline at end of file diff --git a/docs/assets/ImagesSp1/Sp13DDesignNode.png b/docs/assets/ImagesSp1/Sp13DDesignNode.png new file mode 100644 index 0000000..3c25e59 Binary files /dev/null and b/docs/assets/ImagesSp1/Sp13DDesignNode.png differ diff --git a/docs/assets/ImagesSp1/Sp13DDesignUpdated.png b/docs/assets/ImagesSp1/Sp13DDesignUpdated.png new file mode 100644 index 0000000..b7b69e5 Binary files /dev/null and b/docs/assets/ImagesSp1/Sp13DDesignUpdated.png differ diff --git a/docs/assets/ImagesSp1/Sp1NodeBottomSide.png b/docs/assets/ImagesSp1/Sp1NodeBottomSide.png new file mode 100644 index 0000000..88ccffb Binary files /dev/null and b/docs/assets/ImagesSp1/Sp1NodeBottomSide.png differ diff --git a/docs/assets/ImagesSp1/Sp1NodeUpperSide.png b/docs/assets/ImagesSp1/Sp1NodeUpperSide.png new file mode 100644 index 0000000..3050dd1 Binary files /dev/null and b/docs/assets/ImagesSp1/Sp1NodeUpperSide.png differ diff --git a/docs/assets/ImagesSp1/Sp1NodeUpperSideNew.png b/docs/assets/ImagesSp1/Sp1NodeUpperSideNew.png new file mode 100644 index 0000000..fd490b7 Binary files /dev/null and b/docs/assets/ImagesSp1/Sp1NodeUpperSideNew.png differ diff --git a/docs/assets/ImagesSp1/assemblyOfNodeSideview.jpg b/docs/assets/ImagesSp1/assemblyOfNodeSideview.jpg new file mode 100644 index 0000000..9804245 Binary files /dev/null and b/docs/assets/ImagesSp1/assemblyOfNodeSideview.jpg differ diff --git a/docs/assets/ImagesSp1/assemblyOfNodeTopview.jpg b/docs/assets/ImagesSp1/assemblyOfNodeTopview.jpg new file mode 100644 index 0000000..45df188 Binary files /dev/null and b/docs/assets/ImagesSp1/assemblyOfNodeTopview.jpg differ diff --git a/docs/assets/Technical/node casing v3.f3d b/docs/assets/Technical/node casing v3.f3d new file mode 100644 index 0000000..2401fc5 Binary files /dev/null and b/docs/assets/Technical/node casing v3.f3d differ diff --git a/docs/assets/Technical/node lower body.stl b/docs/assets/Technical/node lower body.stl new file mode 100644 index 0000000..430f183 Binary files /dev/null and b/docs/assets/Technical/node lower body.stl differ diff --git a/docs/assets/Technical/node upper body.stl b/docs/assets/Technical/node upper body.stl new file mode 100644 index 0000000..891d29e Binary files /dev/null and b/docs/assets/Technical/node upper body.stl differ diff --git a/docs/brainstorm/Feedback.md b/docs/brainstorm/Feedback.md new file mode 100644 index 0000000..ef24117 --- /dev/null +++ b/docs/brainstorm/Feedback.md @@ -0,0 +1,36 @@ +# Feedback + +### Studieomgeving(Led by Sam) + +* "Betere zitplekken" +* "Mensen minder praten" +* "Geluidsgehalte lager in studieomgeving" +* "Zachtere lachten" +* "Minder domme mensen" + +### What are we going to do to improve the study area? +We are going to build multiple sensor nodes and hang them around study areas to measure the sound level. These nodes are going to send the data to a server, which is going to process the data and send it to the main node that is located at the coffee machine. This node is going to show the data so the student can quickly find a quiet spot to work. + + +### Feedback about physical node design(Led By Sam) + +* "Cool" +* "Goed" +* "Prima" +* "Is wel Nice" +* "Vet idee" +* "Duidelijker maken wat lampjes rechts doen" +* "Beetje te druk" +* "Display in midden" +* "Ventilatie niet in het midden focus niet op scherm" +* "Lampjes mischien afleidend" + + +### Conclusion(led by Bram and Sam) +We got a lot of positive feedback like "Cool" and "Vet idee". But we also got some feedback about the design of the node. + +We Wil use this Feedback and see what we can do to change the design in a way that is more accepted by our target audience. +The design will be updated to include: +`smaller holes for less distraction. +`ventilation at the bottom for better airflow. +`Remove the lamps on top of the node for less distraction. \ No newline at end of file diff --git a/docs/brainstorm/Questions Enquete.md b/docs/brainstorm/Questions Enquete.md index a695ce5..e826a51 100644 --- a/docs/brainstorm/Questions Enquete.md +++ b/docs/brainstorm/Questions Enquete.md @@ -1,5 +1,11 @@ # Questions -How clean are the toilets (clean, normal, disgusting) -How clean is the study area (clean, normal, disgusting) -What do you think of the temparature in the study area (hot, perfect, cold) +## Criteria +Questions shouldnt be able to measure using sensors. 3 possible answers. + +## Questions +How clean are the toilets? (clean, normal, disgusting). +How clean is the study area? (clean, normal, disgusting). +What do you think of the temperature in the study area? (hot, perfect, cold). +How crowded would you say the study area is?(not at all, its fine, really crowded). +Is there enough help available? (no, decently, yes). diff --git a/docs/node-documentation/node-design.md b/docs/node-documentation/node-design.md new file mode 100644 index 0000000..01fba8e --- /dev/null +++ b/docs/node-documentation/node-design.md @@ -0,0 +1,64 @@ +# Node Design + +## Design Process (led by sietse) +### Thoughts + +Before making the design i was thinking about the following things: + +- The node should be compact and simple +- The node should have a screen +- The node should have a bar with led's to show how much sound is picked up on the node +- The node should have a hexagon grid where the sensors are located behind +- The node should have two lights on top +- The nodes should be powered by batteries + +I also thought about the following things on how to make the design. I have decided to make the design using fusion360, because i have some experience with it and i think it is a good tool to make the design. I wanted it to be really easy to assemble so i split the design in two parts. The top and the bottom. The top part will be the part with the screen and the sensors, and the bottom part will be the part with the whole circuitboard. + +### Bottom design +I made the final design of sprint 1 using fusion360. I used the original drawing from Bram and modified it using the feedback we've got from the usertest. I begun making the bottom side of the node, because this could serve me as a template to make the rest. The bottom side was pretty easy to make because i only had to sketch and measure a few things. It eventually looked like this: + +![The Bottom Side of the Node](../assets/ImagesSp1/Sp1NodeBottomSide.png) + +### Top design +When i went to work on the upper side it took some more time than the bottom one. since i had to make cutouts for the screen and led bar and the hexagon grid. The hexagon grid was the hardest because i used the geometric pattern fucntion on my hexagon object and i had to make sure that there would still be room between the hexagons. I made it so the screens have like a indent on the top part. Otherwise the battery, sensors and esp32 wouldnt be able to fit underneath the grid. The final product looks like this: + +![The Upper Side of the Node](../assets/ImagesSp1/Sp1NodeUpperSide.png) + +### Assembly + +#### First assembly +The part was finished on 15/2 at 11am. I first screwed the pcb in the bottom part which was really easy to do. When trying to put the top part on the bottom part i noticed that the holes were not aligned, and the batteryholder was fatter than i thought. I tried to cut some material away from the top part but it was still not fitting. + +It looked like this from the top: + +![The Assembly of the Node Topview](../assets/ImagesSp1/assemblyOfNodeTopview.jpg) + +You can see that the oled screen cutouts and the led bar cutouts are not aligned with the components on the pcb. + +--- + +And like this from the side view: + +![The Assembly of the Node Sideview](../assets/ImagesSp1/assemblyOfNodeSideview.jpg) + +Here you can see that the wifi antenna of the esp32 is not fitting in the top part, because the fillet is too small. + +#### Second assembly +In fusion360 i made the cutouts for the screen and the led bar lower on the part. I also made the fillet on the top part a bit bigger, and adjusted the fillet on top too. We also decided we'd take this oppurtunitty to make vent holes in the bottom aswell. This is because hot air rises and with this there would be a little bit of air coming through the node for more accurate readings. I then printed the new design and it took around 7 hours. The new design looks like this: + + +![The New Upper Side of the Node](../assets/ImagesSp1/Sp1NodeUpperSideNew.png) + +The new design fits perfectly and looks like this: + +... + + +### Conclusion + +```mermaid +graph LR +A[Design Sketch] -->|Usertest| B(Fusion360 design) +B -->|Not fitting| C[New fusion360 design] +C -->|assembly| D[Finished product] +``` \ No newline at end of file diff --git a/docs/rpi-documentation/Reverse Proxy.md b/docs/rpi-documentation/Reverse Proxy.md new file mode 100644 index 0000000..e82b736 --- /dev/null +++ b/docs/rpi-documentation/Reverse Proxy.md @@ -0,0 +1,46 @@ +### Reverse proxy + + +#### Introduction +A reverse proxy is for example used to host 2 services on the same port. This is useful for us because we can use the same port for the websockets and the webserver. + +#### How to use a reverse proxy +We are going to use `Apache2` as our reverse proxy. This is because it is easy to use and has a lot of documentation. It also hosts our webserver so it is easy to configure and we don't have to install another program. + +#### Additional modules +We need to enable the `proxy` and `proxy_wstunnel` modules. These are used to proxy the websockets. + +You can install them with these commands on a Raspberry Pi. For other linux distributions its may be different. + +```bash +$ sudo a2enmod proxy +$ sudo a2enmod proxy_wstunnel +``` + +#### Script +The enabled apache2 config scripts are found in `/etc/apache2/conf-enabled/`. You can create a new file with the name of your service. For example `studyarea.conf`. +```apache + + DocumentRoot /home/pi/www/html/ + + # Enable proxying WebSockets + ProxyPass /ws ws://localhost:8001/ + + # Enable proxying HTTP + ProxyPass /ws http://localhost:8080/ + +``` +Because VirtualHost is listening on port 80, we can use the same port for the webserver and the websockets. The `ProxyPass` is used to proxy the websocket. The `/ws` is the path where the websockets are hosted. Its hosted on `localhost/ws` so it kinda creates a new subdomain for the websocket. The `localhost:8001` is the address of the websockets and the `localhost:8080` is the address of the webserver. + + +`DocumentRoot` is the path where the files are for the website. + + + +### Sources: + +* https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html +* https://www.serverlab.ca/tutorials/linux/web-servers-linux/how-to-reverse-proxy-websockets-with-apache-2-4/ +* https://gist.github.com/mortenege/91ec6fe02dca6f736303a00f8cea2731 +* https://www.jscape.com/blog/forward-proxy-vs-reverse-proxy#:~:text=While%20a%20forward%20proxy%20proxies,is%20providing%20file%20transfer%20services. +* https://webmasters.stackexchange.com/questions/143106/functional-difference-between-proxypass-and-proxypassreverse-in-apache \ No newline at end of file diff --git a/docs/rpi-documentation/websockets.md b/docs/rpi-documentation/websockets.md index c5a612e..b04b637 100644 --- a/docs/rpi-documentation/websockets.md +++ b/docs/rpi-documentation/websockets.md @@ -7,8 +7,14 @@ With websockets you can establish a connection between the client and the server ### How to use websockets There are different languages to serve websockets with, but we are going to use Python with the library `websockets`. This library is easy to use and has a lot of documentation. +## Issues + +### Ports +We can only use certain ports like 113, 80, 443. These are common ports and are not blocked by firewalls. Something in the network is blocking all other ports which makes it hard to use websockets. #### Sources: -* https://websockets.readthedocs.io/en/stable/index.html \ No newline at end of file +* https://websockets.readthedocs.io/en/stable/index.html + +**Written by Sam** \ No newline at end of file diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..8f1e261 --- /dev/null +++ b/web/index.html @@ -0,0 +1,70 @@ + + + + + + + + Climate-Measuring-Box + + + + + + +
+ +
+ + +
+
+
Temperatuur:

Not connected

+
+
+

Not connected

+
+
+
+
Luchtvochtigheid:

Not connected

+
+
+

Not connected

+
+
+
+
Lichtintensiteit:

Not connected

+
+
+

Not connected

+
+
+
+ + +
+
+

Live graph:

+
+
+
+
Time until POST request to API:

Connect to port

+
+
+

API data:

+
+
+
+ + + + + diff --git a/web/main.js b/web/main.js new file mode 100644 index 0000000..dcb0137 --- /dev/null +++ b/web/main.js @@ -0,0 +1,63 @@ +// Make lines in the graph of the live data +Plotly.plot("liveGraph", [ + { + x: timeArray, // Use timeArray as x values + y: newArrayTemp, + mode: "lines", + line: { color: "#80CAF6" }, + name: "Temperature", + }, + { + x: timeArray, // Use timeArray as x values + y: newArrayHumid, + mode: "lines", + line: { color: "#FFA500" }, + name: "Humidity", + }, + { + x: timeArray, // Use timeArray as x values + y: newArrayLight, + mode: "lines", + line: { color: "#00FF00" }, + name: "Light / 100", + }, +]); + +let cnt = 0; + +// Update the graph every 1 ms +let interval = setInterval(function () { + var time = new Date(); + + var update = { + x: [[time]], + y: [[newArrayTemp], [newArrayHumid], [newArrayLight]], + }; + + var olderTime = time.setMinutes(time.getMinutes() - 1); + var futureTime = time.setMinutes(time.getMinutes() + 1); + + var minuteView = { + xaxis: { + type: "date", + range: [olderTime, futureTime], + }, + }; + Plotly.relayout("liveGraph", minuteView); + + apiGraph = document.getElementById("apiGraph"); + Plotly.newPlot( + apiGraph, + [ + { + x: dateArray, + y: valueArray, + }, + ], + { + margin: { t: 0 }, + } + ); + + if (cnt === 100) clearInterval(interval); +}, 1); diff --git a/web/styles.css b/web/styles.css new file mode 100644 index 0000000..ac30244 --- /dev/null +++ b/web/styles.css @@ -0,0 +1,128 @@ +body { + background-color: white; + align-content: center; + text-align: center; + font-family: "inter", sans-serif; + margin: 0; + } + + h1 { + opacity: 0.8; + color: black; + margin: auto; + width: 50%; + } + + h2 { + text-align: center; + color: black; + opacity: 0.8; + } + + p1 { + color: solid white; + } + + .liveGraph{ + width: 90%; + height: 100%; + + } + + .divCnt{ + text-align: begin; + } + + .apiGraph{ + height: 100%; + width: 90%; + } + + .statusElement{ + display:inline-block; + border: solid #1f82d3 2px; + border-radius: 10px; + width: 90%; + } + + .statusText{ + font-size: 20px; + } + + .flex-LiveData { + display: flex; + align-content: begin; + flex-wrap: wrap; + flex-direction: row; + justify-content: space-evenly; + gap: 5px; + padding: 10px; + } + + .flex-LiveData > div { + border: solid #1f82d3 2px; + padding: 15px 0; + font-size: 30px; + border-radius: 10px; + height: fit-content; + width: 30%; + } + + .flex-graph { + display: flex; + align-content: begin; + flex-wrap: wrap; + justify-content: space-evenly; + gap: 5px; + padding: 10px; + + } + + .flex-graph > div { + position: relative; + border: solid #1f82d3 2px; + padding: 15px 0; + font-size: 30px; + border-radius: 10px; + flex-basis: 95%; + } + + @media screen and (max-width: 850px) { + .flex-LiveData>div { + width: 100%; + } + } + + ul { + margin: 0; + padding: 20px 0; + } + + .navbar { + text-align: center; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + } + + a{ + padding: 10px; + color: black; + text-decoration: none; + font-weight: bold; + } + + li{ + display: inline-block; + padding: 10px; + margin: 0 5px; + border-radius: 5px; + transition: 0.3s; + } + .navbar a:hover { + background-color: #196bad; + } + + img { + max-width: 100%; + height: auto; + } + \ No newline at end of file