Go Down

Topic: [tuto]Communication Qt Arduino (Read 4979 times) previous topic - next topic

Vicolaships

Apr 02, 2013, 12:40 pm Last Edit: Apr 03, 2013, 09:15 am by Vicolaships Reason: 1
Pré-requis
Aucun ! Tout est expliqué et détaillé, aucune connaissance particulière n'est nécessaire. C'est réalisable par tout le monde !

Objectif
On va contrôler un servomoteur grâce a une application Qt. La communication se fait par le câble USB
Voir la vidéo

Matériel
  • Un Arduino (j'utilise un Arduino Nano 3.0)

  • Un PC, s'il n'est pas sous Linux il faudra adapter le code Qt (le mien est sous Ubuntu 12.04.2 desktop (64 bits))

  • Un servomoteur


Installation
Il faut installer Qt Creator et compiler ExtSerialPort :
Code: [Select]
sudo apt-get install -y qtcreator && git clone https://code.google.com/p/qextserialport/ && cd qextserialport && qmake && make && sudo make install

Arduino
On branche l'Arduino sur l'USB après avoir branché le servomoteur :
Rouge : 5V
Marron : GND
Jaune : D9

Démarrer un projet Arduino et compiler/transférer ce code :
Code: [Select]
#include <Servo.h>

Servo srv;
int incomingByte = 0;

void setup()
{
 Serial.begin(9600); // on defini le baud-rate
 srv.attach(9); // on attache un servo en D9
}

void loop()
{
if (Serial.available() > 0)
{
 // lecture des bytes arrivant :
 incomingByte = Serial.read();
 srv.write(incomingByte); // on écrit la valeur recue sur le servo
 //Serial.print(incomingByte);    
}
}


Projet Qt Creator
Créez un projet Qt Creator: Projet Qt Widget : Application graphique Qt
Nommer le projet "USB_servo" et le nom de la classe "USB_servo" (laisser le reste par défaut)

Aller dans formulaires, et créer les éléments suivants :

Widget - Nom
Qdial - "dial"
Qslider - "slider"
Qlcdnumber - "lcd"

Une fois les éléments crées appuyer sur F4 pour éditer les signaux/slots (ou cliquer en haut sur l'icône "Editer signaux/slots)
Créer les signaux suivants :

Emetteur - Signal - Receveur - Slot
dial - sliderMoved(int) - lcd - display(int)
dial - sliderMoved(int) - slider - setValue(int)
slider - sliderMoved(int) - dial - setValue(int)
slider - sliderMoved(int) - lcd - display(int)

Modifier le contenu des fichiers suivants comme suit :

USB_servo.pro
Code: [Select]
QT       += core gui

TARGET = USB_servo
TEMPLATE = app

#add qExtSerialPort libs
CONFIG += extserialport

SOURCES += main.cpp\
        usb_servo.cpp

HEADERS  += usb_servo.h

FORMS    += usb_servo.ui


usb_servo.h
Code: [Select]
#ifndef USB_SERVO_H
#define USB_SERVO_H

#include <QMainWindow>
#include <QtGui>
#include <qextserialport.h>

namespace Ui {
class USB_servo;
}

class USB_servo : public QMainWindow
{
    Q_OBJECT
   
public:
    explicit USB_servo(QWidget *parent = 0);
    void init_port(); // initialisation du port
    ~USB_servo();

public slots:
void transmitCmd(int value); // fonction d'envoi
   
private:
    Ui::USB_servo *ui;
    QextSerialPort *port;
};

#endif // USB_SERVO_H


usb_servo.cpp
Code: [Select]
#include "usb_servo.h"
#include "ui_usb_servo.h"

USB_servo::USB_servo(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::USB_servo)
    // Création de l'intefarce ("formulaires")
{
    init_port(); //initiation of the port
    ui->setupUi(this);
    connect(ui->dial, SIGNAL(sliderMoved(int)), this, SLOT(transmitCmd(int)));
    // On connecte le mouvement du bouton a l'envoi de la commande
    connect(ui->slider, SIGNAL(sliderMoved(int)), this, SLOT(transmitCmd(int)));
    // On connecte le mouvement du slider a l'envoi de la commande
    transmitCmd(90);
    // On initialise le servo à 90°
}

USB_servo::~USB_servo()
{
    delete ui;
}

void USB_servo::init_port(void)
{
    QString dev_port = "/dev/ttyUSB0";
    port = new QextSerialPort(dev_port); //on ouvre le port
    // ls /dev/ | grep USB   << Permet de donner la liste des périphériques USB

     port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
    if(!port->isOpen())
    {
        QMessageBox::warning(this, "Impossible d'ouvrir le port", dev_port);
    }

    // On parametre la liaison :
    port->setBaudRate(BAUD9600);
    port->setFlowControl(FLOW_OFF);
    port->setParity(PAR_NONE);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_1);
}

void USB_servo::transmitCmd(int value)
{
    QByteArray byte; //byte a envoyer
    qint64 bw = 0; //bytes really writen

    byte.clear(); // on efface le contenu de byte
    byte.append(value); // on ajoute "value" a byte

    if(port != NULL){ // on vérifie que le port existe toujours
        bw = port->write(byte); // on écrit les byte
        //(bw récupere le nombre de byte écris)
        qDebug() << bw << "byte(s) written | Value sent:" << value << "(dec)";
        port->flush(); // on attend la fin de la transmission
    }

}


Branchez l'Arduino si ce n'est pas déjà fait et lancez la commande suivante dans un terminal :
Code: [Select]
ls /dev/ | grep USB

Le résultat devrait être ttyUSB0 par exemple. Modifier ligne 21 de usb_servo.cpp pour que le périphérique corresponde.
Pour exécuter le programme : Ctrl + R ou clic sur la flèche "lecture" verte en bas à gauche.

Remarque
Chez moi le programme Qt a parfois du mal a ouvrir le port, débrancher et rebrancher l'Arduino si cela arrive.
Arduino Nano v3.0 | Ubuntu 13.04

zoroastre

Yep!

Le fichier zip n'étant pas disponible à ce moment précis où je tente en vain de le télécharger.

Je me demande s'il s'agit bien de python ou de c++.

Bref!

Sous python, je vérifiais régulièrement si un port Usb était dispo ou pas (Linux uniquement).

Code: [Select]

def scan():
    """scan for available ports. return a list of device names."""
    f = glob.glob('/dev/ttyUSB*')
    if len(f) == 0:
        return None
    else:
        return f[0]


Dans la routine principale :

Code: [Select]
...
if scan() != device:
                        closeSerialPort()
                        time.sleep(2)
                        openSerialPort()
...


Vf bitty.py pour l'essentiel.

@+

Zoroastre.
Gné! ;)

Vicolaships

Salut !
Bon mon hébergeur semble pas marcher chez tout le monde alors j'ai rajouté dans le tutoriel comment créer le projet Qt.
A+
Arduino Nano v3.0 | Ubuntu 13.04

tymop

Bonjour,
je ne comprend pas #include "ui_usb_servo.h" car ce fichier n'existe pas.
Et mon complateur le le comprend pas non plus.

Est ce normal ?

Note : je débute sous QT.

XavierMiller


tymop

C'est quoi cet UI ? J'ai bien un fichier usb_servo.ui, mais je pense que ce n'est pas de ce fichier qu'il est question.

Je me doutais bien qu'il manquait ce fichier ui_usb_servo.h, mais je ne sais absoluent pas du tout ce qu'il doit y avoir dedans ?

XavierMiller

le ui_usb_servo.h est généré par QT sur base de l'interface graphique

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy