Android Things - связь с Bluetooth-устройствами с низким энергопотреблением

  1. Понимание Bluetooth с низким энергопотреблением (BLE)
  2. Начало работы с BLE на Android
  3. Слово о пользовательских услугах / характеристиках ГАТТ
  4. Создание сервера
  5. Константы
  6. AndroidManifest.xml
  7. Создание сервиса ГАТТ
  8. Запуск сервера
  9. Возврат значения счетчика
  10. Увеличение счетчика
  11. Тестирование сервера GATT
  12. Создание клиента
  13. Сканирование устройств BLE
  14. Подключение к серверу ГАТТ
  15. Обнаружение услуг
  16. Чтение значения счетчика
  17. Обновление пользовательского интерфейса при получении значения счетчика
  18. Получать уведомления при изменении значения
  19. Добавляем немного веселья (то есть создание физического объекта)
  20. Физическое счетчик
  21. Приложение Android Wear
  22. Заключение

Android Things поддерживает API-интерфейсы Bluetooth и Bluetooth с низким энергопотреблением.
В этом сообщении мы будем использовать API-интерфейс Bluetooth LE для связи между сервером ( доска объявлений Android ) и клиентом ( приложение Android на телефоне / часах ).

Мы создадим счетчик для нашей удивительности : каждый раз, когда вы чувствуете себя удивительно ( по любой причине ), нажмите кнопку на вашем мобильном устройстве. Счастливый кот переместит свою лапу и увеличит ваш счетчик удивительности.

Понимание Bluetooth с низким энергопотреблением (BLE)

BLE основан на спецификации, называемой «Общий профиль ATTribute» ( GATT ), которая определяет, как передавать и получать короткие фрагменты данных, известные как «атрибуты» между сервером и клиентом.

В нем упоминаются такие понятия, как «профили», «услуги», «характеристики» и «дескрипторы».

Профиль - это набор (1 или несколько) сервисов.
Каждый сервис ( который можно представить как поведение ) может содержать одну или несколько характеристик, которые инкапсулируют данные.

Для обеспечения совместимости Bluetooth SIG (Специальная группа по интересам) предварительно настроил несколько профилей и служб.
Представьте, что мы хотим создать собственное клавиатурное устройство. Для обеспечения совместимости мы должны будем следовать HID (Human Interface Device) через профиль GATT:

Профиль - это в основном спецификация, которая говорит нам, что Сервисы мы должны будем реализовать.
Чтобы создать нашу пользовательскую клавиатуру, нам нужно будет реализовать 3 обязательных сервиса (HID, Battery, Device Info) и опционально сервис Scan Parameters.

Если мы посмотрим на Обслуживание батареи , который показывает состояние батареи в устройстве, мы можем видеть, что оно содержит одну и обязательную характеристику только для чтения с именем Уровень заряда батареи ,
Эта характеристика инкапсулирует значение int между 0 и 100, которое представляет собой процент заряда батареи устройства. Он также имеет необязательное свойство «Уведомлять», что означает, что клиент может подписаться на него, чтобы получать автоматические уведомления при изменении значения.

Он также имеет необязательное свойство «Уведомлять», что означает, что клиент может подписаться на него, чтобы получать автоматические уведомления при изменении значения

Начало работы с BLE на Android

официальная документация лучший способ начать работу с Bluetooth Low Energy на Android.

Google также предоставляет 2 примера проектов:

После развертывания этих двух проектов вы сможете сканировать сервер Android Things GATT:

Услуги и характеристики однозначно идентифицируются UUID.
Здесь RPI3 предоставляет 3 службы: общий атрибут (0x1801), общий доступ (0x1800) и службу текущего времени (0x1805). Последний имеет две характеристики: текущее время (0x2A2B) и информацию о местном времени (0x2A0F)

Слово о пользовательских услугах / характеристиках ГАТТ

Хотя внедрение сервисов, определенных Bluetooth SIG, является рекомендуемым способом, также возможно создание собственных проприетарных сервисов ( и мы сделаем это сегодня ). В некоторых случаях это может быть предпочтительным решением, но вы не сможете воспользоваться преимуществами взаимодействия.

Вы должны использовать 128-битные случайные UUID для своих нестандартных услуг и характеристик. Короткие 16-битные UUIDs предназначены только для услуг / характеристик, определенных стандартом Bluetooth.

Создание сервера

Теперь, когда мы знакомы с ключевыми понятиями BLE, мы можем приступить к реализации нашего сервера GATT.

Наш проект Android Things представит единый сервис с двумя характеристиками:

  • AwesomenessCounter: доступное только для чтения, уведомляемое свойство, которое показывает, сколько раз вы были удивительными до сих пор
  • AwesomenessInteractor: когда клиент записывает значение в эту характеристику, устройство должно двигать лапу кошки и увеличивать счетчик удивительности.

Следующий код будет в значительной степени вдохновлен образец-Bluetooth-ле-gattserver , Если вам нужно создать сервер GATT, вы можете использовать этот проект в качестве справочного или следовать официальной документации.

Константы

Мы определим следующие константы:

SERVICE_UUID = UUID. fromString ("795090c7-420d-4048-a24e-18e60180e23c"); CHARACTERISTIC_COUNTER_UUID = UUID. fromString ("31517c58-66bf-470c-b662-e352a6c80cba"); CHARACTERISTIC_INTERACTOR_UUID = UUID. fromString ("0b89d2d4-0ea6-4141-86bb-0c5fb91ab14a"); DESCRIPTOR_CONFIG_UUID = UUID. fromString ("00002902-0000-1000-8000-00805f9b34fb");

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

Также обратите внимание на константу DESCRIPTOR_CONFIG_UUID:
Каждая характеристика содержит значение. Если мы возьмем пример характеристики «Уровень заряда батареи», она содержит значение от 0 до 100. Характеристика также может содержать некоторые дескрипторы. Дескрипторы определяют метаданные, такие как описание и информация представления.

Некоторые примеры Дескрипторы ГАТТ :

  • Описание пользователя признака ( 0x2901 ): Предоставляет текстовое описание пользователя для значения признака.
  • Valid Range ( 0x2906 ): Определяет диапазон характеристики.
  • Конфигурация характеристики клиента ( 0x2902 ): определяет, как характеристика может быть настроена конкретным клиентом.

Если клиент хочет подписаться на характеристику, чтобы он мог автоматически уведомляться об изменении значения, он должен выполнить операцию записи в дескрипторе «Конфигурация характеристики клиента», чтобы уведомить о своем намерении.

Здесь мы определяем DESCRIPTOR_CONFIG_UUID, чтобы клиенты могли подписаться на значение CHARACTERISTIC_COUNTER_UUID, если они хотят.

AndroidManifest.xml

Сначала мы объявляем разрешения BLUETOOTH и BLUETOOTH_ADMIN. BLUETOOTH_ADMIN требуется для запуска обнаружения или автоматического включения Bluetooth на устройстве.

<использование-разрешения android: name = "android.permission.BLUETOOTH" /> <использование-разрешения android: name = "android.permission.BLUETOOTH_ADMIN" /> <использование-функция android: name = "android.hardware.bluetooth_le" / >

Мы также указываем, что нашему приложению для работы требуется функция bluetooth_le. Если Bluetooth LE является дополнительной функцией вашего приложения, установите для этой функции значение android: required = "false".

Когда программа Android Things запускается, она должна начать рекламу, чтобы другие устройства могли видеть, какие службы BLE она предоставляет, и могут подключаться к ней.

// Адаптер Bluetooth требуется для любой активности Bluetooth. mBluetoothManager = (BluetoothManager) getSystemService (BLUETOOTH_SERVICE); BluetoothAdapter BluetoothAdapter = mBluetoothManager. getAdapter (); // Некоторые настройки рекламы. Мы не устанавливаем время ожидания рекламы //, так как наше устройство всегда подключено к сети переменного тока. Настройки AdvertiseSettings = новые настройки AdvertiseSettings. Строитель (). setAdvertiseMode (AdvertiseSettings. ADVERTISE_MODE_BALANCED). setConnectable (true). setTimeout (0). setTxPowerLevel (AdvertiseSettings. ADVERTISE_TX_POWER_MEDIUM). build (); // Определяет, какой сервис рекламировать. Данные AdvertiseData = новые данные AdvertiseData. Строитель (). setIncludeDeviceName (true). setIncludeTxPowerLevel (false). addServiceUuid (новый ParcelUuid (SERVICE_ID)). build (); // Запускает рекламу. mBluetoothLeAdvertiser = bluetoothAdapter. getBluetoothLeAdvertiser (); mBluetoothLeAdvertiser. startAdvertising (настройки, данные, mAdvertiseCallback);

Реклама энергоемкая. Здесь наше устройство всегда подключено к сети переменного тока, поэтому оно будет постоянно рекламироваться.
Если он работает от батареи, хорошей идеей будет добавить тайм-аут и физическую кнопку для запуска рекламного процесса. Кроме того, вам нужно будет остановить рекламу, как только клиент подключен.

Для метода startAdvertising требуется экземпляр AdvertiseCallback, определенный ниже:

private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback () {@Override public void onStartSuccess (AdvertiseSettings settingsInEffect) {Журнал. я (TAG, «LE Реклама началась».); } @Override public void onStartFailure (int errorCode) {Журнал. w (TAG, "LE Advertise Failed:" + errorCode); }};

Создание сервиса ГАТТ

Мы должны программно определить наш сервис GATT.
Помните, наш сервис должен содержать 2 характеристики:

  • Счетчик (только для чтения, поддерживает подписки через дескриптор конфигурации)
  • Интерактор (только для записи)

private BluetoothGattService createService () {Служба BluetoothGattService = новый BluetoothGattService (SERVICE_UUID, SERVICE_TYPE_PRIMARY); // Характеристика счетчика (только для чтения, поддерживает подписки) BluetoothGattCharacteristic counter = new BluetoothGattCharacteristic (CHARACTERISTIC_COUNTER_UUID, PROPERTY_READ | PROPERTY_NOTIFY, PERMISSION_READ); BluetoothGattDescriptor counterConfig = новый BluetoothGattDescriptor (DESCRIPTOR_CONFIG_UUID, PERMISSION_READ | PERMISSION_WRITE); счетчик addDescriptor (counterConfig); // Характеристика интегратора BluetoothGattCharacteristic interactiveor = new BluetoothGattCharacteristic (CHARACTERISTIC_INTERACTOR_UUID, PROPERTY_WRITE_NO_RESPONSE, PERMISSION_WRITE); оказание услуг . addCharacteristic (counter); оказание услуг . addCharacteristic (интерактор); возвратный сервис; }

Запуск сервера

Затем мы запускаем сервер Bluetooth LE с помощью метода openGattServer.

mGattServer = mBluetoothManager. openGattServer (mContext, mGattServerCallback); mGattServer. addService (createService ());

Этот метод принимает экземпляр BluetoothGattServerCallback, который содержит обратные вызовы для реализации при чтении или записи характеристики / дескриптора.

Возврат значения счетчика

Когда клиент GATT читает CHARACTERISTIC_COUNTER_UUID, мы должны вернуть значение счетчика.
Для этого мы переопределяем метод onCharacteristicReadRequest нашего BluetoothGattServerCallback и возвращаем currentCounterValue, если есть запрос на чтение для характеристики счетчика:

@Override public void onCharacteristicReadRequest (устройство BluetoothDevice, int requestId, int offset, характеристика BluetoothGattCharacteristic) {if (CHARACTERISTIC_COUNTER_UUID. Равно (характеристика. GetUuid ())) {byte [] value = Ints. toByteArray (currentCounterValue); mGattServer. sendResponse (устройство, requestId, GATT_SUCCESS, 0, значение); }}

Увеличение счетчика

Когда клиент GATT пишет в CHARACTERISTIC_INTERACTOR_UUID, мы должны увеличить значение счетчика.
Для этого мы можем переопределить метод onCharacteristicWriteRequest:

@Override public void onCharacteristicWriteRequest (устройство BluetoothDevice, int requestId, BluetoothGattCharacteristic характеристика, логическое значение prepareWrite, логическое значение responseNeeded, int offset, byte [] значение) {if (CHARACTERISTIC_INTERACTOR_UUID. Equals (характеристика. GetUuueC ()); notifyRegisteredDevices (); }}

Обратите внимание на вызов notifyRegisteredDevices ().
Поскольку значение счетчика изменилось, мы должны уведомить устройства. Мы увидим реализацию позже, но сначала давайте обработаем подписку.

Если клиент хочет получать уведомления о любых изменениях в значении характеристики счетчика, он должен записать свое намерение в дескрипторе конфигурации.
Мы переопределяем onDescriptorWriteRequest и сохраняем ссылку на устройство Bluetooth в частном списке с именем mRegisteredDevices:

@Override public void onDescriptorWriteRequest (устройство BluetoothDevice, int requestId, дескриптор BluetoothGattDescriptor, логическое значение prepareWrite, логическое значение responseNeeded, int offset, byte []) {if (DESCRIPTOR_CONFIG_UUID. Equals (descriptor. GetUuals ()) ENABLE_NOTIFICATION_VALUE, значение)) {mRegisteredDevices. добавить устройство ); } else if (Массивы. равно (DISABLE_NOTIFICATION_VALUE, значение)) {mRegisteredDevices. удалить (устройство); } if (responseNeeded) {mGattServer. sendResponse (устройство, requestId, GATT_SUCCESS, 0, ноль); }}}

Теперь мы можем создать наш метод notifyRegisteredDevices, который просто вызывает notifyCharacteristicChanged для каждого подписанного устройства:

private void notifyRegisteredDevices () {BluetoothGattCharacteristic характеристика = mGattServer. getService (SERVICE_UUID). getCharacteristic (CHARACTERISTIC_COUNTER_UUID); для (устройство BluetoothDevice: mRegisteredDevices) {byte [] value = Ints. toByteArray (currentCounterValue); контрхарактеристика. setValue (значение); mGattServer. notifyCharacteristicChanged (устройство, характеристика, ложь); }}

Тестирование сервера GATT

Мы закончили написание нашего сервера GATT.
Прежде чем мы начнем создавать клиента, мы сначала проверим сервер, чтобы убедиться, что мы правильно реализовали все функции.

Для тестирования устройств Bluetooth LE вы можете использовать nRF Connect для мобильных устройств приложение.
Это приложение позволяет сканировать устройства с низким энергопотреблением Bluetooth и позволяет читать, писать, подписываться на характеристики.

После запуска приложения мы видим, что RPI3 является рекламой. Как только мы подключимся к нему, мы сможем увидеть наш пользовательский сервис (UUID = 7950…)

Используя это приложение, мы можем просмотреть все характеристики данного сервиса.
Мы можем нажать на кнопку чтения (синего цвета), чтобы прочитать значение характеристики счетчика ( здесь значение равно 0x2A [42] ).
Мы также можем получать уведомления при изменении характеристики счетчика, записывать в характеристику интерактора и видеть, что значение автоматически увеличивается.


Создание клиента

Мы протестировали наше приложение Android Things, и оно работает хорошо.
Теперь нам нужно создать мобильный клиент, который сможет подключаться к рекламному устройству и читать / писать по характеристикам.

Сканирование устройств BLE

Когда клиентское приложение Android запускается, первое, что он должен сделать, - это сканировать доступные устройства Bluetooth LE.

Сканирование устройств BLE может быть довольно сложным, поскольку первоначальный API (SDK 18) изменился в SDK 21, а также был расширен в SDK 23 ( источник: Что следует иметь в виду при разработке приложения BLE для Android ).
Для упрощения мы будем использовать унифицированную стороннюю библиотеку сравнения: Совместимая библиотека Android BLE Scanner

BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat. getScanner (); // Мы хотим получать список найденных устройств каждую секунду. Настройки ScanSettings = новые ScanSettings. Строитель (). setScanMode (ScanSettings. SCAN_MODE_LOW_LATENCY). setReportDelay (1000). build (); // Мы только хотим сканировать устройства, рекламирующие наш пользовательский сервис ScanFilter scanFilter = new ScanFilter. Строитель (). setServiceUuid (новый ParcelUuid (SERVICE_UUID)). build (); сканер startScan (Arrays. asList (scanFilter), настройки, mScanCallback);

Опять же, сканирование требует много энергии. Мы должны создать обработчик, который останавливает сканирование через несколько секунд ( например, 10 секунд ) и прекращает сканирование, как только мы находим нужное устройство.

Метод startScan использует ScanCallback, реализованный ниже:

private final ScanCallback mScanCallback = new ScanCallback () {@Override public void onScanResult (int callbackType, ScanResult result) {// Мы сканируем с задержкой отчета> 0. Это никогда не будет вызвано. } @Override public void onBatchScanResults (список <ScanResult> results) {if (! Results. IsEmpty ()) {ScanResult result = results. получить (0); Устройство BluetoothDevice = результат. getDevice (); Строка deviceAddress = устройство. getAddress (); // Устройство обнаружено, мы можем автоматически подключиться к нему и остановить сканирование}} @Override public void onScanFailed (int errorCode) {// Ошибка сканирования}};

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

Подключение к серверу ГАТТ

Чтобы подключиться к серверу GATT, используйте адрес устройства, чтобы получить экземпляр BluetoothDevice, а затем вызовите метод connectGatt:

Устройство BluetoothDevice = mBluetoothAdapter. getRemoteDevice (deviceAddress); mGatt = устройство. connectGatt (mContext, false, mGattCallback);

Этот метод принимает BluetoothGattCallback, очень похожий на BluetoothGattServerCallback, который мы видели ранее, содержащий методы обратного вызова, когда характеристика / дескриптор была прочитана / записана.

- ПРЕДУПРЕЖДЕНИЕ - Callback Hell Incoming - ВНИМАНИЕ -
Будь готов! Вы увидите последовательность обратных вызовов. С каждой операцией связан обратный вызов. Мы не можем одновременно выполнять две операции Bluetooth, например, две операции записи. Нам придется подождать, пока один из них закончится, прежде чем мы сможем начать следующий.

Обнаружение услуг

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

@Override public void onConnectionStateChange (BluetoothGatt gatt, int status, int newState) {if (newState == BluetoothProfile. STATE_CONNECTED) {Журнал. i (TAG, «Подключено к клиенту GATT. Попытка запустить обнаружение службы»); Гатт DiscoverServices (); } else if (newState == BluetoothProfile. STATE_DISCONNECTED) {Журнал. i (TAG, «Отключено от клиента GATT»); }}

Затем метод DiscoverServices вызовет метод onServicesDiscovered, который необходимо переопределить.
Наш клиент хочет получать уведомления о каждом изменении CHARACTERISTIC_COUNTER_UUID, поэтому это подходящее место для начала записи в дескриптор:

@Override public void onServicesDiscovered (BluetoothGatt gatt, int status) {if (status! = BluetoothGatt. GATT_SUCCESS) {// Обработать возврат ошибки; } // Получить характеристику счетчика BluetoothGattCharacteristic характеристика = гатт. getService (SERVICE_UUID). getCharacteristic (CHARACTERISTIC_COUNTER_UUID); // Включаем уведомления для этой характеристики локально. setCharacteristicNotification (характеристика, правда); // Пишем в дескрипторе конфигурации, чтобы получать уведомления при изменении значения BluetoothGattDescriptor descriptor = характеристика. getDescriptor (DESCRIPTOR_CONFIG_UUID); дескриптор setValue (BluetoothGattDescriptor. ENABLE_NOTIFICATION_VALUE); Гатт writeDescriptor (дескриптор); }

Чтение значения счетчика

Теперь мы хотим прочитать значение счетчика. Мы не можем сделать это в методе onServicesDiscovered, поскольку в дескрипторе уже есть ожидающая операция записи.
Итак, мы переопределим onDescriptorWrite и начнем читать нашу характеристику здесь, после того, как дескриптор был написан:

@Override public void onDescriptorWrite (BluetoothGatt gatt, дескриптор BluetoothGattDescriptor, int status) {if (DESCRIPTOR_CONFIG_UUID. Equals (descriptor. GetUuid ())) {BluetoothGattCharacteristic характеристика = гатт. getService (SERVICE_UUID). getCharacteristic (CHARACTERISTIC_COUNTER_UUID); Гатт readCharacteristic (характеристика); }}

Обновление пользовательского интерфейса при получении значения счетчика

Когда характеристика прочитана, будет вызван метод onCharacteristicRead.
Здесь мы можем получить характеристическое значение и обновить интерфейс:

@Override public void onCharacteristicRead (BluetoothGatt gatt, BluetoothGattCharacteristic характеристика, статус int) {readCounterCharacteristic (характеристика); } private void readCounterCharacteristic (характеристика BluetoothGattCharacteristic) {если (CHARACTERISTIC_COUNTER_UUID. равно (характеристика. getUuid ())) {байт [] данные = характеристика. getValue (); int value = Ints. fromByteArray (data); // Обновить пользовательский интерфейс}}

Получать уведомления при изменении значения

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

@Override public void onCharacteristicChanged (BluetoothGatt gatt, BluetoothGattCharacteristic характеристика) {readCounterCharacteristic (характеристика); }

И ... мы сделали!
Ну, не совсем ... Мы закончили с BLE-частью, но все еще нет ни физического счетчика, ни счастливчика.

Добавляем немного веселья (то есть создание физического объекта)

В тот момент, если я скажу вам, что мы написали все эти вещи только для того, чтобы иметь переменную, которая автоматически увеличивается, когда клиент отправляет запрос на запись, вы, вероятно, скажете что-то вроде «Все это даром!?!» .
Благодаря Android Things мы добавим немного веселья и создадим физический объект вокруг этой программы.

Физическое счетчик

Дисплей, используемый здесь, будет «MAX7219 8-значный модуль».

Как следует из названия, он использует MAX7219 для управления отображением сегмента.
В предыдущем посте ( Использование внешних дисплеев ), мы уже упоминали о MAX7219 для управления светодиодной матрицей 8x8. Хорошо, что вы можете использовать тот же драйвер ( Библиотека светодиодного управления ) взаимодействовать с этим устройством через SPI.

Пример: запись «0042»:

LedControl ledControl = new LedControl (SPI_NAME); ledControl. setDigit (3, 0, false); ledControl. setDigit (2, 0, false); ledControl. setDigit (1, 4, false); ledControl. setDigit (0, 2, false);

Мы будем использовать Lucky Cat.
Чтобы переместить кошачью лапу, нам просто нужно прикрепить лапу к серводвигателю ( здесь, используя резинку ).

Чтобы переместить кошачью лапу, нам просто нужно прикрепить лапу к серводвигателю ( здесь, используя резинку )

И затем мы перемещаем сервопривод при изменении значения счетчика:

Серво серво = новый серво (PWM_NAME); серво setPulseDurationRange (1, 2); серво setAngleRange (- 90, 90); серво setEnabled (true); серво setAngle (servo. getMaximumAngle ()); Нить . сон (1000); серво setAngle (servo. getMinimumAngle ());

Приложение Android Wear

Первоначально это не планировалось, но, поскольку он использует точно такие же API, мне понадобилось всего 10 минут, чтобы перенести ( я имею в виду, скопировать / вставить ) клиент Android (телефон) в приложение Android Wear.

Заключение

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

Чтобы упростить статью, я не рассматривал крайние случаи ( такие как проверка возвращаемых значений, включение Bluetooth, если он еще не включен и т. Д. ) Здесь.
Вы можете найти полную реализацию на github.com/Nilhcem/blefun-androidthings ,

com/Nilhcem/blefun-androidthings   ,

О школе
О школе

О школе

Школа была открыта в 1959г. Первые выпускники были выпущены в 1966 г. Учредителем является МНО РТ, Горисполком. Координаты школы: Республика Татарстан, 420012, г. Казань, ул. Муштари д.6.
История

История

Школа № 18 была создана в 1959 году, как первая школа в республике Татарстан с углублённым изучением английского языка. Реформирование школьного образования проводится в школе по
Похожие новости /   Комментарии

    Обновления сайта

    Здравствуйте. Сегодня наконец то мы обновили наш сайт. Теперь на сайте доступны библиотеки для чтения, Вы всегда можете задать вопрос администратору сайта. Получить консультацию на все интересующие вопросы. Ознакомится с новыми событиями и новостями. В дальнейшем сайт будет наполнятся свежими новостями и статьями.

    О школе

    Школа была открыта в 1959г. Первые выпускники были выпущены в 1966 г. Учредителем является МНО РТ, Горисполком. Координаты школы: Республика Татарстан, 420012, г. Казань, ул. Муштари д.6. Полное название- Средняя школа №18 с углублённым изучением английского языка Директор: Шевелёва Надия Магсутовна. Научный руководитель: Русинова Сазида Исмагиловна,

    История

    Школа № 18 была создана в 1959 году, как первая школа в республике Татарстан с углублённым изучением английского языка. Реформирование школьного образования проводится в школе по эволюционному пути, избегая резких преобразований, опасных в этой системе человеческой деятельности. С этой целью 7 лет школа работала в условиях экспериментальной площадки, где