pera: a water rocket that reports its own readings to a PHP dashboard
P.E.R.A. Water Data Collection System
At a glance
- What is it?
- pera is a student prototype that reads a water rocket's sensors on an Arduino, pushes each measurement from an ESP8266 with an HTTP GET, and stores it in MySQL behind a PHP dashboard for review. It is a good teaching example of an end to end telemetry path, and it ships in demo mode with an unauthenticated upload endpoint and credentials in its git history.
- Who is it for?
- Adopt pera if you are teaching or prototyping an end to end sensor path and want the firmware, the upload endpoint and the review UI in one small tree. Do not adopt it as a production data system, since the upload URL sits outside the dashboard login, the schema is inferred, the firmware ships in demo mode and the licence is not stated.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 23 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A student payload that measures itself
P.E.R.A. stands for Ponent Exploration and Research in Aerospace, and it is described as a LleidaDrone and Liquid Galaxy project for collecting water and atmosphere readings from a water rocket payload. The wider initiative, by the LleidaDrone Association, looks past the altitude range of typical drones and involves engineering students in atmospheric and space work.
The technical problem is modest and well defined. An Arduino reads a set of sensors on the rocket, an ESP8266 connected to it uploads each reading, and a small PHP and MySQL web application stores the rows so that a signed in user can review the logs afterwards.
The repository holds three things: the pitch, the dashboard, and the uploader sketch. There is a PDF with the project objectives and system description, a prototype video showing the hardware and the dashboard, the dashboard directory, and the firmware file.
The documentation is candid about the maturity. It calls this a student-era prototype, notes that the dashboard UI is an admin template, and says the firmware ships in demo mode. That framing matters for how you should read the rest of this, and it is also the main reason the project is worth looking at: the interesting part is the shape of the data path, which is complete from sensor to screen, not the polish.
The whole path fits in one diagram
The architecture section draws the flow from the sensors to the screen, and it is worth reading slowly because each arrow is a decision.
The chain starts with sensors, or demo stubs, feeding an Arduino sketch called LG_Water_Data_Uploader.ino. The sketch talks to the ESP8266 with AT commands over SoftwareSerial. The ESP8266 then makes an HTTP GET request to upload-waterdata.php. That PHP endpoint writes into a MySQL database called water-records, and the PHP dashboard, with its login and tables, is what a person finally looks at.
The parameters carried in the GET request are the reading itself, and the list is fixed: sea, lon, lat, stemp, atemp, hum, slp, ph, tds and rkt. Those are the sea name, longitude, latitude, sea temperature, air temperature, humidity, sea level pressure, pH, total dissolved solids, and the rocket identifier.
Each step of that chain is deliberately simple, and each one also carries a limitation. The GET is a query string on a public URL, which is easy to read and easy to forge. The sketch builds one reading at a time through a function called buildTelemetryRequest(). And the endpoint is described as validating the parameters and inserting a row with a prepared statement, which is the right way to write the insert and does not change the fact that the request itself is unauthenticated.
Building the dashboard: schema, environment file and vhost
The stack requirements are PHP 7.4 or newer, with 8.x working, with mysqli, MySQL 5.7 or newer or MariaDB, and a web server whose document root is the dashboard directory, or you adjust UPLOAD_PATH in the sketch instead. The firmware side needs the Arduino IDE with SoftwareSerial, which is built in.
The database is created by loading the schema file:
mysql -u root -p < dashboard/schema.sqlThe documentation is honest about that file. It is an inferred MySQL schema, none was committed originally, the column types and the timestamp column name recorded_at are inferred, and the details of the users and water-records columns live in CONTRIBUTING.md and in the schema file. If a live database already exists, compare names before importing.
Credentials go outside git, and the .env.example file says to copy it locally:
cp .env.example .envThe values to set are DB_SERVER, DB_USERNAME, DB_PASSWORD and DB_NAME, and process environment variables override the .env file. If nothing is set at all, the application falls back to localhost, root, an empty password and the database name lg-dashboard, which the documentation restricts to a local demo only.
Then you point the vhost at the dashboard directory, open login.php, and register the first account at register.php. Open registration is unchanged from the original app, which is a fact to know before the app faces a network.
Verifying the pipeline with one curl request
Before you wire a rocket to it, the documentation tells you to confirm that a row can be inserted, and it gives the exact request to send from the dashboard host.
curl -sS "http://localhost/upload-waterdata.php?sea=Bay%20of%20Bengal&lon=88E&lat=21N&stemp=293K&atemp=301K&hum=82%25&slp=101325Pa&ph=7.8&tds=740mgl&rkt=LG%20Rocket%202FA"The response tells you what happened. A valid row returns Success!, and empty or malformed parameters return HTTP 400.
This is a useful step rather than a formality, because it separates the two halves of the system. If the curl succeeds, the PHP endpoint, the schema and the database credentials are all working, and anything that fails afterwards is on the firmware side. The query carries every parameter the endpoint expects, including a value with a space in it, the rocket identifier LG Rocket 2FA, which shows that the endpoint handles the encoding correctly.
The value in the example is also a reminder of what this system is for. The sea name and the coordinates are the sort of reading a water rocket launched over water would produce, and the rkt parameter is what ties a row back to a specific launch.
The firmware ships with simulated readings until you wire sensors
The Arduino sketch is where the hardware knowledge lives, and the documentation walks through it in the order a person would actually do the work.
You open LG_Water_Data_Uploader.ino in the Arduino IDE and edit the block marked network configuration: HOST, WIFI_SSID, WIFI_PASS, and UPLOAD_PATH if the dashboard is not at the web root.
Then the important switch. Leave DEMO_MODE as true until real sensors are connected. With DEMO_MODE at its default of true, the values are simulated, and the sketch builds one reading through buildTelemetryRequest(). Set it to false and fill in the sensor stubs for real hardware, and the stubs are in the readLongitude(), readLatitude() and the other read*() functions. Those functions are the plug-in points where a real sensor driver goes.
The wiring is specific. ESP8266 RX and TX go to pins 2 and 3 for SoftwareSerial, and ESP_BAUD has to match the AT firmware baud rate. The serial monitor runs at 9600 baud and prints each AT command as it goes, starting with AT, then AT+CWMODE=1, AT+CWJAP and AT+CIPMUX=0, and then CIPSTART, CIPSEND and CIPCLOSE for each reading.
That log is the debugging tool. When a reading does not arrive, the AT transcript tells you whether the failure is in the Wi-Fi join, the socket setup or the request itself.
The upload endpoint is not behind the login, and the old password is in the history
Two security notes in the documentation deserve to be read before anything else, because both are permanent properties of the repository rather than settings you can change later.
The first is that the upload URL is not behind the dashboard login. The instruction is to treat it as a device endpoint and not to expose it on an open network without additional controls. The login protects the review pages, and the endpoint that writes rows sits outside it, so anyone who knows the URL can insert a row. The parameters are validated, and the insert is a prepared statement, but validation is not authentication.
The second is about history. Database credentials used to be hardcoded in dashboard/config.php and they are in the git history of the repository. The instruction is to rotate that password on any live MySQL host that used it, then set the new password only in the environment or in a local .env file, and never to commit the new value. The .env file and .DS_Store are gitignored.
The second note is the one that matters for a shared project. A password that is in git history is compromised for everyone who ever cloned the repository, and rewriting history does not un-clone it. Rotating on the server is the only step that actually fixes it.
The rest of the tree is also documented honestly. dashboard/icons and dashboard/plugins are leftovers from the admin template, with icon fonts, chart libraries and editors, and they are still referenced by the pages, so they stay in the tree with an explanation in CLEANUP.md.
What this prototype is for, and what to use instead of it
The honest framing is that pera is a teaching artefact with a complete path from a sensor to a screen, not a data platform, and knowing which one you are looking at decides what to do with it.
The alternative for a real deployment is a managed ingestion service or a general IoT platform, and the difference in approach is exactly the difference the prototype skips. Instead of a device posting a query string to a PHP file that writes to a MySQL table, a hosted service issues a device credential, authenticates every message, buffers it, and stores it in a time series store that is designed for irregular sampling and retention. The trade is the opposite of the one this project makes: the prototype has no dependency beyond PHP and MySQL and no vendor, while a hosted service removes the database work and the endpoint hardening and adds a dependency and a bill.
There is a middle option too, and it is the one a student team often reaches for: keep the firmware and the measurement logic, but write the readings to a file or push them to a general purpose queue instead of a bespoke PHP endpoint. That removes the web server and the schema inference from the picture while keeping the part of the project that is actually the interesting part.
Either way, the licence question is unresolved from the repository alone. The licence field on the repository is not classified, and the documentation does not state a licence for the code, so anyone planning to build on this tree should ask the authors rather than assume.
The project is not archived and the last push was on 2026-10-01, and there are no GitHub releases, so the working tree is the artefact.
Editorial conclusion
Adopt pera if you are teaching or prototyping an end to end sensor path and want the firmware, the upload endpoint and the review UI in one small tree. Do not adopt it as a production data system, since the upload URL sits outside the dashboard login, the schema is inferred, the firmware ships in demo mode and the licence is not stated. Verify first that you rotate any database password that the git history contains, that you put the upload endpoint behind a shared secret or a network control before anything points at it, and that the columns in dashboard/schema.sql match an existing live database before you import it.
Frequently asked questions
What is the P.E.R.A. water data collection system?
It is a LleidaDrone and Liquid Galaxy project for collecting water and atmosphere readings from a water rocket payload. An Arduino reads the sensors, an ESP8266 uploads each reading with an HTTP GET, and a PHP and MySQL dashboard is used to review the logs.
How do I set up the pera dashboard database?
Create the database and load the inferred schema with mysql -u root -p < dashboard/schema.sql, then copy the environment file with cp .env.example .env and set DB_SERVER, DB_USERNAME, DB_PASSWORD and DB_NAME. The schema and the recorded_at column name were inferred rather than committed originally, so compare names against an existing live database before importing.
How do I test the pera upload endpoint?
Send a GET request to upload-waterdata.php with the parameters it expects, which are sea, lon, lat, stemp, atemp, hum, slp, ph, tds and rkt. A valid row returns Success! and empty or malformed parameters return HTTP 400.
How do I switch the pera firmware from demo readings to real sensors?
Set DEMO_MODE to false and fill in the stubs in readLongitude(), readLatitude() and the other read*() functions, then edit HOST, WIFI_SSID, WIFI_PASS and UPLOAD_PATH in the network configuration block. The ESP8266 RX and TX wires go to pins 2 and 3, and ESP_BAUD must match the AT firmware baud rate.
Is the pera upload endpoint protected by the dashboard login?
No. The upload URL is not behind the dashboard login and should be treated as a device endpoint, not exposed on an open network without additional controls. The documentation also states that old database credentials are in the git history and must be rotated on any live MySQL host that used them.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/omairqazi29-pera)Was this useful?