02 Урок. Знакомство с датчиками
Датчик угловой скорости
Датчик угловых скоростей предназначен для измерения угловой скорости вращающегося объекта. Измерять угловую скорость необходимо для того, чтобы можно было остановить вращение спутника – стабилизировать его. Также с помощью датчика угловой скорости можно заставить спутник вращаться с определенной скоростью.
Принцип работы датчика угловой скорости
Основным измерительным элементом датчика угловой скорости является специальный микроэлектромеханический (МЭМС) гироскоп. Это не обычный гироскоп, в котором с большой скоростью вращается диск, а миниатюрный вибрационный гироскоп. Внутри МЭМС гироскопа есть кольцо, которое, колеблется в одной плоскости. Если такой гироскоп поставить на вращающуюся платформу, плоскость которой совпадает с плоскостью колебаний кольца, то на нее начнет действовать сила Кориолиса пропорциональная скорости вращения платформы. Сила Кориолиса измеряется с использованием пьезоэлементов, которые выдают напряжение, пропорциональное приложенной силе.

Рисунок 1. Устройство датчика угловой скорости
Определив силу Кориолиса и зная скорость колебания, можно вычислить угловую скорость и ее изменение (угловое ускорение).

Рисунок 2. Микросхема чувствительного элемента
Проверка работоспособности датчика угловой скорости
Подключите датчик угловой скорости и СЭП к БКУ. Откройте Notepad++ и напишите программу на Python или на С.
Код на Python:
def control(): # Основная функция программы, в которой вызываем остальные функции
hyro_result = [0,0,0,0] # Инициализируем hyro_result
num = 1 # Номер Датчика угловой скорости
print "Enable angular velocity sensor №", num
hyro_turn_on(num) # Включаем ДУС
sleep(1) # Ждем включения 1 секунду
print "Get RAW data from angular velocity sensor"
for i in range(10): #Считываем показания 10 раз
hyro_result = hyro_request_raw(num) #записываем ответ функции
# hyro_request_raw в переменную hyro_result
if not hyro_result[0]: # если датчик не вернул сообщение об ошибке,
print "state:", hyro_result[0], "x_raw =", hyro_result[1], \
"y_raw =", hyro_result[2], "z_raw =", hyro_result[3]
# Выводим данные
elif hyro_result[0] == 1: # если датчик вернул сообщение об ошибке 1
print "Fail because of access error, check the connection"
elif hyro_result[0] == 2: # если датчик вернул сообщение об ошибке 2
print "Fail because of interface error, check your code"
sleep(1) # Показания считываются раз в секунду
print "Disable angular velocity sensor №", num
hyro_turn_off(num) # Выключаем ДУС
Код на С:
#include "libschsat.h"
int control(){
uint16_t num = 1; // Номер Датчика угловой скорости
int16_t hyro_result[] = {0, 0, 0, 0};
printf("Enable (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) angular velocity sensor № %d", num);
hyro_turn_on(num); // Включаем ДУС
Sleep (1); //Ждем включения 1 секунду
printf("\nGet (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) RAW data from angular velocity sensor\n");
int i;
for (i = 0; i < 10; i++) { //Считываем показания 10 раз
hyro_result[0] = hyro_request_raw(num,& hyro_result[1],& hyro_result[2],& hyro_result[3]);
if (!hyro_result[0])
{
printf("state: (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) %d", i);
printf(" (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) x_raw = %d", hyro_result[1]);
printf(" (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) y_raw = %d", hyro_result[2]);
printf(" z_raw = %d\n", hyro_result[3]);
}
else if (hyro_result[0] == 1)
{
printf("Fail (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) because of access error, check the connection");
}
else if (hyro_result[0] == 2)
{
printf("Fail (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) because of interface error, check your code");
}
Sleep(1);
}
printf("\nDisable (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) angular velocity sensor № %d\n", num);
hyro_turn_off(num);
return 0;
}
Запустите программу и протестируйте работу ДУС.
Анализ кода
Обратите внимание, после символа # пишут комментарии, которые никак не влияют на работу программы.
Программа начинается с объявления функции control().
Затем мы создаем список hyro_result для получения данных от датчика и переменную num, хранящую номер датчика.
Далее оператор print выводит сообщение о включении датчика.
Затем функция hyro_turn_on(num) включает датчик с указанным номером.
Функция sleep(1) приостанавливает выполнение программы на 1 секунду. Затем в цикле for i in range(10): мы 10 раз считываем и выводим значение датчика.
Показания датчика считываем с помощью функции hyro_request_raw(num).
Магнитометр
Назначение магнитометра
Информацию об ориентации спутник получает по датчику угловой скорости и магнитометру. Информация об угле нужна для того чтобы разворачивать спутник в необходимую сторону, а информация об угловой скорости необходима для того чтобы стабилизировать спутник, т.е. погасить угловое вращение. Управляющий момент создается с помощью двигателя маховика.
Принцип работы магнитометра
Работа магнитометра основана на применении магниторезистивного эффекта, когда электрическое сопротивление проводника изменяется в соответствии с направлением линий магнитного поля. В основе датчика лежит слой пермаллоя (специального сплава никеля с железом), который обладает сильным магниторезистивным эффектом. Электрическое сопротивление пермаллоя меняется обычно в пределе ±5 % в зависимости от силы и направления действующего магнитного поля.

Рисунок 3. Устройство магнитометра
Таким образом, измеряя силу тока, протекающего через слой пермаллоя при подаче постоянного напряжения +5В можно определить направление линий магнитного поля. Для того чтобы измерить направление магнитных линий по всем трем осям используют три маленьких датчика, ориентированных по осям X, Y и Z, установленные в одной микросхеме.

Рисунок 4. Направление линий магнитного поля

Рисунок 5. Датчик
Проверка работоспособности магнитометра
Откройте Notepad++ и напишите программу на Python или на С.
Код на Python:
def control(): # Основная функция программы, в которой вызываем остальные функции
mgn_result = [0,0,0,0] # Инициализируем mgn_result
num = 1 # номер магнитометра
print "Enable magnetometer №", num
magnetometer_turn_on(num)
sleep(1)
print "Get RAW data from magnetometer"
for i in range(10):
mgn_result = magnetometer_request_raw(num)
if not mgn_result[0]: # если датчик вернул сообщение об ошибке,
print "state:", mgn_result[0], "x_raw =", mgn_result[1], \
"y_raw =", mgn_result[2], "z_raw =", mgn_result[3]
# Обратите внимание на символ переноса строки!
elif mgn_result[0] == 1:
print "Fail because of access error, check the connection"
elif mgn_result[0] == 2:
print "Fail because of interface error, check your code"
sleep(1)
print "Disable magnetometer №", num
magnetometer_turn_off(num)
Код на С:
#define LSS_OK 0
#define LSS_ERROR 1
#define LSS_BREAK 2
#include <stdio.h>
#include <stdint.h>
#include "libschsat.h"
int control() // Основная функция программы, в которой вызываем остальные функции
{
int16_t mgn_result[] = {0,0,0,0}; // Инициализируем mgn_result
uint16_t num = 1; // номер магнитометра
int i;
printf("Rnable (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) magnetometer №%d\n", num);
magnetometer_turn_on(num);
Sleep(1);
printf("Get (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) RAW data from magnetometer\n");
for (i = 0; i < 1000; i++)
{
mgn_result[0] = magnetometer_request_raw(num,& mgn_result[1],& mgn_result[2],& mgn_result[3]);
if (!mgn_result[0])// если датчик вернул сообщение об ошибке,
{
printf("\nstate:%d, (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) \nx_raw =%d,\ny_raw =%d, \nz_raw =%d\n",i, mgn_result[1], mgn_result[2], mgn_result[3]); //Обратите внимание на символ переноса строки!
}
else if (mgn_result[0] == 1){
printf("Fail (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) because of access error, check the connection");
}
else if (mgn_result[0] == 2){
printf("Fail (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) because of interdace error, check your code");
}
Sleep(0.1);
}
printf("Disable (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) magnetometer №%d\n", num);
magnetometer_turn_off(num);
return 0;
}
Запустите программу и протестируйте работу магнитометра.
Анализ кода
Программа начинается с объявления функции control().
Затем мы создаем список mgn_result для получения данных от датчика и переменную num, хранящую номер магнитометра.
Далее оператор print выводит сообщение о включении датчика.
Затем функция magnetometer_turn_on(num) включает магнитометр с указанным номером.
Функция sleep(1) приостанавливает выполнение программы на 1 секунду. Затем в цикле for i in range(10): мы 10 раз считываем и выводим значение магнитометра.
Показания магнитометра считываем с помощью функции magnetometer_request_raw(num).
Солнечные датчики
Назначение солнечных датчиков
Назначение солнечных датчиков – определение расположения спутника относительно Солнца. Так-как положение Солнца относительно Земли в любой момент времени известно достаточно точно, следовательно, можно определить и расположение спутника относительно Земли.
Принцип работы солнечных датчиков
В основе солнечного датчика лежит фотодетектор, который измеряет яркость света. Самые популярные фотодетекторы — это фоторезисторы и фотодиоды.
Фоторезистор состоит из материала, сопротивление которого меняется в зависимости от интенсивности падающего света.
В отличие от фоторезистора фотодиод выдает напряжение под действием света. Фотодиодные датчики бывают нескольких типов — LEP (Latheral Effect Photodiode), QD-фотодиод (Quadrant Detector) или матричные.

Рисунок 6. Фотодиодные датчики
LEP фотодиод – это одиночный фотодиод с большой чувствительной поверхностью.

Рисунок 7. LEP фотодиод
QD-фотодиод состоит из четырех независимых фотодиодов, расположенных симметрично относительно центра чувствительной поверхности.

Рисунок 8. QD-фотодиод

Рисунок 9. Расчет положения пятна на поверхности QD-фотодиода
Расчет положения пятна на поверхности QD-фотодиода получается из соотношений выходных токов фотодиодов.
Матричный датчик содержит большое количество фотодиодов и позволяет определить положение Солнца еще точнее.

Рисунок 10. Матричный датчик
Проверка работоспособности солнечных датчиков
Подключите по очереди солнечные датчики и СЭП к БКУ и проверьте их работу. Откройте Notepad++ и напишите программу на Python или на С.
Код на Python:
def control(): # Основная функция программы, в которой нужно вызывать остальные функции
sun_result = [0,0,0] # Инициализируем sun_result
num = 1
print "Enable sun sensor №", num
sun_sensor_turn_on(num)
sleep(1)
print "Get RAW data from sun sensor"
for i in range(10):
sun_result = sun_sensor_request_raw(num)
if not sun_result[0]: # если датчик вернул сообщение об ошибке,
print "state:", sun_result[0], "raw =", sun_result[1], \
sun_result[2]
elif sun_result[0] == 1:
print "Fail because of access error, check the connection"
elif sun_result[0] == 2:
print "Fail because of interface error, check your code"
sleep(1)
print "Disable sun sensor №", num
sun_sensor_turn_off(num)
Код на С:
#include <stdio.h>
#include <stdint.h>
#include "libschsat.h"
#define LSS_OK 0
#define LSS_ERROR 1
#define LSS_BREAK 2
int control(){ //Основная функция программы
uint16_t sun_result[] = {0, 0, 0}; // инициализируем sun_result
uint16_t num = 1; // номер солнечного датчика
printf("Enable (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) sun sensor №%d\n", num);
sun_sensor_turn_on(num); //включаем датчик
Sleep(1); //Ждем включения 1 секунду
printf("Get (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) RAW data from sun sensor №%d\n", num);
int i;
for (i = 0; i < 10; i++) //считываем показаия 10 раз
{
sun_result[0] = sun_sensor_request_raw(num,& sun_result[1],& sun_result[2]);/*проверить как работает, очень странно, что работает
если не работает задать sun_result[0] */
if (!sun_result[0]){ //если датчик не вернул сообщение об ошибке,
printf("state: (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) %d raw = %d, %d\n", i, sun_result[1], sun_result[2]);
}
else if (sun_result[0] == 1) { //если датчик вернул сообщение об ошибке 1
printf("Fail because of access error, check the connection\n");
}
else if (sun_result[0] == 2) { //если датчик вернул сообщение об ошибке 2
printf("Fail (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) because of interface error, check you code\n");
}
Sleep(1); //показания считываются раз в секунду
}
printf("Disable (http://www.opengroup.org/onlinepubs/009695399/functions/printf.html) sun sensor №%d\n", num);
sun_sensor_turn_off(num); //выключаем солнечный датчик
return 0;
}
Запустите программу и протестируйте работу солнечного датчика. Поочередно протестируйте все 4 солнечных датчика.
Анализ кода
Программа начинается с объявления функции control().
Затем мы создаем список sun_result для получения данных от датчика и переменную num, хранящую номер датчика.
Далее оператор print выводит сообщение о включении датчика.
Затем функция sun_sensor_turn_on(num) включает датчик с указанным номером.
Функция sleep(1) приостанавливает выполнение программы на 1 секунду.
Затем в цикле for i in range(10): мы 10 раз считываем и выводим значение датчика.
Показания датчика считываем с помощью функции sun_sensor_request_raw(num).