ATmega16 + DS18B20 + LED + Matlab / Simulink = AR

Pensei em de alguma forma brincar com os sensores DS18B20 . Sim, não apenas para obter os valores de temperatura (o que todos podem fazer), mas também de alguma forma visualizá-los. Havia uma ideia simples. Colocamos a webcam. Acendemos a luz em uma moldura regular; em uma estranha, a apagamos. Subtraia a imagem - apenas o flash permanece. Nele, procuramos a localização do sensor, que está fisicamente conectado ao LED no espaço. E então processamento matemático. Bem, tudo isso em simulinka. Sob katom, é descrito como receber belas imagens. E para aqueles que não querem entender, sugiro olhar para os experimentos no final do artigo.


Circuitry


O circuito é extremamente simples. O coração é o ATmega16. Todos os sensores DS18B20 ficam no mesmo pino (no meu caso, no PB0 da porta PORTB). O próprio pino é puxado para a tensão de alimentação através de um resistor de 4,7 kΩ. O esquema é escalável. A imagem é clicável.



Todos os LEDs são conectados à porta PORTA através de resistores de terminação. Um polígono cinza significa que esse LED está fisicamente conectado ao DS18B20. O pino de redefinição é puxado alto através de um resistor de 10 kΩ para evitar redefinição acidental devido a interferência. O microcontrolador tem clock de 16 MHz de quartzo. Coloque o mais próximo possível das conclusões. Tanques de carga são usados ​​internamente. Configurado via fusível. Saída separada de conectores ICP (para upload de firmware) e UART para "comunicação". Capacidades C1 (eletrólito 10 μF) e C2 (cerâmica 100 nF). Coloque o mais próximo possível dos pinos de energia do microcontrolador. Utilizado para evitar descargas acidentais durante a transferência de carga.

Montagem de circuitos

O que é um polígono cinza?

Firmware + algoritmo de trabalho


O firmware foi escrito em C no Atmel Studio 7 IDE. As fontes são postadas no GitHub . O código está maximamente documentado.
O projeto está dividido em vários níveis de abstração:
  • Hardware - o nível mais baixo, a ligação máxima ao hardware. Trabalhe com a periferia do microcontrolador.
  • Middleware é o meio termo entre Hardware e Drivers. Por exemplo, a implementação do protocolo 1-Wire.
  • Drivers - nível do driver. Por exemplo, trabalhando com o chip DS18B20.
  • Aplicação - o nível mais alto de abstração. Por exemplo, recebendo e transmitindo temperatura via UART.

Uma rápida olhada na função principal. Primeiro vem a tabela de endereços ROM. É necessário que o endereço do sensor conectado fisicamente ao LED zero (pendurado no PA0 da porta PORTA) esteja na posição zero, etc. Para obter a ROM, existe uma função sendROMToUART . Você só precisa lembrar que o sensor deve estar no barramento sozinho, caso contrário, haverá um conflito de endereços.
principal
int main(void)
{	
	const uint8_t ROM[][sizeof(ROM_T)] = /* ROM array */
	{
		{0x26, 0x00, 0x00, 0x04, 0x4B, 0x15, 0x89, 0x28}, // 0
		{0x71, 0x00, 0x00, 0x04, 0x4A, 0xC0, 0x65, 0x28}, // 1
		{0xA5, 0x00, 0x00, 0x04, 0x4A, 0xCB, 0xCE, 0x28}, // 2
		{0x41, 0x00, 0x00, 0x04, 0x4A, 0xAC, 0x65, 0x28}, // 3
		{0x22, 0x00, 0x00, 0x04, 0x4B, 0x06, 0x0D, 0x28}, // 4
		{0x86, 0x00, 0x00, 0x04, 0x4A, 0xF6, 0x46, 0x28}  // 5
	};
	
	uint8_t nDevices = sizeof(ROM) / sizeof(ROM_T); /* Number of DS18B20 devices */
	
	initUART(MYUBRR); /* Initialization of UART with appropriate baudrate */
	initTimer0(); /* Initialization of Timer/counter0 */
	initLED(nDevices); /* Initialization of LEDs */
	
	{ /* DS18B20s initialization */
		uint8_t nDevices = sizeof(ROM) / sizeof(ROM_T); /* Number of DS18B20 devices */
		ROM_T *pROM = (ROM_T *)&ROM; /* Pointer to ROM array */
		
		initDQ(); /* Initialization of DQ pin */
		
		while (nDevices--) /* For all DS18B20 */
			initDS18B20(pROM++, RESOLUTION_11BIT); /* Initialization of DS18B20 with appropriate resolution */
	}
	
	sei(); /* Global enable interrupts */
	
	while (1) /* Infinite loop */
	{
		sendTemperatureToUART((ROM_T *)&ROM, nDevices); /* Execute function routine */
	}
}

A seguir, é apresentada a inicialização dos periféricos e do próprio DS-ok com a resolução apropriada. O período de amostragem da temperatura depende disso. Para 11 bits, isso é 375 ms. Em um loop infinito, o programa lê continuamente a temperatura de cada sensor e a envia via UART.

O trabalho com LEDs é baseado em interrupções. Pelo UART, o LED ID vem 2 vezes seguidas em um quadro par e ímpar. No primeiro, o LED acende. O temporizador apaga após um certo tempo (no meu caso, 15 ms). A segunda vez é simplesmente ignorada. O temporizador é configurado no modo CTC para que ocorra uma interrupção a cada 1 ms.
código
volatile uint8_t ledID = 0; /* Current ledID value */
volatile uint8_t ledID_prev = 255;  /* Previous ledID value */
volatile uint8_t duration = FLASH_DURATION; /* Flash duration value */

ISR(USART_RXC_vect) /* UART interrupt handler */
{
	ledID = UDR; /* Assign ledID to receive via UART value */
	if (ledID != ledID_prev) /* If current ledID equal to previous value */
	{
		turnOnLED(ledID); /* Turn on the ledID LED */
		timer0Start(); /* Start Timer0 */
		ledID_prev = ledID; /* Previous ledID assign to current */
		duration = FLASH_DURATION; /* Update LED flash duration */
	}
}

ISR(TIMER0_COMP_vect) /* Timer0 compare interrupt handler */
{
	if (--duration == 0) /* Decrement Duration value each 1ms and if it reach to 0 */
	{
		timer0Stop(); /* Stop Timer0 */
		turnOffAllLED(); /* Turn off all LEDs */
		timer0Clear(); /* Clear Timer0 counter register */
	}
}

As seções de código sensíveis ao tempo, que são sinais de 1 fio, são agrupadas em uma construção ATOMIC_BLOCK . Todas as configurações básicas são feitas em global.h . O UART opera a uma velocidade de 250.000. Rápido e sem erros para o quartzo de 16 MHz. O driver DS18B20 possui a funcionalidade mínima necessária para este projeto. O resto - veja o código. Haverá perguntas - pergunte, não seja tímido. Gostaria também de lembrá-lo sobre as configurações dos fusíveis. É necessário definir a capacidade de relógio do quartzo externo neles, caso contrário, será do gerador interno (e é no máximo 8 MHz e não é muito estável). Bem, programe o bit CKOPT, caso contrário, o quartzo acima de 8 MHz não será iniciado. Eu tenho fusível alto = 0xD9 , fusível baixo = 0xFF .

Modelo Simulink + algoritmo de operação


Versão Matlab R2015b . No Simulink , além de o built-in biblioteca, usado principalmente Computer Vision System Toolbox e Imagem Aquisição Toolbox . O modelo inteiro e os arquivos relacionados são carregados no GitHub . Abaixo está uma descrição detalhada com exemplos ilustrativos. Todas as imagens são clicáveis.

Módulo WebCamTemp


Os blocos amarelos indicam blocos de porta COM. Transmissor, receptor e configurador separadamente. As configurações da porta devem corresponder exatamente às do microcontrolador (velocidade, paridade, número de bits, etc.). O receptor mede a temperatura agrupando-a em uma matriz unidimensional do tamanho [n 1] do tipo int16 , onde n é o número de DS18B20 (eu tenho 6). Cada elemento dessa matriz é dividido ainda mais por 16 . Isto é da folha de dados na página 6. O transmissor envia o valor atual do contador para o contador . Apenas acende um LED específico. Marcando de 0 a n. Período 2 amostras. Os blocos responsáveis ​​por exibir / salvar o fluxo de vídeo estão agrupados em azul. Verde - blocos para receber informações de vídeo. Na verdade, a própria webcam. Existem muitas configurações, diferentes, dependendo do fabricante. A imagem é exibida em tons de cinza. Tão interessante. O bloco Diff faz a diferença entre os quadros anteriores e os atuais. O bloco ímpar Downsample apenas destaca a diferença acesa - não um LED aceso, mas não vice-versa. O bloco Downsample até pula apenas os quadros onde o LED está apagado.

Img diff
, — . ( ). , . 0.25.



Img cinza
, — , . , . .



O Frame Rate Display exibe o FPS atual. Todo o processamento está nos LEDs do bloco . Vamos considerar o seguinte.

Módulo de LEDs


Violet agrupou blocos de obtenção de Gaussianos 2D . Precisamos de dois: Interferência e Opacidade . Eles diferem em sigma. O centro deles está no ponto máximo (onde o LED estava aceso). As coordenadas estão localizadas no bloco Máximo . Em vez de gerar constantemente esses gaussianos (e o expoente é uma operação matemática muito demorada), decidiu-se eliminá-los. Para fazer isso, no arquivo m, dois Int e Op são gerados com dimensões 2 vezes maiores com o centro no meio, dos quais, além disso, os necessários são simplesmente cortados com os blocos Interferência de corte e Opacidade do corte .

Exemplo de trabalho
— . — . — . — . 0.25.



Blocos de memória estão circulados em verde. Seu objetivo é armazenar as coordenadas e gaussianos para cada LED. Consideramos com mais detalhes abaixo. O bloco de cores Para destina - se a criar uma distribuição de temperatura e um mapa de cores. Também será discutido abaixo. Sinal unidade composição Compositing misturas das duas imagens Image1 e Image2 da seguinte forma:


O bloco Inserir texto impõe texto formatado (neste caso, temperatura) na imagem. Aceita n variáveis ​​e coordenadas no formato [XY] . Você pode selecionar a fonte e seu tamanho. Os blocos dentro do retângulo vermelho implementam o algoritmo de média móvel . As transições tornam-se menos trêmulas, o que preserva os nervos e agrada os olhos.

Exemplo
, — 8- . ( ) .



Módulos de memória


A interferência de memória e a opacidade da memória armazenam conjuntos Gaussianos 2D, pontos de memória - coordenadas para cada LED.

Interferência na memória e opacidade da memória
. Address . . . Delay LEDs ( , ). . Enable . , ( Maximum Threshold LEDs). — . . [H W n], HxW — -, n — /.

Pts de memória
. . Permute Matrix , [Y X], [X Y].

Para colorir o módulo


Verde - Processamento de opacidade . Resuma a matriz de entrada na terceira dimensão. Nós normalizamos ao máximo. Multiplique pelo valor do ganho (de 0 a 1) (1) . No total, temos uma matriz com Gaussianos sobrepostos e um ganho máximo . Usado como um fator para misturar imagens. Vermelho - recebendo um mapa colorido de temperaturas. Aqui um pouco de matemática diferente, todos os mesmos gaussianos. É descrito pela fórmula (2) . Grosso modo, a temperatura em um ponto arbitrário é a média ponderada de todos os sensores. Mas a influência de cada sensor em uma proporção percentual é proporcional ao valor do Gaussiano nele. A soma de tudo é tomada como 100%.


