Мобильная система дистанционного контроля инфузии. Разработка

 


ТЗ: имеется оптический датчик, тороидальной формы, который надевается на колбу капельницы и регистрирует падающие капли. Датчик при пролете капли выдает импульс амплитудой около 3 В и длительностью ~70мс. Микропроцессор регистрирует импульс и раз в 10 секунд инициализирует отправку данных на сервер, через Wi-Fi соединение, отправляя данные о количестве капель, объеме введенной жидкости, частоте пролета капель. Серверное приложение обрабатывает и накапливает данные, при необходимости информирует медперсонал о нарушении режима процедуры или о скором ее окончании. Кроме того, сервер может по локальной сети на мобильное приложение отправить медсестре сообщение о том, что требуется ее внимание.
Поскольку высокого быстродействия тут не требуется, как и большого объема памяти, был выбран недорогой 8-битный микропроцессор ATmega328, работающий на частоте 16 Мгц.
Первая схема была собрана довольно быстро, датчик подключен, для удобства пользования также был подключен TFT-дисплей, на котором пока отображается техническая информация.

Макетная плата с микропроцессором (плата Arduino Nano)
Оптический датчик

В дальнейшем, конечно, все будет по-другому, придумаю и напечатаю на 3D принтере красивый корпус, с элементами управления, корпус датчика тоже необходимо сменить для универсальности использования.

После того как я удостоверился в работоспособности датчика и схемы, пришло время задуматься о подключении Wi-Fi модуля. И тут оказалось, что по соотношению цена/доступность/функциональность, при всем богатстве выбора, другой альтернативы нет… Конечно же, это ESP8266, для которого есть множество прошивок, библиотек, примеров и большое комьюнити. И один такой, когда-то купленный на али, у меня нашелся:h

Модуль ESP8266

Он, правда, использует 3.3 В логику, поэтому пришлось использовать конвертер уровней для согласования с 5-вольтовой ардуинкой и внешний стабилизатор на 3.3В, поскольку модуль потребляет до 250 ma тока.
В среду Ардуино была установлена SDK, позволяющая писать свои прошивки. К слову, процессор на борту намного мощнее ATmega328, работает на частоте 80 Мгц, на плате также установлена flash-память для прошивок объемом 1 Мб, из внешних интерфейсов — uart порт. Для его программирования нужен USB-TTL конвертер.

Решение — взять Ардуино плату, которая уже содержит такой конвертер на микросхеме ch340g (у китайских клонов), чтобы процессор ардуинки не мешал обмену информацией по порту, в режиме заливки прошивки, необходимо вывод Reset закоротить на Gnd. Выяснилось, что все переходники и платы, основанные на ch340g под Windows 10 х64, не могут нормально работать с ESP8266. Это выяснилось после похода на радиорынок, где я купил USB-TTL конвертер на 5/3.3 Из-за того, что он собран на ch340G, он не заработал (. К счастью, я купил два разных, и второй заработал без проблем.

Решил не использовать AT прошивки с официального сайта, а написать свою. Дело в том, что при использовании AT прошивки всем процессом будет управлять Arduino, которая также опрашивает датчик, управляет экраном, передает данные… Я же сделал так, что ардуинка раз в несколько секунд отправляет данные по Serial порту на Es8266, а уж Wi-Fi модуль сам управляет отправлением сообщения на сервер, проверяет наличие подключения к серверу, дисконнекта от роутера Wi-Fi согласно написанной мною прошивке. Такое разделение мне мне показалось очень удобным.

Прототип, полностью работающий и отправляющий данные на сервер.

Для отладки нужен был сервер, и я взял простой многопоточный сокет сервер на java, который потом не трудно будет перенести в андроид приложение. Код его приведен ниже:

package capcapserv;
import java.io.*;

import java.net.*;
/**
 *
 * @author Владимир
 */
public class CapCapServ {
 static final int PORT = 2323;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
             ServerSocket s = new ServerSocket(PORT);
      System.out.println("Server Started");
      try {
         while (true) {
            // Блокируется до возникновения нового соединения:
            Socket socket = s.accept();
            try {
               new ServeOneJabber(socket);
               System.out.println("client Started");
            }
            catch (IOException e) {
               // Если завершится неудачей, закрывается сокет,
               // в противном случае, нить закроет его:
               socket.close();
                 System.out.println("Socket closed 1");
            }
         }
      }
      finally {
         s.close();
         System.out.println("Socket closed 2");
      }
    }
    
}
class ServeOneJabber extends Thread {
   private Socket socket;
   private BufferedReader in;
   private PrintWriter out;
  
   public ServeOneJabber(Socket s) throws IOException {
      socket = s;
      in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      // Включаем автоматическое выталкивание:
      out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
            .getOutputStream())), true);
      // Если любой из вышеприведенных вызовов приведет к
      // возникновению исключения, то вызывающий отвечает за
      // закрытие сокета. В противном случае, нить
      // закроет его.
      start(); // вызываем run()
   }
  
   public void run() {
      try {
         while (true) {
             if (!socket.isConnected())
            {
                System.out.println("Disconnect ");
                break;
            }
            String str = in.readLine();
            out.println(0);
            
            {
     
            System.out.println("Echoing: " + str);
            
            }
         }
         System.out.println("closing...");
      }
      catch (IOException e) {
         System.err.println("IO Exception");
      }
      finally {
         try {
             System.err.println("Socket  closed by finally"); 
            socket.close();
            
         }
         catch (IOException e) {
            System.err.println("Socket not closed");
         }
      }
   }
}
Данные на экране с датчика
Эти же данные, приходящие на сервер

Как видно с двух выше расположенных фотографий, данные с устройства по Wi-Fi успешно попадают на сервер.

Таким образом, промежуточный результат есть, но впереди еще большая работа!

Вторая часть!