Tachoanzeige in Qt programmieren

Alles rund um die Programmierung mit Qt
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hi,

zurzeit beschäftige ich mit dem Programm Qt, habe gesehen das man
grafische Oberflächen damit programmieren kann. Nun habe ich einen
Tachoinstrumenten programmiert und bin wie folgt vorgegangen.
Habe mir in Gimp die Bilder eines Tachos zusammen geschnitten und mit
dem QT Designer die einzelnen png Bilder plaziert ein die Nadel jetzt
auch zum laufen gebracht. Ich habe für die Programmierung slider benutzt
mit der man durch ziehen des des Buttons der Geschwidisgkeitszeiger
bewegt wird.

Nun zu meiner Frage ich möchte gerne die Pfeiltaste auf der Tastatur
benutzen damit sich der Zeiger bewegt, habe in der bibliothek nicht
gescheites gefunden, was mich weiterbringt, vielleicht könnt ihr mir
weiterhelfen??



Hier ist der Code für die Rotaion des Zeigers:

Code: Alles auswählen

 Image {
        id: zeiger
        x: 218; y: 0
        height: 215
        smooth: true
        source: "geschw_zeiger.png"
        transform: Rotation {
            id: zeigerRotation
            origin.x: 5; origin.y: 215
            //! [needle angle]
            angle: Math.min(Math.max(-150, root.value*3.5 - 200), 150)
            Behavior on angle {
                SpringAnimation {
                    spring: 0.4
                    damping: .15
                }
            }
            //! [needle angle]
        }
    }

ich danke euch schonmal im Voraus.

Gruss
Flat
Dateianhänge
tachoanzeige.jpg
tachoanzeige.jpg (107.07 KiB) 12317 mal betrachtet
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hi,

weißt denn hier keiner eine Antwort zu meiner Frage?
Ich wäre auch noch für tipps dankbar, was man am Tachoinstrumenten noch machen kann.
Würde mich auf ein paar Kommentare freuen.

Gruss
Flat
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Tachoanzeige in Qt programmieren

Beitrag von franzf »

Der Code, den du gepostet hat, schaut nach QML aus. Wieso du das machst -k.A., deinem Text nach wars wohl nicht Absicht, oder doch?
Ich selber hab noch nie was mit QML gemacht, hab aber sofort in der Qt-Doku das "QML KeyEvent Element" gefunden, was wohl genau das machen sollte, was du suchst.
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hi,

Danke nochmal für deine Antwort. Nun habe ich jetzt das Problem, dass ich nicht genau weis wie ich das eingeben soll.
Wo ich noch den Slider benutzt habe wurde der Zeiger mit einem Eingabewert Value bewegt.
Ich will das der Value wert, wenn ich jetzt auf die Up Taste drauf drücke, hoch zählt.
Ich hoffe ich konnte mich verständlich ausdrücken.
Hier ist ein Abschnitt vom Code:

Code: Alles auswählen

    Zeiger {
        id: zeiger
        x: 420
        y: 80
        anchors.verticalCenterOffset: 0
        anchors.horizontalCenterOffset: 0
        anchors.centerIn: parent
        value: 20
        Keys.onPressed: { if (event.key == Qt.Key_Up);

            ???

        }
    }
Ich bin neu in Qml, deshalb würde ich mich eure Hilfe freuen.
Ich danke schonmal im Voraus.
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hi,

habe das jetzt so gelöst indem ich den value wert mit der Up taste auf 100 rotiert lasse
und mit der Down Taste auf 0. Hier ist der Code:

Code: Alles auswählen

focus: true
    Keys.onPressed: { if (event.key === Qt.Key_Up)

            root.value= 100;

     else if (event.key ===Qt.Key_Down)

            root.value= 0
             }
Nun möchte ich aber nur eine Taste benutzen.
Sprich wenn ich auf Up drücke soll es auf den Value wert = 100 laufen und wenn ich loslasse dann soll es auf den value wert = 0 zurück rotieren.
Und ich habe gleich noch eine frage, wie kann ich den Value wert anzeigen lassen, sodass man z.B nicht auf die Nadelstellung achten muss sondern den Wert direkt ablesen kann.

Ich danke für eure Tipps

Gruss
Flat
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hi,

So nun bin ich schon ein stückchen weiter.

ich habe endlich ein funktionierendes Programm gefunden, dass auf die
serielle Schnittstelle zugreifen kann. Habe auch schon mit einem
Mikrocontroller Daten gesendet und mit dem Beispielprogramm die Daten
empfangen.

Hab nun das Problem, dass ich nicht weiß wie ich die Zeiger zum laufen
bringe, da ich alles in qml geschrieben habe und der Serial Port in c++
geschrieben ist.

Könnt ihr mir vielleicht sagen wie ich das mit einander verknüpfen kann.
Sprich ich möchte die Zeiger mit Signal ans Slots bewegen
Habe auch schon danach gegoogelt aber wurde nicht so richtig fündig bzw.
der Lösungsansatz ist mir nicht so richtig klar.

Ich möchte wenn ich jetzt vom Mikrocontroller auf die Taste draufdrücke
eine byte verschicken sagen wir mal (1111 1111), der Zeiger soll jetzt
bei diesem code anfangen zu laufen und wenn ich wieder loslasse soll es
wieder runterlaufen (0000 0000).

Ich habe im Programm das Beeispiel mit dem PortListener
herausgeschrieben.
Jetzt möchte ich wenn ich ein Signal von 1111 1111 bekomme den Zeiger,
was ich qml geschrieben habe per Signal und Slot bewegen.


Es hört sich vielleicht trivial an aber für mich der nicht so gute
Kenntnisse in c++ Programmieren hat ist es schon etwas aufwändiger,
daher würde ich mich für eure Tipps und Lösungsvorschläge freuen.
Ich habe das BeispielProgramm mit der Serielle Schnittstelle angehängt.
Das andere Programm womit die Zeiger bewegt werden sind ebenfalls auch angehängt

Code: Alles auswählen

#include "PortListener.h"
#include <QtDebug>

PortListener::PortListener(const QString & portName)
{
    qDebug() << "hi there";
    this->port = new QextSerialPort(portName, QextSerialPort::EventDriven);
    port->setBaudRate(BAUD9600);
    port->setFlowControl(FLOW_OFF);
    port->setParity(PAR_NONE);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_2);

    if (port->open(QIODevice::ReadWrite) == true) {
        connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
        connect(port, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool)));
        if (!(port->lineStatus() & LS_DSR))
            qDebug() << "warning: device is not turned on";
        qDebug() << "listening for data on" << port->portName();
    }
    else {
        qDebug() << "device failed to open:" << port->errorString();
    }
}

void PortListener::onReadyRead()
{
    QByteArray bytes;
    int a = port->bytesAvailable();
    bytes.resize(a);
    port->read(bytes.data(), bytes.size());
    qDebug() << "bytes read:" << bytes.size();
    qDebug() << "bytes:" << bytes;
}

void PortListener::onDsrChanged(bool status)
{
    if (status)
        qDebug() << "device was turned on";
    else
        qDebug() << "device was turned off";
}

Hier ist der Qml Code vom Zeiger:

Code: Alles auswählen

    Image {
        id: zeiger
        x: 235; y: 12
        width: 11
        height: 228
        smooth: true
        source: "GeschwZeiger.png"
        transform: Rotation {
            id: zeigerRotation
            origin.x: 5; origin.y: 225
            //! [needle angle]
            angle: Math.min(Math.max( root.value * 3 -150 ), root.value +50)

                //Math.min(Math.max(-150, root.value*3.5 - 200), 150)
            Behavior on angle {
                SpringAnimation {
                    spring: 0.08
                    damping: .25
                }
            }
            //! [needle angle]
        }
    }
Ich danke euch schonmal im Voraus

Gruss
Flat
Dateianhänge
qextserialport-1.2beta2.tar.gz
(165.71 KiB) 256-mal heruntergeladen
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

kann mir den keiner weiter helfen zu meiner Problemstellung.
Wäre für Läsungsvorschläge, Tipps oder auch für Beispielprogramme sehr dankbar.

Gruss
Flat
jerry42
Beiträge: 126
Registriert: 9. Oktober 2008 10:48

Re: Tachoanzeige in Qt programmieren

Beitrag von jerry42 »

Hi,

mit QML hab ich noch nicht viel gemacht, aber hier sollte eigentlich genau das beschrieben sein, was du machen willst:

http://doc.qt.nokia.com/4.7-snapshot/qt ... -qml-and-c

grüße
jerry42
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hallo,

@ jerry42

vielen dank für deine Antwort.
Ich habe das jetzt so gelöst indem ich den Value wert vom Zeiger von der Qml datei
mit der QDeclarativeProperty in c++ zugreifen kann.

Beispiel:

Du erstellst in deinem QML root Objekt eine Property und weist diese
dann z.B. deinem Zeiger zu.

z.B. main.qml

Code: Alles auswählen


import QtQuick 1.0
//! [imports]

