В этой статье мы узнаем о взаимодействии датчика NPK почвы с платой Arduino и создадим свой собственный измеритель уровня питательных веществ в почве на основе Arduino. Измерение содержания в почве N (nitrogen — азота) , P (phosphorus — фосфора) и K (potassium — калия) необходимо для определения того, сколько дополнительных питательных веществ следует добавить в почву для повышения плодородия сельскохозяйственных культур, которые мы хотим на ней выращивать.
Плодородие почвы определяется с помощью датчиков NPK. Основным компонентом удобрения почвы является азот, фосфор и калий. Знание концентрации питательных веществ в почве может помочь нам узнать о дефиците или избытке питательных веществ в почвах, используемых для поддержки производства растений.
Существует множество методов измерения содержания питательных веществ в почве, например, использование некоторых оптических датчиков или спектрометра . Но метод спектрального анализа неудобен, а его недостатком является то, что данные верны только на 60-70% . При сравнении метода спектрального анализа с традиционными методами мокрой химии точность продуктов еще не полностью определена, учитывая скудность данных в этом отношении.
Итак, здесь мы будем использовать датчик NPK JXCT почвы для определения азота, фосфора и калия в почве. Датчик NPK JXCT — это недорогой, быстро реагирующий, высокоточный и портативный датчик, работающий по протоколу Modbus RS485. Преимущество этого датчика перед традиционным методом обнаружения заключается в том, что он обеспечивает очень быстрое измерение и высокую точность данных . Все, что вам нужно, — это вставить его зонд в почву и получить показания с помощью Arduino.
Если вы не работали с протоколом Modbus RS485, то у нас на сайте есть несколько статей (одни из лучших в сети по данной тематике) по его использованию с платой Arduino:
- последовательная связь по протоколу Modbus RS-485 с Arduino (ведомой);
- последовательная связь по протоколу Modbus RS-485 с Arduino (ведущей);
- считывание информации с датчиков в Arduino по протоколу Modbus.
Необходимые компоненты
- Плата Arduino Nano (купить на AliExpress).
- Датчик NPK (купить на AliExpress).
- Модуль OLED дисплея с диагональю 0.96 дюйма и интерфейсом I2C (купить на AliExpress).
- MAX485 TTL to RS485 Converter Module (модуль преобразования логики TTL в RS485) ( купить на AliExpress).
- Источник питания постоянного тока 9-12 В
- Макетная плата.
- Соединительные провода.
Реклама: ООО «АЛИБАБА.КОМ (РУ)» ИНН: 7703380158
Датчик NPK почвы (Soil NPK Sensor)
Датчик NPK почвы подходит для определения содержания азота, фосфора и калия в почве. Он помогает определить плодородие почвы, тем самым облегчая систематическую оценку состояния почвы. Датчик может быть зарыт в почву на длительное время. Он имеет высококачественный зонд, устойчивость к ржавчине, электролитическому сопротивлению, солевой и щелочной коррозии, что обеспечивает его долгосрочную работу. Поэтому он подходит для всех видов почв. Он может применяться для обнаружения щелочной почвы, кислой почвы, субстратной почвы, почвы для рассады и почвы из кокосовых отрубей.
Датчик не требует никаких химических реагентов . Поскольку он имеет высокую точность измерения, быструю скорость отклика и хорошую взаимозаменяемость, его можно использовать с любым микроконтроллером. Вы не можете использовать датчик напрямую с микроконтроллером, так как у него есть порт связи Modbus. Следовательно, вам нужен любой модуль Modbus, такой как RS485/MAX485, чтобы подключить датчик к микроконтроллеру.
Датчик работает от 9-24 В и потребляет очень мало энергии. Говоря о точности датчика, она составляет до 2%. Разрешение измерения азота, фосфора и калия составляет до 1 мг/кг (мг/л).
Используя этот датчик NPK, вы можете создать свой собственный измеритель NPK в почве на базе Arduino или любую облачную систему мониторинга содержания питательных веществ в почве на основе Интернета вещей.
Технические характеристики датчика
1. Питание: 9 В-24 В.
2. Диапазон измерения: 0-1999 мг/кг (мг/л).
3. Рабочая температура: 5-45 °C.
4. Разрешение: 1 мг/кг.
5. Точность: ±2% полной шкалы.
6. Выходной сигнал: RS485.
7. Скорость передачи данных: 2400/4800/9600.
8. Класс защиты: IP68.
Интерфейсный модуль MAX485 TTL — RS-485
Интерфейсный модуль MAX485 TTL to RS-485 позволяет нам использовать дифференциальную сигнализацию RS-485 для надежной последовательной связи на большие расстояния до 1200 метров или на меньшие расстояния в условиях сильных электрических помех и обычно используется в промышленных условиях. Он поддерживает скорость передачи данных до 2,5 Мбит/с , но с увеличением расстояния максимальная поддерживаемая скорость передачи данных снижается.
Внешний вид модуля RS-485 показан на следующем рисунке.
Модуль работает с типичный последовательным уровнем TTL с точки зрения микроконтроллера, в то время как модуль RS-485 заботится о преобразовании электрических сигналов между TTL и дифференциальной сигнализацией, используемой RS-485. Значительным преимуществом RS-485 является то, что он поддерживает несколько устройств (до 32) на одном кабеле, что обычно называется «многоточечным» соединением.
Технические характеристики модуля
1. Используется интерфейсный чип MAX485
2. Использует дифференциальную сигнализацию для помехоустойчивости
3. Расстояния до 1200 метров
4. Скорость до 2,5 Мбит/с
5. Многоточечная связь поддерживает до 32 устройств на одной шине.
6. Красный светодиод питания.
7. Работает от напряжения 5 В.
Распиновка и подключение модуля
Назначение контактов (распиновка) модуля RS-485 приведена в следующей таблице.
Название контакта | Назначение контакта |
VCC | 5V |
A | вход/выход линии RS-485 |
B | вход/выход линии RS-485 |
GND | GND (0V) |
R0 | выход приемника (RX pin) |
RE | разрешение работы приемника |
DE | разрешение работы передатчика |
DI | вход передатчика (TX pin) |
Как видите, контакты на модуле RS-485 расположены очень логично — с одной стороны к модулю подключается устройство, а с другой — линия.
Взаимодействие датчика NPK почвы с Arduino
Схема подключения датчика NPK почвы к плате Arduino Nano с помощью модуля Modbus MAX485 приведена на следующем рисунке.
Подключите выводы R0 и DI от Modbus к контактам D2 и D3 платы Arduino с помощью программного последовательного порта. Аналогично, нам нужно включить высокий уровень DE и RE . Для этого подключите выводы DE и RE к выводам D7 и D8 Arduino. Датчик NPK имеет 4 провода. Коричневый — это VCC, которому требуется источник питания 9 В–24 В. Вывод GND черного цвета. Поэтому подключите его к GND Arduino. Синий провод, который является выводом B, подключен к выводу B MAX485, а желтый провод , который является выводом A, подключен к выводу A MAX485.
0,96-дюймовый OLED-дисплей SSD1306 мы подключаем к плате Ардуино по интерфейсу I2C. Подключите контакты VCC и GND OLED-дисплея к контактам 3,3 В и GND Arduino. Аналогично подключите его контакты SDA и SCL к контактам A4 и A5 платы Arduino. Вы можете следовать принципиальной схеме и собрать схему на макетной плате или изготовить собственную печатную плату.
Команды Modbus RTU для датчика NPK
Команды Modbus могут давать указания устройству Modbus:
1. Изменить значение в одном из его регистров, которое записывается в регистры флагов и хранения.
2. Прочитать порт ввода-вывода: прочитать данные из дискретных портов и портов флагов;
3. Дать команду устройству отправить обратно одно или несколько значений, содержащихся в его регистре флагов и хранения.
Команда Modbus содержит адрес Modbus устройства, для которого она предназначена (от 1 до 247). Только адресуемое устройство ответит и выполнит команду, даже если другие устройства ее получат.
Датчик NPK имеет 3 различных кадра запроса для считывания значений азота (N), фосфора (P) и калия (K). Формат этих кадров приведен в инструкции по эксплуатации датчика. Для данных NPK применяются следующие отдельные кадры запросов:
1. Азот: {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c}
Кадр запроса для получения значения содержания азота в почве:
В ответ вы получите следующее:
Вы можете рассчитать концентрацию азота в почве из полученного ответа. Например, если вы получили 0030 в качестве ответа, то значение азота почвы будет:
0020 H(шестнадцатеричное) = 32 (десятичное) => азот = 32 мг/кг
2. Фосфор: {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc}
Кадр запроса для получения значения содержания фосфора в почве:
В ответ вы получите следующее:
Вы можете рассчитать концентрацию фосфора в почве из полученного ответа. Например, если вы получили 0030 в качестве ответа, то значение фосфора в почве будет:
0025 H (шестнадцатеричный) = 37 (десятичный) => фосфор = 37/кг
3. Калий: {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0}
Кадр запроса для получения значения содержания калия в почве:
В ответ вы получите следующее:
Вы можете рассчитать содержание калия в почве из полученного ответа. Например, если вы получили ответ 0030, то значение содержания калия в почве будет:
0030 H(шестнадцатеричное) =48 (десятичное) => Калий = 48 мг/кг
Исходный код программы
Исходный код программы для сопряжения датчика NPK почвы с Arduino и получения значения питательных веществ почвы от датчика с помощью команд Modbus приведен ниже. Вы можете отправить команду и получить значение в шестнадцатеричном коде. Для получения данных об измеренном содержании питательных веществ почвы шестнадцатеричный код необходимо преобразовать в десятичный.
Поскольку мы используем OLED-дисплей для отображения значений питательных веществ в почве (азот, фосфор и калий) в мг/кг, вам понадобятся библиотеки для работы с OLED дисплеем. Загрузите следующие библиотеки и добавьте их в Arduino IDE.
1. Библиотека Adafruit SSD1306 : Загрузить
2. Библиотека Adafruit GFX : Загрузить
Вот полный исходный код программы. Скомпилируйте код и загрузите его на плату Arduino Nano.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
#include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define RE 8 #define DE 7 //const byte code[]= {0x01, 0x03, 0x00, 0x1e, 0x00, 0x03, 0x65, 0xCD}; const byte nitro[] = {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c}; const byte phos[] = {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc}; const byte pota[] = {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0}; byte values[11]; SoftwareSerial mod(2,3); void setup() { Serial.begin(9600); mod.begin(9600); pinMode(RE, OUTPUT); pinMode(DE, OUTPUT); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //initialize with the I2C addr 0x3C (128x64) delay(500); display.clearDisplay(); display.setCursor(25, 15); display.setTextSize(1); display.setTextColor(WHITE); display.println(" NPK Sensor"); display.setCursor(25, 35); display.setTextSize(1); display.print("Initializing"); display.display(); delay(3000); } void loop() { byte val1,val2,val3; val1 = nitrogen(); delay(250); val2 = phosphorous(); delay(250); val3 = potassium(); delay(250); Serial.print("Nitrogen: "); Serial.print(val1); Serial.println(" mg/kg"); Serial.print("Phosphorous: "); Serial.print(val2); Serial.println(" mg/kg"); Serial.print("Potassium: "); Serial.print(val3); Serial.println(" mg/kg"); delay(2000); display.clearDisplay(); display.setTextSize(2); display.setCursor(0, 5); display.print("N: "); display.print(val1); display.setTextSize(1); display.print(" mg/kg"); display.setTextSize(2); display.setCursor(0, 25); display.print("P: "); display.print(val2); display.setTextSize(1); display.print(" mg/kg"); display.setTextSize(2); display.setCursor(0, 45); display.print("K: "); display.print(val3); display.setTextSize(1); display.print(" mg/kg"); display.display(); } byte nitrogen(){ digitalWrite(DE,HIGH); digitalWrite(RE,HIGH); delay(10); if(mod.write(nitro,sizeof(nitro))==8){ digitalWrite(DE,LOW); digitalWrite(RE,LOW); for(byte i=0;i<7;i++){ //Serial.print(mod.read(),HEX); values[i] = mod.read(); Serial.print(values[i],HEX); } Serial.println(); } return values[4]; } byte phosphorous(){ digitalWrite(DE,HIGH); digitalWrite(RE,HIGH); delay(10); if(mod.write(phos,sizeof(phos))==8){ digitalWrite(DE,LOW); digitalWrite(RE,LOW); for(byte i=0;i<7;i++){ //Serial.print(mod.read(),HEX); values[i] = mod.read(); Serial.print(values[i],HEX); } Serial.println(); } return values[4]; } byte potassium(){ digitalWrite(DE,HIGH); digitalWrite(RE,HIGH); delay(10); if(mod.write(pota,sizeof(pota))==8){ digitalWrite(DE,LOW); digitalWrite(RE,LOW); for(byte i=0;i<7;i++){ //Serial.print(mod.read(),HEX); values[i] = mod.read(); Serial.print(values[i],HEX); } Serial.println(); } return values[4]; } |
Объяснение работы кода
Этот код Arduino предназначен для взаимодействия с датчиком NPK (азот, фосфор и калий), который обычно используется для измерения уровня этих питательных веществ в почве. Затем эта информация отображается на OLED-экране.
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define RE 8 #define DE 7 |
Этот раздел подключает необходимые библиотеки для последовательной связи, связи по интерфейсу I2C и функциональности для OLED-дисплея. Он также определяет некоторые параметры, такие как ширина и высота экрана для OLED-дисплея, номер контакта для сброса и номера контактов для контактов RE (Receive Enable) и DE (Driver Enable), используемых в протоколе RS485.
1 2 3 4 5 6 |
const byte nitro[] = {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c}; const byte phos[] = {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc}; const byte pota[] = {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0}; byte values[11]; SoftwareSerial mod(2,3); |
Эта часть кода объявляет и инициализирует массивы, содержащие последовательности байтов для запроса показаний азота, фосфора и калия с датчика. Она также инициализирует массив байтов для хранения значений ответа и программный последовательный интерфейс на контактах 2 и 3.
1 2 3 4 5 6 7 8 |
void setup() { Serial.begin(9600); mod.begin(9600); pinMode(RE, OUTPUT); pinMode(DE, OUTPUT); //... OLED display initialization and message... } |
В функции setup() инициализируется аппаратный последовательный порт и программный последовательный порт со скоростью передачи данных 9600. Она также устанавливает контакты RE и DE как выходные контакты. Дополнительно она инициализирует OLED-дисплей и показывает на нем приветственное сообщение.
1 2 3 4 5 6 7 |
void loop() { byte val1,val2,val3; val1 = nitrogen(); val2 = phosphorous(); val3 = potassium(); //... Print values to the serial monitor and OLED display... } |
Это основной цикл программы, в котором непрерывно запрашиваются и извлекаются значения азота, фосфора и калия из датчика, используя соответствующие функции. Затем эти значения выводятся в окно монитора последовательной связи и на OLED-дисплей.
1 2 3 4 5 6 7 8 9 |
byte nitrogen(){ //... Send request, read response, return value... } byte phosphorous(){ //... Send request, read response, return value... } byte potassium(){ //... Send request, read response, return value... } |
Это функции, которые обрабатывают отправку последовательностей байтов запроса датчику и считывание ответа. Они возвращают значения показаний датчика. В каждой функции сначала устанавливаются высокие уровни на контактах DE и RE, что указывает на необходимость записи в шину. Затем отправляется последовательность байтов запроса для соответствующего питательного вещества. После отправки устанавливаются низкие уровни на контактах DE и RE, что указывает на необходимость считывания с шины. Затем считывается ответ датчика в массив «values» и возвращается интересующее значение.
Примечание: код программы способен измерять значения NPK в почве до 255 мг/кг. Это потому, что мы считываем только 8-битное значение. Согласно техническому описанию датчика, вы можете измерять значение до 1999 мг/кг. Чтобы прочитать такое значение, нам нужно считывать 16-битные данные, что потребует внесения соответствующих изменений в программу.
Мониторинг данных NPK почвы на OLED-дисплее
После загрузки кода на плату Arduino Nano OLED дисплей инициализируется вместе с датчиком. Датчику потребуется некоторое время для стабилизации работы, поэтому вначале его показания могут быть неверными.
Как только датчик стабилизируется, вы можете окунуть датчик в почву, чтобы получить показания NPK. Концентрация азота, фосфора и калия в почве будет отображаться в мг/кг.
Аналогично поместите датчик в различные образцы почвы. Вы увидите изменение значений NPK в зависимости от типа почвы.
Видео, демонстрирующее работу проекта
Помимо измерения NPK в почве, вы также можете измерить влажность почвы с помощью датчика влажности почвы, pH почвы с помощью датчика pH почвы , а также EC и соленость почвы с помощью датчика EC почвы.
Таким образом, вы можете сделать свой собственный измеритель NPK почвы на основе платы Arduino, используя приведенное выше руководство, и определить плодородие почвы.