Skip to content

Commit fdda2c7

Browse files
committed
adding files
0 parents  commit fdda2c7

16 files changed

+1519
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pro.user
2+
*.qmlc

README.md

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# QML OLED Renderer
2+
3+
Renders a QML application to a **SSD1309 OLED display**.
4+
5+
![OLED Display](./doc/OLED-qml.jpg)
6+
7+
```qml
8+
import QtQuick 2.6
9+
10+
Item {
11+
id: root
12+
visible: true
13+
width: 128
14+
height: 64
15+
16+
Rectangle {
17+
id: indicator
18+
anchors.bottom: parent.bottom
19+
anchors.bottomMargin: 5
20+
x: 5
21+
width: 15
22+
height: width
23+
radius: width / 2
24+
color: "black"
25+
}
26+
27+
Text {
28+
anchors.centerIn: parent
29+
text: "Hello World!"
30+
}
31+
}
32+
```
33+
34+
Tested on the [CHIP single board computer](https://getchip.com/) conected to TWI2.
35+
36+
![CHIP Setup](./doc/CHIP-SSD1309.jpg)
37+
38+
## Install
39+
40+
Requires Qt Version 5.4 or higher. For the Debian package install this means that you need at least the packages from Debian Stretch.
41+
42+
```bash
43+
sudo apt install qtdeclarative5-dev qt5-default qtchooser qtbase5-dev qml-module-qtquick2
44+
```
45+
46+
Then you can install the `qml-oled-renderer` with:
47+
```bash
48+
qmake
49+
make
50+
sudo make install
51+
```
52+
53+
## Usage
54+
55+
```
56+
sage: qml-oled-renderer [options] source
57+
Renders QML applications to a SSD1306 OLED display
58+
59+
Options:
60+
-h, --help Displays this help.
61+
-w, --width <weight> OLED screen width
62+
-b, --bus <bus> I2C bus to which the OLED is connected
63+
-a, --address <address> I2C address of the OLED screen
64+
-f, --fps <fps> Number of frames to render per second
65+
66+
Arguments:
67+
source QML source file`
68+
```
69+
70+
The OLED renderer does not work without any display device. You can easily create visual framebuffer device using `XVfb`:
71+
72+
```bash
73+
sudo apt-get install xvfb
74+
```
75+
76+
And the start the application as follows:
77+
```bash
78+
Xvfb -shmem -screen 0 128x64x16 &
79+
DISPLAY=:0 qml-oled-renderer main.qml
80+
```

animationdriver.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "animationdriver.h"
2+
3+
AnimationDriver::AnimationDriver(int msPerStep)
4+
: m_step(msPerStep)
5+
, m_elapsed(0)
6+
{
7+
8+
}
9+
10+
void AnimationDriver::advance()
11+
{
12+
m_elapsed += m_step;
13+
advanceAnimation();
14+
}
15+
16+
qint64 AnimationDriver::elapsed() const
17+
{
18+
return m_elapsed;
19+
}
20+

animationdriver.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef ANIMATIONDRIVER_H
2+
#define ANIMATIONDRIVER_H
3+
4+
#include <QtCore/QAnimationDriver>
5+
6+
class AnimationDriver : public QAnimationDriver
7+
{
8+
public:
9+
AnimationDriver(int msPerStep);
10+
11+
void advance() override;
12+
qint64 elapsed() const override;
13+
14+
private:
15+
int m_step;
16+
qint64 m_elapsed;
17+
18+
};
19+
20+
#endif // ANIMATIONDRIVER_H

doc/CHIP-SSD1309.jpg

317 KB
Loading

doc/OLED-qml.jpg

201 KB
Loading

main.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <QGuiApplication>
2+
#include <QCommandLineParser>
3+
#include <QStringList>
4+
#include "oledrenderer.h"
5+
#include "ssd1306driver.h"
6+
7+
int main(int argc, char *argv[])
8+
{
9+
QGuiApplication app(argc, argv);
10+
qApp->setApplicationName("QML OLED Renderer");
11+
12+
QCommandLineParser parser;
13+
parser.setApplicationDescription("Renders QML applications to a SSD1306 OLED display");
14+
parser.addHelpOption();
15+
parser.addPositionalArgument("source", "QML source file");
16+
parser.addOptions({
17+
{{"w", "width"}, "OLED screen width", "weight"},
18+
{{"h", "height"}, "OLED screen height", "height"},
19+
{{"b", "bus"}, "I2C bus to which the OLED is connected", "bus"},
20+
{{"a", "address"}, "I2C address of the OLED screen", "address"},
21+
{{"f", "fps"}, "Number of frames to render per second", "fps"}
22+
});
23+
24+
parser.process(app);
25+
26+
const QStringList args = parser.positionalArguments();
27+
if (args.length() < 1) {
28+
qCritical() << "please specify a source file";
29+
return -1;
30+
}
31+
QString sourceFile = args.first();
32+
33+
int width = parser.isSet("w") ? parser.value("w").toInt() : 128;
34+
int height = parser.isSet("h") ? parser.value("h").toInt() : 64;
35+
int bus = parser.isSet("b") ? parser.value("b").toInt() : 2;
36+
int address = parser.isSet("a") ? parser.value("a").toInt() : 0x3c;
37+
int fps = parser.isSet("f") ? parser.value("f").toInt() : 10;
38+
39+
Ssd1306Driver driver;
40+
if (!driver.openDevice(QSize(width, height), bus, address)) {
41+
qCritical() << "cannot open OLED display";
42+
return -1;
43+
}
44+
QObject::connect(qApp, &QGuiApplication::aboutToQuit, &driver, &Ssd1306Driver::clearScreen);
45+
46+
OledRenderer renderer;
47+
QObject::connect(&renderer, &OledRenderer::imageRendered, [&driver](const QImage &image) {
48+
const auto mono = image.convertToFormat(QImage::Format_Mono, Qt::MonoOnly | Qt::ThresholdDither);
49+
driver.writeImage(mono);
50+
});
51+
renderer.loadQmlFile(sourceFile, QSize(width, height), 1.0, fps);
52+
53+
return app.exec();
54+
}

main.qml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import QtQuick 2.6
2+
3+
Item {
4+
id: root
5+
visible: true
6+
width: 128
7+
height: 64
8+
9+
Rectangle {
10+
property bool isRight: false
11+
12+
id: indicator
13+
anchors.bottom: parent.bottom
14+
anchors.bottomMargin: 5
15+
x: (isRight ? 5 : (root.width - width) - 5)
16+
width: 15
17+
height: width
18+
radius: width / 2
19+
color: "black"
20+
21+
Behavior on x {
22+
PropertyAnimation {
23+
duration: 500
24+
}
25+
}
26+
27+
Timer {
28+
id: moveTimer
29+
running: true
30+
repeat: true
31+
interval: 500
32+
onTriggered: indicator.isRight = !indicator.isRight
33+
}
34+
}
35+
36+
Text {
37+
anchors.centerIn: parent
38+
text: "Hello World!"
39+
}
40+
}

0 commit comments

Comments
 (0)