Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Garagem Privada — Controlo de Entradas e Saídas

Embedded Systems course project (Sistemas Embutidos 2023/24): a private-garage gate that detects an approaching vehicle with proximity sensors, relays the event to a cloud server, waits for a human to authorize the opening, and then drives the gate motor.

The distributed logic is written in Rust (async, tonic gRPC over Tokio); the sensor and motor firmware is Arduino C++ talking to the Raspberry Pi over USB serial.

Architecture

   ┌─── garage (local network) ──────────────────────┐
   │                                                 │
   │  Arduino #1 ──── USB serial (9600) ───┐          │
   │  2× IR proximity sensors (A0, A1)     │          │
   │  emits "proximity_alert"              ▼          │
   │                              ┌──────────────┐    │        ┌─────────────────┐
   │                              │ Raspberry Pi │    │  gRPC  │ DigitalOcean    │
   │                              │  `raspberry` │◄───┼───────►│ droplet         │
   │                              │  :50005      │    │        │ `droplet`       │
   │                              └──────────────┘    │        │ :55555          │
   │  Arduino #2 ──── USB serial (9600) ───▲          │        └─────────────────┘
   │  servo on pin 8                       │          │           operator says
   │  reacts to "SWITCH"                   │          │           Y/N to open
   └─────────────────────────────────────────────────┘

Two binaries share one crate:

Binary Entry point Role
raspberry src/raspberry_server.rs Runs on the Pi. Owns both serial links, hosts the Raspberry gRPC service.
droplet src/droplet_server.rs Runs on the cloud VM. Hosts the Droplet gRPC service, prompts the operator.

Request flow

  1. sensors.ino reads two Sharp GP2Y0A41SK0F IR sensors, converts voltage to distance (12.08 / (V - 0.25)) and prints proximity_alert on serial whenever either reading drops below 10 cm.
  2. util::arduino_sensors (spawned by RaspberryService::new) reads that serial line and issues a local gRPC RaspberryListener call with the alert.
  3. RaspberryService::raspberry_listener forwards the alert to the droplet and flips its block flag — while blocked, further alerts are ignored, so one approaching car produces exactly one authorization request.
  4. DropletService::droplet_listener answers ACK_RASPBERRY_REQUEST and spawns util::hold_for_input, which prompts on the droplet's stdin: OPEN GATE? (Y/Yes, N/No).
  5. Y sends open back to the Pi, N sends no_open. Either clears the block flag; open additionally calls util::send_open_command.
  6. send_open_command writes SWITCH to Arduino #2, sleeps 5 s, writes SWITCH again — servo.ino toggles the servo between 180° and 90°, so the gate opens and closes back after five seconds.

The operator prompt is a stdin dialogue reached over SSH. The presentation's architecture diagram sketches a web GUI in front of the droplet for admin/user access; that frontend was not implemented.

Repository layout

proto/embutidos.proto      gRPC contract: Raspberry + Droplet services
build.rs                   tonic-build codegen for the proto
src/
  raspberry_server.rs      `raspberry` binary main
  droplet_server.rs        `droplet` binary main
  raspberry.rs             RaspberryService — alert relay, block flag, gate command
  droplet.rs               DropletService — ack + operator prompt
  requests.rs              gRPC client helpers (try_/request pairs)
  util.rs                  constants (IPs, ports, serial devices), serial I/O, SafeBool
  signatures.rs            RSA sign/verify helpers — entirely commented out
.cargo/config              cross-compilation linker for armv7 (Raspberry Pi)
sistemas-embutidos/        second copy of the crate + the Arduino sketches
  arduino_code/sensors.ino Arduino #1 — proximity sensors
  arduino_code/servo.ino   Arduino #2 — gate servo
projeto_se/                report (PDF) and presentation (PPTX)

The two crate copies

src/ and sistemas-embutidos/src/ are the same code; the only difference is the constants block in util.rs:

