Добавить firmware/dac1

This commit is contained in:
elios 2025-11-06 15:04:09 +00:00
parent c56b00adc9
commit 85d49411bf

520
firmware/dac1 Normal file
View file

@ -0,0 +1,520 @@
// ============================================================
// ИНТЕРАКТИВНЫЙ ТЕСТОВЫЙ СКЕТЧ ДЛЯ XL4015 + ESP32 DAC
// ============================================================
// Управление через Serial Monitor (115200 baud)
// ============================================================
#define DAC_PIN 25 // GPIO25 = DAC1
// Текущие значения
uint8_t current_dac = 0;
float current_voltage = 0.0;
// Калибровочные значения (будут обновляться)
uint8_t cal_1s = 246; // Для 4.2V
uint8_t cal_2s = 195; // Для 8.4V
uint8_t cal_3s = 145; // Для 12.6V
uint8_t cal_4s = 0; // Для 16.8V
// Настройка времени калибровки (в секундах)
int calibration_delay = 10; // По умолчанию 10 секунд
void setup() {
Serial.begin(115200);
delay(1000);
// Устанавливаем начальное значение DAC
dacWrite(DAC_PIN, 0);
current_dac = 0;
printWelcome();
printMenu();
}
void loop() {
// Проверяем, есть ли данные в Serial
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim(); // Убираем пробелы
processCommand(command);
}
}
// ============================================================
// ОБРАБОТКА КОМАНД
// ============================================================
void processCommand(String cmd) {
cmd.toLowerCase(); // Приводим к нижнему регистру
Serial.println();
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.print("📨 Команда: ");
Serial.println(cmd);
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
// ========== ПРЯМОЕ УПРАВЛЕНИЕ DAC ==========
if (cmd.startsWith("d") || cmd.startsWith("dac")) {
// Команды: d100, dac100, d 100, dac 100
int value = extractNumber(cmd);
if (value >= 0 && value <= 255) {
setDAC(value);
} else {
Serial.println("❌ Ошибка: значение должно быть 0-255");
Serial.println(" Пример: d100 или dac150");
}
}
// ========== УПРАВЛЕНИЕ ПО БАНКАМ ==========
else if (cmd == "1s") {
setVoltageForCells(1);
}
else if (cmd == "2s") {
setVoltageForCells(2);
}
else if (cmd == "3s") {
setVoltageForCells(3);
}
else if (cmd == "4s") {
setVoltageForCells(4);
}
// ========== КАЛИБРОВКА ==========
else if (cmd == "cal" || cmd == "calibrate") {
runCalibration();
}
else if (cmd == "quickcal") {
runQuickCalibration();
}
// ========== НАСТРОЙКА ВРЕМЕНИ КАЛИБРОВКИ ==========
else if (cmd.startsWith("delay")) {
int value = extractNumber(cmd);
if (value >= 1 && value <= 30) {
calibration_delay = value;
Serial.print("✅ Задержка калибровки установлена: ");
Serial.print(value);
Serial.println(" секунд");
} else {
Serial.println("❌ Ошибка: значение должно быть 1-30 секунд");
Serial.println(" Пример: delay5 или delay10");
}
}
// ========== СОХРАНЕНИЕ КАЛИБРОВКИ ==========
else if (cmd.startsWith("save1s")) {
int value = extractNumber(cmd);
if (value >= 0 && value <= 255) {
cal_1s = value;
Serial.print("✅ Сохранено: 1S = DAC ");
Serial.println(value);
}
}
else if (cmd.startsWith("save2s")) {
int value = extractNumber(cmd);
if (value >= 0 && value <= 255) {
cal_2s = value;
Serial.print("✅ Сохранено: 2S = DAC ");
Serial.println(value);
}
}
else if (cmd.startsWith("save3s")) {
int value = extractNumber(cmd);
if (value >= 0 && value <= 255) {
cal_3s = value;
Serial.print("✅ Сохранено: 3S = DAC ");
Serial.println(value);
}
}
else if (cmd.startsWith("save4s")) {
int value = extractNumber(cmd);
if (value >= 0 && value <= 255) {
cal_4s = value;
Serial.print("✅ Сохранено: 4S = DAC ");
Serial.println(value);
}
}
// ========== ИНФОРМАЦИЯ ==========
else if (cmd == "info" || cmd == "status") {
printStatus();
}
else if (cmd == "cal_values" || cmd == "cv") {
printCalibrationValues();
}
// ========== БЫСТРЫЕ КОМАНДЫ ==========
else if (cmd == "min") {
setDAC(255);
Serial.println("⬇️ Установлено минимальное напряжение (DAC=255)");
}
else if (cmd == "max") {
setDAC(0);
Serial.println("⬆️ Установлено максимальное напряжение (DAC=0)");
}
else if (cmd == "mid") {
setDAC(128);
Serial.println("➡️ Установлено среднее значение (DAC=128)");
}
// ========== ПОШАГОВОЕ ИЗМЕНЕНИЕ ==========
else if (cmd == "+" || cmd == "up") {
if (current_dac < 255) {
setDAC(current_dac + 1);
Serial.println("⬆️ DAC +1");
}
}
else if (cmd == "-" || cmd == "down") {
if (current_dac > 0) {
setDAC(current_dac - 1);
Serial.println("⬇️ DAC -1");
}
}
else if (cmd == "++" || cmd == "up10") {
if (current_dac <= 245) {
setDAC(current_dac + 10);
Serial.println("⬆️ DAC +10");
}
}
else if (cmd == "--" || cmd == "down10") {
if (current_dac >= 10) {
setDAC(current_dac - 10);
Serial.println("⬇️ DAC -10");
}
}
// ========== ПОМОЩЬ ==========
else if (cmd == "help" || cmd == "?" || cmd == "menu") {
printMenu();
}
// ========== НЕИЗВЕСТНАЯ КОМАНДА ==========
else {
Serial.println("❌ Неизвестная команда!");
Serial.println(" Введи 'help' для списка команд");
}
Serial.println();
}
// ============================================================
// ФУНКЦИИ УПРАВЛЕНИЯ
// ============================================================
void setDAC(uint8_t value) {
dacWrite(DAC_PIN, value);
current_dac = value;
Serial.println();
Serial.println("╔═══════════════════════════════════╗");
Serial.print ("║ DAC установлен: ");
Serial.print(value);
Serial.print(" (");
Serial.print((value * 100.0) / 255.0, 1);
Serial.println("%) ║");
Serial.println("╚═══════════════════════════════════╝");
Serial.println();
Serial.println("📊 СЕЙЧАС ИЗМЕРЬ НАПРЯЖЕНИЕ НА VOUT-1!");
Serial.println(" И запиши результат.");
}
void setVoltageForCells(uint8_t cells) {
uint8_t dac_value;
float target_voltage;
switch(cells) {
case 1:
dac_value = cal_1s;
target_voltage = 4.2;
break;
case 2:
dac_value = cal_2s;
target_voltage = 8.4;
break;
case 3:
dac_value = cal_3s;
target_voltage = 12.6;
break;
case 4:
dac_value = cal_4s;
target_voltage = 16.8;
break;
default:
Serial.println("❌ Ошибка: недопустимое количество банок!");
return;
}
dacWrite(DAC_PIN, dac_value);
current_dac = dac_value;
Serial.println();
Serial.println("╔═══════════════════════════════════╗");
Serial.print ("║ Установлено для ");
Serial.print(cells);
Serial.println("S батареи ║");
Serial.print ("║ Целевое: ");
Serial.print(target_voltage, 1);
Serial.println("V ║");
Serial.print ("║ DAC: ");
Serial.print(dac_value);
Serial.println(" ║");
Serial.println("╚═══════════════════════════════════╝");
Serial.println();
Serial.println("📊 Проверь напряжение вольтметром!");
Serial.print(" Должно быть около ");
Serial.print(target_voltage);
Serial.println("V");
}
// ============================================================
// КАЛИБРОВКА
// ============================================================
void runCalibration() {
Serial.println();
Serial.println("╔═══════════════════════════════════════════╗");
Serial.println("║ РЕЖИМ ПОЛНОЙ КАЛИБРОВКИ ║");
Serial.println("╚═══════════════════════════════════════════╝");
Serial.println();
Serial.println("⚠️ ПОДГОТОВКА:");
Serial.println(" 1. Подключи вольтметр к VOUT-1");
Serial.println(" 2. НЕ подключай нагрузку!");
Serial.println(" 3. Приготовь ручку и бумагу");
Serial.println();
Serial.print("⏱️ Задержка на измерение: ");
Serial.print(calibration_delay);
Serial.println(" секунд");
Serial.println(" (Изменить: delay5, delay10, delay15 и т.д.)");
Serial.println();
Serial.println("📋 Для каждого значения DAC:");
Serial.print(" - Жди ");
Serial.print(calibration_delay);
Serial.println(" секунд стабилизации");
Serial.println(" - Измерь напряжение");
Serial.println(" - Запиши в таблицу");
Serial.println();
Serial.println("Нажми ENTER для начала...");
// Ждём нажатия Enter
while(Serial.available() == 0) {
delay(100);
}
Serial.readString(); // Очищаем буфер
Serial.println();
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println(" НАЧАЛО КАЛИБРОВКИ");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
// Проходим по значениям DAC с шагом 25
for (int dac_value = 0; dac_value <= 255; dac_value += 25) {
dacWrite(DAC_PIN, dac_value);
Serial.println();
Serial.print("┌─ DAC = ");
Serial.print(dac_value);
Serial.println(" ─────────────────────");
Serial.println("│");
Serial.print("│ Ожидание ");
Serial.print(calibration_delay);
Serial.print(" сек");
// Ждём стабилизации с анимацией
int steps = calibration_delay * 2; // Каждые 0.5 секунды точка
for (int i = 0; i < steps; i++) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("│");
Serial.println("│ 🔔 ЗВУКОВОЙ СИГНАЛ - ИЗМЕРЯЙ СЕЙЧАС!");
Serial.println("│");
Serial.println("│ 📊 ИЗМЕРЬ НАПРЯЖЕНИЕ НА VOUT-1!");
Serial.print("│ Запиши: DAC ");
Serial.print(dac_value);
Serial.println(" = _____ V");
Serial.println("│");
// Дополнительная пауза для записи (3 секунды)
Serial.println("│ (3 сек на запись");
for (int i = 0; i < 6; i++) {
delay(500);
Serial.print(".");
}
Serial.println(")");
Serial.println("└─────────────────────────────────");
}
Serial.println();
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println("✅ КАЛИБРОВКА ЗАВЕРШЕНА!");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println();
Serial.println("📋 Теперь найди в таблице значения DAC для:");
Serial.println(" - 4.2V (1S) → введи: save1s [значение]");
Serial.println(" - 8.4V (2S) → введи: save2s [значение]");
Serial.println(" - 12.6V (3S) → введи: save3s [значение]");
Serial.println(" - 16.8V (4S) → введи: save4s [значение]");
Serial.println();
Serial.println("Пример: save1s 150");
// Возвращаемся к DAC=0
dacWrite(DAC_PIN, 0);
}
void runQuickCalibration() {
Serial.println();
Serial.println("╔═══════════════════════════════════════════╗");
Serial.println("║ РЕЖИМ БЫСТРОЙ КАЛИБРОВКИ ║");
Serial.println("╚═══════════════════════════════════════════╝");
Serial.println();
Serial.println("Проверяются только ключевые точки:");
Serial.println();
int key_values[] = {0, 50, 100, 150, 200, 255};
for (int i = 0; i < 6; i++) {
int dac_value = key_values[i];
dacWrite(DAC_PIN, dac_value);
Serial.print("DAC = ");
Serial.print(dac_value);
Serial.print(" → Измерь напряжение");
for (int j = 0; j < 4; j++) {
delay(500);
Serial.print(".");
}
Serial.println(" СЕЙЧАС!");
delay(2000);
}
Serial.println();
Serial.println("✅ Быстрая калибровка завершена!");
dacWrite(DAC_PIN, 0);
}
// ============================================================
// ИНФОРМАЦИЯ И МЕНЮ
// ============================================================
void printWelcome() {
Serial.println();
Serial.println("╔═════════════════════════════════════════════════╗");
Serial.println("║ ║");
Serial.println("║ XL4015 + ESP32 DAC ТЕСТОВЫЙ СКЕТЧ ║");
Serial.println("║ Управление зарядным устройством ║");
Serial.println("║ ║");
Serial.println("╚═════════════════════════════════════════════════╝");
Serial.println();
Serial.println("✅ Система готова к работе!");
Serial.println("📌 GPIO25 (DAC1) подключен к FB через 470Ω");
Serial.println("⚡ Напряжение DAC: 0-3.3V (0-255 в коде)");
Serial.println();
}
void printMenu() {
Serial.println();
Serial.println("╔═══════════════════════════════════════════════════╗");
Serial.println("║ СПИСОК КОМАНД ║");
Serial.println("╠═══════════════════════════════════════════════════╣");
Serial.println("║ ПРЯМОЕ УПРАВЛЕНИЕ DAC: ║");
Serial.println("║ d[число] Установить DAC (0-255) ║");
Serial.println("║ Примеры: d100, dac150, d 200 ║");
Serial.println("║ min DAC = 255 (минимум VOUT) ║");
Serial.println("║ max DAC = 0 (максимум VOUT) ║");
Serial.println("║ mid DAC = 128 (среднее) ║");
Serial.println("║ + / up DAC +1 ║");
Serial.println("║ - / down DAC -1 ║");
Serial.println("║ ++ / up10 DAC +10 ║");
Serial.println("║ -- / down10 DAC -10 ║");
Serial.println("╠═══════════════════════════════════════════════════╣");
Serial.println("║ УПРАВЛЕНИЕ ПО БАНКАМ: ║");
Serial.println("║ 1s 4.2V (1S батарея) ║");
Serial.println("║ 2s 8.4V (2S батарея) ║");
Serial.println("║ 3s 12.6V (3S батарея) ║");
Serial.println("║ 4s 16.8V (4S батарея) ║");
Serial.println("╠═══════════════════════════════════════════════════╣");
Serial.println("║ КАЛИБРОВКА: ║");
Serial.println("║ cal Полная калибровка (0-255, шаг 25)║");
Serial.println("║ quickcal Быстрая калибровка (6 точек) ║");
Serial.println("║ save1s [N] Сохранить DAC для 1S (4.2V) ║");
Serial.println("║ save2s [N] Сохранить DAC для 2S (8.4V) ║");
Serial.println("║ save3s [N] Сохранить DAC для 3S (12.6V) ║");
Serial.println("║ save4s [N] Сохранить DAC для 4S (16.8V) ║");
Serial.println("║ Пример: save1s 150 ║");
Serial.println("╠═══════════════════════════════════════════════════╣");
Serial.println("║ ИНФОРМАЦИЯ: ║");
Serial.println("║ info Текущий статус ║");
Serial.println("║ cv Значения калибровки ║");
Serial.println("║ help Показать это меню ║");
Serial.println("╚═══════════════════════════════════════════════════╝");
Serial.println();
Serial.println("💡 Начни с команды 'cal' для калибровки!");
Serial.println();
}
void printStatus() {
Serial.println();
Serial.println("╔═══════════════════════════════════╗");
Serial.println("║ ТЕКУЩИЙ СТАТУС ║");
Serial.println("╠═══════════════════════════════════╣");
Serial.print ("║ DAC значение: ");
Serial.print(current_dac);
Serial.print(" (");
Serial.print((current_dac * 100.0) / 255.0, 1);
Serial.println("%) ║");
Serial.print ("║ DAC напряжение: ");
Serial.print((current_dac * 3.3) / 255.0, 2);
Serial.println("V ║");
Serial.println("╚═══════════════════════════════════╝");
Serial.println();
}
void printCalibrationValues() {
Serial.println();
Serial.println("╔═══════════════════════════════════════╗");
Serial.println("║ КАЛИБРОВОЧНЫЕ ЗНАЧЕНИЯ ║");
Serial.println("╠═══════════════════════════════════════╣");
Serial.print ("║ 1S (4.2V): DAC = ");
Serial.print(cal_1s);
Serial.println(" ║");
Serial.print ("║ 2S (8.4V): DAC = ");
Serial.print(cal_2s);
Serial.println(" ║");
Serial.print ("║ 3S (12.6V): DAC = ");
Serial.print(cal_3s);
Serial.println(" ║");
Serial.print ("║ 4S (16.8V): DAC = ");
Serial.print(cal_4s);
Serial.println(" ║");
Serial.println("╚═══════════════════════════════════════╝");
Serial.println();
Serial.println("Для изменения используй команды:");
Serial.println(" save1s [число], save2s [число], и т.д.");
Serial.println();
}
// ============================================================
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
// ============================================================
int extractNumber(String str) {
// Убираем все не-цифры в начале
int startIndex = 0;
while (startIndex < str.length() && !isDigit(str[startIndex])) {
startIndex++;
}
// Извлекаем число
String numberStr = str.substring(startIndex);
numberStr.trim();
if (numberStr.length() > 0) {
return numberStr.toInt();
}
return -1; // Ошибка
}