Multiple max6675 arduino based industrial temperature monitoring system

Полезные ссылки

  • Библиотка для работы с MAX6675K. Основна на коде более старой билиотеки от Adafruit.
  • Библиотека Adafruit для работы с MAX6675K.
  • Библиотека Adafruit для работы с MAX31855.
  • Библиотека для работы с MAX31855 поновее, чем Adafruit.
  • https://www.instructables.com/id/Power-and-Temperature-Data-Logger-With-ESP32-and-A/
  • http://www.esp8266learning.com/wemos-max6675-example.php
  • http://www.esp32learning.com/code/esp32-and-max6675-example.php
  • http://henrysbench.capnfatz.com/henrys-bench/arduino-temperature-measurements/max6675-temp-module-arduino-manual-and-tutorial/
  • http://www.electronoobs.com/eng_arduino_tut24.php
  • https://protosupplies.com/product/max6675-thermocouple-temperature-module/

Терморезистор

Ключевым компонентом нашей схемы является терморезистор, который используется для определения температуры. Термистор представляет собой резистор, сопротивление которого изменяется в зависимости от температуры. Существует два типа подобных термисторов: NTC (Negative Temperature Co-efficient — с отрицательным температурным коэффициентом) и PTC (Positive Temperature Co-efficient — с положительным температурным коэффициентом). Мы в нашем проекте будем использовать терморезистор NTC типа – его сопротивление уменьшается с повышением температуры. На следующих рисунках приведены график зависимости сопротивления подобного терморезистора от температуры и его типовой внешний вид.

Расчет температуры с помощью терморезистора

Схема используемого нами делителя напряжения представлена на следующем рисунке.

Напряжение на терморезисторе в этой схеме можно определить из известного напряжения:

Vout=(Vin*Rt)/(R+Rt).

Из этой формулы можно выразить значение сопротивления терморезистора Rt (R – известное сопротивление 10 кОм):

Rt=R(Vin/Vout)-1.

Значение Vout мы затем будем определять в коде программы с помощью считывания значения на выходе АЦП на контакте A0 платы Arduino.

Математически, сопротивление терморезистора можно вычислить с помощью известного уравнения Стейнхарта-Харта (Stein-Hart equation).

T = 1/(A + B*ln(Rt) + C*ln(Rt)3).

В этой формуле A, B и C — константы, Rt – сопротивление терморезистора, ln — натуральный логарифм.

Мы для проекта использовали терморезистор со следующими константами: A = 1.009249522×10−3, B = 2.378405444×10−4, C = 2.019202697×10−7. Эти константы можно определить с помощью данного калькулятора, введя в нем значения сопротивления терморезистора при трех значениях температуры или вы их можете непосредственно узнать из даташита на ваш терморезистор.

Таким образом, для определения значения температуры нам будет нужно только значение сопротивления терморезистора – после его определения мы просто подставляем его значение в уравнение Стейнхарта-Харта и с его помощью рассчитываем значением температуры в кельвинах. Алгоритм определения температуры в нашем проекте представлен на следующем рисунке.

Использование термопары

Если вы используете интерфейсный чип AD595, можно просто подключить выходное напряжение к аналоговому входу на вашем Arduino (или другом микроконтроллере) и произвести дополнительную математическую операцию, чтобы преобразовать ваши 10 мВ/°C в числовое значение на выходе.

Если вы планируете использовать MAX6675/MAX31855 или их аналоги, подключение будет чуть сложнее. Первое: Vin и GND надо подключить к источнику питания 3-5 В. Оставшиеся три пина (data пины) подключаются к цифровым контактам Arduino:

  • CLK (clock — часы) — входа на MAX6675/MAX31855 (и выход на Arduino), который сигнализирует, когда надо передавать новый бит данных;
  • DO (data out — вывод данных) выход с MAX6675/MAX31855 (входа на Arduino), через который передается каждый бит данных;
  • CS (chip select — выбор чипа) вход на MAX6675/MAX31855 (выход с Arduino), который сообщает, когда настало время считать показания термопары и вывести больше данных.

В начале скетчей для Arduino надо инициализировать эти пины. В нашем конкретном примере DO подключается к цифровому пину digital 3 на Arduino, CS — к цифровому пину digital 4, а CLK подключается к пину 5.

Если вы используете MAX31855 v1.0 в зашумленных условиях, рекомендуется добавить конденсатор на 0.01 мкФ между контактами термопары (смотрите на рисунке выше).

MAX31855 не поддерживает заземленные термопары. Если сенсор заземляется, чип вернет вам ошибку.

Пример работы

Итак, с теоретической основой закончили, можно приступать к соединению датчика температуры и Arduino. Схема подключения:

Естественно, речь идет об использовании сенсора в воздушной среде. В том случае, если требуется измерять нагрев жидкости, то нужен герметичный датчик температуры DS18B20.

Алгоритм обработки

Сама последовательность действий достаточно проста. Только для упрощения, в приведенном примере, она рассчитана на наличие единственного сенсора на линии 1-Wire.

  1. Определить ИД датчика термостата
  2. Отправить команду по ИД на измерение температуры
  3. Ждать 750 мс, пока устройство отработает и поместит данные в оперативную память
  4. Дать функциональную команду на чтение памяти датчика температуры ds18b20

Сам скетч для Arduino

Здесь требуется примечание. Существует множество библиотек работы с 1-Wire выполняющих подключение датчика температуры DS18B20 к Arduino. В представленном скетче, будет использоваться вариант «OneWire», которую можно скачать с официальной страницы разработчиков ПО Arduino (https://playground.arduino.cc/Learning/OneWire). Там же, есть информация для ознакомления со списком функций в библиотеке.

Есть нюанс в приведенном скетче, он относится к физической схеме подключения питания датчика и соответствующим взаимодействием процедур библиотеки. Если используется паразитное, то DataSerial.Write(0х44), о запросе температуры, нужно заменить на DataSerial.Write(0x44, 1).

Что касается конечных пользователей, то пользуясь этой инструкцией, им будет несложно выполнить подключение инфракрасного датчика ds18b20 температуры для Ардуино. Все достаточно прозрачно, скетч элементарен, а простота схемы достойна уважения.

Преобразовываем показания с термистора в температуру

Естественно, от сопротивления на термисторе нам не холодно не жарко. Нам надо узнать именно температуру! Если вам достаточно на скорую руку оценить температуру (например, если температура ниже какого-то значения X, выполняем определенную задачу, если же выше какого-то Y, выполняем другую задачу), вы можете просто использовать таблицу зависимости температуры от сопротивления.

Уравнение достаточно сложное и требует большого количества переменных-параметров, которых может не быть для конкретного термистора. Вместо этого уравнения можно использовать упрощенное B parameter уравнение.

Для этой зависимости нам надо знать исключительно To (этот параметр для комнатной температуры (25 °C) = 298.15 K), B (в данном конкретном случае равен 3950 — коэффициент, который зависит от используемого термистора), и Ro (сопротивление при комнатной температуре. В данном случае он равен 10 КОм). Подставляем R (измеренное сопротивление) и получаем значение T (температура по Кельвину), которую преобразовываем в °C.

В программе для Arduino, которая приведена ниже, рассчитывается температура в °C.

// к какому аналоговому пину мы подключены

#define THERMISTORPIN A0

// сопротивление при 25 градусах по Цельсию

#define THERMISTORNOMINAL 10000

// temp. для номинального сопротивления (практически всегда равна 25 C)

#define TEMPERATURENOMINAL 25

// сколько показаний используем для определения среднего значения

#define NUMSAMPLES 5

// бета коэффициент термистора (обычно 3000-4000)

#define BCOEFFICIENT 3950

// сопротивление второго резистора

#define SERIESRESISTOR 10000

int samples;

void setup(void) {

Serial.begin(9600);

analogReference(EXTERNAL);

}

void loop(void) {

uint8_t i;

float average;

// сводим показания в вектор с небольшой задержкой между снятием показаний

for (i=0; i

samples = analogRead(THERMISTORPIN);

delay(10);

}

// рассчитываем среднее значение

average = 0;

for (i=0; i

average += samples;

}

average /= NUMSAMPLES;

Serial.print(«Average analog reading «);

Serial.println(average);

// конвертируем значение в сопротивление

average = 1023 / average — 1;

average = SERIESRESISTOR / average;

Serial.print(«Thermistor resistance «);

Serial.println(average);

float steinhart;

steinhart = average / THERMISTORNOMINAL; // (R/Ro)

steinhart = log(steinhart); // ln(R/Ro)

steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)

steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)