src/ (root) sistemas-embutidos/src/
RASPBERRY_IP 127.0.0.1 192.168.1.231
DROPLET_IP 127.0.0.1 192.168.1.82
ARDUINO_SENSORS_COM_PORT /dev/ttyACM0 /dev/ttyACM1
ARDUINO_SERVO_COM_PORT /dev/ttyACM1 /dev/ttyACM0

So the root crate is the loopback/dev configuration and sistemas-embutidos/ is the snapshot as deployed on the lab network. Only the root crate has a build directory. Ports are the same in both: Pi 50005, droplet 55555. Addresses are compile-time constants — changing a host means editing util.rs and rebuilding.

Building

Requires a Rust toolchain (edition 2021) and protoc for tonic-build.

cargo build --release                 # host build, both binaries
cargo build --release --bin raspberry
cargo build --release --bin droplet

Cross-compiling for the Raspberry Pi

.cargo/config pins the linker for the 32-bit ARM hard-float target:

[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"

With the target and a cross GCC installed:

rustup target add arm-unknown-linux-gnueabihf
sudo apt install gcc-arm-linux-gnueabihf   # provides arm-linux-gnueabihf-gcc
cargo build --release --target arm-unknown-linux-gnueabihf --bin raspberry

Note: recent Cargo warns that .cargo/config is deprecated in favour of .cargo/config.toml; renaming the file silences it.

Firmware

Flash sistemas-embutidos/arduino_code/sensors.ino to the sensor board and servo.ino to the motor board with the Arduino IDE (or arduino-cli). Confirm which board enumerates as which /dev/ttyACM* and make util.rs match — the two copies of the crate disagree on the ordering because it depends on plug-in order.

Running

On the droplet:

./droplet     # binds DROPLET_IP:55555, then blocks on stdin when an alert arrives

On the Pi (both Arduinos connected via USB):

./raspberry   # binds RASPBERRY_IP:50005 and opens the sensor serial port

Trigger by putting a hand or object within 10 cm of either IR sensor; the droplet terminal prompts, and y drives the gate.

Both binaries must be reachable at the compiled-in addresses — with the lab constants that means the Pi and the droplet on the same subnet (or port forwarding to the real droplet IP).

Known limitations

These are honest notes on the state of the code as submitted, not a task list.

  • No message authentication. signatures.rs is one large comment block: the RSA sign/verify helpers were written and then disabled. The Metadata and Signature messages in embutidos.proto are declared but never populated, and the current proto's request/response messages have no fields to carry them. Traffic is plaintext gRPC with no auth, so anything that can reach port 50005 can open the gate by sending the open string.
  • Busy-wait main loops. Both main functions end in an empty loop {} to keep the runtime alive, which spins a core at 100%. tokio::signal::ctrl_c().await (the signal feature is already enabled) would be the fix.
  • Panic-on-error style. unwrap/expect throughout util.rs, requests.rs, and both services: a missing serial device or an unreachable peer aborts the process instead of degrading.
  • Concurrent prompts. hold_for_input is spawned per alert, so overlapping alerts create several tasks competing for the same stdin.
  • Duplicated crate. Two tracked copies that differ only in constants; config belongs in a file or environment variables rather than a second checkout.
  • Fixed 5 s open window, hardcoded in send_open_command.
  • Minor firmware comment drift: servo.ino says pin 9 but attaches pin 8; sensors.ino says "every 10 seconds" for a 1000 ms delay.

Hardware

  • Raspberry Pi (32-bit ARM, arm-unknown-linux-gnueabihf)
  • 2× Arduino Uno — one for sensing, one for the motor
  • 2× Sharp GP2Y0A41SK0F IR distance sensors (4–30 cm) on A0 / A1
  • 1× servo motor on digital pin 8
  • DigitalOcean droplet as the external access-management server

Documented assembly constraints (from the presentation): cable length between the Pi and the Arduinos, spacing between the two sensor boards, and the torque limit of the servo relative to a real gate.

Documentation

  • projeto_se/Garagem_Privada___Controlo_de_Entradas_e_Saidas.pdf — project report
  • projeto_se/Apresentacao_SE.pptx — final presentation (architecture diagram, assembly photo, demo)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages