How I turned my height-adjustable desk into an IoT desk

In this article, I'll show you how I turned my manual height-adjustable desk into an automated IoT desk. I'll cover how to size and run the motors, and how to connect your IoT device to Google using Heroku as the public interface. In short, this project has two features. First: the table connects from Google Smart Home to Heroku using voice commands, and second: Heroku and the table itself communicate using the MQTT Internet of Things protocol. MQTT is a good solution for the Internet of Things and also for overcoming some of the other obstacles that we will have to face.

First of all, I will say that I did this project just to have fun. I hope you find the article entertaining and that it motivates you to take the time to do something of your own.

The same table

Hardware

The first and probably most difficult part of the job is redoing the table. In a previous life, the table had a detachable handle, it was located at the edge of the tabletop. At first I thought about attaching something to the handle hole without having to interfere with the design of the table. I purchased several drives to figure out how to attach the motor to the table, but to no avail. Then an idea appeared: a rod running the length of the entire table, which would connect its legs so that they would lower and rise at the same time. If I attach a suitable drive to the rod, then I can use a belt to connect the rod and the motor. It would also be possible to equip the table with a motor without interfering too much with its design.

Making a table for the balcony with your own hands

If the finished products are not satisfactory in size, appearance or cost, there is always the opportunity to assemble a folding structure yourself. Moreover, the process does not cause any particular difficulties.

To manufacture the structure, you need to stock up on material, hinges and fasteners. The tabletop can be cut from furniture board, thick plywood, chipboard or MDF.

What is the difference between MDF and laminated chipboard?

If slabs are used, it is recommended to finish the ends with an edge that matches the color. To do this, you will need an iron and a sharp knife to cut off the excess. When installing a table in a room decorated with wood, a wooden table top will look more harmonious.

An option is proposed for producing the simplest design of a folding table from furniture panels for a balcony.

Two parts made of chipboard will be used as supports (can also be made of wood, but we used what was at hand). You can make one support, but the table turns out to be quite large, so for the strength of the structure it is better to install two support elements that fold in different directions. You will also need two bars. One is for fastening the tabletop, the second is for fixing the supports.

Table. Materials and equipment for making a table.

RequiredIllustration
Furniture panel size 1000 x 500 mm

Bars 40 x 50 mm, length 600 mm (2 pcs.)

Laminated chipboard size 450 x 450 mm

Universal hinges (2 pcs.)

Furniture hinges (2 pcs.)

Self-tapping screws

Step 1.

The furniture board is varnished and dried.

Furniture board

If necessary, the tabletop can be polished (before applying paint)

Step 2.

Markings are applied to the wall to secure the block. It will be installed at a height of 700 mm from the floor. When carrying out work, you must use a level.

Step 3.

Using four self-tapping screws, the block is fixed to the wall.

Step 4.

At a distance of 30 mm from the edges, two door hinges are attached to it.

Step 5.

Two triangular parts are cut out of a piece of laminated chipboard (or the triangles are assembled from timber), which will serve as supports.

Assembling a triangular support from bars

The bars are fastened with self-tapping screws and a perforated corner. For reliability, all joints are glued with wood glue

Step 6.

Both support legs are applied vertically. Marks are made for attaching piano (furniture) hinges.

Step 7

Furniture hinges are attached with self-tapping screws to the legs and the wall.

The corners are held on piano hinges

This is what the supports look like when folded

Step 8

A block is attached to the inside of the tabletop (parallel to the first one). The distance from the outer edge is 200 mm.

Step 10. The table top is placed on top of a block with hinges attached to the wall. On the inside, it is attached with self-tapping screws to the free hinge flap.

The tabletop is supported by two short hinges located horizontally. There is a beam fixed under the tabletop

Folded table

A functional and reliable structure that does not take up extra space on the balcony is ready. If necessary, the table top rises, the legs move at an angle to the center and securely hold the structure.

Compact structures purchased from the manufacturer or assembled with your own hands, distinguished by budget and functionality, in some cases are irreplaceable interior items.

The Importance of Torque

After ordering the drive and belt I needed, I started looking on Amazon for a high torque motor.
And - oh, miracle! — I found many suitable engines! Or so it seemed to me... Having bought a small motor, I waited about a month for its arrival from China. I was so excited when the motor finally arrived! I couldn't wait for the weekend to finally put everything together and have my motorized desk. Things didn't go according to plan. I spent the day cutting a hole for a rod in the metal paneling of the table. At that point I only had hand tools, so the process took longer than I expected. Towards the end of the day I finished assembling the table and was ready to try it out.

I turned on the motor, the voltage on my desktop power supply and... nothing happened. A few moments later, the motor began to rotate and grind the teeth of the purchased belt. I learned two lessons from this: the belt obviously doesn't do the job, and "High Torque Motor" doesn't mean "I can lift anything." Second lesson: you need to look at the size of the motor compared to your fingers. Mine turned out to be tiny!

On the left in the photo is the motor and belt. At the top right is a motor attached to the table (you'll see more about what's going on later). Bottom right is the motor in position on the table.

Types of computer desks

Table models differ in their shape. The master chooses the shape of the product based on the size of the room, the location of other interior details, the design style, and the purpose of the table. The following types of structures are distinguished:

Suitable motor

To select the appropriate motor, it was necessary to calculate how much torque was required to raise the tabletop.
I was surprised at how easy it was to do. Torque is force multiplied by the length of the lever arm. Well, I had the lever arm (this is the handle of the table), I just needed to calculate the force that would easily turn the lever arm. I loaded the table by strapping a milk jug to the handle and gradually added water to the jug until the lever began to rotate. Turning the handle up with the jug filled, I made sure that the weight easily turned the handle. I found out that the lever arm length is 11 cm and the required force is 4 lbs. Substituting these numbers into the formula, I found out that the motor must produce a torque of at least 19.95 kgf.cm. And he began to look for him.

I decided to redo the table permanently. I knew that the rod passing through the middle of the table was hollow. By looking for a twin shaft motor, I could cut the rod and reassemble it with the motor in the middle. By purchasing two motors with a torque of 20 kgf.cm, I ensured that there was enough torque to lift the table.

On another fine Saturday, I disassembled my table into four parts, filing the motor shafts so that they could be used when assembling the rod. I made more holes in the metal to accommodate the motors. This time there was no belt: the motors were connected directly to the rod, the holes were quite large. As evening wore on, I reassembled the desk and loaded it with office supplies.

The top two photos are the motors fully installed on the table.
The two bottom photos are of an integrated rod that runs along the length of the table with the help of motors. I connected the motors and connected them to the power supply. When I turned on the power, I saw the table move! This time I was more confident because I had chosen the correct motor sizes. I doubled the engines power just to be sure, but it was amazing to see them moving!

However, let me clarify that the table was slow. I made a video to show a friend how the table works, but he had to turn on the time acceleration on the video so as not to watch 5 minutes of the table changing the position of the tabletop.

Option 1. Instructions for making a table for a manual router

Materials for making a milling table

To build a milling table you will need:

  • 4 square bars;
  • chipboard and plywood scraps, the dimensions of which are determined when constructing the table drawing;
  • hardware (nuts, bolts, screws, hinges, etc.);
  • jack;
  • metallic profile;
  • six-millimeter steel plate;
  • aluminum guides;
  • movable carriage-support (guide from the saw);
  • manual frezer.

Drawing of a homemade milling table (option 1)

In any case, before you start making any such table, the drawing must be completed indicating all dimensions and determining the location of the working elements relative to each other.

Step by step assembly

Let us consider in detail each step in the manufacture and fastening of each element of a homemade milling table.

1st step. To make a stationary base for the table, you will need bars and chipboard cuttings, from which we twist the legs and further strengthen the rigidity with the help of horizontal connecting panels made of plywood. In the right side part we cut a hole for the start button, which will be connected to the hand router.

2nd step. The table top is made of chipboard. We make it liftable together with a router, for which we install hinges and make an additional support base from 15 mm plywood.

3rd step. To move the workpiece smoothly along the table, for example, to cut a groove in it, a moving carriage-stop is used. We cut a groove in the tabletop for the guides of the movable stop and install a metal profile into it. You can use a guide from an old saw as a stop carriage.

4th step. We also make the longitudinal stop from chipboard and make it movable to adjust the gaps around the cutter. To ensure mobility, we cut perpendicular grooves in the upper part of the stop and fasten the stop to the tabletop with clamps. We cut a small groove in the middle to suck out chips and other milling waste.

5th step. From thin plywood we make a box with a hole for connecting a vacuum cleaner hose, which will remove dust and shavings formed during the milling process. We fasten the box behind the perpendicular stop.

6th step. We take a six-millimeter steel plate and screw it to the tabletop flush with the surface. During the fastening process, we make sure that its edges do not protrude above the tabletop, otherwise the parts being processed will cling to them. A manual router will be attached to the plate from below.

7th step. We attach the router by the aluminum base to the bottom of the plate using bolts, but do not forget to pre-drill holes for the bolts in the base. Attaching the hand tool to a removable plate rather than directly to the table saves routing depth and allows for easy cutter changes.

8th step. We are building a router lift. To do this, we use a car jack, which allows us to change the height of the cutter with maximum accuracy.

9th step. We remove the handles from the router and instead screw in aluminum guides, which we connect to the jack mechanism.

Design and video of a homemade milling table for a manual router

Before you start making a milling table, you need to accurately determine its design features. This article provides instructions on how to make a simple router table. For other details of the first assembly option, see the video below.

We check the reliability of fastening of all elements - and the milling table is ready with your own hands!

We offer several more models of wood milling machines made by yourself for your taste.

Turnovers are important. Final version

I finally realized that it all comes down to two things: torque and RPM.
It was necessary to find a motor with a sufficient number of revolutions at an already known torque. It wasn't that difficult. Although I did not find a dual shaft motor, I did find a right angle gearbox that converts a single shaft motor into a dual shaft motor.

Long story short, the next month was a month of waiting for the transmission from China, and the Saturday after the wait I had a table that moved at the right speed.


The last motor itself is on the left, and the installed one is on the right. A little hardware and a lot of software.

I wasn't happy with the huge power supply sitting on my desk just to control the height of the tabletop. In addition, in order to change the position of the table from one to another and back again, I swapped the wires. A small problem, but the design was made to ideally just press a button and have several height presets.

Height-adjustable desk: advantages and disadvantages

The main advantages of the structures under consideration include:

  • The ability to alternate body positions during long-term “sedentary” work.
  • Good adaptability. It is easy to choose the height for each individual.
  • A modern approach to workplace organization. In some cases this may be important.
  • Large lifting weight (more than 100 kg). For models with electric drive.
  • A wide range of. It will almost always be possible to select a model that best meets the requirements.


The mechanical mechanism is the most reliable due to its simplicity.
At the same time, there are also quite serious disadvantages:

  • Inconvenient mechanical adjustment method.
  • Cheap designs are characterized by a kind of “tremor” - when raised, the table surface can sway or tremble during operation.
  • Car lift models rely on electricity and require additional maintenance. For computer desks, it is not always possible to organize cable management using improvised means. The result is unexpected expenses.
  • High price.


Tabletops can also be adjustable and adjusted to specific angles.

Bluetooth

The first solution was to add Bluetooth to the table.
After all, it seems like almost every device in the house has Bluetooth, and the phone seems like a convenient control interface for something like my desk. So now I bought a motor controller board, a Nordic NRF52 Bluetooth board, distance sensors and started messing around with the controller firmware.

At the end of the article I will leave links to the software and firmware that I wrote for the project. Feel free to comment on the code: I don't do firmware professionally and would like some guidance.

As a quick introduction, the ESP32 is written in C++ using Arduino libraries to interface with the BLE Terminal app on the phone. Installing and configuring BLE is quite complex. First you need to create all the characteristics for the values ​​that you would like to control via BLE. Think of a characteristic as a variable in your code. BLE wraps a variable in many handlers to get and set the value of that variable.

The characteristics are then packaged into a service with its own UUID, which makes the service unique and identifiable from the application. Finally, you must add this service to the advertisement payload so that your service can be discovered by the device. When a remote device connects to your service and sends data via characteristics, the table recognizes that the user wants to adjust the height to a different preset and begins to move.

To adjust the height, the tabletop has a TFMini-S LiDAR sensor built into the bottom that determines the current height. It's a funny sensor: it's called LiDAR, but it's actually a laser. It uses optics and an LED to determine the flight time of IR radiation. One way or another, the sensor determines the height of the table. The control board then detects the difference between the current height and the requested height and starts the motor, which rotates in the desired direction. Some major parts of the code are below, but you can see the entire file here.

void setup() { Serial.begin(115200); Serial2.begin(TFMINIS_BAUDRATE); EEPROM.begin(3); // used for saving the height presets between reboots tfminis.begin(&Serial2); tfminis.setFrameRate(0); ledcSetup(UP_PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION); ledcAttachPin(UP_PWM_PIN, UP_PWM_CHANNEL); ledcSetup(DOWN_PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION); ledcAttachPin(DOWN_PWM_PIN, DOWN_PWM_CHANNEL); state_machine = new StateMachine(); state_machine->begin(*t_desk_height, UP_PWM_CHANNEL, DOWN_PWM_CHANNEL); BLEDevice::init("ESP32_Desk"); ... BLEServer *p_server = BLEDevice::createServer(); BLEService *p_service = p_server->createService(BLEUUID(SERVICE_UUID), 20); /* ——————- SET HEIGHT TO PRESET CHARACTERISTIC ————————————— */ BLECharacteristic *p_set_height_to_preset_characteristic = p_service->createCharacteristic(...); p_set_height_to_preset_characteristic->setCallbacks(new SetHeightToPresetCallbacks()); /* ——————- MOVE DESK UP CHARACTERISTIC ———————————————- */ BLECharacteristic *p_move_desk_up_characteristic = p_service->createCharacteristic(...); p_move_desk_up_characteristic->setCallbacks(new MoveDeskUpCallbacks()); /* ——————- MOVE DESK UP CHARACTERISTIC ———————————————- */ BLECharacteristic *p_move_desk_down_characteristic = p_service->createCharacteristic(...); p_move_desk_down_characteristic->setCallbacks(new MoveDeskDownCallbacks()); /* ——————- GET/SET HEIGHT 1 CHARACTERISTIC —————————————— */ BLECharacteristic *p_get_height_1_characteristic = p_service->createCharacteristic(...); p_get_height_1_characteristic->setValue(state_machine->getHeightPreset1(), 1); BLECharacteristic *p_save_current_height_as_height_1_characteristic = p_service->createCharacteristic(…); p_save_current_height_as_height_1_characteristic->setCallbacks(new SaveCurrentHeightAsHeight1Callbacks()); /* ——————- GET/SET HEIGHT 2 CHARACTERISTIC —————————————— */ … /* ——————- GET/SET HEIGHT 3 CHARACTERISTIC ——— ——————————— */ … /* ——————- END CHARACTERISTIC DEFINITIONS —————————————— */ p_service->start(); BLEAdvertising *p_advertising = p_server->getAdvertising(); p_advertising->start(); xTaskCreate( updateDeskHeight, // Function that should be called "Update Desk Height", // Name of the task (for debugging) 1024, // Stack size NULL, // Parameter to pass 5, // Task priority NULL // Task handle); } There's a lot more going on in the file, but this code has enough context to understand what's going on. Note that we create and configure all BLE callbacks for all characteristics, including manual movement, setting and retrieving preset values, and most importantly, aligning the table according to the preset.

The image below shows the interaction with the characteristics for adjusting the table height. The final piece of the puzzle is the state machine, which knows the current table height, the user's desired height, and operates on those two values.

So finally I had a table that did everything I wanted. I could save heights to presets and retrieve heights from memory to set the desk to my favorite positions. I used BLE Terminal on my phone and computer so I could send raw messages to my desk and monitor its position. It worked, but I knew the battle with BLE was just beginning.


A bare bluetooth interface... All that remained at the moment was to learn how to write applications for iOS...

After all this, my wife said something that changed the whole project: “What if we made it controlled by your voice?”

In addition to being cool and adding a new device to the Google Assistant list, there was no need to write an application for iOS to control the table. And you no longer had to take out your phone to adjust the height. Another small victory!

How to choose

Before you go to the store, you should ask yourself, what kind of height-adjustable table do you actually need? First of all, you need to proceed from the tasks, the solution of which will justify the feasibility of such a purchase. The second important factor is size. Such tables are quite large in size, so it makes sense to take measurements in advance of the place where it should stand.


Such furniture adapts to a person’s height and ergonomics, which allows him or her not to slouch while working.

In general, it is recommended to pay attention to the following:

  1. Structural diagram. Mechanical lifting or using electric drives.
  2. Material. If a large load is expected (monitor, printer, system unit), it is better to choose models with a metal frame and a massive tabletop. Models for paper work may be simpler.
  3. Number of supports. Again, it all depends on the load.
  4. Maximum lift height.
  5. Frequency of use. How often is the height supposed to be adjusted?


Note! In some tables with a mechanical lifting system, the adjustment process is carried out using a pin in the corresponding hole on the support. This means that you will have to remove all objects from the countertop that could fall during this procedure, which is extremely inconvenient if such an action must be performed constantly.


Adjustable furniture is an excellent prevention of various diseases of the spinal column.

Adding IoT

Now let's talk about upgrading the table to voice control via Google Smart Home and how to connect it with Wi-Fi.
Adding Wi-Fi was easy enough. I replaced the Nordic NRF52 microcontroller with an ESP32 with built-in WiFi. Most of the software was portable because it was written in C++, and both devices could be programmed using Platform.IO and Arduino libraries, including tfmini-s, which I wrote to measure the current height of the table.

Below is the architecture of the table interaction system with Google Smart Home. Let's talk about the interaction between me and Google.

So, Bluetooth was turned on. It's time to figure out how to interact with Google Smart Home. This technology controlled the home using Smart Home Actions. What's interesting about its actions is that the service acts as an OAuth2 server, and not as a client. Most of the work done on the server involved implementing an OAuth2 Node.js Express application that reaches Heroku and acts as a proxy between Google and my desk.

I was lucky: there was a decent implementation of the server using two libraries. The first library, node-oauth2-server, was found here. The second express-oauth-server library for Express connectivity was found here.

const { Pool } = require("pg"); const crypto = require("crypto"); const pool = new Pool({ connectionString: process.env.DATABASE_URL }); module.exports.pool = pool; module.exports.getAccessToken = (bearerToken) => {...}; module.exports.getClient = (clientId, clientSecret) => {...}; module.exports.getRefreshToken = (bearerToken) => {...}; module.exports.getUser = (email, password) => {...}; module.exports.getUserFromAccessToken = (token) => {...}; module.exports.getDevicesFromUserId = (userId) => {...}; module.exports.getDevicesByUserIdAndIds = (userId, deviceIds) => {...}; module.exports.setDeviceHeight = (userId, deviceId, newCurrentHeight) => {...}; module.exports.createUser = (email, password) => {...}; module.exports.saveToken = (token, client, user) => {...}; module.exports.saveAuthorizationCode = (code, client, user) => {...}; module.exports.getAuthorizationCode = (code) => {...}; module.exports.revokeAuthorizationCode = (code) => {...}; module.exports.revokeToken = (code) => {...}; Next comes setting up the Express application itself. Below are the endpoints required for the OAuth server, but you can read the full file here. const express = require("express"); const OAuth2Server = require("express-oauth-server"); const bodyParser = require("body-parser"); const cookieParser = require("cookie-parser"); const flash = require("express-flash-2"); const session = require("express-session"); const pgSession = require("connect-pg-simple")(session); const morgan = require("morgan"); const { google_actions_app } = require(“./google_actions”); const model = require(“./model”); const { getVariablesForAuthorization, getQueryStringForLogin } = require(“./util”); const port = process.env.PORT || 3000; // Create an Express application. const app = express(); app.set("view engine", "pug"); app.use(morgan("dev")); // Add OAuth server. app.oauth = new OAuth2Server({ model, debug: true, }); // Add body parser. app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(express.static("public")); // initialize cookie-parser to allow us access the cookies stored in the browser. app.use(cookieParser(process.env.APP_KEY)); // initialize express-session to allow us track the logged-in user across sessions. app.use(session({...})); app.use(flash()); // This middleware will check if the user's cookie is still saved in browser and user is not set, then automatically log the user out. // This usually happens when you stop your express server after login, your cookie still remains saved in the browser. app.use((req, res, next) => {...}); // Post token. app.post("/oauth/token", app.oauth.token()); // Get authorization. app.get("/oauth/authorize", (req, res, next) => {...}, app.oauth.authorize({...})); // Post authorization. app.post(“/oauth/authorize”, function (req, res) {…}); app.get(“/log-in”, (req, res) => {…}); app.post("/log-in", async (req, res) => {...}); app.get("/log-out", (req, res) => {...}); app.get("/sign-up", async (req, res) => {...}); app.post("/sign-up", async (req, res) => {...}); app.post("/gaction/fulfillment", app.oauth.authenticate(), google_actions_app); app.get('/healthz', ((req, res) => {…})); app.listen(port, () => { console.log(`Example app listening at port ${port}`); }); There is quite a lot of code, but I will explain the main points. The two OAuth2 routes used by the server are /oauth/token and /oauth/authorize. They are used to obtain a new token or refresh expired tokens. Next, you need to make the server respond to Google's action. You'll notice that the /gaction/fulfillment endpoint points to the google_actions_app object.

Google sends requests to your server in a specific format and provides a library to help process those requests. Below are the functions needed to communicate with Google, and the entire file is here. Finally, there is the /healthz endpoint, which I'll cover at the end of the article.

The /gaction/fulfillment endpoint uses a middleware called app.oauth.authenticate(), the hard work of running the OAuth2 server went into making this middleware work. It verifies that the bearer token provided to us by Google refers to an existing user and has not expired. The route then sends the request and response to the google_actions_app object.

Google sends requests to your server in a specific format and provides a library to help you parse and process those requests. Below are the functions needed to communicate with Google, but you can view the entire file here.

const { smarthome } = require('actions-on-google'); const mqtt = require('mqtt'); const mqtt_client = mqtt.connect(process.env.CLOUDMQTT_URL); const model = require('./model'); const { getTokenFromHeader } = require('./util'); mqtt_client.on('connect', () => { console.log('Connected to mqtt'); }); const updateHeight = { "preset one": (deviceId) => { mqtt_client.publish(`/esp32_iot_desk/${deviceId}/command`, "1"); }, "preset two": (deviceId) => { mqtt_client.publish(`/esp32_iot_desk/${deviceId}/command`, "2"); }, "preset three": (deviceId) => { mqtt_client.publish(`/esp32_iot_desk/${deviceId}/command`, "3"); }, }; const google_actions_app = smarthome({...}); google_actions_app.onSync(async (body, headers) => {...}); google_actions_app.onQuery(async (body, headers) => {...}); google_actions_app.onExecute(async (body, headers) => {...}); module.exports = { google_actions_app }; When you add a smart action to your Google account, Google will issue a sync request. This request allows you to find out which devices are available from your account. Next comes the polling request: Google queries your devices to determine their current state.

When you first add a Google activity to your Smart Home account, you'll notice that Google first sends a sync request and then a polling request to get a holistic view of your devices. The last one is a request that Google tells your devices to do something.

Popular designs

Depending on the size of the room and how many people will use the table, choose its shape and size. There are several variations in design type:

  1. T-shaped - suitable for large rectangular rooms. The standard size is 80 x 160 cm. The desk has exactly these dimensions. If the tabletop will be used for holidays, then the product will be especially convenient - the birthday person can sit at the head, he has the opportunity to see everyone else. If the seats at the head of the table are unoccupied, then this part is the ideal place for decoration. Easy to approach from either side, making serving easy.
  2. U-shaped - suitable for rooms of any size. Suitable for coffee, office and kitchen tables. One of the most popular options.
  3. E-shaped - used in spacious rooms. Suitable for mass celebrations.
  4. Oval or round table. Not suitable for small spaces. Oval tables seat 4 people freely, round tables seat no more than 5.


T-shaped


U-shaped


E-shaped


Oval


Round

A large table is suitable for celebrations and holidays with many guests. Small size products are ideal for small families. Standard tabletop sizes are:

  • 4 people – from 80 x 120 to 100 x 150;
  • 6 people – from 80 x 180 to 100 x 200;
  • 8 people – from 80 x 240 to 100 x 260;
  • 12 people – from 80 x 300 – 100 x 320.


Standard tabletop sizes

According to their purpose, tables are divided into the following types:

  • office or computer;
  • kitchen;
  • low magazine;
  • dressing room with built-in mirror;
  • dinner table;
  • for TV.


Office


Kitchen


Low magazine


Dressing room with built-in mirror


Dining


For TV

Tables are classified according to the shape of the base:

  1. With 4 legs. A classic, the model is justified by the variety of materials and seating comfort.
  2. With 2 legs. There are options with two X-shaped legs or durable ones made of solid wood with a jumper at the bottom.
  3. Designer designs. There are tables with 3 legs, stylized in Baroque style. Options with one support have a round or oval shape; such a table can accommodate a large company.


With 4 legs


With 2 legs


Designer

Products are made from a variety of materials. The choice is determined by the purpose and operating conditions:

  1. Chipboard is a low-cost raw material. The low cost of the structure is reflected in wear resistance. These countertops don't last long.
  2. Fiberboard. A more expensive and reliable option. High moisture resistance, long service life.
  3. Solid wood. The products are characterized by durability and reliability. They look aesthetically pleasing and can easily be combined with any design solution. High quality natural material is expensive.
  4. Glass. Glass countertops are easy to clean from dirt and visually expand the space.
  5. Stone. In order to make a stone table, natural and artificial raw materials are used. The stone structure is heavy and dense.
  6. Mosaic. Mosaic elements can be ceramic glass or acrylic. Available materials include eggshells, shells, pebbles, and wood cuts.
  7. Boards. This product is easiest to make yourself. To increase the service life of furniture, tongue and groove boards are used.

By design, tables are either stationary or folding. The first are characterized by massiveness and high price. Folding options are easy to fold and move to the desired location; they are compact and convenient. This option is especially convenient for a small kitchen.


Chipboard


Fiberboard


Solid wood


Glass


Stone


Mosaic


Boards

“Features” (trait) of the Google Smart Home device

Google uses device features to provide user interface elements for managing your Google devices and to create voice control communication patterns.
Some of the features include the following settings: ColorSetting, Modes, OnOff, and StartStop. It took me a while to decide which feature would work best in my application, but later I decided on the modes. You can think of modes as a drop-down list where you select one of N predefined values, or in my case, height presets. I named mine "height" and the possible values ​​are "preset one", "preset two" and "preset three". This allows me to control my desk by saying, “Hey Google, set my desk height to preset one,” and Google will send the corresponding execution request to my system. You can read more about the features of Google devices here.

Materials and tools for work

The master needs to prepare the following set:

  1. Electric jigsaw.
  2. Drill.
  3. Fasteners (screws, screws, nails, metal corners).
  4. Wood impregnation compositions.
  5. Stain, acrylic varnish for surface decoration.
  6. Construction pencil.
  7. Roulette, level.

For retractable systems and shelves, it is necessary to select additional fittings (grooves, rollers for the retractable panel).

Project in action

Finally, Google Smart Home and my computer started communicating.
Previously, I used ngrok to run the Express server locally. Now that my server is finally working well enough, it's time to make it available to Google at any time. This meant hosting the application on Heroku, a PaaS provider that makes it easy to deploy and manage applications. One of the main advantages of Heroku is its add-ons mode. With add-ons, it's very easy to add CloudMQTT and a Postgres server to your application. Another advantage of using Heroku is that it is easy to build and deploy. Heroku automatically detects what code you are using and builds/deploys it for you. You can find more information about this by reading about Heroku Buildpacks. In my case, whenever I push code to Heroku's git remote, it installs all my packages, removes all development dependencies, and deploys the application, all with a simple "git push heroku main" command.

With just a few clicks, CloudMQTT and Postgres were available to my application, and I only needed to use a few environment variables to integrate these services with my application. Heroku did not demand money. However, CloudMQTT is a third-party add-on for $5 per month.

I believe the need for Postgres needs no comment, but CloudMQTT deserves more attention.

Existing varieties

Fundamentally, all such tables are the same: base, legs with height adjustment function and tabletop. Nevertheless, there are quite a lot of differences, some quite significant.


Convenience is achieved primarily by matching the parameters of furniture to the characteristics of a person’s physique. An adjustable table helps achieve this.

There are a number of criteria by which you can determine the type of table:

  • Adjustment method. Mechanical or using an electric motor.
  • Table top material. Glass, plastic, wood.
  • Form. Rectangular, round, corner.
  • Purpose. Children's, writing, computer, office.
  • Options. Monitor mounts, cable management, remote control, sockets.


Additional Information! The simplest (and cheapest) is a table with manual height adjustment. The presence of an automatic lift will significantly increase the cost of the design, so you should carefully weigh everything before going to the store!


Externally, the transformer consists of an adjustable base and tabletops of various shapes, designs and colors.

From the Internet to a private network. The hard way

There are several ways to provide access to an application or, in my case, an Internet of Things device.
The first is to open a port on my home network to expose the device to the Internet. In this case, my Heroku Express application will send a request to my device using the public IP address. This would require me to have a public static IP as well as a static IP for the ESP32. The ESP32 would also have to act as an HTTP server and listen to instructions from Heroku all the time. This is a large overhead for a device that receives instructions several times a day. The second method is called "hole punch". With it, you can use a third-party external server to allow your device to access the Internet without the need for port forwarding. Your device basically connects to a server, which sets an open port. Another service can then connect directly to your internal device by receiving an open port from the external server. Finally, it connects directly to the device using this open port. The approach may or may not be entirely correct: I only read part of the article about it.

There's a lot going on inside the hole puncher, and I don't fully understand what's going on. However, if you're interested, there are some interesting articles that explain more. Here are two articles I read to better understand hole punching: Wikipedia and an MIT article written by Brian Ford and others.

From Internet to Private Network via IoT

I wasn't very happy with these decisions.
I've connected a lot of smart devices in the house and never had to open a port on the router, so there was no port forwarding. Also, hole punching seems much more complex than what I'm looking for and is better suited for P2P networks. Upon further research, I discovered MQTT and learned that it is a protocol for IoT. It has several advantages such as low power consumption, configurable fault tolerance, and does not require port forwarding. MQTT is a publisher/subscriber protocol, which means that the table is a subscriber to a certain topic, and the Heroku application is the publisher of this topic. So Google contacts Heroku, this request is analyzed to determine the requested device and its new state or mode. The Heroku app then publishes a message to the CloudMQTT server deployed as an add-on on Heroku, instructing the table to move to the new preset. Finally, the table subscribes to the topic and receives the message published by the Heroku app, finally the table adjusts its height as requested! In the googleactionsapp file, you will notice that there is an updateHeight function that publishes one number in the MQTT topic for a specific device ID. This is how the Heroku app publishes a request to move a table in MQTT.

The last step is to receive the message on the ESP32 and move the table. I'll show some highlights of the code for the table below, and all the source code is here.

void setup() { Serial.begin(115200);
… tfminis.begin(&Serial2); tfminis.setFrameRate(0); ... state_machine = new StateMachine(); state_machine->begin(*t_desk_height, UP_PWM_CHANNEL, DOWN_PWM_CHANNEL); setup_wifi(); client.setServer(MQTT_SERVER_DOMAIN, MQTT_SERVER_PORT); client.setCallback(callback); ... } When the table boots up, we first start communication between the TFMini-S - the distance sensor - to get the current height of the table. We then configure the state machine to move the table. The state machine receives commands via MQTT and is then responsible for matching the user's request with the actual table height read by the distance sensor. Finally, we connect to the Wi-Fi network, connect to the MQTT server, and set up a callback for any data received on the MQTT topic we are subscribed to. Below I will show the callback function. void callback(char *topic, byte *message, unsigned int length) { ... String messageTemp; for (int i = 0; i < length; i++) { messageTemp += (char)message ;
} if (messageTemp == "1") { state_machine->requestStateChange(ADJUST_TO_PRESET_1_HEIGHT_STATE); } if (messageTemp == "2") { state_machine->requestStateChange(ADJUST_TO_PRESET_2_HEIGHT_STATE); } if (messageTemp == "3") { state_machine->requestStateChange(ADJUST_TO_PRESET_3_HEIGHT_STATE); } ... } The state machine logs the state change received in the MQTT topic. It then processes the new state in the main loop. void loop() { if (!client.connected()) { reconnect(); } client.loop(); state_machine->processCurrentState(); } The main loop performs several tasks: first, it reconnects to the MQTT server if it is not already connected. Then it processes all data received through the MQTT topic. Finally, the code executes by moving the tabletop to the desired location requested in the MQTT topic. That's all! The table is fully voice controlled and communicates with Google to receive commands!

Recommendations for selection

Since the range of corner work tables is quite wide, the buyer may simply get confused. Therefore, in order to make the right choice and purchase a really high-quality item that will be easy to use and will suit the interior, you need to follow some rules.

1. The appearance of the table plays an important role, but still, when choosing, first of all you should pay attention to the quality of its materials. Solid wood products are considered the most durable and durable, but their cost is quite high. The most affordable and practical tables are made of chipboard or MDF, and they also look no worse than models made of natural wood. It is important that the surface has a protective coating, all ends must be treated with a special tape, and the fasteners must be securely screwed and not loose.

2. You can always determine the reliability of furniture by the quality of fittings and moving elements. Conscientious manufacturers pay special attention to such aspects, since not only the appearance of the table, but also its functionality depends on them. The fittings must be carefully selected, firmly fixed, and made in the same style and color scheme. The moving elements of drawers and shelves should work smoothly and silently, without jamming or applying much force.

3. Before choosing a corner desk, you need to take measurements of the room. Otherwise, it will interfere with free movement around the room or will not fit at all in the area allocated to it. It is recommended to measure the angle for the table with a small allowance.

4. Furniture design can be anything. Tables with smooth, rounded shapes are quite popular, as they look more elegant, in contrast to models with straight, strict lines. The color of the product should be chosen depending on the palette of the overall interior of the room. A universal option is light wood or its imitation.

Above all, a corner desk should be comfortable, so it is recommended to sit at it before purchasing to make sure it is comfortable. All parameters of a piece of furniture, namely height, length, width and number of shelves, must be suitable for the person who will constantly use it.

Latest notes

The last endpoint I didn't mention is the /healthz endpoint.
This is because Google expects a fairly quick response, and loading the Heroku app on every request doesn't work for me. I set up a ping service to ping the /healthz endpoint every minute to keep the service up and ready to respond. If you plan to do something like this, remember that it will use up all the free hours at the booth. Everything is fine now: this is the only application used on Heroku. Plus, for $7 a month, you can upgrade to Heroku's Hobby plan with always-on app support. Creating an IoT device involves a lot of overhead at the beginning. I designed the hardware, built the control circuit, configured the MQTT server, wrote an Express OAuth2 server, and learned how to interact with Google Smart Home through actions. The initial overhead was huge, but I feel like I've achieved a lot! Not to mention, the MQTT server, Express OAuth2 app server and Google Smart Home Actions can be used for another project. Smart homes are interesting to me, and I may try to expand my repertoire of IoT devices to include sensors that monitor what's happening around my home and report it via MQTT. Sensors for soil monitoring, temperature and light sensors will be very interesting to monitor and analyze.

What's next?

Countertop heights are now measured unreliably at best.
I use a generally working infrared distance sensor TFMini-S. It has been noticed that the height of the table changes slightly throughout the day as the ambient lighting in the room changes. I ordered a rotation angle sensor to count the rotations of the rod as it passes through the table. This should give me more precise movements at any time of the day. I also have access to a server that I host in the basement. On it I can explore my own Mosquitto MQTT server, Node-RED and Express OAuth2 applications if I want to host something myself. Finally, now all the electronics are right on my desk. I plan to organize the devices so that everything is nice and neat! Thank you for reading the article! For convenience, I provide all the links.

  • Torque Calculator
  • 90 degree right angle gear box
  • BLE Terminal
  • Platform.IO
  • TFMini-S Arduino Driver
  • Google Smart Home Actions
  • Node OAuth2 Server
  • Express OAuth2 Server
  • ESP32 IoT Desk Server model.js
  • ESP32 IoT Desk Server index.js
  • ESP32 IoT Desk Server google_actions.js
  • Google Smart Home Device Traits
  • NGROK
  • ESP32 IoT Desk Firmware
  • Node-RED
  • Heroku
  • Heroku Hobby Plan
  • Heroku Buildpacks
  • Wikipedia Hole Punching
  • MIT Paper on Hole Punching by Bryan Ford et al.

  • C++ developer

More courses

  • Data Science Profession Training
  • Data Analyst training
  • Profession Ethical hacker
  • Frontend developer
  • Profession Web developer
  • Course "Python for Web Development"
  • Advanced course “Machine Learning Pro + Deep Learning”
  • Machine Learning Course
  • Course "Mathematics and Machine Learning for Data Science"
  • Unity game developer
  • JavaScript Course
  • Profession Java developer
  • Data Analytics Course
  • DevOps course
  • Profession iOS developer from scratch
  • Profession Android developer from scratch
Rating
( 1 rating, average 4 out of 5 )
Did you like the article? Share with friends:
For any suggestions regarding the site: [email protected]
Для любых предложений по сайту: [email protected]