//! [0]
Rectangle {
    color: "#545454"
    width: 1280
    height: 600
    focus: true
    property int zeigerVal

    // Dial with a slider to adjust it
    Zeiger {
        id: zeiger
        anchors.centerIn: parent
        value: zeigerVal

    }
Im C++ Code kannst du nun mit QDeclarativeProperty diesen Wert
verändern:

z.B. main.cpp

Code: Alles auswählen

#include <QtGui/QApplication>
#include <QtDeclarative>
#include "qmlapplicationviewer.h"

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    QDeclarativeView view;
    view.setSource(QUrl("qml/tacho/main.qml"));
    view.show();

    QDeclarativeProperty property(view.rootObject(), QString("zeigerVal"));
    property.write(50);
    return app.exec();
}
Nun habe ich das Problem mit dem Byte senden, da ich später die Blinker
und die Zeiger einzeln ansteuern möchte, brauche ich einen kleinen
Quellcode mit dem ich dies Realisieren kann.

Wie kann ich die Propertys nun ändern wenn ich sagen wir mal ein byte
von 0x01 sende?

Ich hoffe ich habe mich verstandlich ausgedrückt.
Hoffe du kannst mir hierbei auch helfen.

Gruss
Flat
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Guten Morgen,

kann mir hier jemand behiflich sein. Habe das Projekt angehangen.

Der Mikrocontroller schickt hier 0x10 für den Zeiger
und 0x20 für den Warnblink.

Code: Alles auswählen

int main(void)
{
//##### INIT ########
	uint8_t state = 0;
	UART_Init();
	sei(); //Global interrupt ein	
	
//	EMD("\nInitialisiert\n");
//##### ENDE INIT ########	

	DDRD=0; //Tasten-PORT auf Eingang
	PORTD=255; //pullup

	DDRB=255; //LED-PORT auf Ausgang
	PORTB=255; //LED aus

	// Initialisierung wie oben

	while(1) {
		if ((PIND & (1<<4)) == 0) { // Schalter gedrückt
		//	state = (state + 1) % 2; // Zustand ändern
		//	PORTB = state?255:0; // und ausgeben (alle Pins)
		//	_delay_ms(1000); // 1 s warten
		
			UART_sendByte(0x10); // Geschwindigkeitszeiger
		
		}
		if ((PIND & (1<<7)) == 0) {
			
			UART_sendByte(0x20); //Warnblink

		}
	}	
					 
}
Nun möchte ich in der Empfangsroutine die den Code anpassen und die Signals und Slots einfügen.
Kann mir einer dabei behilflich sein. Das gesamte Projekt habe ich angehangen.

Gruss
Flat
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Sorry habe gerade gesehen, dass ich vergessen habe die datei hier anzuhängen.
Da die datei zu gross war, habe ich es auf folgende Seite angehangen.

http://www.mikrocontroller.net/topic/258716#new

Gruss
Flat
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Hallo Leute,

ich habe es jetzt geschafft die bytes zu empfangen

ich sende einen Buchstaben "Z" und empfange im PortListener genau den byte, es zeigt mir auch an das ich nur ein byte empfangen habe.
Alles schön und gut aber ich schaffe es nicht die Zeiger mit dem empfangenen byte zu manipulieren.

Die Zeiger variable ist in Qml geschrieben. Die main.qml lasse ich mit dem folgenden Befehl anzeigen

Code: Alles auswählen

view.setSource(QUrl::fromLocalFile("qml/TachoNEU/main.qml"));
Die variable des Zeigers "zeigerVal" möchte ich in der Klasse PortListener manipulieren wenn ich einen Byte schicke.

Dazu habe ich jetzt in der PortListener.h folgendes geschrieben:

Code: Alles auswählen

class PortListener : public QObject
{
Q_OBJECT

public:
    PortListener (const QDeclarativeView , QObject *parent = 0);
    PortListener(const QString & portName);
    QByteArray readbyte();

private:
    QDeclarativeProperty myProp1;
    QextSerialPort *port;
    QByteArray bytes;


private slots:
    void onReadyRead();
    void onDsrChanged(bool status);

};

mit der QDeclarativeProperty möchte ich nun meine Property wert "zeigerVal"
in PortListener.cpp verändern können und in der Haupt main.cpp anzeigen können.

Hier der Code für das lesen der Ports, was auch wunderbar klappt.

Code: Alles auswählen