steinhart = 1.0 / steinhart; // инвертируем

steinhart -= 273.15; // конвертируем в градусы по Цельсию

Serial.print(«Temperature «);

Serial.print(steinhart);

Serial.println(» *C»);

delay(1000);

}

Для того, чтобы получить еще более точные измерения, рекомендуется учесть точный номинал резистора. В данном случае он, например, не будет равен ровно 10 КОм, а будет принимать значение близкое к 10 КОм.

Подробнее о датчике температуры:

В основу работы термопары заложен термоэлектрический эффект, это процесс возникновения ЭДС (электродвижущей силы) на спайке (соединении) разнородных металлов, интенсивность которой прямо пропорциональна температуре в месте этого соединения. Возникающая в термопаре ЭДС очень мала и её нельзя измерить используя аналоговые входы Arduino, но с этой задачей справляется чип max6675. Сигнал с термопары сначала поступает на операционные усилители чипа, а уже потом на 12 битный АЦП, далее данные выводятся по шине SPI в виде двух байт, старшие 12 бит которых являются числом температуры. Для преобразования 12 битного числа в °C его нужно разделить на 4, получается что температура выводится с разрешением 0,25 °C. Так как данные из чипа только читаются, без отправки данных чипу, то на его шине SPI отсутствует вывод MOSI. Немаловажным фактом является и то, что в чипе max6675 реализована функция компенсации холодного спая. Дело в том, что ЭДС возникает не только на спае металлов термопары, но и на соединении этих металлов с проводом, что без функции компенсации холодного спая влияло-бы на показания температуры.

Для работы с чипом max6675 рекомендуем воспользоваться одноимённой библиотекой max6675, которая реализует получение данных чипа по программной шине SPI, значит, для подключения можно использовать любые выводы Arduino.

Общие принципы работы датчика температуры DS18B20

DS18B20 представляет собой однопроводный цифровой датчик температуры от компании Maxim IC. Выдает значение температуры в градусах Цельсия, способен измерять температуру с 9-12 битной точностью в диапазоне от -55 до 125 градусов Цельсия с точностью +/-0.5 градуса. Каждый датчик DS18B20 имеет 64-битный уникальный номер (Serial number), вытравленный на корпусе датчика, что позволяет подключать огромное число подобных датчиков к одной шине данных. С помощью данного датчика можно измерять температуру воздуха, жидкостей и земли. В некоторых магазинах датчик продается в комплекте с резистором сопротивлением 4,7 кОм.

Особенности датчика DS18B20:

  • однопроводный интерфейс (1-Wire interface), что позволяет использовать для подключения датчика только один контакт микроконтроллера (в нашем случае платы Arduino Uno);
  • каждый датчик имеет 64-битный уникальный последовательный код (номер), хранящийся в ПЗУ (ROM) датчика;
  • способность подключения к одной шине множества датчиков позволяет создавать на его основе приложения для распределенного (в пространстве) измерения температуры;
  • не требует никаких внешних компонентов;
  • может быть запитан от линии данных;
  • поддерживает напряжение питания от 3.0V до 5.5V;
  • способен измерять температуру в диапазоне от –55°C до +125°C (–67°F до +257°F) с точностью ±0.5°C (в диапазоне от –10°C до +85°C);
  • можно выбрать разрешающую способность (разрешение) датчика: от 9 до 12 бит;
  • преобразует значение температуры в 12-битное цифровое слово длительностью 750 мс (max.);
  • можно настраивать энергонезависимую (nonvolatile, NV) сигнализацию (сигнал тревоги);
  • опции сигнала тревоги позволяют идентифицировать и определить адрес датчика, чья температура не соответствует запрограммированным границам;
  • может применяться в устройствах термоконтроля, промышленных системах, потребительских продуктах, термометрах и в любых других системах, где требуется измерение температуры.

Более подробную информацию о принципах работы датчика DS18B20 вы можете посмотреть в следующей статье на нашем сайте.

PART 2 K-Thermocouple temperature read

So, let’s start building this project. The first thing we will do, is see how to read the real temperature. Below we can see a K type thermocouple, and the MAX 66 75 breakout module. This will amplify and compensate the voltage created by the thermocouple. It has an SPI communication so we’ll have to connect these pins to the Arduino SPI port.

Use the connections below and let’s test it out. On a breadboard I connect the MAX 66 75 and the thermocouple. Be careful, the thermocouple has polarity so connect positive to positive and negative to negative. Connect the SPI pins to the Arduino and also supply 5V and GND.

Download schematic here:

Методика считывания аналогового напряжения

Для того, чтобы определить температуру, мы должны измерить сопротивление. При этом на Arduino нет встроенного измерителя сопротивления. Но зато есть возможность считать напряжение с помощью аналогово-цифрового конвертера. Так что нам надо преобразовать сопротивление в напряжение. Для этого мы последовательно добавим в схему подключения еще один резистор. Теперь, когда вы будете мерять напряжение по центру, с изменением сопротивления, будет меняться и напряжение.

Скажем, мы используем резистор с постоянным номиналом 10K и переменный резистор, который называется R. При этом напряжение на выходе (Vo), которое мы будем передавать Arduino, будет равно:

Vo = R / (R + 10K) * Vcc,

где Vcc — это напряжение источника питания (3.3 В или 5 В)

Теперь мы хотим подключить все это к Arduino. Не забывайте, что когда вы измеряете напряжение (Vi) с использованием АЦП на Arduino, вы получите числовое значение.

ADC value = Vi * 1023 / Vcc

Теперь мы совмещаем два напряжения (Vo = Vi) и получаем:

ADC value = R / (R + 10K) * Vcc * 1023 / Vcc

Что самое прекрасное, Vcc сокращается!

ADC value = R / (R + 10K) * 1023

То есть вам неважно, какое напряжение питания вы используете!

В конце мы все же хотим получить R (сопротивление). Для этого надо использовать еще одно преобразование, в котором R переносятся в одну сторону:

R = 10K / (1023/ADC — 1)

Отлично. Давайте попробуем, что из этого всего выйдет. Подключите термистор к Arduino как это показано на рисунке ниже:

Подключите один контакт резистора на 10 КОм к контакту 5 В, второй контакт резистора 10 КОм 1% — к одному контакту термистора. Второй контакт термистора подключается к земле. ‘Центр’ двух резисторов подключите к контакту Analog 0 на Arduino.

Теперь запустите следующий скетч для Arduino:

// значение ‘другого’ резистора

#define SERIESRESISTOR 10000

// к какому пину подключается термистор

#define THERMISTORPIN A0

void setup(void) {

Serial.begin(9600);

}

void loop(void) {

float reading;

reading = analogRead(THERMISTORPIN);

Serial.print(«Analog reading «);

Serial.println(reading);

// преобразуем полученные значения в сопротивление

reading = (1023 / reading) — 1;

reading = SERIESRESISTOR / reading;

Serial.print(«Thermistor resistance «);

Serial.println(reading);

delay(1000);

}

В результате вы должны получить значения, которые соответствуют измеренным с помощью мультиметра.

Способ 2: чтение датчика DS18B20 по адресу

Мы знаем, что каждому DS18B20 назначен уникальный 64-битный адрес, чтобы отличать их друг от друга. В этом методе мы найдем этот адрес для соответствующей маркировки каждого датчика. Затем этот адрес можно использовать для считывания каждого датчика в отдельности.

Поиск адресов датчиков DS18B20s на шине

Следующий скетч обнаруживает все DS18B20, присутствующие на шине, и печатает их адреса на 1-Wire в монитор последовательного порта.

Вы можете подключать только один датчик за раз, чтобы определить его адрес (или последовательно добавлять по одному новому датчику, чтобы вы могли идентифицировать каждый из них по его адресу). Затем вы можете пометить каждый датчик.

Теперь откройте монитор последовательного порта. Вы должны получить что-то подобное:

Рисунок 6 – Нахождение адресов 1-Wire всех датчиков DS18B20 на шине

Скопируйте все адреса, так как они нам понадобятся в следующем скетче.

Чтение показаний датчиков DS18B20 по адресу

Следующий скетч считывает температуру датчиков DS18B20 по их адресам. Прежде чем приступить к загрузке скетча, вам нужно изменить адреса датчиков DS18B20 на те, которые вы определили в предыдущем скетче.

Вывод вышеприведенного эскиза выглядит так

Рисунок 7 – Вывод показаний нескольких датчиков DS18B20 методом адреса

Объяснение кода

Как обычно, скетч начинается с включения библиотек, объявления вывода, к которому подключена шина датчиков, и создания объекта библиотеки .

Далее мы вводим адреса, которые были найдены ранее для каждого датчика температуры. В нашем случае имеем следующее.

Во фрагменте настройки мы инициализируем библиотеку путем вызова функции и инициализируем последовательную связь с ПК.

В цикле мы просто посылаем команду всем датчикам для преобразования температуры, используя функцию .

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

Вышеприведенная функция просто вызывает библиотечные функции для отображения температуры в градусах Цельсия и для отображения температуры в градусах Фаренгейта.

Расчет температуры с помощью терморезистора

Схема используемого нами делителя напряжения представлена на следующем рисунке.

Напряжение на терморезисторе в этой схеме можно определить из известного напряжения:

Vout=(Vin*Rt)/(R+Rt).

Из этой формулы можно выразить значение сопротивления терморезистора Rt (R – известное сопротивление 10 кОм):

Rt=R(Vin/Vout)-1.

Значение Vout мы затем будем определять в коде программы с помощью считывания значения на выходе АЦП на контакте A0 платы Arduino.

Математически, сопротивление терморезистора можно вычислить с помощью известного уравнения Стейнхарта-Харта (Stein-Hart equation).

T = 1/(A + B*ln(Rt) + C*ln(Rt)3).

В этой формуле A, B и C — константы, Rt – сопротивление терморезистора, ln — натуральный логарифм.

Мы для проекта использовали терморезистор со следующими константами: A = 1.009249522×10−3, B = 2.378405444×10−4, C = 2.019202697×10−7. Эти константы можно определить с помощью данного калькулятора, введя в нем значения сопротивления терморезистора при трех значениях температуры или вы их можете непосредственно узнать из даташита на ваш терморезистор.

Таким образом, для определения значения температуры нам будет нужно только значение сопротивления терморезистора – после его определения мы просто подставляем его значение в уравнение Стейнхарта-Харта и с его помощью рассчитываем значением температуры в кельвинах.

2Подключение преобразователяMAX31865 к Arduino

Есть несколько популярных библиотек Arduino для работы с MAX31865. Но наиболее популярная и проверенная, вероятнее всего, библиотека от Adafruit. Скачаем и установим её.

Библиотеку от Adafruit можно также установить через менеджер библиотек Arduino IDE: Tools Manage Libraries… и в поле фильтра ввести MAX31865. Выбрать интересующую библиотеку, нажать кнопку Install и дождаться окончания установки.

Откроем из примеров библиотеки единственный скетч для MAX31865 и загрузим его в память Arduino.

Загрузка примера из библиотеки для MAX31865

Обратите внимание, что в функции setup() необходимо указать, по какой схеме вы подключаете датчик. По умолчанию стоит трёхпроводная схема, что указывается константой MAX31865_3WIRE

Для 2- и 4-проводных подключений датчика названия констант, соответственно, MAX31865_2WIRE и MAX31865_4WIRE. Также следует обратить внимание на константы в начале скетча RREF и RNOMINAL, которые определяют референсное (опорное) сопротивление и номинальное сопротивление термодатчика, соответственно.

Теперь подключим модуль с MAX31865 к Arduino по такой схеме (соответствие выводов можно поменять в скетче):

Схема подключения модуля MAX31865 к Arduino
Вывод модуля Вывод Arduino
CLK D13
SDI D11
SDO D12
CS D10
VIN 3V3
GND GND

Если запустить теперь монитор последовательного порта из Arduino IDE, то мы должны увидеть ежесекундно обновляющиеся показания термодатчика.

цифровая электроника вычислительная техника встраиваемые системы

Arduino и датчик температуры термопары на основе MAX6675

