In both public places and homes, it is common for people to place trust in water filtration systems, assuming that they consistently provide safe drinking water. However, in the event of water quality degradation due to factors such as a malfunctioning filter or corroded pipes, this assumption can pose potential health risks such as infections and kidney stones.
In homes, where water serves not only as a vital resource for gardening but also for drinking, the reliance on a consistently high-quality water source becomes even more crucial, as it directly impacts both human consumption and the health of plants and soil in gardens.
The Hardware:To address the challenge of maintaining water quality within households, the NRF7002DK is employed to monitor water turbidity. The device then transmits this data to a mobile application, empowering users to seamlessly monitor and assess the quality of their water supply.
The NRF7002DK features 6 ADC channels, conveniently resembling the form factor of an Arduino. For reading water turbidity, we utilize the Turbidity sensor, connecting it to the A0 pin or channel 0 of the ADC port. This enables the acquisition of analog values, crucial for precise turbidity measurements.
However, there's a caveat: the ADC operates with an internal reference voltage of 0.6v, while the Turbidity sensor outputs a voltage ranging from 0-5v. To overcome this challenge, I've implemented the following solution to ensure the proper functioning of the sensor.
1.] Increasing the gain of the ADC: The ADC of the devkit can have the following gain values:
ADC_GAIN_1_6 -> ADC_ref *6 = 0.6 x 6 = 3.6v
ADC_GAIN_1_5 -> ADC_ref *5 = 0.6 x 5 = 3.0v
ADC_GAIN_1_4 -> ADC_ref *4 = 0.6 x 4 = 2.4v
ADC_GAIN_1_3 -> ADC_ref *3 = 0.6 x 3 = 1.8v
For my purpose I have chosen the gain as ADC_GAIN_1_3 which means the internal reference is now 1.8v. but the problem still persist so we now need to use a Voltage Divider Resistor Pair.
2.] Using a voltage divider resistor pair: The voltage divider pair is just like a potentiometer but has fixed resistor values. We have input voltage of 5v and we need to get 1.8v. The resistor values can be calculated with the help of this website -> https://www.allaboutcircuits.com/tools/voltage-divider-calculator/
The values of the resistor used are 56K pull down resistor and 100K which is directly attached to the analog output of the sensor.
SANITY CHECK!!
if you want to check if the circuit works correctly then you can also simulate the circuit. I used "Proto" App which is free available on Play store.
Here I have used a AC source of 5v volts but our sensor will only output positive values thus the output will lie from 0-1.8v.
To get the value we simply just connect the A0 pin in between the two resistors this completes the voltage divider.
I've completed the PCB design for the circuit. You can download the Gerber files and submit them to your preferred manufacturer. The board is single-sided, allowing for easy at-home DIY manufacturing.
If you want to change the gain values then you also need to calculate the voltage divider resistors values.
Here I have used DF robot gravity turbidity sensor. It detects water quality by measuring the levels of turbidity, or the opaqueness. It uses light to detect suspended particles in water by measuring the light transmittance and scattering rate, which changes with the amount of total suspended solids (TSS) in water. As the TTS increases, the liquid turbidity level increases.
To measure Turbidity we first perform Analog Read and then we convert the value to voltage levels. Using this formula.
Voltage = sensorValue * (5.0 / 1024.0)
From the graph we can see that that the Turbidity and the voltage have inverse relationship. Thus, Turbidity ∝ 1/V.
To power the Project you will also need 18650 battery shield. This shield comes with USB power output and also has 5.0v as wells as 3.3v output options.
Connecting the 7002dk with all other components:
To program the 7002dk you will need nrf connect sdk and the vs code extension. You can find the resources on getting started -> here.
Configuring the ADC as stated above:
#define ADC_NODE DT_NODELABEL(adc)
static const struct device *adc_dev = DEVICE_DT_GET(ADC_NODE);
#define ADC_RESOLUTION 8 // 2*8 = 256
#define ADC_CHANNEL 0 // ADC channel 0 = A0
#define ADC_PORT SAADC_CH_PSELP_PSELP_AnalogInput0
#define ADC_REFRENCE ADC_REF_INTERNAL // 0.6 internal reference
#define ADC_GAIN ADC_GAIN_1_3 // 0.6 * 3 = 1.8v
Now making a ADC structure that needs to be passed to adc_channel_setup() function.
struct adc_channel_cfg ch0_cfg = {
.gain = ADC_GAIN,
.reference = ADC_REFRENCE,
.acquisition_time = ADC_ACQ_TIME_DEFAULT,
.channel_id = ADC_CHANNEL,
#ifdef CONFIG_ADC_NRFX_SAADC
.input_positive = ADC_PORT
#endif
};
adc_channel_setup(adc_dev, &ch1_cfg); //Setting up the ADC channel with configurations
Reading the ADC values and publishing them. For publishing the data to the MQTT broker I have used this example provided by Nordic semiconductors.
int16_t sample_buffer[1]; //buffer for storing the values
struct adc_sequence sequence = { //setting the ADC sequence while reading the values
.channels = BIT(ADC_CHANNEL),
.buffer = sample_buffer,
.buffer_size = sizeof(sample_buffer),
.resolution = ADC_RESOLUTION
};
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void Sensor_read(){
k_msleep(SLEEP_TIME_MS);
adc_read(adc_dev,&sequence);
int32_t my_val = sample_buffer[0];
int32_t adc_vref = adc_ref_internal(adc_dev);
adc_raw_to_millivolts(adc_vref, ADC_GAIN, ADC_RESOLUTION, &my_val);
my_val = map(my_val, 0, 1800, 2500, 4500);
publish_to("Sensors/Turbidity",my_val);
}
void publish_to(char* topic, uint32_t* value){
char buff[32] = {0};
itoa(value, buff, 10);
data_publish_custom_topic(&client, MQTT_QOS_1_AT_LEAST_ONCE, buff , sizeof(buff), topic);
}
To convent the ADC value we use adc_raw_to_millivolts() function. This will output a value from 0mv to 1800mv. Thus we need a map function to map this value with the 0-4.5v range. After mapping the voltage values can be sent to the a dashboard hosted on node-red.
Comments