
Introduction
Shrimp farming relies on maintaining optimal water quality, but traditional monitoring methods are inefficient, labor-intensive, and prone to inaccuracies. Farmers typically rely on manual sampling and periodic testing, which fail to capture sudden fluctuations in key parameters such as temperature, pH, turbidity, dissolved oxygen, and total dissolved solids (TDS). These fluctuations can quickly lead to shrimp stress, disease outbreaks, and mass mortality, significantly impacting productivity and profitability.
Furthermore, many shrimp farms are located in remote areas where Wi-Fi connectivity is unreliable or unavailable, making real-time monitoring and remote data access challenging. Existing solutions often require expensive infrastructure, frequent maintenance, and complex calibration processes, limiting their practicality for small and medium-scale farmers.
Without an automated, real-time monitoring system, farmers are unable to detect water quality issues early enough to take corrective action. This lack of timely intervention leads to higher operational costs, increased shrimp mortality rates, and reduced overall yield. There is a critical need for a cost-effective, real-time, and low-maintenance monitoring solution that ensures continuous data collection, instant alerts, and seamless remote access for improved farm management.
To address these challenges, we developed the Smart Shrimp Monitoring Buoy powered by a Particle B-SoM, designed for real-time, automated water quality monitoring in remote aquaculture environments.
The buoy continuously measures temperature, pH, turbidity, dissolved oxygen (DO), and total dissolved solids (TDS) using high-precision sensors. The B-SoM module ensures reliable cellular connectivity, enabling farmers to access live water quality data remotely, even in areas without Wi-Fi coverage.
Key features of our solution include:
- Real-time monitoring: The system collects and transmits water quality data at regular intervals, allowing farmers to respond quickly to critical changes.
- Automated alerts: When parameters exceed safe thresholds, farmers receive instant notifications, enabling immediate corrective action.
- Solar-powered operation: The buoy is equipped with 6V solar panels and a DFRobot solar charge controller, ensuring continuous operation without frequent maintenance.
- Rugged and low-maintenance design: The waterproof, floating buoy is built to withstand harsh aquatic conditions while minimizing maintenance efforts.
- Scalability and affordability: The system is designed to be cost-effective and easily scalable, making it accessible to shrimp farmers of all sizes.
By providing automated, real-time, and remote water quality monitoring, our solution reduces shrimp mortality, improves farm productivity, and minimizes operational costs, leading to more sustainable and profitable shrimp farming.
B524 SoM
The B-SoM is the cornerstone of this shrimp monitoring project, functioning as a dependable IoT module for cellular connectivity. Built on the Particle IoT platform, it comes equipped with a free global embedded SIM card and data plan.
To interface with the module, we utilize the M.2 SoM Evaluation Board, a user-friendly breakout board that provides access to the B-SoM’s essential pins and functionalities. This facilitates smooth development and deployment within our shrimp monitoring system. The evaluation board includes a variety of features, such as USB ports for both the nRF52840 MCU and the cellular modem, an SD card connector, an Ethernet connector, a barrel jack power connector, buttons, an RGB LED, a charge status LED, and a connector for a LiPo battery. These components collectively enhance the board’s versatility and ease of use in the project.
For a quick start with the BSoM read this tutorial.
To utilize the full capabilities of the B524 SoM with the Particle platform, you’ll need to set up your Particle account and configure your device. Follow the steps here to get started.
LM35 temperature sensor
The LM35 sensor measures water temperature, which is essential for maintaining proper shrimp metabolism and health. Shrimp are highly sensitive to temperature changes, so monitoring and maintaining a stable temperature range helps improve growth and survival rates. We are using the waterproof version of the temperature sensor.
The sensor operates by generating an analog voltage proportional to temperature, providing a simple and accurate method for temperature measurement.
Here is the sample code for getting temperature from lm35 and will print in the Serial monitor.
#define TEMP_PIN A0 void setup() { Serial.begin(9600); } void loop() { int sensorValue = analogRead(TEMP_PIN); float voltage = sensorValue * (3.3 / 4095.0); float temperatureC = voltage * 100.0; // LM35 gives 10mV per degree Celsius Serial.println("Temperature: " + String(temperatureC) + "°C"); delay(1000); }
pH sensor
The pH sensor is used to measure water acidity or alkalinity, which is crucial for creating an optimal environment for shrimp. It operates by detecting the voltage difference caused by hydrogen ion activity in the solution. This sensor is factory-calibrated, eliminating the need for additional calibration.
In shrimp farming, maintaining a pH level between 6.5 and 8.5 is essential for promoting growth, ensuring proper oxygen availability, and minimizing ammonia toxicity. Its plug-and-play design and compatibility with microcontrollers make it user-friendly for both beginners and professionals. Additionally, the use of the DFRobot pH library simplifies data processing, ensuring accurate and reliable pH readings for the project.
// Sample code for getting pH values #include "DFRobot_ESP_PH.h" #include <EEPROM.h> #define PH_PIN A1 DFRobot_ESP_PH ph; float voltage, phValue, temperature = 25.0; // Default temperature void setup() { Serial.begin(9600); ph.begin(); } void loop() { int sensorValue = analogRead(PH_PIN); voltage = sensorValue * (3.3 / 4095.0); // Convert analog reading to voltage phValue = ph.readPH(voltage, temperature); // Get pH value using library function Serial.print("pH: "); Serial.println(phValue); delay(1000); }
Turbidity sensor
The turbidity sensor measures water clarity by detecting the amount of light scattered by suspended particles in the water. High turbidity reduces light penetration, limiting photosynthesis in aquatic plants and decreasing oxygen production. Excessive suspended particles can clog shrimp gills, causing stress and making them more vulnerable to diseases.
Poor water clarity also affects shrimp feeding behavior, as they rely on visual cues to locate food. Additionally, high turbidity often indicates organic matter buildup, which can lead to harmful bacterial growth and deteriorate water quality. Monitoring turbidity levels helps farmers take timely actions, such as adjusting aeration or filtration, to maintain a healthy environment for shrimp.
// Sample code for getting Turbidity Values #define SensorPin A0 #define VREF 3.3 // Adjust for Particle devices (3.3V reference) float volt; float ntu; void setup() { Serial.begin(115200); pinMode(SensorPin, INPUT); } void loop() { volt = 0; for (int i = 0; i < 800; i++) { volt += ((float)analogRead(SensorPin) / 4095) * VREF; // Adjust for 12-bit ADC } volt = volt / 800; volt = round_to_dp(volt, 2); // Map voltage to the required range volt = mapf(volt, 0.0, 3.3, 1.83, 3.68); // Calculate NTU using the quadratic equation ntu = 493.17 * pow(volt, 2) - 3749.1 * volt + 7152.3; // Limit NTU values between 0 and 2000 if (ntu < 0) { ntu = 0; } else if (ntu > 2000) { ntu = 2000; } Serial.print("Voltage: "); Serial.print(volt); Serial.println(" V"); Serial.print("Turbidity: "); Serial.print(ntu); Serial.println(" NTU"); delay(1000); } float round_to_dp(float in_value, int decimal_place) { float multiplier = powf(10.0f, decimal_place); in_value = roundf(in_value * multiplier) / multiplier; return in_value; } float mapf(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
The code reads analog voltage from the turbidity sensor 800 times and converts it into a calibrated voltage value. This voltage is then used in a formula to calculate turbidity (NTU), ensuring values stay within the 0–2000 range. Finally, the voltage and NTU values are displayed on the Serial Monitor to help monitor water clarity.
TDS sensor
The TDS sensor measures dissolved solids and salinity by detecting the electrical conductivity of the water. Higher conductivity indicates a higher concentration of dissolved minerals, salts, and organic matter, which directly impacts shrimp health and growth. Excessive TDS levels can cause osmotic stress in shrimp, affecting their ability to regulate water and salt balance.
Poor water quality with high dissolved solids can also lead to gill irritation, reduced oxygen uptake, and increased susceptibility to diseases. Conversely, low TDS levels may indicate a lack of essential minerals needed for shrimp development. Regular monitoring of TDS levels helps maintain optimal water conditions, ensuring a balanced environment for healthy shrimp farming.
// Sample code for getting TDS value #include <math.h> #define TDS_PIN A2 #define VREF 3.3 // Reference voltage for B SoM (3.3V) #define TDS_FACTOR 0.5 // Conversion factor for TDS void setup() { Serial.begin(9600); pinMode(TDS_PIN, INPUT); } void loop() { int rawValue = analogRead(TDS_PIN); // Read sensor output float voltage = rawValue * (VREF / 1024.0); // Convert to voltage float ecValue = (133.42 * voltage * voltage * voltage - 255.86 * voltage * voltage + 857.39 * voltage) * 0.01; float tdsValue = ecValue * TDS_FACTOR; // Convert EC to TDS Serial.println("TDS: " + String(tdsValue) + " ppm"); delay(1000); }
Dissolved oxygen sensor
Dissolved oxygen refers to the extent of free, non-compound oxygen present in water or other liquids. It’s one of the most important parameters when assessing water quality due to its influence on the organisms living within a body of water. A DO level that’s too high or too low can harm aquatic life and affect water quality. The dissolved oxygen sensor measures the concentration of oxygen in water using an electrochemical or optical method. It helps ensure sufficient oxygen levels for shrimp respiration.
There are three types of dissolved oxygen sensor measurements: galvanic, polarographic, and optical. We are using the galvanic dissolved oxygen sensor for this project due to its reliability and simplicity.
Before getting the dissolved oxygen sensor probe to work, we need to prepare the probe. To prepare the probe, you need to dissolve approximately 4 grams of KCL crystals in 52 grams of water to create a 7.5% KCL solution.
Preparation includes adding 7.5% KCL solution into the membrane cap, ensuring the membrane is wrinkle-free, filling 2/3 of the cap with KCL, and securing the cap to eliminate air bubbles. The electrode tube should be free of air bubbles to prevent reading fluctuations. For detailed instructions, visit Dissolved Oxygen Probe Preparation.
We are using single-point calibration, which involves calibrating the saturated dissolved oxygen at a fixed temperature, suitable for stable temperature environments.
Use an LM35 temperature sensor to measure the temperature of the liquid and note down the value in °C. Next, wet the DO probe in the same liquid and gently shake off any excess water droplets to ensure the probe membrane is clean and hydrated. Then, expose the probe to air while maintaining natural airflow around it (avoid using a fan or artificial airflow). Wait for the output voltage from the DO probe to stabilize, and once stable, record the voltage. This voltage represents the saturated dissolved oxygen voltage at the current temperature. Use this recorded voltage value in your final code for calibration, as it corresponds to 100% dissolved oxygen saturation at the measured temperature.
// Code to get the reference voltage #include <Arduino.h> #define VREF 5000 //VREF(mv) #define ADC_RES 1024 //ADC Resolution uint32_t raw; void setup() { Serial.begin(9600); } void loop() { raw = analogRead(A1); Serial.println("raw:\t" + String(raw) + "\tVoltage(mv)" + String(raw * VREF / ADC_RES)); delay(1000); } // Code to get the DO value in mg/L #include <Arduino.h> // Pin and constants #define DO_PIN A1 // Analog pin for DO sensor #define VREF 3300 // Reference voltage in mV #define ADC_RES 4096 // 12-bit ADC resolution #define TWO_POINT_CALIBRATION 0 #define READ_TEMP(25) // Current water temperature (°C) // Single-point calibration values ( Here we are using Single Point calibration) #define CAL1_V(1455) // Calibration voltage at CAL1_T (mV) #define CAL1_T(25) // Calibration temperature (°C) //Two-point calibration needs to be filled CAL2_V and CAL2_T #define CAL2_V(1300) //mv #define CAL2_T(15) //℃ // DO lookup table (saturation values from 0°C to 40°C) const uint16_t DO_Table[41] = { 14460, 14220, 13820, 13440, 13090, 12740, 12420, 12110, 11810, 11530, 11260, 11010, 10770, 10530, 10300, 10080, 9860, 9660, 9460, 9270, 9080, 8900, 8730, 8570, 8410, 8250, 8110, 7960, 7820, 7690, 7560, 7430, 7300, 7180, 7070, 6950, 6840, 6730, 6630, 6530, 6410 }; uint8_t Temperaturet; uint16_t ADC_Raw, ADC_Voltage, DO; // DO calculation using calibration int16_t readDO(uint32_t voltage_mv, uint8_t temperature_c) { #if TWO_POINT_CALIBRATION == 0 uint16_t V_saturation = (uint32_t) CAL1_V + 35 * temperature_c - CAL1_T * 35; return (voltage_mv * DO_Table[temperature_c]) / V_saturation; #else uint16_t V_saturation = ((temperature_c - CAL2_T) * (CAL1_V - CAL2_V)) / (CAL1_T - CAL2_T) + CAL2_V; return (voltage_mv * DO_Table[temperature_c]) / V_saturation; #endif } void setup() { Serial.begin(9600); } void loop() { Temperaturet = (uint8_t) READ_TEMP; ADC_Raw = analogRead(DO_PIN); ADC_Voltage = (uint32_t) VREF * ADC_Raw / ADC_RES; DO = readDO(ADC_Voltage, Temperaturet); Serial.print("Temp:\t" + String(Temperaturet) + "\t"); Serial.print("ADC:\t" + String(ADC_Raw) + "\t"); Serial.print("Volt:\t" + String(ADC_Voltage) + "mV\t"); Serial.println("DO:\t" + String(DO)); delay(1000); }
Rain sensor
The rain sensor detects precipitation levels by measuring changes in electrical resistance when water droplets land on its conductive grid. This data helps monitor rainfall intensity and its impact on shrimp farming conditions. Rain can cause sudden temperature drops, stressing shrimp and slowing their growth. It also lowers pH levels, dilutes essential minerals, and reduces salinity, making the water less suitable for shrimp.
Heavy rainfall increases turbidity by washing debris into the pond, which decreases oxygen levels and affects shrimp health. By using a rain sensor, farmers can receive real-time alerts and take preventive measures to maintain optimal water quality.
// Code to detect rain #include <Arduino.h> #define RAIN_SENSOR_PIN A4 // Define the pin for the rain sensor void setup() { Serial.begin(115200); } void loop() { static unsigned long timepoint = millis(); if (millis() - timepoint > 1000U) { // Every 1 second timepoint = millis(); // Read Rain Sensor int rainValue = analogRead(RAIN_SENSOR_PIN); bool isRaining = rainValue < 1000; // Adjust threshold based on sensor readings // Serial Print Serial.print("Rain Sensor Value: "); Serial.print(rainValue); Serial.print(" | Rain Detected: "); Serial.println(isRaining ? "Yes" : "No"); } }
Power management
The system is powered by six solar panels (6V each) connected in parallel to increase current. The panels are wired to the 5V Solar Power Manager, which regulates the power flow to the 1800mAh battery. This battery stores energy and provides stable power for night or cloudy conditions.
The Dissolved oxygen sensor needs 9V to operate, to compensate the voltage we have used the LM2596S Buck converter power supply.
Antenna
To enhance cellular connectivity and ensure stable data transmission in remote or aquatic locations, we upgraded the default antenna to a rubber duck antenna for use with the Particle B-SoM. This antenna features a durable, flexible exterior and connects via a standard SMA connector, offering omnidirectional radiation that’s ideal for buoy-based systems, which may shift due to wind or water currents. To connect the antenna to the B-SoM’s U.FL port, we used a 15cm U.FL to SMA female bulkhead RF cable assembly. Operating across a wide frequency range (698–960 MHz and 1710–2690 MHz) with up to 5 dBi gain, the rubber duck antenna significantly improves performance in low-signal areas compared to embedded or PCB antennas. The sleek form factor also adds a more professional, rugged aesthetic to the final device, making it suitable for both field and demonstration use.
3D model
We designed a custom 3D model with a trapezoidal body and a circular semi-spherical base to function as a floating buoy. This distinctive shape enhances balance and stability on the water surface while offering ample room to mount sensors and securely enclose the electronics.
The full structure comprises three main parts: the upper trapezoidal section, the semi-spherical middle, and a flat circular base for holding internal components. The trapezoidal and semi-spherical parts were 3D printed using PLA, chosen for its lightweight, water-resistant, and outdoor-friendly properties. For saving the time and the filament the base was laser-cut from 2mm yellow acrylic.
Assembly
Before getting into the assembly, we finalized the code and the circuit using a breadboard and jumpers.
First, we secured the sensors on their corresponding slots.
Next, we secure the sensors breakout boards on the one side of acrylic and remaining on the other side.
Then, we attached the solar panels and the rain sensor.
After that, we fixed the three parts with the M3 nuts and bolts.
Once complete, here is what the final version looked like.
Ubidots dashboard
We used Ubidots to visualize real-time sensor data from the buoy. The Particle B-SoM sends temperature, pH, turbidity, dissolved oxygen, TDS, and rain sensor data to the Ubidots platform using webhooks. Ubidots provides a clean, user-friendly dashboard where each parameter can be monitored through graphs, gauges, and indicators.
Interconnecting Particle Cloud with Ubidots
- Create an account at ubidots.com.
- Create a new device and note the device label.
- In the Particle console, go to Integrations > New Integration > Ubidots.
Set the event name and paste the Ubidots API endpoint:
- https://industrial.api.ubidots.com/api/v1.6/devices/{device-label}
- Use the POST method and include your Ubidots Token in the header.
- Format your JSON body with the variable labels and values as
{ "temperature": "{{{temperature}}}", "ph": "{{{ph}}}", "turbidity": "{{{turbidity}}}", "do": "{{{do}}}", "tds": "{{{tds}}}", "rain": "{{{rain}}}" }
Once configured, data from the buoy will appear in Ubidots and can be customized into a real-time monitoring dashboard.
Sending alerts with Ubidots
To create alerts, navigate to Data > Events, and then “Create Event.”
- In the Triggers section:
- Click “Add Variable.”
- Select your device and variable
- Set condition:
- “is greater than” for upper limit
- “is less than” for lower limit
- Enter the threshold value
- In the Action section:
- Click “Add Action.”
- Select “Send SMS.”
- Enter the recipient’s phone number (e.g., +1234567890)
- Type the SMS message ( Hi there, {{Variable name}} was {{Trigger value}} at {{Trigger timestamp}} )
- In the Settings section, name your event (e.g., “Temperature High Alert”)
- Click “Save.”
- Test by sending a value that triggers the condition.
Once everything is configured, you get alerts like this when the values cross the thresholds.
What does this offer
The Smart Shrimp Monitoring Buoy offers a practical and impactful solution to the challenges of traditional shrimp farming by enabling real-time, automated water quality monitoring — especially in remote, low-connectivity environments. By reducing shrimp mortality, improving yield, and minimizing manual labor, it empowers farmers with timely insights and greater control over their operations.
Looking ahead, future improvements could include integrating predictive analytics and AI-driven insights to anticipate harmful trends before they occur, expanding sensor support for additional parameters like ammonia and nitrate, and developing a companion mobile app for even more accessible monitoring. By continuing to enhance functionality and ease of use, this system can further revolutionize sustainable aquaculture practices and support smarter farming at scale.
Assets for replication
You can find all the necessary resources and assets required to replicate this project in the GitHub repository.