Categories
Connected Devices and Networked Interaction

Assignment 3: Web-connected Environmental Monitor

The Idea

The project consists of developing a web-connected environmental monitor using a Raspberry PI  The device will send it’s data to a server via HTTPs every hour, whereas the RESTful API and it’s server will be provided to us. In this post I will go through several steps, starting at setting up our Raspberry Pi and later on setting up our environmental sensors and web client setup. You can find the code and circuit schematic at the end of the blog post.

The Process

Bill of Materials

Raspberry PI 4 Model B
DHT11 Temperature and humidity sensor.
SSD1306 LED Monochrome screen.
Female to female jumper cables.
USB to Serial Converter FT232RL.

Raspberry Pi 4 model B.
Raspberry Pi 4 model B.

Setting up the Pi

There are several approaches to setting up our pi, I followed Tom Igoe’s Setting up a Rasberry Pi guide in order to get it up and running. In a few words, we weill have to download the Rasbian OS into an SD card which we will insert into our Pi.Once we have our Pi with the SD card inside, we can look at the GPIO pins it has in order to identify it’s TXD and RXD pins. The TXD pin from our Serial to USB adapter will connect to the RXD pin on the Raspberry PI. The RXD pin in pur PI, consequently, will go to the TXD pin of our adapter. We also have to connect the GND pin in the adapter into a GND pin in the Pi. This will give our Pi and laptop a common GND.

GPIO Pin diagram
GPIO Pin diagram
GPIO pin detail.
GPIO pin detail.
Serial to USB adapter
Serial to USB adapter
Pi connections to UART to USB module.
Pi connections to UART to USB module.

There are tons of guides on how to talk through serial with you Pi through OSX. I used a windows OS with a Linux subsystem. To set this up I followed the following guide: Microsoft’s guide to setup Node with wsl in Windows. For the specific commands to talk to the Raspberry PI with a linux subsystem in windows I followed this guide made by Micheal Hirsch: Use USB-Serial adapters via Windows Subsystem for Linux. In any case, we need to check the COM port our computer recognizes connected with the PI. Once we have that, we can use our terminal to open the communication. 

COM port detected
COM port detected
Serial port command.
Serial port command.
Serial connection with Pi succesful
Serial connection with Pi successful

Now that we have our serial port open, let’s update our Pi so that it’s up to date with the latest updates from Raspbian. To do this we first need to access the Raspi-config menu to setup our network settings. With an internet connection available, it’s a matter of using apt-get as a super-user to update Raspbian. 

Raspi-config menu.
Raspi-config menu.
Distro-upgrade console log.
Distro-upgrade console log.

Getting the Data

SSH connection to the Pi

I did not want to have to have my serial connection up everytime I wanted to access my PI, so I decided to access it through SSH. the command is pretty straightforward, it’s just necessary to have a username, password, and the IP address of your device in the network you’re connected to. The IP address can be found with the  `ifconfig` command. This is demonstrated below. It is usually found after the “inet”.

IP address of your device.
IP address of your device.
SSH into PI.
SSH into PI.

DHT11 Temperature and Humidity Sensor

I decided to use a DHT11 temperature and humidity because it’s cheap, precise enough for a hobbyist project, and easy to find documentation. I also found an npm package called node-dht-sensor which would allow me to use the sensor directly with node, which seemed nice. Mainly I just grabbed the data given to me as an object by the node-dht-sensor package and separated it into Temperature and humidity. In the code you can identify this object called as ‘sensorReadings’. 

Log sensor data function.
Log sensor data function.

At this point I decided that logging the data was also my best option. So I wrote all of my logs into a ‘data.text file. This later served an unexpectedly to make my job of displaying the data much easier.

Log Success!
Log Success!
DHT11 temperature sensor.

The package website included a diagram for wiring the sensor. Even though the wiring is straightforward it was useful to see right away it didn’t involve a difficult setup. The sensor has a pin to 3.3V, another for GND, and one output pin to connect to the GPIO pin in the Raspberry PI. 

DHT11 Connection Diagram
DHT11 Connection Diagram

I wanted the sensor to be as precise as possible, so when I saw some examples with the library I wondered why there weren’t any float values. After looking around for a while, I foudn the following : “According to the data sheet, the accuracy of DHT11 is ±2℃. So reporting with decimals doesn’t make sense. If the sensor is reporting 22 degrees the temperature might be anywhere between 20 and 24.” (Taken from here). There is another model called the DHT22 which apparently has a lower variance of ±0.2℃, and I will use it next time. A degree or two of difference seems too unreliable for me.

