Our professor tasked us to create a self balancing robot which can:
- send back data to a QT program through modbus in order to create a graph, and
- be controlled by the QT program also using modbus
most of us managed to get the first part up and running using this library, but none of us has managed to send data back to the ESP32 through the QT program.
graph
data
we managed to get the PS5 controller hooked up to QT using this example code, but that’s about the farthest we got
gamepad input QT
we’ve tried using modbus_write_register but it kept returning a -1 value on qDebug
void MainWindow::sendTcpRequest(void)
{
if(m_tcpActive)
{
tcpConnect();
}
if(m_tcpModbus == NULL)
{
ui->connectionStatus->setText("Not Connected");
return;
}
ui->connectionStatus->setText("Connection Established");
const int slave = ui->slaveId->value();
const int func = 04;
const int addr = ui->addressReg->value();
int num = ui->coilNum->value();
uint8_t dest[1024];
uint16_t * dest16 = (uint16_t *) dest;
memset(dest, 0, 1024);
memset(dest_2, 0 ,1024);
int ret = -1;
bool is16Bit = false;
const QString dataType = descriptiveDataTypeName(func);
QString noteValue = "";
modbus_set_slave(m_tcpModbus, slave);
ret = modbus_read_registers( m_tcpModbus, addr, num, dest16);
is16Bit = true;
//ui->debugLabel->setText();
//qDebug() << ret;
int shit = 123;
int asdf = modbus_write_register(m_tcpModbus, 9, shit);
qDebug() << asdf;
if(ret == num)
{
bool b_hex = is16Bit;
QString qs_num;
ui->regTable->setRowCount( num );
for(int i = 0; i < num; ++i)
{
spinVal = ui->spinBox->value();
Xmin = plotcount - spinVal;
int dataraw = is16Bit ? dest16[i] : dest[i];
int data;
if(dataraw >= 32768){
data = dataraw - 65536;
} else {
data = dataraw;
}
QTableWidgetItem * dtItem =
new QTableWidgetItem( dataType );
QTableWidgetItem * addrItem =
new QTableWidgetItem ( QString::number( addr+i ) );
qs_num = QString::asprintf( b_hex ? "0x%04x" : "%d", data);
QTableWidgetItem * dataItem =
new QTableWidgetItem( qs_num );
QTableWidgetItem * datanumItem =
new QTableWidgetItem( QString::number(data) );
switch (i){
default:
noteValue = "-";
break;
case 0:
noteValue = "angleSample";
break;
case 1:
noteValue = "finalSpeed";
break;
case 2:
noteValue = "targetSpeed";
break;
case 3:
noteValue = "targetAngle";
break;
case 4:
noteValue = "INIT_SAMPLE_SIZE";
break;
case 5:
noteValue = "CENTER_OF_MASS_OFFSET";
break;
case 6:
noteValue = "KP";
break;
case 7:
noteValue = "KI";
break;
case 8:
noteValue = "KD";
break;
case 9:
noteValue = "LEFT-TRIG";
break;
case 10:
noteValue = "RIGHT-TRIG";
break;
}
QTableWidgetItem * noteItem =
new QTableWidgetItem(noteValue);
dtItem->setFlags(dtItem->flags() &
~Qt::ItemIsEditable);
addrItem->setFlags(addrItem->flags() &
~Qt::ItemIsEditable);
dataItem->setFlags( dataItem->flags() &
~Qt::ItemIsEditable);
datanumItem->setFlags( datanumItem->flags() &
~Qt::ItemIsEditable);
noteItem->setFlags( noteItem->flags() &
~Qt::ItemIsEditable);
ui->regTable->setItem(i, DataTypeColumn, dtItem);
ui->regTable->setItem(i, AddrColumn, addrItem);
ui->regTable->setItem(i, DataColumn, dataItem);
ui->regTable->setItem(i, DatanumColumn, datanumItem);
ui->regTable->setItem(i, NoteColumn, noteItem);
//double val = 3*(qSin((double)plotcount*2)+2); //for testing
switch (i) {
case 0:
series->append(plotcount, data);
plotcount++;
if (plotcount > Xmax){
Xmin++;
Xmax = plotcount;
}
// if (data >= Ymax){
// Ymax = (data + 10);
// }
chart->axisX()->setRange(Xmin, Xmax-1);
// chart->axisY()->setRange(Ymin, Ymax);
break;
case 1:
series1->append(plotcount, data);
plotcount++;
if (plotcount > Xmax){
Xmin++;
Xmax = plotcount;
}
// if (data >= Ymax){
// Ymax = (data + 10);
// }
chart->axisX()->setRange(Xmin, Xmax-1);
// chart->axisY()->setRange(Ymin, Ymax);
break;
case 2:
series2->append(plotcount, data);
plotcount++;
if (plotcount > Xmax){
Xmin++;
Xmax = plotcount;
}
// if (data >= Ymax){
// Ymax = (data + 10);
// }
chart->axisX()->setRange(Xmin, Xmax-1);
// chart->axisY()->setRange(Ymin, Ymax);
default:
break;
}
}
ui->regTable->resizeColumnToContents(0);
ui->debugLabel->setText("Refresh Success!");
}
else
{
ui->debugLabel->setText("Refresh Error!");
}
}
and this is the code used in the ESP32 side of things which returns a zero value
regData.Hreg(0, angleSample);
regData.Hreg(1, finalSpeed);
regData.Hreg(3, targetAngle);
regData.Hreg(4, INIT_SAMPLE_SIZE);
regData.Hreg(5, CENTER_OF_MASS_OFFSET);
regData.Hreg(6, KP);
regData.Hreg(7, KI);
regData.Hreg(8, KD);
LTval = regData.Hreg(9);
RTval = regData.Hreg(10);
regData.task();
Serial.print("Left Trigger: ");
Serial.print(LTval);
Serial.print(" | Right Trigger: ");
Serial.println(RTval);
any help would be appriciated
Tristan Charis Eleazer Lam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.