Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Мониторинг состояния реки: Arduino-система контроля качества воды

Компоненты и расходные материалы

Arduino MKR1000 (MKR FOX 1200) × 1
Датчик уровня воды × 1
pH-датчик × 1
Светодиод (белый) × 1
Резистор 220 Ом × 2
Фоторезистор × 1
Провода-перемычки × 1 комплект

Необходимые инструменты

Приложения и онлайн-сервисы

О проекте

Обзор

Река или озеро — отличное место для отдыха. Но если вода загрязнена, вся радость пропадает. Многие люди зависят от речной воды для скота и не могут позволить давать животным грязную воду.

Представьте: вы живете у реки. Не хотите просыпаться ночью от наводнения. Или сосед сбрасывает бензин в реку — вы не хотите, чтобы животные заболели.

MyRiver решает все эти проблемы. Устройство работает в изолированных зонах благодаря Sigfox, так что доступно всем. Оно измеряет pH воды, уровень загрязнения инновационным методом и уровень воды. Мониторинг в реальном времени на телефоне или компьютере через Wia. Мгновенные уведомления при проблемах.

Мониторинг состояния реки: Arduino-система контроля качества воды

Функциональность

Устройство на базе Arduino MKR FOX, рассчитано на удаленную работу. Размещается в реке/озере, мониторится откуда угодно. Благодаря низкопотребляющему режиму SAM D работает долго от 2 АА батареек.

Измерения каждые 30 минут, затем сон (минимум 20 мин).

MKR FOX считывает:

Данные отправляются в Sigfox → Wia → обработка и визуализация. Пользователь получает уведомления.

Мониторинг состояния реки: Arduino-система контроля качества воды

Буфер (12 байт) кодируется в HEX для Sigfox. Wia конвертирует обратно в строку, парсит в значения датчиков, обрабатывает, шлет уведомления при выходе за нормы.

Мониторинг состояния реки: Arduino-система контроля качества воды

MKR FOX может слать только 12 байт через Sigfox. Максимальное сырое значение каждого датчика — 1024 (10-битный АЦП), поэтому каждый датчик получает 4 байта (1/3 буфера). Arduino конвертирует целые в строки, дописывает ведущие нули до 4 символов, склеивает в 12-байтовую строку.

Мониторинг состояния реки: Arduino-система контроля качества воды

Пример: фоторезистор = 620 → 0620; уровень воды = 24 → 0024. Объединяются в буфер и отправляются.

Устройство в действии

Фото функциональности (лучше смотреть видео выше).

Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды

Преимущества

Пользователь получает:

Сборка проекта

Шаг 1: Необходимое оборудование

Все компоненты паяются вместе. Материалы:

Мониторинг состояния реки: Arduino-система контроля качества воды

Шаг 2: Подключение схемы

Схема может показаться запутанной (компоненты не на макетке). При сложностях скачайте Fritzing-файл и перемещайте провода на экране.

Мониторинг состояния реки: Arduino-система контроля качества воды

Как должна выглядеть готовая схема:

Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды

Подготовка MKR FOX

Подключение батарейного отсека и антенны. Батарейный отсек подключается ПОСЛЕ датчиков. Остальная проводка — в разделе Final.

Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды

Шаг 3: Разбор кода

3 основные части:

Read Sensors

struct GetValue {
  int riverLevel() {
    const int val = analogRead(A2);
    if(proDebug) { Serial.print(" River Level "); Serial.println(val); }
    return val;
  }
  int riverPh() {
    const int val = (analogRead(A1) / 5 * 3.3);
    if(proDebug) { Serial.print(" River Ph "); Serial.println(val); }
    return val;
  }
  int riverPol() {
    const int val = analogRead(A3);
    if(proDebug) { Serial.print(" River Pollution "); Serial.println(val); }
    return val;
  }
};

Структура с методами для каждого датчика.

Format Buffer

String data(int level, int ph, int pol) {
  int values[3] = {level, ph, pol};
  String newValues;
  for(int i = 0; i < 3; i++) {
    if(values[i] < 10) { newValues += "000"; Serial.println("Option 1"); }
    else if(values[i] < 100) { newValues += "00"; Serial.println("Option 2"); }
    else if(values[i] < 1000) { newValues += "0"; Serial.println("Option 3"); }
    newValues += values[i];
    Serial.print(" Run "); Serial.print(i); Serial.print("/3 "); Serial.println(newValues);
  }
  return newValues;
}

