Skip to content

Instantly share code, notes, and snippets.

@esmarr58
Last active October 1, 2025 15:17
Show Gist options
  • Select an option

  • Save esmarr58/3778218d05586936ef9a2dd1041fd13d to your computer and use it in GitHub Desktop.

Select an option

Save esmarr58/3778218d05586936ef9a2dd1041fd13d to your computer and use it in GitHub Desktop.
void MainWindow::manejarPuertosSeriales(QComboBox *comboBox, int baud)
{
if (!comboBox) {
qWarning() << "Debes pasar un QComboBox válido.";
return;
}
// --- Poblar puertos ---
auto poblarPuertos = [comboBox]() {
comboBox->blockSignals(true);
comboBox->clear();
comboBox->addItem("Seleccionar puerto", QVariant());
const QList<QSerialPortInfo> puertos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &info : puertos) {
const QString nombre = info.portName();
const QString desc = info.description().isEmpty() ? "Sin descripción" : info.description();
const QString texto = QString("%1 — %2").arg(nombre, desc);
comboBox->addItem(texto, nombre);
}
comboBox->blockSignals(false);
};
poblarPuertos();
QObject::disconnect(comboBox, nullptr, this, nullptr);
QObject::connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
[this, comboBox, baud](int idx) {
if (idx <= 0) {
if (serialActual && serialActual->isOpen()) {
QString nombre = serialActual->portName();
qDebug() << "Cerrando puerto:" << nombre;
serialActual->close();
QMessageBox::information(this, "Desconectado",
"Se ha desconectado el puerto " + nombre);
}
if (serialActual) {
serialActual->deleteLater();
serialActual = nullptr;
}
return;
}
const QString nombrePuerto = comboBox->currentData().toString();
if (serialActual && serialActual->isOpen()) {
qDebug() << "Cerrando puerto previo:" << serialActual->portName();
serialActual->close();
serialActual->deleteLater();
serialActual = nullptr;
}
serialActual = new QSerialPort(this);
serialActual->setPortName(nombrePuerto);
serialActual->setBaudRate(baud);
serialActual->setDataBits(QSerialPort::Data8);
serialActual->setParity(QSerialPort::NoParity);
serialActual->setStopBits(QSerialPort::OneStop);
serialActual->setFlowControl(QSerialPort::NoFlowControl);
if (!serialActual->open(QIODevice::ReadWrite)) {
qWarning() << "No se pudo abrir" << nombrePuerto << ":" << serialActual->errorString();
QMessageBox::warning(this, "Error",
"No se pudo abrir el puerto " + nombrePuerto + "\n" +
serialActual->errorString());
serialActual->deleteLater();
serialActual = nullptr;
comboBox->blockSignals(true);
comboBox->setCurrentIndex(0);
comboBox->blockSignals(false);
return;
}
qDebug() << "Conexión OK en" << nombrePuerto;
QMessageBox::information(this, "Conectado",
"Se ha conectado exitosamente al puerto " + nombrePuerto);
connect(serialActual, &QSerialPort::readyRead,
this, &MainWindow::onReadyRead,
Qt::UniqueConnection);
});
}
void MainWindow::onReadyRead()
{
if (!serialActual) return;
while (serialActual->canReadLine()) {
const QByteArray datos = serialActual->readLine().trimmed();
emit serialLineaRecibida(QString::fromUtf8(datos));
}
}
void MainWindow::onSerialLineaRecibida(const QString &linea)
{
// Ejemplo de respuesta: {"ok":true,"temp":25.5,"humedad":65.8}
const QByteArray bytes = linea.toUtf8();
QJsonParseError perr;
const QJsonDocument doc = QJsonDocument::fromJson(bytes, &perr);
if (perr.error != QJsonParseError::NoError || !doc.isObject()) {
qWarning() << "JSON inválido:" << perr.errorString() << "en" << linea;
return;
}
const QJsonObject obj = doc.object();
// (Opcional) valida "ok"
if (obj.contains("ok") && obj.value("ok").isBool() && !obj.value("ok").toBool()) {
qWarning() << "Mensaje con ok=false";
return;
}
bool datosValidos = false;
// Validar que AMBOS datos existen
if (obj.contains("temp") && obj.value("temp").isDouble() &&
obj.contains("humedad") && obj.value("humedad").isDouble()) {
temperatura = obj.value("temp").toDouble();
humedad = obj.value("humedad").toDouble();
datosValidos = true;
ui->displayTemperatura->display(QString::number(temperatura, 'f', 1));
ui->displayHumedad->display(QString::number(humedad, 'f', 1));
}
// Solo graficar si estamos en modo REAL (no simulado) y hay datos válidos
if (!ui->checkBox->isChecked() && datosValidos) {
serieTemperatura->append(contadorX, temperatura);
serieHumedad->append(contadorX, humedad);
// Mover ventana de visualización si es necesario
if (contadorX > ejeX->max()) {
ejeX->setRange(contadorX - 60, contadorX);
}
contadorX++;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment