Envoi d'une séquence de commandes et attente de réponse
Problème : Comment envoyer une séquence de commandes à un appareil connecté via le port série et attendre une réponse, avec gestion des délais d'attente et des conditions d'erreur.
Solution utilisant la State Machine de Qt Framework :
Avantages :
- Asynchrone, non bloquant
- Gestion automatique des délais d'attente
- Code clair et lisible structure
Mise en œuvre :
-
Créer une machine à états :
- Créez une QStateMachine et définissez les états pour chaque étape de la séquence de communication (par exemple, démarrage, envoi, attendu).
-
Définir des générateurs d'actions :
- Définir des fonctions qui décrivent les actions à effectuer lors de l'entrée dans chaque état, comme envoyer des commandes ou attendre des réponses.
-
Connectez-vous Signaux et transitions :
- Connectez des signaux (par exemple, readyRead) pour passer d'un état à un autre.
- Utilisez GuardedSignalTransition pour ajouter des conditions aux transitions en fonction des données reçues.
-
Créer un programmeur Objet :
- Utilisez StatefulObject comme classe de base pour gérer la machine à états et les signaux.
- Enveloppez le port série avec AppPipe (un QIODevice non bloquant) et définissez des actions pour envoyer des commandes et attendre des réponses.
-
Émuler l'appareil Comportement (facultatif) :
- Créez un autre StatefulObject (appareil) pour simuler les réponses de l'appareil aux commandes.
-
Dans la fonction principale :
- Programmeur et appareil instantanés objets.
- Connectez leurs AppPipes pour permettre la communication.
- Démarrez l'objet Programmeur et suivez son état.
- Démarrez éventuellement l'objet Appareil et suivez son état.
Exemple Code :
// Programmer object using Qt's State Machine Framework
class Programmer : public StatefulObject {
Q_OBJECT
AppPipe m_port;
QStateMachine m_mach;
State s_boot, s_send;
public:
Programmer() : StatefulObject() {
connectSignals();
m_mach.setInitialState(&s_boot);
send(&s_boot, &m_port, "boot\n");
expect(&s_boot, &m_port, "boot successful", &s_send, 1000, &s_failed);
... // Define other states and actions
}
void start() { m_mach.start(); }
};
// main function
int main() {
QApplication app;
Programmer prog;
Device dev;
dev.pipe().addOther(&prog.pipe());
prog.pipe().addHasOutgoing([](const QByteArray &data){ qDebug() << "> " << data; });
prog.pipe().addHasIncoming([](const QByteArray &data){ qDebug() << "< " << data; });
prog.start();
return app.exec();
}
Copier après la connexion
Avantages :
- Code propre et structuré, minimisant le risque de conditions de concurrence ou de réponses manquées.
- Possibilité d'ajouter des transitions d'état complexes et des scénarios de gestion des erreurs.
- Extensibilité pour prendre en charge diverses communications protocoles avec différentes séquences de commandes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!