Термопара типа K является наиболее распространенным типом термопар. Она недорогая, точная, надежная и имеет широкий температурный диапазон. В этой статье показано, как использовать микроконтроллер Arduino Uno / Nano с модулем дисплея OLED для считывания данных термопары типа K. Как и следовало ожидать, существует аналоговый интерфейс MAX6675 для прямого цифрового преобразования выходных данных термопары типа K. Программное обеспечение, выполняемое в фоновом режиме, переводит показания термопары в воспринимаемые значения температуры в градусах Цельсия или Фаренгейта.

Микросхема MAX6675, доступная в 8-контактном корпусе SO, выполняет компенсацию холодного спая и оцифровывает сигнал от термопары типа K. Окончательный вывод данных производится в 12-разрядном формате, совместимом с SPI.

Микросхема также имеет функцию обнаружения открытой термопары. Для быстрого создания прототипа было бы лучше использовать предварительно смонтированную плату MAX6675, а не чистую микросхему, припаянную к адаптеру SMD, потому что отладочная плата обычно доступна в виде экономичного комплекта, который включает термопару типа K. Выше приведено изображение такого модуля.

Подключение данного модуля с MAX6675 к Arduino выполняется довольно просто: Vcc к 5 V, Gnd к Gnd, SO к D4, CS/SS к D5, CSK к D6. Термопара подключается к модулю MAX6675 с противоположной стороны от контактов, ведущих к Arduino.

Ниже приведен простой скетч для теста. Для работы с модулем вам понадобится библиотека MAX6675 (https://github.com/adafruit/MAX6675-library).

Окно последовательного монитора при запуске программы может выглядеть следующим образом:

Теперь подключим к полученной конструкции OLED-дисплей 128 × 64 к Arduino по шине I2C (OLED SDA к A4, OLED SCL к A5).

Код программы приведен далее. Как видно из кода, он усредняет выходную информацию оборудования термопары в 25 раз, чтобы получить разумные показания термометра. Следует отметить, что это замедлит обновление дисплея, но не повлияет на реакцию термопары. На экране дисплея отображается максимальная температура в верхнем левом углу, минимальная температура в верхнем правом углу и текущая температура в нижней строке.

Использование Arduino и термопары с MAX6675 – это простой и недорогой способ создания простого, но надежного ручного цифрового термометра.

Recent Articles

  1. Using an ATtiny Programmer gives you massive memory savings and complete control for low power operations.

  2. How to unbrick an ATtiny: What to do when your ATtiny seems dead — it is probably not — find out how to fix it here.

  3. Charlieplexing: How to drive multiple LEDs with very few microcontroller outputs that will let you save microcontroller I/O for other uses.

  4. Learn how to use the TP4056 properly. There’s a right way, and a wrong way, to use it to safely charge Lithium Ion batteries.

  5. A tutorial on using the ADS1115 precision 16 bit ADC for low power use.

  6. How to use an arduno Nano as an ISP (In System Programmer)

    Arduino Nano ISP: How to program an ATmega328P using an Arduino Nano as the ISP programmmer. One common problem: Programming a sketch into the chip without a reset control — solved here.

2Принципы управления драйвером MAX7219

Драйвер MAX7219 управляется по последовательному интерфейсу SPI. Никаких неожиданностей здесь нет, всё стандартно, как мы уже не раз разбирали. Выбор ведомого (CS) низким уровнем, скорость обмена до 10 МГц.

Данные передаются посылками по 16 бит. В первых 8-ми битах содержится адрес регистра, в который необходимо передать данные (или команду). А вторые 8 бит, собственно, данные. Для каждого регистра будут свои данные, т.к. регистры отличаются по назначению.

Формат командной посылки драйвера MAX7219

Регистров всего 14, чуть позднее мы познакомимся с большинством из них подробнее. В таблице адреса регистров обозначены как, например, 0xX3. Что это значит? Сигнатура «0x» говорит о том, что дальнейшее число записано в шестнадцатеричном виде. Далее идёт «X», что означает, что первая половина байта не влияет и может быть любой. Я буду здесь всегда ставить ноль. И последнее число, собственно, адрес регистра. В рассматриваемом примере «0xX3» адрес регистра – «3», и будем записывать его как «0x03».

Карта регистров драйвера MAX7219

MSB означает most significant bit, т.е. наиболее значимый бит. Это старший бит в байте. Напротив, LSB означает least significant bit, т.е. наименее значимый бит. Это младший бит байта.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector