smart_chargeESP32/firmware/dac1

520 lines
No EOL
21 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================================
// ИНТЕРАКТИВНЫЙ ТЕСТОВЫЙ СКЕТЧ ДЛЯ 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; // Ошибка
}