Загрузка данных


#include <Wire.h>

// --- I2C Адреса устройств ---
const uint8_t ACCEL_ADDR = 0x68;  // Адрес MPU6050
const uint8_t LIGHT_ADDR = 0x50;  // Адрес планки S01.0 (IntroSat)

// --- Пины управления маховиком ---
const int MOTOR_PWM_PIN = PA1;    // ШИМ скорость (0-255)
const int MOTOR_DIR_PIN = PA2;    // Направление вращения

// --- Пороги срабатывания ---
const float ACCEL_THRESHOLD = 1.5;   // Порог ускорения в g (покой ~1.0g)
const uint16_t LIGHT_THRESHOLD = 5000; // Порог света (настройте под свои значения)

void setup() {
  // Настройка порта отладки (Serial1 для UART PA9/PA10 или Serial для USB CDC)
  Serial1.begin(115200);
  Wire.begin();

  // Настройка пинов маховика
  pinMode(MOTOR_PWM_PIN, OUTPUT);
  pinMode(MOTOR_DIR_PIN, OUTPUT);

  // Пробуждаем акселерометр
  Wire.beginTransmission(ACCEL_ADDR);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial1.println("Система CubeSat запущенa. Опрос датчиков 0x68 и 0x50...");
}

void loop() {
  // ==================== 1. ЧТЕНИЕ АКСЕЛЕРОМЕТРА (0x68) ====================
  int16_t rawX, rawY, rawZ;
  Wire.beginTransmission(ACCEL_ADDR);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom((uint8_t)ACCEL_ADDR, (uint8_t)6, (uint8_t)true);

  rawX = (Wire.read() << 8) | Wire.read();
  rawY = (Wire.read() << 8) | Wire.read();
  rawZ = (Wire.read() << 8) | Wire.read();

  float ax = rawX / 16384.0;
  float ay = rawY / 16384.0;
  float az = rawZ / 16384.0;

  // Модуль суммарного ускорения: A = sqrt(ax^2 + ay^2 + az^2)
  float totalAccel = sqrt(ax * ax + ay * ay + az * az);

  // ==================== 2. ЧТЕНИЕ ОСВЕЩЕННОСТИ (0x50) ====================
  uint16_t lightValue = 0;
  
  Wire.beginTransmission(LIGHT_ADDR);
  Wire.write(0x00); // Указываем регистра данных
  Wire.endTransmission(false);
  Wire.requestFrom((uint8_t)LIGHT_ADDR, (uint8_t)2, (uint8_t)true);

  if (Wire.available() >= 2) {
    uint8_t highByte = Wire.read();
    uint8_t lowByte = Wire.read();
    lightValue = (highByte << 8) | lowByte;
  }

  // ==================== ВЫВОД ДАННЫХ В КОНСОЛЬ ====================
  Serial1.print("Ускорение: "); Serial1.print(totalAccel, 2); Serial1.print(" g | ");
  Serial1.print("Свет (0x50): "); Serial1.print(lightValue);

  // ==================== 3. ЛОГИКА УПРАВЛЕНИЯ МАХОВИКОМ ====================
  if (totalAccel > ACCEL_THRESHOLD) {
    // Включение при превышении ускорения (стабилизация)
    digitalWrite(MOTOR_DIR_PIN, HIGH);
    analogWrite(MOTOR_PWM_PIN, 220);
    Serial1.println(" -> [МАХОВИК] Включен: Стабилизация");
  } 
  else if (lightValue < LIGHT_THRESHOLD) {
    // Включение при низкой освещенности (поворот к солнцу)
    digitalWrite(MOTOR_DIR_PIN, LOW);
    analogWrite(MOTOR_PWM_PIN, 120);
    Serial1.println(" -> [МАХОВИК] Включен: Поиск света");
  } 
  else {
    // Отключение маховика
    analogWrite(MOTOR_PWM_PIN, 0);
    Serial1.println(" -> [МАХОВИК] Выключен");
  }

  delay(200);
}
#include <Wire.h>

// --- I2C Адреса устройств ---
const uint8_t ACCEL_ADDR    = 0x68; // Адрес акселерометра MPU6050
const uint8_t FLYWHEEL_ADDR = 0x60; // Адрес Flywheel Module (уточните по I2C сканеру)

// Адреса 4 планок освещенности S01.0 (задаются DIP-переключателями SW1: 0x50, 0x51, 0x52, 0x53)
const uint8_t LIGHT_ADDRS[4] = {0x50, 0x51, 0x52, 0x53};

// --- Пороги срабатывания ---
const float ACCEL_THRESHOLD    = 1.5;   // Порог ускорения в g
const uint16_t LIGHT_THRESHOLD = 3000;  // Порог освещенности для ориентации

// Чтение данных с планки S01.0
uint16_t readLightSensor(uint8_t addr) {
  uint16_t value = 0;
  Wire.beginTransmission(addr);
  Wire.write(0x00);
  if (Wire.endTransmission(false) == 0) {
    Wire.requestFrom((uint8_t)addr, (uint8_t)2, (uint8_t)true);
    if (Wire.available() >= 2) {
      value = (Wire.read() << 8) | Wire.read();
    }
  }
  return value;
}

// Передача заданной скорости на модуль маховика по I2C
void setFlywheelSpeed(int8_t speed) {
  Wire.beginTransmission(FLYWHEEL_ADDR);
  Wire.write(speed); // Передача значения скорости (-100...100 или 0...255)
  Wire.endTransmission();
}

void setup() {
  // Настройка порта отладки (Serial1 для UART PA9/PA10 или Serial для USB CDC)
  Serial1.begin(115200);
  Wire.begin(); // Инициализация I2C1 (PB6 - SCL, PB7 - SDA)

  // Инициализация / Пробуждение MPU6050
  Wire.beginTransmission(ACCEL_ADDR);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial1.println("Система CubeSat запущенa: 4 датчика света + акселерометр + маховик.");
}

void loop() {
  // ==================== 1. ЧТЕНИЕ АКСЕЛЕРОМЕТРА ====================
  int16_t rawX, rawY, rawZ;
  Wire.beginTransmission(ACCEL_ADDR);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom((uint8_t)ACCEL_ADDR, (uint8_t)6, (uint8_t)true);

  rawX = (Wire.read() << 8) | Wire.read();
  rawY = (Wire.read() << 8) | Wire.read();
  rawZ = (Wire.read() << 8) | Wire.read();

  float ax = rawX / 16384.0;
  float ay = rawY / 16384.0;
  float az = rawZ / 16384.0;
  float totalAccel = sqrt(ax * ax + ay * ay + az * az);

  // ==================== 2. ЧТЕНИЕ 4 ДАТЧИКОВ ОСВЕЩЕННОСТИ ====================
  uint16_t lightValues[4];
  uint16_t maxLight = 0;
  uint8_t brightestFace = 0;

  for (int i = 0; i < 4; i++) {
    lightValues[i] = readLightSensor(LIGHT_ADDRS[i]);
    if (lightValues[i] > maxLight) {
      maxLight = lightValues[i];
      brightestFace = i; // Определение грани с максимальной освещенностью
    }
  }

  // Вывод данных в Монитор порта
  Serial1.print("Ускорение: "); Serial1.print(totalAccel, 2); Serial1.print(" g | ");
  Serial1.print("Свет [0..3]: ");
  for (int i = 0; i < 4; i++) {
    Serial1.print(lightValues[i]);
    if (i < 3) Serial1.print(", ");
  }

  // ==================== 3. ЛОГИКА УПРАВЛЕНИЯ МАХОВИКОМ ====================
  if (totalAccel > ACCEL_THRESHOLD) {
    // Включение маховика для гашения вращения при резком ускорении
    setFlywheelSpeed(80);
    Serial1.println(" -> [МАХОВИК] Стабилизация");
  } 
  else if (maxLight < LIGHT_THRESHOLD) {
    // Вращение для поиска источника света, если все грани в тени
    setFlywheelSpeed(40);
    Serial1.println(" -> [МАХОВИК] Поиск света");
  } 
  else {
    // Остановка маховика при нормальном положении
    setFlywheelSpeed(0);
    Serial1.print(" -> [МАХОВИК] Выкл (Солнце на грани ");
    Serial1.print(brightestFace);
    Serial1.println(")");
  }

  delay(200);
}