Introduction to LCD Displays and GUI Applications
This is the first video in a set of three on Qt application development on the Beaglebone or any other embedded Linux device. This video introduces the LCD module that I used, reviews it and then discusses how you can install it and develop very basic on-board GTK GUI applications.
[youtube id=”yXTJC-_rlMY” width=”600″ height=”350″]
Setting up QT Creator for C++ ARM Embedded Linux Development
This leads to the second video where I set up a full toolchain for Qt application development under embedded Linux (Qt for embedded devices). This toolchain allows us to cross compile Qt applications for the Beaglebone, deploy the applications directly to the beaglebone with a single click and even use remote debugging using gdbserver to diagnose any problems with our applications. The main use of this platform is for GUI application development when a LCD module, or external display is present.
[youtube id=”kP7uvOu9hoQ” width=”600″ height=”350″]
Thad Failor (via YouTube) provides some information on how to deal with the requirement to execute . /usr/local/angtrom/arm/environment-setup in advance of starting QtCreator. The steps are:
– Open Qt Creator
– Open your project
– Click Projects under [Your Beaglebone Kit]
– Click Build
– Scroll down to the bottom and click details
– Click on Batch
– Edit Paste the contents of the “. /usr/local/angstrom/arm/environment-setup” removing any of the “export” commands.
Example Qt Embedded Linux Application on the Beaglebone
This is the third video in a set of three on Qt application development on the Beaglebone or any other embedded Linux device. This toolchain allows us to cross compile Qt applications for the Beaglebone, deploy the applications directly to the beaglebone with a single click and even use remote debugging using gdbserver to diagnose any problems with our applications. The main use of this platform is for GUI application development when a LCD module, or external display is present.
In this the final video in this series I demonstrate an example application that uses a BMA 180 accelerometer and LED to act as output/input devices and I provide the full source code. I explain how the source code is structured and how the physical circuit was configured.
[youtube id=”yNvOyY9zK1o” width=”600″ height=”350″]
Source Code
The full source code for the code in these videos is available on my github site. You can clone this by typing:
1 |
git clone git://github.com/derekmolloy/beagleboneQT.git |
at the Linux prompt, or by installing some git tools under Windows.
The QtCreator project file is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#------------------------------------------------- # # Project created by QtCreator 2013-03-03T16:36:32 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = beagleboneQT target.files=beagleboneQT target.path=/home/root INSTALLS+=target TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ SimpleGPIO.cpp \ EasyDriver.cpp \ BMA180Accelerometer.cpp HEADERS += mainwindow.h \ SimpleGPIO.h \ EasyDriver.h \ BMA180Accelerometer.h FORMS += mainwindow.ui |
And the core C++ files are mainwindow.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/* * mainwindow.h * The main window for the QT Application * * Copyright Derek Molloy, School of Electronic Engineering, Dublin City University * www.eeng.dcu.ie/~molloyd/ * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTimer> #include "BMA180Accelerometer.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_ledOnButton_clicked(); void on_ledOffButton_clicked(); void on_ledAutoButton_clicked(); void on_lightLevelDial_valueChanged(int value); //manually created void newAccelerometerDataSlot(); private: Ui::MainWindow *ui; unsigned int GREEN_LED_PIN; BMA180Accelerometer *accelerometer; bool autoLEDState; QTimer dataTimer; void autoLED(bool value); }; #endif // MAINWINDOW_H |
And mainwindow.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
/* * mainwindow.cpp * The main window for the QT Application * * Copyright Derek Molloy, School of Electronic Engineering, Dublin City University * www.eeng.dcu.ie/~molloyd/ * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mainwindow.h" #include "ui_mainwindow.h" #include "SimpleGPIO.h" #include "BMA180Accelerometer.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // Green LED Pin // use SimpleGPIO.h to setup the LED Pin correctly as an output pin using MODE 7 (GPIO0_7) // if you don't understand these steps watch my video on YouTube // "Beaglebone: GPIO Programming on ARM Embedded Linux" gpio_omap_mux_setup("eCAP0_in_PWM0", "07"); //gpio0_7 P9 header pin# 42 this->GREEN_LED_PIN = 7; //gpio number (0x32)+7 = 7 state of the class for sharing gpio_export(this->GREEN_LED_PIN); gpio_set_dir(this->GREEN_LED_PIN, OUTPUT_PIN); // Set up the Accelerometer this->accelerometer = new BMA180Accelerometer(3, 0x40); this->accelerometer->setBandwidth(BW_150HZ); this->accelerometer->setRange(PLUSMINUS_1_G); autoLED(false); connect(&this->dataTimer, SIGNAL(timeout()), this, SLOT(newAccelerometerDataSlot())); this->dataTimer.start(100); } // My manually created Slot void MainWindow::newAccelerometerDataSlot() { accelerometer->readFullSensorState(); double p = accelerometer->getPitch(); double r = accelerometer->getRoll(); ui->pitchSlider->setValue((int)p); ui->rollSlider->setValue((int)-r); QString pitchString = "", rollString = ""; pitchString.append(QString("%1").arg((int)p)); rollString.append(QString("%1").arg((int)-r)); ui->pitchNumber->display(pitchString); ui->rollNumber->display(rollString); int dialValue = ui->lightLevelDial->value(); if(this->autoLEDState){ if(((int)p)>=dialValue || ((int)-r)>=dialValue){ ::gpio_set_value(this->GREEN_LED_PIN, HIGH); } else{ ::gpio_set_value(this->GREEN_LED_PIN, LOW); } } } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_ledOnButton_clicked() { ::gpio_set_value(this->GREEN_LED_PIN, HIGH); autoLED(false); } void MainWindow::on_ledOffButton_clicked() { ::gpio_set_value(this->GREEN_LED_PIN, LOW); autoLED(false); } void MainWindow::on_lightLevelDial_valueChanged(int value) { QString temp = ""; temp.append(QString("%1").arg(value)); ui->lightLevelEdit->clear(); ui->lightLevelEdit->insert(temp); } void MainWindow::on_ledAutoButton_clicked() { autoLED(true); } void MainWindow::autoLED(bool state){ if(state){ this->autoLEDState = true; ui->statusBar->showMessage("Auto LED Enabled"); } else{ this->autoLEDState = false; ui->statusBar->showMessage("Auto LED Disabled"); } } |