ATmega16 + DS18B20 + LED + Matlab / Simulink = AR

Ich dachte daran, irgendwie mit den DS18B20- Sensoren herumzuspielen . Ja, nicht nur um die Temperaturwerte zu erhalten (was jeder tun kann), sondern auch um sie irgendwie zu visualisieren. Es gab eine einfache Idee. Wir setzen die Webcam. Wir zünden das Licht auf einem geraden Rahmen an, auf einem ungeraden löschen wir es. Subtrahieren Sie das Bild - nur der Blitz bleibt übrig. Darauf suchen wir nach der Position des Sensors, der physisch an der LED im Raum befestigt ist. Und dann die mathematische Verarbeitung. Nun, das alles in Simulinka. Unter katom wird beschrieben, wie man schöne Bilder erhält. Und für diejenigen, die nicht verstehen wollen, empfehle ich, die Experimente am Ende des Artikels zu betrachten.


Schaltung


Die Schaltung ist extrem einfach. Das Herz ist der ATmega16. Alle DS18B20-Sensoren hängen an einem Pin (in meinem Fall an PB0 des PORTB-Ports). Der Pin selbst wird über einen 4,7-kΩ-Widerstand auf die Versorgungsspannung gezogen. Das Schema ist skalierbar. Das Bild ist anklickbar.



Alle LEDs sind über Abschlusswiderstände mit dem PORTA-Port verbunden. Ein graues Polygon bedeutet, dass diese LED physisch mit dem DS18B20 verbunden ist. Der Rücksetzstift wird durch einen 10 kΩ-Widerstand hochgezogen, um ein versehentliches Zurücksetzen aufgrund von Interferenzen zu vermeiden. Der Mikrocontroller wird mit 16 MHz Quarz getaktet. Schließen Sie die Schlussfolgerungen so nah wie möglich an. Ladetanks werden intern verwendet. Über Sicherung konfiguriert. ICP-Konnektoren (zum Hochladen der Firmware) und UART für "Kommunikation" getrennt ausgeben. Kapazitäten C1 (Elektrolyt 10 μF) und C2 (Keramik 100 nF). Stellen Sie das Gerät so nah wie möglich an die Stromanschlüsse des Mikrocontrollers. Wird verwendet, um versehentliche Entladungen während der Lastübertragung zu vermeiden.

Schaltungsanordnung

Was ist ein graues Polygon?

Firmware + Arbeitsalgorithmus


Die Firmware wurde in C in Atmel Studio 7 IDE geschrieben. Quellen werden auf GitHub veröffentlicht . Der Code ist maximal dokumentiert.
Das Projekt ist in mehrere Abstraktionsebenen unterteilt:
  • Hardware - die niedrigste Ebene, maximale Bindung an Hardware. Arbeiten Sie mit der Peripherie des Mikrocontrollers.
  • Middleware ist der Mittelweg zwischen Hardware und Treibern. Zum Beispiel die Implementierung des 1-Wire-Protokolls.
  • Treiber - Fahrerebene. Zum Beispiel mit dem DS18B20-Chip arbeiten.
  • Anwendung - die höchste Abstraktionsebene. Zum Beispiel Empfangen und Senden von Temperatur über UART.

Ein kurzer Blick durch die Hauptfunktion. Zuerst kommt die Tabelle der ROM-Adressen. Es ist erforderlich, dass sich die Adresse des Sensors, der physisch mit der Null-LED verbunden ist (hängt an der PA0 des PORTA-Anschlusses), in der Nullposition usw. befindet. Um ROM zu erhalten, gibt es eine sendROMToUART- Funktion . Sie müssen sich nur daran erinnern, dass sich der Sensor nur am Bus befinden muss, da sonst ein Adresskonflikt auftritt.
Haupt
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 */
	}
}

Als nächstes erfolgt die Initialisierung der Peripheriegeräte und des DS-ok selbst mit der entsprechenden Auflösung. Die Temperaturabtastperiode hängt davon ab. Für 11 Bits sind dies 375 ms. In einer Endlosschleife liest das Programm kontinuierlich die Temperatur von jedem Sensor und sendet sie über UART.

Die Arbeit mit LEDs basiert auf Interrupts. Bei UART wird die LED-ID zweimal hintereinander in einem geraden und ungeraden Frame angezeigt. Beim ersten Mal leuchtet die LED auf. Der Timer erlischt nach einer bestimmten Zeit (in meinem Fall 15 ms). Das zweite Mal wird einfach ignoriert. Der Timer ist im CTC-Modus so konfiguriert, dass alle 1 ms ein Interrupt auftritt.
Code
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 */
	}
}

Die zeitkritischen Abschnitte des Codes, bei denen es sich um 1-Draht-Signale handelt, werden in ein ATOMIC_BLOCK- Konstrukt eingeschlossen. Alle Grundeinstellungen werden in global.h vorgenommen . UART arbeitet mit einer Geschwindigkeit von 250.000. Schnell und fehlerfrei für 16-MHz-Quarz. Der DS18B20-Treiber verfügt über die für dieses Projekt erforderliche Mindestfunktionalität. Der Rest - siehe Code. Es wird Fragen geben - fragen Sie, seien Sie nicht schüchtern. Ich möchte Sie auch an die Einstellungen der Sicherungen erinnern. Es ist notwendig, die Taktfähigkeit des externen Quarzes in ihnen einzustellen, andernfalls wird sie vom internen Generator stammen (und sie liegt bei maximal 8 MHz und ist nicht sehr stabil). Nun, programmieren Sie das CKOPT-Bit, sonst startet Quarz über 8 MHz nicht. Ich habe High Fuse = 0xD9 , Low Fuse = 0xFF .

Simulink-Modell + Operationsalgorithmus


Matlab R2015b Version . In der Simulink , zusätzlich zu der eingebauten Bibliothek, hauptsächlich verwendet , Computer Vision System Toolbox und Bild Aquisition Toolbox . Das gesamte Modell und die zugehörigen Dateien werden auf GitHub hochgeladen . Nachfolgend finden Sie eine detaillierte Beschreibung mit veranschaulichenden Beispielen. Alle Bilder sind anklickbar.

WebCamTemp-Modul


Die gelben Blöcke zeigen COM-Port-Blöcke an. Sender, Empfänger und Konfigurator getrennt. Die Porteinstellungen müssen genau mit dem Mikrocontroller übereinstimmen (Geschwindigkeit, Parität, Anzahl der Bits usw.). Der Empfänger empfängt Temperatur, es in ein eindimensionales Array der Größe Gruppierung [n 1] Typ int16 , wobei n - die Anzahl DS18B20 (I 6) aufweist . Jedes Element dieses Arrays wird weiter durch 16 geteilt . Dies geht aus dem Datenblatt auf Seite 6 hervor. Der Sender sendet den aktuellen Zählerwert an den Zähler . Es leuchtet nur eine bestimmte LED. Ticking von 0 bis n. Periode 2 Proben. Die Blöcke, die für die Anzeige / Speicherung des Videostreams verantwortlich sind, sind blau gruppiert. Grüne Blöcke zum Empfangen von Videoinformationen. Eigentlich die Webcam selbst. Es gibt viele Einstellungen, die je nach Hersteller unterschiedlich sind. Das Bild wird in Grautönen angezeigt. So interessant. Der Diff- Block macht den Unterschied zwischen dem vorherigen und dem aktuellen Frame. Der ungerade Downsample- Block hebt nur den beleuchteten Unterschied hervor - keine leuchtende LED, aber nicht umgekehrt. Der Downsample- Block überspringt sogar nur Frames, bei denen die LED nicht leuchtet .

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



Img grau
, — , . , . .



Die Bildratenanzeige zeigt die aktuellen FPS an. Die gesamte Verarbeitung erfolgt in den Block- LEDs . Wir werden es wie folgt betrachten.

LED-Modul


Violett gruppierte Blöcke zum Erhalten von 2D-Gaußschen . Wir brauchen zwei: Interferenz und Opazität . Sie unterscheiden sich im Sigma. Ihr Zentrum befindet sich am Maximalpunkt (an dem die LED leuchtet). Die Koordinaten befinden sich im Block Maximum . Anstatt solche Gaußschen ständig zu erzeugen (und der Exponent ist eine sehr zeitaufwändige mathematische Operation), wurde beschlossen, sie auszuschneiden. Zu diesem Zweck werden in der m-Datei zwei Int und Op mit 2-mal größeren Größen mit der Mitte in der Mitte generiert , von denen die erforderlichen einfach mit den Blöcken Crop Interference und Crop Opacity zugeschnitten werden .

Arbeitsbeispiel
— . — . — . — . 0.25.



Speicherblöcke sind grün eingekreist. Ihr Zweck ist es, die Koordinaten und Gaußschen Werte für jede LED zu speichern. Wir werden im Folgenden näher darauf eingehen. Der To- Farbblock dient zum Erstellen einer Temperaturverteilung und einer Farbkarte. Wird auch unten diskutiert. Signalzusammensetzungseinheit Compositing Mischungen der beiden Bilder Image1 und Image2 auf folgende Weise:


Der Block Text einfügen fügt dem Bild formatierten Text (in diesem Fall Temperatur) hinzu. Akzeptiert n Variablen und Koordinaten im Format [XY] . Sie können die Schriftart und ihre Größe auswählen. Die Blöcke innerhalb des roten Rechtecks ​​implementieren den Algorithmus für den gleitenden Durchschnitt . Übergänge werden weniger nervös, was die Nerven schont und das Auge erfreut.

Beispiel
, — 8- . ( ) .



Speichermodule


Speicherinterferenz und Speicheropazität speichern 2D-Gauß-Sätze, Speicherpunkte - Koordinaten für jede LED.

Speicherstörungen und Speicheropazität
. Address . . . Delay LEDs ( , ). . Enable . , ( Maximum Threshold LEDs). — . . [H W n], HxW — -, n — /.

Speicher pts
. . Permute Matrix , [Y X], [X Y].

Modul färben


Grün - Deckkraftverarbeitung . Fassen Sie das Eingabearray in der dritten Dimension zusammen. Wir normalisieren es auf das Maximum. Multiplizieren Sie mit dem Verstärkungswert (von 0 bis 1) (1) . Insgesamt haben wir ein Array mit überlagerten Gaußschen und maximaler Verstärkung . Wird als Faktor zum Mischen von Bildern verwendet. Rot - erhält eine Farbkarte der Temperaturen. Hier ein bisschen andere Mathematik, alle die gleichen Gaußschen. Es wird durch Formel (2) beschrieben . Grob gesagt ist die Temperatur an einem beliebigen Punkt der gewichtete Durchschnitt aller Sensoren. Der Einfluss jedes Sensors in einem prozentualen Verhältnis ist jedoch proportional zum Wert des darin enthaltenen Gaußschen. Die Summe aller wird als 100% angenommen.


Es bleibt zu überlegen, wie sich die Temperaturverteilung in eine Farbkarte verwandelt. Was blau eingekreist ist, verwandelt eine bestimmte Temperatur in einen Wert zwischen 0 und 1. In der roten Zone berechnet der Prelookup- Block den Index, nach dem der Wert von Rot, Grün und Blau gesucht wird. Das Farbarray enthält 64 Werte. Zwischenprodukte werden durch Interpolation berechnet. Von den Funktionen gibt es zwei Modi: relativ und absolut. An der relativ kältesten und heißesten Stelle entsprechen das Minimum und das Maximum des Eingabearrays. In absoluten Zahlen gibt es einige konstante Werte. Im ersten Fall ist es bequemer, das Temperaturverteilungsprofil zu betrachten. In der anderen ändert sich absolut.

m Datei


Es wird zu Beginn vor der Simulation ausgeführt und führt Variablen in den Arbeitsbereich ein.
Code
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


Es enthält die wichtigsten Steuervariablen, darunter:
  • H — .
  • W — .
  • minT — .
  • maxT — .
  • sigmaInt — Interference.
  • sigmaOp — Opacity.
  • gain — Factor.
  • T — .
  • nAvr — .

H und W müssen mit dem Strom im WebCamera-Block übereinstimmen. minT und maxT beeinflussen die Farbkarte im absoluten Temperaturmodus. T wird von 0 auf 1 gesetzt. Manchmal sind der COM-Anschluss und die Webcam nicht synchron. Die Phase des Differenzbildes kann sich um 180 ° ändern. Und wo es ein Maximum geben sollte, gibt es ein Minimum. Und das System kann eine beliebige Koordinate wählen, die nicht der Realität entspricht. Hierfür gibt es ein Schwellensystem. nAvr ist die Anzahl der Durchschnittswerte im gleitenden Durchschnitt. Je größer es ist, desto glatter werden die Übergänge, aber die Relevanz geht verloren (eine Zeitverschiebung erscheint). Um die Wirkung der verbleibenden Variablen zu verstehen, kann man ohne anschauliche Beispiele nicht verstehen.

SigmaInt-Effekt
. , , . — .



SigmaOp-Effekt
.



Effekt erzielen
- . «» « » .



Experimente


Das Folgende sind einige Experimente.

Fenster öffnen


Sensoren sind am Fenster am Bett verstreut. Das Fenster öffnet und schließt sich nach einer Weile. Ein gutes Beispiel für den Unterschied zwischen dem relativen (links) und dem absoluten (rechts) Modus. Bei der ersten Methode ist es zweckmäßig, die Verteilung und bei der zweiten die Verteilung der Kälte oder die Wiederherstellung der Wärme zu berücksichtigen.



Windowsill


Sensoren befinden sich entlang der Fensterbank. Das Fenster öffnet sich - das Profil ändert sich. Die kältesten und wärmsten Zonen sind deutlich sichtbar.



Ist es oben wärmer?


Sie sagen, dass die Oberseite wärmer ist. Dieses Experiment ist eine vollständige Bestätigung dafür. In der 10. Sekunde öffnet sich das Fenster, in der 30. - es schließt sich.



Fazit


Ein solches Schema ersetzt keine vollwertige Wärmebildkamera. Aber er kann die Ausbreitung der Luftmassen nicht sehen. Und zu einem Preis ist dieses Design unvergleichlich niedriger. Sie können eine andere Farbkarte verwenden. Sie können andere Funktionen anstelle von Gaußschen übernehmen. Sie können sogar die Baugesetze ändern. Oder schreiben Sie OpenCV + QT neu, um Geschwindigkeit und Komfort zu gewährleisten. Aber das habe ich mir vorgestellt - ich habe es erreicht. Nur zum Spaß .

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


All Articles