Create a device that monitors the “health” and needs of plants by measuring the quality of light they receive and the temperature and moisture of the soil. This will help optimize watering and ensure better growth.
How does it work?LTR-390-UV (Light and UV): The sensor measures how much light (an element necessary for photosynthesis) and UV rays a plant receives. This allows you to determine whether the plant is in too dark a place or, conversely, is not receiving too much direct sunlight, which can burn the leaves.
The LTR390-UV sensor’s UV index readings from 0 to 10 open up opportunities for growers to better understand and manage one of the most important environmental factors.
Rak12023/RAK12035 (soil sensor): This sensor measures soil temperature and moisture.
Before using the sensor, it is necessary to calibrate it to your greenhouse soil. The RAK12035 is a capacitive sensor and its absolute values depend heavily on the type of soil (sand, clay, peat substrate, etc.). Without calibration, the values obtained will be just abstract numbers and not a clear percentage of moisture.
The essence of calibration:
You need to determine the two extreme values that the sensor will show in your specific soil:
Dry soil value (0%): Take your greenhouse soil and dry it completely (for example, in an oven on low temperature). Place the sensor in this dry soil and record the reading. This will be your 0% moisture point.
Fully saturated soil value (100%): Moisten the same soil abundantly until it is saturated with water, but not liquid mud. Place the sensor and record the reading. This will be your 100% humidity point. These two values need to be entered into the software code that controls the sensor. The system will then be able to convert any intermediate reading into a clear percentage between 0% and 100%.
The system analyzes the data:
Moderate UV levels (UVI 1-3) can be beneficial, promoting plant vigor and resilience, but higher values (UVI 4+) require close monitoring and control to avoid stress and damage to plants.
Interpreting Soil Moisture Readings (%)
After calibration, you will receive a moisture reading in percentages that can be interpreted as follows:
0-10%: Critically dry. The soil is too dry. Most plants are experiencing severe stress, wilting. Roots may be starting to dry out. Urgent watering is necessary.
10-30%: Dry. Time to water. Although plants may not look wilted, lack of moisture is already starting to stunt growth and reduce future yields.
30-70%: The optimal moisture range for most plants. This is the "safe zone" where plant roots can easily absorb water and nutrients. The watering strategy for most popular greenhouse crops (tomatoes, peppers, cucumbers) should be to maintain moisture in this range.
70-85%: Very humid. This level is suitable for moisture-loving plants, such as cucumbers, especially during their active growth and fruiting. However, for tomatoes or peppers, prolonged exposure to such moisture increases the risk of root diseases.
85-100%: Waterlogged, saturated soil. This is the danger zone. There is almost no air left in the soil, which is necessary for root respiration. If this condition persists for a long time, it causes root rot, oxygen starvation and ultimately the death of the plant. This level can only be seen immediately after very abundant watering.
Green benefits:- Water saving: Plants are watered only when they really need it, thus avoiding water waste.
- Sustainable cultivation: Helps to grow plants at home (for food or decoration) more efficiently, reduces the need for chemical fertilizers, as the plant grows in optimal conditions.
- Promotes biodiversity in urban environments.
To avoid damage to the gateway, make sure to connect the antenna before turning it on!
This step is thoroughly explained in the guide - IoT Education Kit - Setup the Gateway WisGate Edge Lite 2 - that can be found on https://www.hackster.io/520073/iot-education-kit-setup-the-gateway-rak7268v2-6b222f
Step 1: Mounting the WisBlock Components- Place the microprocessor (RAK11300) in the dedicated slot on the motherboard, aligning the pins and holes correctly.
- Press lightly until you hear a click, then secure it using the screws and screwdriver in the kit.
- Carefully connect the LoRa 863-870MHz antenna to its designated location.
- Assemble the UV Light Sensor Lite-On LTR-390UV-01 RAK12019 module by mounting on SENSOR SLOT A of motherboard.
Install Arduino IDE/PlatformIO and support for the RAK11300 board. Install the necessary libraries for the sensors.
Uploading the program code
#include <Arduino.h>
#include "LoRaWan-Arduino.h"
#include <SPI.h>
#include <Wire.h>
#include "UVlight_LTR390.h"
#include "RAK12035_SoilMoisture.h"
// ============================
// LoRaWAN Settings
// ============================
bool doOTAA = true;
#define LORAWAN_APP_PORT 2
#define LORAWAN_APP_INTERVAL 10000 // ms
DeviceClass_t g_CurrentClass = CLASS_A;
LoRaMacRegion_t g_CurrentRegion = LORAMAC_REGION_EU868;
lmh_confirm g_CurrentConfirm = LMH_UNCONFIRMED_MSG;
// OTAA keys (Change it to your own)
uint8_t nodeDeviceEUI[8] = {0x00,0x1F,0x00,0xF0,0xF0,0x06,0xB5,0x00};
uint8_t nodeAppEUI[8] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
uint8_t nodeAppKey[16] = {0xA6,0x00,0x91,0x00,0xD1,0xB8,0x00,0x66,0x61,0x91,0x00,0xDC,0xDD,0x4A,0x53,0xDD};
// ============================
// LoRaWAN Buffers
// ============================
#define LORAWAN_APP_DATA_BUFF_SIZE 8
static uint8_t m_lora_app_data_buffer[LORAWAN_APP_DATA_BUFF_SIZE];
static lmh_app_data_t m_lora_app_data = {m_lora_app_data_buffer, 0, 0, 0, 0};
mbed::Ticker appTimer;
// ============================
// Forward declarations
// ============================
static void lorawan_has_joined_handler(void);
static void lorawan_join_failed_handler(void);
static void lorawan_rx_handler(lmh_app_data_t *app_data);
static void lorawan_confirm_class_handler(DeviceClass_t Class);
void tx_lora_periodic_handler(void);
void send_lora_frame(float uvi, uint8_t uvEmergency, uint8_t soilHumidity, int16_t soilTemp);
// ============================
// LoRa callbacks
// ============================
static lmh_callback_t g_lora_callbacks = {
BoardGetBatteryLevel,
BoardGetUniqueId,
BoardGetRandomSeed,
lorawan_rx_handler,
lorawan_has_joined_handler,
lorawan_confirm_class_handler,
lorawan_join_failed_handler,
nullptr,
nullptr
};
// ============================
// Sensors
// ============================
UVlight_LTR390 ltr;
RAK12035 soilSensor;
// Calibration values for soil sensor
uint16_t zero_val = 73;
uint16_t hundred_val = 250;
// Soil readings
uint8_t soilHumidity = 0;
int16_t soilTemperature = 0;
// ============================
// Helpers
// ============================
void floatToBytes(float value, uint8_t* bytes) {
union { float f; uint8_t b[4]; } u;
u.f = value;
for(int i=0;i<4;i++) bytes[i] = u.b[i];
}
// ============================
// Setup
// ============================
void setup() {
Serial.begin(115200);
while(!Serial){}
pinMode(LED_BUILTIN, OUTPUT);
pinMode(WB_IO2, OUTPUT);
digitalWrite(WB_IO2, HIGH);
delay(300);
Wire.begin();
// Init LTR390
if(!ltr.init()){
Serial.println("Couldn't find LTR390 sensor!");
while(1) delay(1000);
}
ltr.setMode(LTR390_MODE_UVS);
ltr.setGain(LTR390_GAIN_3);
ltr.setResolution(LTR390_RESOLUTION_16BIT);
// Init Soil Sensor
soilSensor.begin();
soilSensor.get_dry_cal(&zero_val);
soilSensor.get_wet_cal(&hundred_val);
// Init LoRa
lora_rak11300_init();
if(doOTAA){
lmh_setDevEui(nodeDeviceEUI);
lmh_setAppEui(nodeAppEUI);
lmh_setAppKey(nodeAppKey);
}
lmh_param_t g_lora_param_init = {LORAWAN_ADR_ON, DR_0, LORAWAN_PUBLIC_NETWORK, 3, TX_POWER_5, LORAWAN_DUTYCYCLE_OFF};
if(lmh_init(&g_lora_callbacks, g_lora_param_init, doOTAA, g_CurrentClass, g_CurrentRegion) != 0){
Serial.println("lmh_init failed");
return;
}
lmh_join();
}
// ============================
// Loop
// ============================
void loop() {
float uvi = 0;
uint8_t uvEmergency = 0;
if(ltr.newDataAvailable()){
uvi = ltr.getUVI();
if(uvi >= 5.0){
uvEmergency = 1;
}
}
soilSensor.get_sensor_moisture(&soilHumidity);
uint16_t tempRaw = 0;
soilSensor.get_sensor_temperature(&tempRaw);
soilTemperature = tempRaw / 10;
send_lora_frame(uvi, uvEmergency, soilHumidity, soilTemperature);
delay(LORAWAN_APP_INTERVAL);
}
// ============================
// Send LoRa Frame
// ============================
void send_lora_frame(float uvi, uint8_t uvEmergency, uint8_t soilHumidity, int16_t soilTemp){
if(lmh_join_status_get() != LMH_SET) return;
uint8_t i = 0;
floatToBytes(uvi, &m_lora_app_data.buffer[i]); i+=4;
m_lora_app_data.buffer[i++] = uvEmergency;
m_lora_app_data.buffer[i++] = soilHumidity;
m_lora_app_data.buffer[i++] = (soilTemp >> 8) & 0xFF;
m_lora_app_data.buffer[i++] = soilTemp & 0xFF;
m_lora_app_data.port = LORAWAN_APP_PORT;
m_lora_app_data.buffsize = i;
lmh_send(&m_lora_app_data, g_CurrentConfirm);
}
// ============================
// LoRa Handlers
// ============================
void lorawan_has_joined_handler(void){
Serial.println("OTAA Network Joined!");
lmh_class_request(g_CurrentClass);
appTimer.attach(tx_lora_periodic_handler, std::chrono::milliseconds(LORAWAN_APP_INTERVAL));
}
void lorawan_join_failed_handler(void){ Serial.println("OTAA join failed!"); }
void lorawan_rx_handler(lmh_app_data_t *app_data){}
void lorawan_confirm_class_handler(DeviceClass_t Class){}
void tx_lora_periodic_handler(void){ appTimer.attach(tx_lora_periodic_handler, std::chrono::milliseconds(LORAWAN_APP_INTERVAL)); }Write code to initialize and read data from UV and soil sensors.
Checking UV sensor readings using a UV spotlight.






_M6kErcYJ84.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)


Comments