Resta considerar como a distribuição de temperatura se transforma em um mapa de cores. O que é circulado em azul transforma a temperatura específica em um valor entre 0 e 1. Na zona vermelha, o bloco de Pré - configuração calcula o índice pelo qual o valor de vermelho, verde e azul é pesquisado. A matriz de cores contém 64 valores. Os intermediários são calculados por interpolação. Dos recursos, existem dois modos: relativo e absoluto. No local mais frio e mais quente relativo, o mínimo e o máximo da matriz de entrada correspondem. Em absoluto, existem alguns valores constantes. No primeiro, é mais conveniente olhar para o perfil de distribuição de temperatura. No outro, suas mudanças absolutas.

arquivo m


É executado no início, antes da simulação, introduzindo variáveis ​​no Espaço de Trabalho.
código
H = 480; % Height of image
W = 640; % Width of image
minT = 20; % Min temperature
maxT = 25; % Max temperature
sigmaInt = 40; % Sigma interference
sigmaOp = 80; % Sigma opacity
gain = 1.0; % Gain value
T = 0.3; % Threshold value
nAvr = 8; % number of means
% ------------------------------------------------------
[M,N] = meshgrid(-W:W, -H:H); % Meshgrid function

R = sqrt(M.^2 + N.^2); % Distance from the center

Int = normpdf(R, 0, sigmaInt); % 2D gaussian for interference
Op = normpdf(R, 0, sigmaOp); % 2D gaussian for opacity

Int = Int/max(max(Int)); % Normalization of interference gaussian
Op = Op/max(max(Op)); % Normalization of opacity gaussian

clear M N R sigmaInt sigmaOp % Delete unused variables from memory

load('MyColormaps','mycmap'); % Load colormap


Contém as principais variáveis ​​de controle entre as quais:
  • H — .
  • W — .
  • minT — .
  • maxT — .
  • sigmaInt — Interference.
  • sigmaOp — Opacity.
  • gain — Factor.
  • T — .
  • nAvr — .

H e W devem corresponder à corrente no bloco WebCamera. minT e maxT afetam o mapa de cores no modo de temperatura absoluta. T está definido de 0 a 1. Às vezes, a porta COM e a webcam estão fora de sincronia. A fase da imagem diferencial pode mudar em 180 °. E onde deveria haver um máximo - há um mínimo. E o sistema pode escolher uma coordenada arbitrária que não corresponde à realidade. Para isso, existe um sistema de limites. nAvr é o número de médias na média móvel. Quanto maior, mais suaves são as transições, mas a relevância é perdida (uma mudança de tempo aparece). Para entender o efeito das demais variáveis, não se pode entender sem exemplos ilustrativos.

Efeito SigmaInt
. , , . — .



Efeito SigmaOp
.



Efeito de ganho
- . «» « » .



Os experimentos


Abaixo estão alguns experimentos.

Janela aberta


Os sensores estão espalhados na cama pela janela. A janela abre e fecha depois de um tempo. Um bom exemplo da diferença entre os modos relativo (esquerdo) e absoluto (direito). Usando o primeiro, é conveniente considerar a distribuição, e o segundo, como o frio é distribuído ou o calor é restaurado.



Peitoril da janela


Os sensores estão localizados ao longo do peitoril da janela. A janela é aberta - o perfil muda. As zonas mais frias e mais quentes são claramente visíveis.



Está mais quente no topo?


Eles dizem que o topo é mais quente. Este experimento é uma confirmação completa disso. No décimo segundo, a janela se abre, no dia 30 - fecha.



Conclusão


Esse esquema não substituirá um termovisor completo. Mas ele não é capaz de ver a propagação de massas de ar. E por um preço esse design é incomparavelmente mais baixo. Você pode usar um mapa de cores diferente nele. Você pode assumir outras funções em vez de gaussianas. Você pode até mudar as leis da construção. Ou reescreva no OpenCV + QT para velocidade e conveniência. Mas é isso que eu concebi - eu consegui. Apenas por diversão .

Source: https://habr.com/ru/post/pt390985/


All Articles