SSD13106 OLED Monochrome screen

At first I thought I would use an ADC converter in order to get data on to the screen. However, after a couple of minutes google searching I was determined to find a way to do it with Node. I had a bunch of trouble using the rpi-oled package. However, the i2c package it required was almost impossible to install, and even then it would not work for me. So I decided to use oled-i2c-bus, which required a package called i2c-bus. It worked great since it was specifically made to avoid using the i2c package. At the end of this page I detail some issues I had working with the screen.

 In any case, I decided to use Moment.js to register the time which had passed since the last message was sent. IT would also read into

SSD1306 LED Monochrome screen.
SSD1306 LED Monochrome screen.
SSD1306 connected!
SSD1306 connected!
SSD1306 error
SSD1306 error. Grabbed from https://tinusaur.org/tag/ssd1306/.

I had this mistake several times while running my code, especially when cleaning the screen occurred right before I wanted to print a new message. I managed to solve this by creating an Asynchronous function out of the displaySensorData() function. In simple terms, I made the function wait for the screen to be cleaned and THEN print the new message. Sounds simple but solves everything.

Asynchronous function to clean the screen and make new message.

Sending the Data

Now came the fun part, sending the data. Fortunately, I had Tom Igoe’s Pi Recipes page, and his  NodeSensors Github repository with the project. One of the first things we had to do was obtain an authorization token from Tom in order to be able to push data into the server. To obtain the key we first needed to find our MAC Address. With the Raspberry PI there will be two MAC addresses: one called eth0 and another called wlan0. I quickly used a google search to find this “Eth0 and wlan0 are not assigned by your ip, eth0 and wlan0 are device names assigned by ubuntu. Eth0 is your ehternet connection and wlan0 is your wireless connection but sometimes wlan0 might be called eth1 instead it all depends on the driver your wireless card is using.” ( found here). In any case, we would be connecting through WiFi, so wlan0 is our address. 

With my MAC Address, the session key given to me, and my hostname I was ready to send the data as a json. This involved using the https npm package with requests. This can be seen in the Github repository.

mac Address Command.

Finding Mac Address
Finding Mac Address

Pre-case version

Cron Job

Response to my GET request.
Response to my GET request.

Making the case

I had thought about making a nice enclosure for the Pi, and had been thinking about 3D printing something for a while so I went with it. It had also been years since I’d opened a 3D modelling software so I decided to go with Blender. I found a Raspberry Pi case .stl file in Thingiverse (VERY recommended website for 3D models for printing.)which seemed cool, rigid, and easy to adapt to my sensor and screen.

3D case taken online.
3D case taken online.
Personalized case.
Personalized case.

To make the the case for my Pi I added two cube meshes that intersected the top face of the Raspberry Pi case .stl file. I later applied an object modifier unto the .stl imported mesh which deletes these two volumes. The result is shown above, and the process shown below.

Blender boolean operation.

I later exported this model in two different .stl files. One for the top half and another for the bottom. This was mainly due to time constraints. Below is the previsualization of the the model, the printing process,and the result.

Cura Ultimaker 3D Print
Cura Ultimaker 3D Print
3d printing model with Ultimaker 2+.
3d printing model with Ultimaker 2+.
Printed top half.
Printed top half.

Issues

Node and npm

At first, when I ran the node or the npm command nothing would appear. So I reinstalled npm and decided to uninstall that version of node and installed nodejs instead. 

Removing Node.
Removing Node.

Installing nodejs and npm correctly. Or at least in a way that it would work for me.

Install npm.
Install npm.
Install Nodejs.
Install Nodejs.

Code

Github Code: https://github.com/lacouture100/Connected-Devices-and-Networked-Interaction-Environmental-Pi-Monitor

Circuit Schematic

Circuit Schematic.
Circuit Schematic. Made with https://www.circuit-diagram.org/
Categories
Connected Devices and Networked Interaction

Assignment 2: Hue light control

Assignment 2: Hue Light Control

The Idea

The project consists of developing a controller to control a lightbulb using HTTP, specifically the Phillips HUE lightbulbs. The main idea was to use an Arduino Nano IoT with multiple sensors to control a light (or several) connected on the same WiFi network.

The Result

Final result!
Final result!

Bill of Materials

– 1 Arduino Nano IoT
– 3 5k potentiometers (like these)
– 1 Breadboard/ PCB (like these
– 1 OLED screen (like this)
– 1 LEDs (like these)
– 1 meter of 22awg wire (like this)
– 1 sheet of 12in x 12in Birch plywood

The Process

Using the Command Line

The system consists of an Arduino Nano 33 IoT connected the same WiFi network as the Phillips Hue Hub. The Hub works with Standard Wired ethernet and ZBee radio. To start, we have to know the private IP Address of the hub inside of the network. Fortunately we could see this IP Address right away.

Hue Hub with IP Address.
Hue Hub with IP Address.

To access the hub we would first need to create a user on it. You can find more detailed information on Tom Igoe’s Github Repository, but a short way of doing would be using your computer’s shell and introducing the command below:

  • curl -X POST -d ‘{“devicetype”:”NAME“}’ HUBIPADDRESS/api

And replace the NAME for one you prefer and HUBIPADDRESS for the Hub’s IP Address.
In my case, it looked like this:

  • curl -X POST -d ‘{“devicetype”:”alvaro“}’ http://172.22.151.185/api

Take into account you need to push the button on top of the Hub and then rapidly send the command in order for the procedure to work. In my case, I received a success message with a user name chosen by the hub. It means I have successfully added a user to the Hub. Mine looked like this: 

Hue User Success
Hue User Success

After we have our new username, we can now access the hub and the lights associated to it. We can find which lights we can access with the following command:

  • curl -X POST HUBIPADDRESS/api/GIVENUSERNAME/lights

Where GIVENUSERNAME is replaced by the username assigned to you by the Hub. After sending this command, the Hue will respond with an unformatted JSON telling you every parameter in the light you are trying to access.  

Hue Response
Unformatted JSON response.

The above message looks much clearer when you format it. I used VS Code and the Beautify plugin in order to format it fast.

Formatted JSON response.
Formatted JSON response.

As you can see, we have several parameters to modify.  Whether it is on or off, brightness, hue, and saturation are only some of them, but they’re the ones I decided to focus on. I decided to test whether I could now control them with my terminal before proceeding with the Arduino Nano.

Set Light Parameter.

Now that I had access to the hue and control as well, It was time to go to Arduino!

Arduino

Now that I had access to the hue and control as well, It was time to go to Arduino. I decided I wanted to control 3 parameters: Brightness, Hue, and Saturation. For testing purposes I first wanted to try my screen. To control the OLED display you need the adafruit_SSD1306.h and adafruit_GFX.h libraries. It took me a while to set it up, mostly because I later found you HAVE to clear the display before any new message. You can see the error that happened in the image below.

128x64 OLED screen error
128×64 OLED screen error
Screen working correctly!
Screen working correctly!
OLED txt snippet.
OLED txt snippet.

Anyway, I decided to utilize a handy function found in Tom’s Repo. The snippet allowed me to easily display any message on the screen. On the screen I printed some of the parameters I wanted to control while testing it’s performance. I decided to add a potentiometer for each of the parameters I wanted to control: three in total.

In order to send accurate values to the Hue I would need to map each potentiometer’s values to the parameter’s min and max range. So I started with Hue, since it was the funnest parameter to play with. I used Arduino’s map function in order to achieve this effect. Since the potentiometer’s values went up to 1023 and the Hue reaches 64000 on it’s hue parameter, we would have to map 0 – 1023 to 0 – 64000.

Mapping the potentiometer to Hue values.
Mapping the potentiometer to Hue values.

I would have to do the same with Brightness and Saturation, however their values had a much smaller range, from 0-255. Now, to display the Hue values being sent on-screen!

Potentiometer on screen.
Potentiometer on screen.

Once I knew the potentiometer was changing and reflecting this change on-screen, I tested it with the lightbulb on the Hue. And it worked!!! 

Arduino controlling light. Hooray!!
Arduino controlling light. Hooray!!
Setup on breadboard with two parameters.
Setup on breadboard with two parameters.

I modified the sketch so that it would display each of the parameters and their value while I was in control. The values would be attached to a JSON which would be sent through HTTP to the hub.

Displaying on-screen and sending the data.
Displaying on-screen and sending the data.

Now that the electronic setup was done, it was time to solder everything up and build an enclosure for it. From the beginning I knew I would use wood and a laser cutter to achieve the precise form I wanted (You can find the template for the laser cutter on the code repository below). At first I decided I would have:

 – An OLED screen to display the data
 – Three potentiometers/knobs to control each parameter.
– An LED to indicate connection
– An ON/OFF button
– A Neopixel ring which would preview the light’s state on the controller.

However, after tinkering for a while trying to find the color ranges on the Phillips hue and how I could translate these values on to the Neopixel ring, I decided to dispose of the feature due to time constraints. 

Cardboard Test for the UI.
Cardboard Test for the UI.
Cut wooden pieces.
Cut wooden pieces.
Preview of the whole build.
Preview of the whole build.
Assembly on to box.
Assembly on to box.
Booting up!
Booting up!
Final result!
Final result!

The Schematic

Circuit Schematic
Circuit Schematic

The Code

Code Repository with laser-cut files : https://github.com/lacouture100/Connected-Devices-and-Networked-Interaction-Assignment-2

Thanks for reading! 

Categories
Connected Devices and Networked Interaction

Assignment 1: Ball Drop Game

Assignment 1: Ball Drop Game

The Idea

The project consists of developing a controller to play Ball Drop Game,  a TCP sockets multiplayer game developed by Tom Igoe.  The main idea was to use an Arduino with multiple sensors to control a player through TCP sockets in a game running on someone’s computer. We learned about the various layers of protocol we need to build a network in order to build this communication. The physical layer and the datalink layer were defined by our hardware and their addresses, in this case the Arduino and the laptop connected to a same WiFi network.

The network layer and the IP adresses were managed by the local network, while the transport layer consisted of a TCP socket between each player(client) and the computer(server). We used sessions to open and close the connection to the server with a physical interface, and finally we sent characters through the connection as commands to the player on-screen. The game itself consists of a screen where each player is a bar, and the idea is to collide with a ball that falls from the top of the screen as many times as possible. 

 

The Video

Bill of Materials

– 1 Arduino Nano IoT
– 5 momentary buttons (like these)
– 1 Breadboard/ PCB (like these)
– 2 LEDs (like these)
– 1 meter of 22awg wire (like this)
– 1 sheet of 12in x 12in Birch plywood

The Process

The system consists of an Arduino Nano 33 IoT connected to five buttons and two LEDs. One of the LEDs indicates power while the other LED indicates connection. The array of four buttons displayed in a rectangular position are the controls for the game, UP, DOWN, RIGHT and LEFT.  The remaining button is used to connect and disconnect from the server.  Below you can see how the player would move in the game.

Ball game by Tom Igoe.
Ball game by Tom Igoe.

We had already connected in class through our computer terminal, and thanks to Tom Igoe’s example the process to implement the same protocol through the Arduino was straightforward. I also have to thank Tirta and Sam Krystal for helping me out with implementing the pull-up logic with the Arduino code Tom had shared. As you can see below, the circuit on the left used a setup where the resistors were connected to ground. On the right, there is no resistor going into ground, since the Arduino’s internal resistors “pull-up” the excess voltage.

First attempt.
First attempt.
Pull-up circuit.

After learning how to use the laser cutter I decided to iterate through cardboard before settling on a wooden enclosure using the plywood. The process wasn’t as fluid as I thought, since the laser cutter did not work perfectly and the seams would not fit sometimes. Anyways, I changed the layout several times until I was satisfied.

Cardboard iterations.
Cardboard iterations.
First prototype.
Several iterations later.

I then proceeded to solder the buttons and the wiring in order to have a button pad. The PCB I had was kind of frustrating to work with because it’s hole arrangement did not permit a symmetric disposition of every element.

Soldering buttons
Soldering buttons
Soldered buttons.
Soldered buttons.

Finally, I decided on the design below. I decided to go for a small breadboard because of its size and weight. I also added another LED, so one of them would indicate the device is on and the other indicates connection.

Enclosure and circuit board.
Enclosure and circuit board.
Drying prototype.
Drying prototype.

Circuit Schematic

Circuit Diagram.
Circuit Diagram.

The Code

Code Repository with laser cut template : https://github.com/lacouture100/Connected-Devices-and-Networked-Interaction-Assignment-1

Thanks for reading!