Цикл добавляет ведущие нули до 4 символов на значение, склеивает в строку.

Parse Data

void parseData(String data) {
  SigFox.beginPacket();
  SigFox.print(data);
  int ret = SigFox.endPacket();
}

Отправка буфера в Sigfox.

Шаг 4: Настройка интеграции Wia + Sigfox

Wia — профессиональная IoT-платформа: виджеты на вебе/мобильном, блок-схемы (Flows) для обработки данных. Данные = события (events).

Нужен аккаунт Sigfox и Wia. Приложение Wia на iOS/Android для уведомлений.

Настройка вебхука в Sigfox (много скриншотов в оригинале):

Шаг 5: Настройка Flow в Wia

Flow конвертирует HEX → String, парсит 3 значения, конвертирует: загрязнение и уровень → «High»/«OK», pH → реальное значение pH. Уведомляет при выходе за нормы.

Пошаговая инструкция со скриншотами (в оригинале много изображений). Ниже код функций Wia (копируйте в Functions).

Wia Functions

processPayload

if(input.body) {
  output.body.name = "value";
  output.body.data = toByteArrayStr(input.body.data.sigfoxData);
}
function toByteArrayStr(sigfoxData) {
  let result = Buffer(sigfoxData, 'hex');
  return result.toString('utf8');
}

processPollution

if(input.body.data) {
  let data = input.body.data;
  if(data == "POLLUTED") {
    output.body.name = "waterLevel";
    output.body.data = data;
  } else { while(1); }
}

processPh

let minVal = 6.5; let maxVal = 8.5;
if(input.body.data) {
  let data = input.body.data;
  if(data > maxVal || data < minVal) {
    output.body.name = "waterPh";
    output.body.data = data;
  } else { while(1); }
}

processLevel

if(input.body.data) {
  let data = input.body.data;
  if(data == "HIGH") {
    output.body.name = "waterLevel";
    output.body.data = data;
  } else { while(1); }
}

riverPollution

let minVal = 200; let maxVal = 0;
if(input.body.data.sigfoxData) {
  let data = input.body.data.sigfoxData;
  let processedData = toByteArrayStr(data);
  let newData = cutString(processedData);
  output.body.name = "waterPollution";
  output.body.data = processData(newData);
}
function toByteArrayStr(sigfoxData) {
  let result = Buffer(sigfoxData, 'hex');
  return result.toString('utf8');
}
function cutString(data) {
  let newVal = data[8]; newVal += data[9]; newVal += data[10]; newVal += data[11];
  let finalVal = parseInt(newVal);
  return finalVal;
}
function processData(data) {
  if(data < minVal) return "POLLUTED"; else return "OK";
}

riverPh

let minVal = 300; let maxVal = 600;
if(input.body.data.sigfoxData) {
  let data = input.body.data.sigfoxData;
  let processedData = toByteArrayStr(data);
  let newData = cutString(processedData);
  let finalVal = (newData / 73.1428571);
  let valueToSend = finalVal.toFixed(2);
  output.body.name = "waterPh";
  output.body.data = valueToSend;
}
function toByteArrayStr(sigfoxData) {
  let result = Buffer(sigfoxData, 'hex');
  return result.toString('utf8');
}
function cutString(data) {
  let newVal = data[4]; newVal += data[5]; newVal += data[6]; newVal += data[7];
  let finalVal = parseInt(newVal);
  return newVal;
}

riverLevel

let minVal = 0; let maxVal = 200;
if(input.body.data.sigfoxData) {
  let data = input.body.data.sigfoxData;
  let processedData = toByteArrayStr(data);
  let newData = cutString(processedData);
  output.body.name = "waterLevel";
  output.body.data = processData(newData);
}
function cutString(data) {
  let newVal = data[0]; newVal += data[1]; newVal += data[2]; newVal += data[3];
  let finalVal = parseInt(newVal);
  return finalVal;
}
function toByteArrayStr(sigfoxData) {
  let result = Buffer(sigfoxData, 'hex');
  return result.toString('utf8');
}
function processData(data) {
  if(data > maxVal) return "HIGH"; else return "OK";
}

