Wireless Setup Documentation
π What is this for? (Quick Summary for New Interns)β
In simple words: This document explains how data travels between the physical pod and our servers over trackside wireless networks. It explains the TCP/IP network connection on port 20006, how the Go server buffers incoming packets, and how 13-byte CAN bus sensor frames are received and verified.
Prepared by: Sirish Sekhar
TuTr Hyperloop Pvt. Ltd. β Private & Confidential
1. Communication
1.1 TCP/IP Protocol Overview :β
The TCP/IP protocol suite is the foundational communication framework of the internet and most local networks. It stands for Transmission Control Protocol/Internet Protocol and consists of a layered set of protocols that allow devices to communicate reliably over both wired and wireless networks.
While TCP - used for end-to-end communication and data integrity & IP - Handles logical addressing and routing of packet.
1.2 Client-Server Connectionβ
How Connection is Establishedβ
- Server starts and listens on IP
0.0.0.0and port20006.- This means it's ready to accept connections from any client on that port.
- A client connects (e.g., another computer or device).
- The server accepts the connection and logs the client's IP.
- The connected client is added to a list of active clients.
- A new separate process (goroutine) starts for that client to keep listening to incoming data.
- The server also keeps checking (every 5 seconds) if the client is still connected by sending a small βpingβ.
- If the client disconnects or doesn't respond, it's removed from the list.
Note: Only one client can be connected to the server.
1.3 CAN Message Processing and Buffer Managementβ
How CAN is Processedβ
- The client sends CAN messages to the server over the TCP connection.
- The server reads data from the client in chunks (using a 1024-byte buffer).
- But a CAN message is always 13 bytes, so:
- The server collects the incoming data into a temporary
dataBuffer. - It waits until it has at least 13 bytes in that buffer.
- The server collects the incoming data into a temporary
- Once there are 13 or more bytes:
- It checks if the first 13 bytes are a valid CAN message (by checking if the length byte equals 8).
- If valid, it processes the message.
- If not valid, it throws away just 1 byte and tries again (to skip bad or misaligned data).
- After processing, it removes that message from the buffer and checks if another complete 13-byte message is waiting.
Why the Buffer is Usedβ
- TCP doesn't guarantee message boundaries, so a single read might have half a CAN message, one full message, or even multiple messages.
- The buffer helps assemble complete messages and process them one-by-one, even if they arrive in parts or bunched together.
2. Edge Computing (Rpi5 Setup)
2.1 - 2.2 - Refer RPi5 Connection Journal for this particular section.
3. CAN Processing with Go
3.1 CAN ID :β
What is CAN ID and How Is It Used?β
Every CAN message your server receives includes:
- Length (1 byte) β Always
8in your case. - CAN ID (4 bytes) β A unique number that tells what type of data the message contains (like a label).
- Data (8 bytes) β Actual data values like voltage, current, speed, etc.
What Happens When a CAN Message Arrives?β
- Your code reads the full 13 bytes (1 length + 4 CAN ID + 8 data).
- It extracts the CAN ID and checks:
- If it's
1281β it means inverter voltage/current data. - If it's
1282β it means inverter fault data. - If it's
1283β it means slip speed and Vrms. - If it's
1284β it means frequency and speed.
- If it's
- Based on the CAN ID, it calls the correct function (
processCANMessage101,102, etc.).
3.2 Buffer :β
How the Data Buffer is Usedβ
Inside each function like processCANMessage101, the 8-byte data is split:
- First 4 bytes: converted into a float32 (e.g., current).
- Next 4 bytes: converted into another float32 (e.g., voltage).
This is done using:
math.Float32frombits(binary.BigEndian.Uint32(data[:4]))
So, the buffer holds raw binary data, and your code decodes it into readable values like 12.45 V or 34.8 A.
Where the Final Values Go?β
All processed values are stored in a shared map called LatestMessage.Data, so other parts of your program (like a dashboard or logger) can easily access the latest sensor readings.
4. AWS IoT Core
πΉ Step 1: Go to AWS IoT Coreβ
- Login to AWS Console
- Go to AWS IoT Core
πΉ Step 2: Register Your Device (Thing)β
- Navigate to Manage > Things > Create things
- Choose Create a single thing
- Name it (e.g.,
Rpi5) - Skip adding device shadow
- Click Next
πΉ Step 3: Create Certificatesβ
- Choose Auto-generate new certificate
- Click Create thing
πΉ Step 4: Download Required Filesβ
Download and save the following to your Raspberry Pi:
device-certificate.pem.crtprivate.pem.keyAmazonRootCA1.pem(link provided in AWS UI)- Save endpoint from AWS (you'll use this later)
- Click Activate the certificate
- Click Attach Policy and create one if needed:
json
CopyEdit
{
"Effect": "Allow",
"Action": "iot:*",
"Resource": "*"
}
Attach it to the certificate.
πΉ Step 5: Transfer Certs to RPiβ
move these files to /home/pi/certs:
device-certificate.pem.crtprivate.pem.keyAmazonRootCA1.pem
Install MQTT Clientβ
bash
CopyEdit
go get github.com/eclipse/paho.mqtt.golang
const (
endpoint = "[your-endpoint.iot.your-region.amazonaws.com:8883](http://your-endpoint.iot.your-region.amazonaws.com:8883/)"
certFile = "certs/device-certificate.pem.crt"
keyFile = "certs/private.pem.key"
caFile = "certs/AmazonRootCA1.pem"
topic = "test/topic"
)
5. Python MQTT Container
Use case :β
- Connects your backend (FastAPI) to AWS IoT Core securely using TLS certificates.
- Whenever a message is received from AWS IoT:
- It formats it and sends it to connected WebSocket clients (like a React frontend).
- The backend also has a
/controlAPI to:- Send control messages (
"enable"or"disable") back to AWS IoT.
- Send control messages (
How It Works :β
-
/wsWebSocket endpoint:Lets the frontend connect and receive live updates (like a real-time dashboard).
-
/controlGET API:Frontend sends
?command=enableor?command=disableβ Backend publishes that to AWS IoT Core
β AWS IoT sends to the device.
6. React Frontend
React helps you build fast, dynamic, and real-time dashboards that feel like mobile apps.
- It updates only what changes (e.g., speed or voltage) without refreshing the whole page.
- Works smoothly with WebSockets to show live data instantly.
- Easy to break your UI into reusable components like charts, meters, and control buttons.
- Works perfectly with backend APIs and AWS IoT messages.
7. InfluxDB Storage & Real-Time Monitoring
Whatβs InfluxDB?β
It's like a time-based database β perfect for storing live sensor data like vehicle speed, current, and voltage with timestamps.
How the Code Works :β
-
Connect to InfluxDB:
The
InitInfluxDB()function connects your Go code to the InfluxDB server (like logging into the database). -
Read CAN Data:
The
logCANMessage()function reads raw CAN bus data (like vehicle speed or battery info) and turns it into human-readable values (like 12.5V, 60km/h). -
Buffer Data:
Instead of sending every message instantly, it collects 5 messages into a temporary storage called a βbufferβ for performance.
-
Write to InfluxDB:
Once the buffer has 5 entries,
writeBatchToInfluxDB()sends all 5 to InfluxDB at once (efficient and fast). -
Repeat Every 0.5s:
The
LogPeriodicCANMessages()function runs in a loop, calling the logger every 0.5 seconds to simulate live data streaming.
8. Additional
8.1 AWS Cognito For secure SSOβ
- Amazon Cognito offers user authentication, authorization, and user management for web and mobile apps.
- It supports SSO (Single Sign-On) via SAML, OIDC, and social logins (Google, Facebook, etc.).
8.2 API Gatewayβ
- Use API Gateway to expose your backend securely (e.g., FastAPI/Go on RPi or AWS ECR).
- Combine with Cognito for login-protected APIs.
- Good for IoT control panel.