Introduction: How to Build an Accurate Wind Tunnel Connected to the Cloud
The aim of this project was to build a tool that could measure the lift/downforce of aerodynamic components. By pairing this with an air speed sensor, this build also allows you to calculate the lift coefficient of any model, so you can scale up your findings to larger objects. By hooking up the sensors to some wifi enabled microcontrollers, this tunnel can also be controlled and monitored wirelessly with all the data saved to the cloud for easy analysis. But don't worry if you don't fancy a computer science project! We have made all the code available, so you can focus on just the tunnel if you prefer.
We've trawled through the research papers and spoken to formula 1 wind tunnel engineers to make our tunnel as accurate as possible within the scope of a small-scale, student project. It was no surprise that there are a few key shapes and ratios to conform to when designing an accurate wind tunnel. You will find all these explained in the relevant sections. All 3D files are also available.
Supplies
Parts Overview
- MDF panels (we used 9mm thickness)
- Perspex (6mm)
- 3D printed parts
- Wood screws (15mm minimum)
- M4 bolts
- M5 bolts
- Hot glue (glue gun)
- Tape
Electronics Overview
- Wifi enabled microcontrollers
- Dual driver MOSFET
- Fan + Power Supply
- Air pressure sensor
- Pitot tube
- Load cell + Amplifier
- Temperature sensor
- DHT11 Temperature sensor
- 12V power supply for microcontrollers
Step 1: Design
A typical wind tunnel can be broken down into three parts: An intake, a test section and a diffuser. The intake smoothly funnels the air into the test section, where the model you are testing sits. After flowing over the model, air then reaches the diffuser, which gradually expands again as air is pulled through by the fan at the end.
Intake
From a design perspective, the intake is the most challenging section. Many small scale tunnels adopt flat panels to channel air into the test section. However, studies have shown the optimal shape to produce the most normal airflow patterns (and thus produce accurate results) is the curve of a specific 5th degree polynomial. Like any other function, you can graph it and transform it so it fits your desired dimensions. We've made a walkthrough guide in Desmos to easily form an equation to fit any sized tunnel.
But how can you get this shape into 3D? Thankfully, the Equation Driven Surface plugin for Fusion 360 turns this into a quick task. Simply type in your equation, the bounds you'd like to draw it between and how often it should generate a point.
Note: The ratio between the intake cross sectional area and the test section cross sectional area should be in the range 6-10. We chose 8 (a 60cm intake and a 21cm test section).
Test section
This section is just a rectangular box. As long as you conform to the area ratio, you can't go too wrong. It's length should be 0.5-3 times its diameter.
Another key consideration regarding the test section is how large of a model you can test in it. It is recommended that the front profile of any test object does not fill more than 10% of the cross section of the test section. Many studies tighten this to 5%. Therefore, you should consider any specific models you would like to test, and choose a suitable test section size accordingly.
Diffuser
The diffuser has two functions. It is essential for reducing the turbulence from the fan that reaches the test section, and for allowing the pressure to normalise, which stabilises the flow and improves the accuracy of experimental results.
Because the test section has a smaller diameter than the intake and diffuser, air must speed up through this section. This is due to Bernoulli's principle, which explains the Venturi Effect that occurs with this tunnel design. This acceleration of the air is intentional: higher air speed means more lift is produced.
Note: The cross sectional area of the fan opening divided by the cross sectional area of the test section should be between 2 and 3. The expansion angle of diffuser panels must not exceed 6 degrees. We chose 5 degrees.
Electronics
There are many ways you could design the electronics solution to achieve the aims we set out.
To measure lift/downforce, we opted for a load cell. This also requires an amplifier board for the microcontroller to receive a useable signal.
To measure the air speed, we have a MPXV7002DP pressure sensor attached to a pitot tube that is mounted on the roof of the test section. We also have a DHT11 temperature sensor so we can adjust the air density value when calculating lift coefficients.
In order to vary the airspeed in the tunnel by electronic means (rather than a costly variable power supply or manual potentiometer), we used a MOSFET. This allows the voltage supplied to the fan to be changed via a PWM signal from the microcontroller. Most budget friendly fans do not have inbuilt speed control.
We used 3 WiFi enabled microcontrollers to manage these sensors. It is very possible to run these sensors from a single board, however using multiple makes the cloud integration easier, as is explained later.
Step 2: Build - Diffuser
Supplies for this step:
- MDF board
- Wood screws
- Fan
Step 1
Screw all 4 MDF side panels into each other. The shape is symmetrical however the top and bottom panels are longer so they overlap with the sides. This allows a screw to secure them: 9mm MDF is a perfect thickness as wood screws can go into the short edge with no issues. Ensure the screws go in horizontally, or they might cause bumps in the MDF.
Step 2
Screw end panel on. This will significantly improve the rigidity of the diffuser.
Step 3
Attach fan.
We chose a 14 inch fan as this fit within the ratios required for our test section size. Specifically, it is a 12V car radiator cooling fan. Radiator fans are generally well suited due to their slim profiles and very safe voltage draw.
Step 3: Build - Test Section
Supplies for this step:
- MDF board
- Wood screws
- Perspex
- Glue
- Pitot tube + tubes
Step 1
Glue the perspex panels into each side panel. As we had access to a CNC, we could set our 6mm perspex flush with the 9mm MDF by glueing it onto a protruding lip in the MDF. An alternative would be to use 9mm perspex lined up with a full cutout.
Step 2
Screw side panels into the bottom test section pannel. The top panel is needed for access, and seals under its own weight.
Step 3
Attach the wooden legs to the underside of both test section and diffuser with glue. The legs on the diffuser have an angled top face to ensure full contact.
Step 4
Push the air speed tubes through the hole in the test section roof and attach to the pitot tube inside the test section. Then glue in the pitot tube mount, so the pitot sits half way through the test section.
Note: The pitot sits a couple of centimetres away from the roof to ensure it is not within the ‘boundary layer’ - a phenomenon where air collects and moves slowly near to the walls of what it is travelling through due to friction. For this reason, you should also avoid testing models close to the walls.
Step 4: Build - Intake
Supplies for this step:
- 3D printed panels
- M4 nuts, bolts + washers
- Glue
- Tape
We designed the intake to be built in three rings. The smallest ring is made up of 4 panels, designed to be identical for ease of printing and assembly. The two larger rings are both made up of 8 panels - 4 identical corner panels and 4 identical straight panels each.
Step 1
Print the panels. We recommend printing at fast, lower quality settings to reduce print times. 0.4mm layer height and ~80mm/s print speeds were a good compromise for us. All panels have been designed with print times in mind: overhangs of mounts are 40 degrees so they don't require supports and we opted for slits instead of holes so there was no opportunity for dodgy hole overhangs to ruin the entire panel.
Step 2
Assemble each ring separately with bolts. A strip of tape on each join will ensure an airtight seal. Due to warping on the largest ring's panels (which came off a different printer) we also used hot glue here to ensure the rigidity of the ring. It would be preferable to reprint these panels, however we had just 6 hours across 2 days for this build.
Step 3
Line up the smallest ring with the test section and mark where the mounts need to be glued to the test section. Attach them and allow time to dry. This alignment is important, so it's better to attach the mounts now you have the first ring as a reference.
Step 4
Line the ring up with the test section. Place the wood support underneath the ring and ensure it is in contact with both underside panels. Attach the first ring with a bolt on each side.
Step 5
Line up the middle ring with the first and place wood supports underneath. Attach with 4 bolts and repeat for the final ring.
Step 5: Build - Wing + Strut
So your tunnel is mostly built...but you need to be able to test something. This is where the wing and its mounting strut come in.
Supplies for this step:
- 3D printed parts
- M4 nuts, bolts + washers
Step 1
Print the 2 parts of the strut, plus the wing and its mount. We printed a NACA2412, which is a specific wing profile with known characteristics that we could compare our results to. You can very easily model wings in Fusion 360 using the Airfoil Generator plugin. Don't forget that any wings you test can be printed at very low infill settings - only the outside faces matter!
Step 2
Glue the wing mount onto the wing. You could print the mount onto the wing directly, but this would require print supports potentially making the wing less smooth. The mount has inbuilt clearance, so when attached to the strut it can pivot to change the wing's angle of attack.
Step 3
With an M4 bolt, attach the wing to the thinner piece of the strut. Since this part will protrude into the test section, it has been designed as a wedge to reduce its affect on the airflow in the tunnel. Although it is shown fully assembled in the final image, hold fire with the larger, bottom section of the strut. This will be mounted later from underneath the tunnel, while the piece with the wing now attached will need to be dropped through the hole in the test section from above before you bolt them together.
Step 6: Electronics Intro
We decided to use Amazon Web Services IoT to stream data. AWS IoT is almost an industry standard at this point, used by organisations small and big. Even Formula 1 uses it to stream data from 100s of sensors, every second, to the cloud for processing.
You can build this entire tunnel without AWS, by simply wiring up a display like this to your microcontrollers and outputting the data there. However, we thought it would be cool to stream and store the data to AWS, which would help us with processing it and allow us to control/monitor the tunnel wirelessly.
Step 7: Electronics - Downforce
'Downforce Device'
Supplies for this step:
- Load Cell (we used a 3kg variant)
- Amplifier (HX711)
- ESP32 microcontroller (or similar)
Connect the HX711 amplifier to the load cell using the provided wiring diagram. Then, wire the HX711 amplifier up to an ESP32 microcontroller using our wiring diagram, or another microcontroller, and modify our code.
You will mount the load cell later in the calibration step.
Step 8: Electronics - Air Speed + Temperature
'Conditions Device'
Supplies for this step:
- ESP32 microcontroller (or similar)
- DHT11 sensor
- Air pressure sensor (we used MPXV7002DP)
For the Conditions device, wire up the DHT11 sensor and pitot tube sensor to another ESP32. Be careful with the pins on the pressure sensor; they are sometimes labelled ambiguously. If you decide to use different pins, ensure they support analog reading, and aren’t going to be interfered with due to WiFi. On an ESP32, pins 32 to 39 are the best to avoid this.
Step 9: Electronics - Fan Control
‘Fan Control Device'
Supplies for this step:
- WeMos D1 microcontroller - Similar to Arduino Uno. (Again, similar boards will work)
- MOSFET
- Power Supply (12V 10A in our case)
Finally, the Fan control device: the board which varies the voltage to the fan electronically. It does this by PWM (Pulse Width Modulation), however requires a MOSFET to do this with the high currents we are dealing with here. Here is a great explanation of how PWM works.
You only need a single pin for PWM. We used pin D6 on a Wemos D1 board, but you can use any analog pin. If you use a different microcontroller, for example an ESP32, ensure the pin you use is supported for analog read. After choosing the PWM pin, connect the other end of the wire to the PWM pin of the MOSFET dual driver, and connect GND to a ground pin on your microcontroller. Insert input wires from your power supply into the MOSFET’s Input terminals. Connect the output wires from the MOSFET driver into the fan connector. We also added a small heat sync to our MOSFET as it was getting very hot…and we had one lying around.
Step 10: Electronics - Power
To power the devices, there are multiple options. You could power each controller individually, via USB cables. You could also use another power supply, and power each microcontroller via the VIN pins. However, you must ensure your power supply supplies enough current for all your microcontrollers. We ended up using a combination of both.
Step 11: Software
Ensure you have the Arduino IDE, VSCode and Node installed on your computer for these steps.
Step 1
Sign up to AWS Console. This setup might take a few minutes, and might require you to enter a few details. Then navigate to the IoT Core panel through the search bar.
For each of the devices you set up in the previous electronics steps, set up a ‘Thing’ in IoT core. Give it a name (We used ‘ConditionThing’, ‘FanThing’, 'DownforceThing'), and then select auto-generate certificates. Next, on the ‘Attach policy’ page, choose ‘create policy’ and give it a meaningful name such as ‘WindTunnelPolicy’. Choose JSON on the right hand side and copy in our policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iot:Receive",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Finally, choose next and download the certificates. Now download the Device Certificate, Amazon Root CA 1 Certificate and Public and Private Key certificates. We have highlighted these in the first image for this step. Save and name them appropriately. Repeat this step for the rest of the devices, and ensure you know which certificates go with which device.
Step 2
This step depends on the microcontrollers used for the devices. If using ESP32 devices for all the devices, you can use our code as it is. Otherwise, you might need to modify it slightly.
First, clone our Github repository. Then, open the ConditionThing code, and in the secrets.h file, fill in your WiFi credentials, your AWS IoT endpoint and the device certificates you downloaded in the previous step. You can copy them by opening them in a text editor such as Sublime Text, and copy the content into the Arduino IDE. Repeat this step for the FanThing and DownforceThing.
Step 3
Flash each device with its corresponding code. After this, each device should start up, connect to AWS IoT and start the right tasks. You can now go to the AWS IoT Core console, and go to the MQTT Test Client tab. You can now send a message to the windtunnel/public topic, and see a message show in the Serial Monitor in Arduino IDE.
You now have cloud-connected microcontrollers! Just a few more steps…
Step 4
We can now setup rules for AWS IoT, so collected data will be stored in AWS DynamoDB. First, go to the Rules tab, under Message Routing. Create a new rule, and give it a meaningful name.
Then in the SQL tab, copy across the correct SQL statement for the correct thing:
ConditonThingRule:
SELECT content.timestamp AS timestamp, content.value_humidity AS humidity, content.value_temperature AS temperature, content.value_airspeed AS airspeed, content.run_id AS run_id, content.counter AS counter, content.device AS device FROM 'windtunnel/ConditionThing/pub'
FanThingRule:
SELECT content.timestamp AS timestamp, content.value AS value, content.run_id AS run_id, content.counter AS counter, content.device AS device FROM 'windtunnel/FanThing/pub'
DownforceThingRule:
SELECT content.timestamp AS timestamp, content.value AS value, content.run_id AS run_id, content.counter AS counter, content.device AS device FROM 'windtunnel/DownforceThing/pub'
In the next tab, choose the DynamoDBv2 action, and create a table in DynamoDB for your data. Next, click the Create new role button to create a role for data to be stored. Hit next, and create. Create rules for all your things, so that all your collected data will come through.
Step 5 (image 2)
Now, let’s set up the web client. From the Github repository, open the WindTunnelWebClientNoAuth folder in an IDE such as VSCode. Navigate to src then utilities, and open settings.ts, and replace the AWS region and IoT endpoint with your region and endpoint. Now, return to the AWS Console and search for AWS Cognito in the search bar. Create a user pool and an identity pool that uses this user pool. Go to IAM, and give the user pool access to AWS IoT. Then, copy the identity pool id from the console, and paste it to its appropriate place in the settings.ts file, and save.
Open command prompt or terminal on your computer, and navigate to the WindTunnelWebClientNoAuth folder. Run ‘npm install’ and after it completes, run ‘npm start’. Open the URL outputted by the shell, and you should see your webclient!
Step 12: Calibration
Supplies for this step:
- Load cell base (3D printed)
Step 1
Set up your load cells by printing out the given load cell base. Make sure it fits your load cell first. Then, screw in the load cell and attach the lower section of the strut you have from Step 5. Our load cell had M5 threads in one side and M4 in the other, so check yours carefully.
Step 2
You can now assemble your strut fully. Unscrew the top mount between test section and intake. Open the top panel of the tunnel and pass the thinner section of the strut, with your wing/object attached, through the hole in the bottom. You can now screw this in to the thicker, bottom section of the strut which has your load cell attached. This requires 2 M4 nuts and bolts.
Step 3
You’ll need to calibrate your load cells; every load cell has its own scale factor. Navigate to our source code and open the ESP32_LoadCellCalibration folder in the Arduino IDE. Flash your downforce thing with that code, and ensure the only weight on the load cell is the fully assembled strut and wing/object that is attached to the top of it. This is to calculate the 0 point.
Then, when the Serial Monitor prompts you to, add a known weight to the load cell, and leave it there until you see a number in the Serial Monitor. Record this value, remove the weight and wait to be prompted again. Repeat this a few times and take an average of the value. Finally, take the average reading and divide this by your known weight that you added to the load cell.
Navigate to the secrets.h file for the load cell you just calibrated, and replace the value for SCALE with your calculated value. Your load cell is now calibrated!
Step 13: Some Extra Details
Here are some extra details that are non-essential to the build, but explain a few decisions as well as the workings behind our codebase.
You might wonder why we have 3 separate microcontrollers rather than only have one connected to every sensor. Having many sensors connected to a single board would leave us quite restrained; in terms of physical space, as we would have to have every sensor very close together, and in terms of bandwidth there are limited pins available on each microcontroller.
Additionally, we decided to use a Real Time Operating System on the ESP32s. This is because ESP32 supports FreeRTOS, allowing us to run multiple tasks one by one, using the inbuilt scheduler. This is a better alternative to the traditional Arduino method, where each line of code only executes through the one loop() function. This could lead to issues; if publishing data takes time, we might lose out on collecting data while waiting for the publish to finish. By using tasks on FreeRTOS, we allow this to work without having this issue.
We also had to find a way to record the time on each device, as the ESP32 doesn’t directly have a way of incrementing time. We considered multiple options; using a physical clock connected to the board, grabbing the time via the NTP, or sending the timestamp ourselves. We decided to go with the final option, as it was the easiest to implement with our current code.
The flow of our code is another philosophy; when the device connects to AWS IoT, it sends a CONNECTED status to the status topic, to let us know it has successfully started up. Then, we send it a GOOD_MORNING message, to provide it with a timestamp to increment time from. When a START message is sent to the devices, they start sending data to AWS IoT, and stop when a STOP message comes through.
Furthermore, with measuring airspeed, we had a couple of options. One of them was to use an anemometer, and the other was to use a pitot tube. We decided to use the pitot tube, as it was less intrusive and affected the airflow inside tunnel much less.
Step 14: Uses
You can use this wind tunnel to test various things, from aerofoils to small models of cars and wings. Because you can calculate lift coefficients from the data this tunnel supplies, it is possible to scale up your findings to larger models (lift coefficient, denoted as Cl, is dimension independent).
It is an incredibly useful tool if you are developing an F1 in schools car, an RC plane or perhaps a rear wing modification for a real car. It is also great for demonstrating effects such as aerodynamic stalling and visualising flow patterns (by attaching tufts to models).
Step 15: Final Thoughts
Thank you for viewing our instructable. We’ve tried to share as much information as possible, so you can choose to make this project as challenging or straightforward as you like. Some additional useful sources are listed below.
Please do comment any questions or thoughts around this build! We still have features we’d like to add, such as a setup for measuring drag and a program to clean up the data and make calculations automatically. We hope to update this instructable in the future.
In case you missed the links earlier, you can find all our code here and all our 3D files here.
-Reuben and Parineet :)
NASA small scale wind tunnel project writeup
Useful research paper on wind tunnel design
ChatGPT - for when electronics won’t work…