Wia Emails (шаблоны уведомлений)

riverPollutionEmail

Automatic Messaging System Data Warning - myWater device ${trigger.source.device.id} detected a problem in the stream. Warning - Water Is Polluted by Insoluble Substances. Information Device ${trigger.source.device.id} Raw Data ${input.body.data}

riverPhEmail

Automatic Messaging System Data Warning - myWater device ${trigger.source.device.id} detected a problem in the stream. Warning - Water Ph is not Appropriate. Water is Contaminated. Information Device ${trigger.source.device.id} Raw Data ${input.body.data}

riverLevelEmail

Automatic Messaging System Data Warning - myWater device ${trigger.source.device.id} detected a problem in the stream. Warning - Water Level is too High, River may be flooding. Information Device ${trigger.source.device.id} Raw Data ${input.body.data}

Настройка переменных

При получении данных Wia обрабатывает их: если значение в пределах мин/макс — безопасно. Лимиты pH и уровня заданы, но порог фоторезистора нужно определить экспериментально:

void setup() {
  pinMode(1, OUTPUT);
  Serial.begin(9600);
  while(!Serial) {};
  digitalWrite(1, HIGH);
}
void loop() {
  const int val = analogRead(A3);
  Serial.println(val);
  delay(5000);
}

Переменная proDebug — если включена, нужен USB-PC и открытый Serial Monitor (для отладки). По умолчанию false для полевой работы.

Библиотеки

Финал

Подключите Arduino к ПК, залейте скетч, убедитесь что батарейный отсек подключен и схема исправна. Далее — корпус.

Корпус из пластиковой бутылки — экологично и дешево. Устройство выглядит так:

Мониторинг состояния реки: Arduino-система контроля качества воды

Фото процесса изготовления корпуса (листайте в оригинале).

Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды

Установка в реку: идете на реку во время высокой воды (прилива) — критично, чтобы устройство не ложно срабатывало на прилив как на наводнение.

Заклейте горлышко бутылки скотчом против проникновения воды.

Тестировали в грязной реке — все тревожки сработали верно.

Мониторинг состояния реки: Arduino-система контроля качества воды

При установке зонда: вода должна быть у низа датчика уровня, но полностью покрывать фоторезистор. Закрепите на берегу скотчем или болтами.

Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды

Предыстория

Смотришь в окно на когда-то красивую реку, а там зеленая слизь — хочется переехать. А если река затопит дом ночью — точно переедешь.

Я подумал над этими проблемами и как решить их одним устройством — родился MyRiver.

В городе у реки — предупредит, если сосед сльет масло. На ферме — предупредит, что вода грязная перед поем скота, и даст время увести скот перед наводнением.

Только pH недостаточно: нерастворимые вещества (ртуть, металлы) не меняют pH. Придумали новый метод уникальный для проекта: фоторезистор измеряет свет от LED, проходящий сквозь воду. Любая примесь меняет пропускание света.

Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды
Мониторинг состояния реки: Arduino-система контроля качества воды

Код

MyRiver — полный код

Полный скетч доступен в разделе Code.

Схемы

Мониторинг состояния реки: Arduino-система контроля качества воды

Fritzing-файл: schematics_lXO5SiusZO.fzz

Производственный процесс

  1. Понимание кислородного (O2) датчика: роль, размещение и признаки отказа
  2. Создайте домашний монитор температуры на Raspberry Pi с MCP9808, InfluxDB и Grafana
  3. Датчик эмоций и ЭЭГ: низкобюджетное железо для детекции эмоций в реальном времени
  4. Устройство точного измерения давления и расхода воздуха на аналоговом датчике
  5. Проект с датчиком DHT11: индикация температуры светодиодами и пьезо-динамиком на Arduino
  6. UnifiedWater v1: полный набор датчиков качества воды на Arduino MKR GSM
  7. 3D RGB Arduclock — Bluetooth-часы на адресных LED с RTC
  8. Простой ИК-датчик препятствий на Arduino: ИК-светодиод и фотодиод
  9. Интерактивная игра с джойстиком и LED-обратной связью на Arduino
  10. Find Me: Умный поисковик вещей на Arduino и Bluetooth