Temos desenvolvido vários projetos para automação de instrumentos e/ou equipamentos para uso em laboratórios de água, e praticamente todos foram “desenvolvidos do zero” (from scratch).
Com o passar do tempo fomos percebendo a necessidade de adotar algum modelo de desenvolvimento “padronizado” que pudesse simplificar e agilizar o desenvolvido de sistemas integrados de automação.
Encontramos no padrão LECIS-ASTM (e LECIS-OMG) uma alternativa interessante e decidimos seguir os princípios fundamentais dessa norma para o desenvolvimento de um sistema multipropósito que facilite o controle automatizado de instrumentos e/ou equipamentos.
O padrão LECIS (Laboratory Equipment Control Interface Specification) define critérios de uma interface para o controle remoto uniforme e integrado de instrumentos e/ou equipamentos para a execução de procedimentos experimentais.
Uma referência importante, em Português, é o trabalho de conclusão de curso do Thiago Arakaki: SISTEMA DE MONITORAMENTO E CONTROLE LABORATORIAL.
A norma LECIS se baseia no princípio do “controle remoto determinístico” de “dispositivos de laboratório”. Os dispositivos de laboratório, que podem ser instrumentos ou equipamentos, são representados como SLMs (Standard Laboratory Modules - Módulos Padronizados de Laboratório), os quais são controlados pelo TSC (Task Sequence Controller - Controlador da Sequência de Tarefas).
Cada instrumento é controlado por um programa SLM que se comunica com um módulo chamado de InstrumentServer que centraliza a comunicação de todos os SLMs dos instrumentos com o TSC. Da mesma forma os equipamentos são controlados pelos respectivos SLMs que por sua vez se comunicam com o EquipmentServer que é o responsável por centralizar a comunicação dos SLMs dos equipamentos com o TSC, conforme o diagrama da figura 353.
Figura 353. Diagrama simplificado da estrutura de um sistema para o controle automatizado de experimento “adaptado” da norma LECIS-ASTM.
O objetivo dessa abordagem é permitir o desenvolvimento de uma interface que permita ao usuário, leigo em programação, configurar o sistema com diferentes módulos para diferentes aplicações e fazer o programa de controle de monitoramento e controle de um experimento de maneira amigável, além de simplificar a incorporação de novos módulos SLMs (instrumentos ou equipamentos).
O comportamento de cada SLM é modelado como uma Máquina de Estados como mostra o diagrama da figura 354.
Apesar da norma LECIS não sugerir, decidimos elaborar um modelo de estados para o TSC indicando os possíveis estados em que um experimento pode estar, como mostra o diagrama da figura 355.
Inicialmente o sistema carrega as informações de todos os módulos disponíveis, listados na variável available_resources
, e exibe na tela inicial para o usuário selecionar quais SLMs serão usados.
Ao clicar no botão “Continuar” o sistema cria as instâncias dos SLMs selecionados com as instâncias dos respectivos estados (inicialmente stateUNCONFIGURED) e os objetos necessários para o fluxo de dados.
Os comandos de cada SLMs são disponibilizados para o sistema como módulos através do comando package require, implementado nos métodos loadSLM das classes instrumentModule
e equipmentModule
.
Destaco a seguir o método loadSLM como um exemplo de como a versatilidade da linguagem Tcl™ viabilizou a implantação de recursos sofisticados no SisProLab™:
method loadSLM {} { #https://stackoverflow.com/questions/33415534/find-all-procs-of-a-namespace-in-tcl package require [[self] getID] set list_procedures [info procs ::[[self] getID]::* ] set list_commands {} foreach p $list_procedures { lappend list_commands [namespace tail $p] } return $list_commands }
Em seguida o sistema envia o comando checkConnection para a placa Arduino e aguarda pelo retorno da string “ACK” para verificar se a placa Arduino está conectada e para executar as rotinas de inicialização dos SLMs, antes de abrir a tela para elaborar a sequência de eventos de um experimento.
Este sistema foi concebido considerando que todos os SLMs estão conectados a uma única placa Arduino.
A segunda tela é aberta exibindo, na esquerda, uma janela com os SLMs ativos; na janela do centro um editor para digitar os comandos de um experimento; e na janela da direita a exibição dos eventos de validação e o registro dos comandos executados ao longo do experimento.
Nessa etapa o TSC entra no estado stateUSER_PROGRAMMING
permitindo ao usuário selecionar, dentre os comandos disponíveis, os eventos de controle e monitoramento de uma corrida experimental.
Após a elaboração do programa experimental é necessário fazer a “validação” para verificar eventuais erros na sintaxe dos comandos e evitar a interrupção do experimento devido a erros no código.
Após a validação o TSC entra no estado stateREADY_TO_RUN_EXPERIMENT
permitindo a execução do experimento.
Durante o experimento os eventos são registrados na janela da direita gerando um “arquivo de log” do experimento.
Download dos arquivos do SisProLab_00 sisprolab_00.zip.
Precisamos implementar o código de um SLM correspondente a uma Bomba de Seringa controlada por um servomotor.
Implementamos no código do Arduino Multicomando o comando startPump que recebe como argumentos a “posição final” e o “intervalo” entre cada deslocamento do servomotor. A posição define o volume que será carregado ou descarregado, dependendo da posição original do êmbolo, enquanto que o intervalo entre cada deslocamento define a velocidade de deslocamento do êmbolo e portanto a “vazão”.
No entanto queremos que o usuário possa fazer uma programação de “alto nível” e amigável para, por exemplo, programar o bombeamento contínuo através de uma coluna e estabelecer como critério de parada um intervalo de tempo ou o sinal de um detector (Ex: fotométrico).
O sistema foi concebido para executar uma sequência linear de eventos com a possibilidade de inserir intervalos de parada temporizados.
Esses eventos podem ser comandos executados diretamente por um SLM ou pelo TSC, e os comandos do TSC poderiam “encapsular” comandos de um SLM.
Diferentes comandos executados por um único SLM podem ser implementados no módulo SLM. Mas os comandos que dependem da interação de diferentes SLMs precisariam ser implementados em um “nível superior” como o TSC.
O comando de bombeio com uma bomba de seringa precisa “necessariamente” sincronizar o servo da seringa com o servo de uma válvula para conectar a seringa com o reservatório para o carregamento, e em seguida conectar a seringa com a coluna para o descarregamento.
Podemos pensar em um comando para o “TSC” do tipo “pump” que faria essa integração.
Mas como implementar essa função no TSC sem ter que definir “de maneira rígida” quais SLMs ficarão sincronizados e como será essa integração?
???
Para fazer essa sincronia vamos precisar implementar no Arduino Multicomando uma mensagem de retorno do comando startPump indicando o final da operação, algo como “END_PUMPING”, sinalizando o momento de acionar a válvula para fazer a devida comutação.
Poderíamos criar um “SLM Integrado” dedicado para essa funcionalidade?... Algo como um “syringePump”?...
Seria um “SLM Integrado” pois não teria correspondência direta com apenas um módulo físico, mas seria o resultado da integração de diferentes módulos físicos.
Download dos arquivos do SisProLab_01 sisprolab_01.zip.
Vamos agora implementar no SisProLab os recursos necessários para permitir a execução de uma ou mais “subrotinas” ao longo de uma rotina principal.
Implementamos no TSC o comando execScript File nTimes, onde “File” é o nome do arquivo contendo a subrotina e o argumento “nTimes” especifica o número de vezes que a subrotina deve ser executada.
Não foi implementada um rotina para “Validar” o script. E portanto o executante deve se lembrar de “validar” o comandos do script antes de salvar o arquivo.
É de grande importância um comando que permita a parada de execução de uma rotina experimental. Mas, dependendo das características de cada SLM, é necessário realizar ações específicas para garantir uma “parada segura”.
Por exemplo, ao interromper uma rotina de análise o bombeamento deve ser interrompido, algumas válvulas devem ser comutadas para evitar eventuais vazamentos, os LEDs de um detector devem ser desligados, aquecedores devem ser desligados etc.
O comando stopExp poderá ser chamado pelo usuário ou por um evento interno do sistema, e cada módulo SLM deve executar as ações “específicas” e necessárias para uma transição segura para o estado stateSTOPPED_EXPERIMENT
.
O sistema permanecerá no estado stateSTOPPED_EXPERIMENT
até receber o comando resumeOperation, para reiniciar o experimento, ou startDisconnection para se desconectar.
A norma Lecis indica o comando estop mas decidimos usar apenas stopExp independente da origem do comando.
Um SLM não pode rejeitar a execução do comando stopExp.
Assim como temos o método startExperiment na classe experimentController
, podemos criar também o método stopExperiment para gerenciar o eventos necessários para o comando stopExp, implementado nos SLMs.
Um das primeiras ações do método stopExperiment é aplicar o evento eventSTOP_EXPERIMENT para alterar o estado do TSC para stateSTOPPING_EXPERIMENT
e dessa forma interromper a execução de comandos de uma subrotina e os comandos seguintes.
Podemos também implementar o método stopScript que será chamado pelo método execScript dependendo do status do experimento. (RUNNING_EXPERIMENT ou STOPPING_EXPERIMENT).
A estratégia básica do método stopExperiment será usar o códito do experimento em andamento e executar “todos” os comandos do programa chamando o método stopExp em cada módulo SLM utilizado.
Assim como outros comandos, o comando stopExp não necessita de argumentos específicos e portanto usamos a constante “NO_ARG”.
No caso da bomba de seringa, o código para controle da(s) bomba(s) de seringa implementado no Arduino Multicomando precisa receber um identificador (id_pump
) para a bomba que está sendo controlada.
Mas como o SLM correspondente à uma bomba de seringa é exclusivo, podemos manter o padrão do comando stopExp com “NO_ARG” e incluir dentro do SLM o id_pump
deixando essa informação “transparente” para o usuário.
Ao iniciar o método stopExperimento o status do experimento é alterado de RUNNING_EXPERIMENT para STOPPING_EXPERIMENT e dessa forma os eventos programados são suspensos.
Logo em seguida é executado o comando stopExp para todos os SLMs e para o TSC.
Para fazer a temporização de espera no comando waitTime usamos a variável global vwait_monitor
que é modificada pelo método changeVwaitMonitor após o intervalo de espera programado.
E para interromper o tempo de espera implementamos o método stopWaitTime que chama “antecipadamente” o método changeVwaitMonitor para modificar o conteúdo da variável vwait_monitor
e dessa forma desativar a interrupção do experimento.