void PortListener::onReadyRead()
{

    bytes = port->readAll();
    qDebug() << "bytes read:" << bytes.size();
    qDebug() << "bytes:" << bytes;
}
Hier möchte ich wenn ich ein "Z" bekommen habe, in myProp1 schreiben und damit den zeiger auf vollausschlag bringen und wenn ich keine Daten bekomme
soll der Zeiger wieder runter laufen. Zum Rotieren der Zeiger ist ein code in qml geschrieben, dass auch sehr gut funktioniert. Doch der Zeiger lässt sich nicht bewegen wenn ich die bytes schicke. Ich hoffe ihr könnt mir helfen. Ich weiss nicht was ich falsch gemacht habe.

Code: Alles auswählen

PortListener::PortListener(const QDeclarativeView , QObject *parent)
    //: myProp1(view.rootObject(), QString("zeigerVal"))
{

    QByteArray bytes;

    QDeclarativeView view;
    QDeclarativeProperty myProp1(view.rootObject(), QString("zeigerVal"));
    view.setSource(QUrl::fromLocalFile("qml/TachoNEU/main.qml"));

    if (bytes == "Z"){
    myProp1.write(100);
    }

    else if(bytes == ""){
        myProp1.write(0);
    }

}

Die main.cpp sieht so aus:

Code: Alles auswählen

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));

    QDeclarativeView view;
    PortListener Interface(view);
    QString portName = QLatin1String("COM1");  // update this to use your port of choice
    PortListener Listener(portName);     // signals get hooked up internally

    view.setSource(QUrl::fromLocalFile("qml/TachoNEU/main.qml"));

    view.show();
    return app->exec();
}
jerry42
Beiträge: 126
Registriert: 9. Oktober 2008 10:48

Re: Tachoanzeige in Qt programmieren

Beitrag von jerry42 »

Hi,

wie ich sehe, rufst du die write Methode im Moment im Konstruktor auf von PortListener.
Tut es denn wenn du ohne bytes Bedingung einfach ein myProp1.write(100) aufrufst?

Vielleicht spielt hier die Erzeugungsreihenfolge mit rein. Hast du denn mal probiert das write in einer Extramethode aufzurufen?
Also wenn Du in onReadyRead bist, zum Beispiel ein byteChanged Signal emitten? und im angebundenen Slot dann die write Methode aufrufen?

Kann natürlich sein, dass es nicht vollständig ist, aber so wie du den Code jetzt hast, kann es ja eigentlich nicht funktionieren. Der Konstruktor wird zuerst aufgerufen, d.h. du machst nur ein write(0);

gruß
jerry42
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Ich habe es jetzt doch hinbekommen.
Danke nochmal :)
Flat
Beiträge: 25
Registriert: 14. Mai 2012 12:02

Re: Tachoanzeige in Qt programmieren

Beitrag von Flat »

Was ich immer Fragen wollte, also folgendes bei meinem Rechner zu Hause
ruckelt der Zeiger wenn es bewegt wird. Und wenn ich beide Zeiger bewege
ist es meist schlimmer. Die Zeiger bleiben stehen und es stürzt ab.
Doch auf meinem Laptop funktioniert das ganze flüssig, okey es hat
etwas mehr Leistung als mein Rechner und hat eine Grafikkarte.
Der Rechner zu Hause, der hat nur eine OnBoard Grafikkarte, hat aber 4GB
Arbeitsspeicher und ein Prozessor mit 3GHz Dual Core, es ruckelt stark.

Woran kann das liegen, ich habe bei beiden Rechnern aktuelle Treiber installiert.
Auf dem Rechner zu Hause läuft Xp und auf meinem Lappi Windows 7.
Kann das vielleicht an dem Betriebssystem liegen ??

Meine andere Frage:

Es geht darum, dass ich die Anwendung die ich
erstellt habe an einem anderen Rechner ausführen möchte. So nun habe ich
herausgefunden, dass ich das dynamisch linken muss und die dazugehörigen
dlls in den Ordner mit einfügen muss, habe ich auch soweit gemacht. Wenn
ich jetzt die exe Datei starte bekomme ich ein weißes Fenster. Was mache
ich falsch.


Habe die folgenden Dlls reingepackt:

libgcc_s_dw2-1.dll
mingwm10.dll
QtCore4.dll
QtDeclarative4.dll
QtGui4.dll
QtNetwork4.dll
QtScript4.dll
QtSql4.dll
QtXmlPatterns4.dll

Wenn ich diese Dlls nicht reinmache, gibt der mir ne Fehlermeldung,
nachdem ich sie alle nacheinander reingemacht habe, zeigt es mir nun ein
weißes Fenster an. Wisst ihr was noch fehlt?
Antworten