├── .gitignore ├── FriendlyARM6410 ├── FriendlyARM6410.pro ├── buttons.cpp ├── buttons.h ├── convert.cpp ├── convert.h ├── images │ └── bg.jpg ├── lcd.h ├── leds.cpp ├── leds.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── pwm.cpp ├── pwm.h ├── remotecamera.cpp ├── remotecamera.h ├── res.qrc ├── speakthread.cpp ├── speakthread.h ├── themes │ └── default.qss ├── vncserver.cpp ├── vncserver.h ├── weather.cpp └── weather.h └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /FriendlyARM6410/FriendlyARM6410.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-09-25T15:31:38 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui network 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = FriendlyARM6410 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | mainwindow.cpp \ 17 | leds.cpp \ 18 | weather.cpp \ 19 | speakthread.cpp \ 20 | buttons.cpp \ 21 | pwm.cpp \ 22 | vncserver.cpp \ 23 | remotecamera.cpp \ 24 | convert.cpp 25 | 26 | HEADERS += mainwindow.h \ 27 | leds.h \ 28 | weather.h \ 29 | speakthread.h \ 30 | buttons.h \ 31 | pwm.h \ 32 | vncserver.h \ 33 | convert.h \ 34 | lcd.h \ 35 | remotecamera.h 36 | 37 | FORMS += mainwindow.ui 38 | 39 | RESOURCES += \ 40 | res.qrc 41 | 42 | QMAKE_CXXFLAGS += -Wno-psabi -Wno-write-strings 43 | 44 | #desktop 45 | linux-g++ { 46 | message(Linux) 47 | DEFINES += DESKTOP 48 | LIBS += -lvncserver 49 | } 50 | 51 | #embeded 52 | linux-arm-g++ { 53 | message(arm-linux) 54 | DEFINES += ARM_LINUX 55 | INCLUDEPATH += /opt/FriendlyARM/xcorpio/libvncserver-0.9.10/_install/include /opt/FriendlyARM/xcorpio/libwebsockets/build_arm/lib/Headers 56 | LIBS += -L/opt/FriendlyARM/xcorpio/libvncserver-0.9.10/_install/lib -lvncserver -lturbojpeg -ljpeg \ 57 | -lcrypt -lcrypto -lssl -lresolv -L/opt/FriendlyARM/xcorpio/libwebsockets/build_arm/lib -lwebsockets 58 | } 59 | -------------------------------------------------------------------------------- /FriendlyARM6410/buttons.cpp: -------------------------------------------------------------------------------- 1 | #include "buttons.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | Buttons::Buttons(QObject *parent) : 12 | QObject(parent) 13 | { 14 | m_fd = ::open("/dev/buttons",O_RDONLY | O_NONBLOCK); 15 | if(m_fd < 0){ 16 | qDebug()<<"open /dev/buttons failed!"; 17 | return; 18 | } 19 | notifier = new QSocketNotifier(m_fd,QSocketNotifier::Read,parent); 20 | connect(notifier,SIGNAL(activated(int)),this,SLOT(buttonClikedTest(int))); 21 | qDebug()<<"notifier: "<isEnabled(); 22 | } 23 | 24 | Buttons::~Buttons() 25 | { 26 | delete notifier; 27 | if(m_fd > 0){ 28 | ::close(m_fd); 29 | } 30 | } 31 | 32 | void Buttons::buttonClikedTest(int fd) 33 | { 34 | //qDebug()<<"some can be read!"; 35 | char buffer[8]; 36 | memset(buffer,0,sizeof(buffer)); 37 | ::read(fd,buffer,sizeof(buffer)); 38 | for(uint i=0;ion[i] = (buffer[i] & 0x01); 40 | emit buttonsClicked(this->on); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /FriendlyARM6410/buttons.h: -------------------------------------------------------------------------------- 1 | #ifndef BUTTONS_H 2 | #define BUTTONS_H 3 | 4 | #include 5 | #include 6 | 7 | class Buttons : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit Buttons(QObject *parent = 0); 12 | ~Buttons(); 13 | 14 | signals: 15 | void buttonsClicked(bool* on); 16 | 17 | public slots: 18 | void buttonClikedTest(int fd); 19 | private: 20 | int m_fd; 21 | QSocketNotifier* notifier; 22 | bool on[8]; //存放当前按键状态 23 | 24 | }; 25 | 26 | #endif // BUTTONS_H 27 | -------------------------------------------------------------------------------- /FriendlyARM6410/convert.cpp: -------------------------------------------------------------------------------- 1 | #include "convert.h" 2 | #include 3 | 4 | QT_BEGIN_NAMESPACE 5 | 6 | void qt_convert_NV21_to_ARGB32(const uchar *yuv, quint32 *rgb, int width, int height) 7 | { 8 | const int frameSize = width * height; 9 | 10 | int a = 0; 11 | for (int i = 0, ci = 0; i < height; ++i, ci += 1) { 12 | for (int j = 0, cj = 0; j < width; ++j, cj += 1) { 13 | int y = (0xff & ((int) yuv[ci * width + cj])); 14 | int v = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 0])); 15 | int u = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 1])); 16 | y = y < 16 ? 16 : y; 17 | 18 | int r = (int) (1.164f * (y - 16) + 1.596f * (v - 128)); 19 | int g = (int) (1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128)); 20 | int b = (int) (1.164f * (y - 16) + 2.018f * (u - 128)); 21 | 22 | r = qBound(0, r, 255); 23 | g = qBound(0, g, 255); 24 | b = qBound(0, b, 255); 25 | 26 | rgb[a++] = 0xff000000 | (r << 16) | (g << 8) | b; 27 | } 28 | } 29 | } 30 | 31 | QT_END_NAMESPACE 32 | 33 | 34 | -------------------------------------------------------------------------------- /FriendlyARM6410/convert.h: -------------------------------------------------------------------------------- 1 | #ifndef CONVERT_H 2 | #define CONVERT_H 3 | #include 4 | #include 5 | 6 | QT_BEGIN_NAMESPACE 7 | 8 | void qt_convert_NV21_to_ARGB32(const uchar *yuv, quint32 *rgb, int width, int height); 9 | 10 | QT_END_NAMESPACE 11 | #endif // CONVERT_H 12 | -------------------------------------------------------------------------------- /FriendlyARM6410/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcorpio/FriendlyARM6410/faaccbdc40f5b17e2bd652c63d35ef2901322403/FriendlyARM6410/images/bg.jpg -------------------------------------------------------------------------------- /FriendlyARM6410/lcd.h: -------------------------------------------------------------------------------- 1 | #ifndef __SAMSUNG_SYSLSI_APDEV_S3C_LCD_H__ 2 | #define __SAMSUNG_SYSLSI_APDEV_S3C_LCD_H__ 3 | 4 | typedef struct { 5 | int Bpp; 6 | int LeftTop_x; 7 | int LeftTop_y; 8 | int Width; 9 | int Height; 10 | } s3c_win_info_t; 11 | 12 | typedef struct { 13 | int width; 14 | int height; 15 | int bpp; 16 | int offset; 17 | int v_width; 18 | int v_height; 19 | }vs_info_t; 20 | 21 | struct s3c_fb_dma_info 22 | { 23 | unsigned int map_dma_f1; 24 | unsigned int map_dma_f2; 25 | }; 26 | 27 | #define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t) 28 | 29 | #define SET_VS_START _IO('F', 103) 30 | #define SET_VS_STOP _IO('F', 104) 31 | #define SET_VS_INFO _IOW('F', 105, vs_info_t) 32 | #define SET_VS_MOVE _IOW('F', 106, u_int) 33 | 34 | #define SET_OSD_INFO _IOW('F', 209, s3c_win_info_t) 35 | #define SET_OSD_START _IO('F', 201) 36 | #define SET_OSD_STOP _IO('F', 202) 37 | 38 | #define GET_FB_INFO _IOR('F', 307, struct s3c_fb_dma_info) 39 | #define SET_FB_CHANGE_REQ _IOW('F', 308, int) 40 | #define SET_VSYNC_INT _IOW('F', 309, int) 41 | 42 | #define FB_DEV_NAME "/dev/fb0" 43 | #define FB_DEV_NAME1 "/dev/fb1" 44 | #define FB_DEV_NAME2 "/dev/fb2" 45 | #define FB_DEV_NAME3 "/dev/fb3" 46 | #define FB_DEV_NAME4 "/dev/fb4" 47 | 48 | #define BytesPerPixel 4 49 | #define BitsPerPixel 24 50 | 51 | #endif //__SAMSUNG_SYSLSI_APDEV_S3C_LCD_H__ 52 | -------------------------------------------------------------------------------- /FriendlyARM6410/leds.cpp: -------------------------------------------------------------------------------- 1 | #include "leds.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | Leds::Leds(QObject *parent) : 10 | QObject(parent) 11 | { 12 | } 13 | 14 | Leds::~Leds() 15 | { 16 | ::close(m_fd); 17 | } 18 | 19 | int Leds::m_fd = ::open("/dev/leds",O_RDONLY); 20 | 21 | void Leds::setLedState(int ledID, int ledState) 22 | { 23 | ioctl(m_fd,ledState,ledID); 24 | } 25 | 26 | void Leds::turnAllOn() 27 | { 28 | ioctl(m_fd,1,0); 29 | ioctl(m_fd,1,1); 30 | ioctl(m_fd,1,2); 31 | ioctl(m_fd,1,3); 32 | } 33 | 34 | void Leds::turnAllOff() 35 | { 36 | ioctl(m_fd,0,0); 37 | ioctl(m_fd,0,1); 38 | ioctl(m_fd,0,2); 39 | ioctl(m_fd,0,3); 40 | } 41 | -------------------------------------------------------------------------------- /FriendlyARM6410/leds.h: -------------------------------------------------------------------------------- 1 | #ifndef LEDS_H 2 | #define LEDS_H 3 | 4 | #include 5 | 6 | 7 | class Leds : public QObject 8 | { 9 | 10 | public: 11 | explicit Leds(QObject *parent = 0); 12 | ~Leds(); 13 | static void setLedState(int ledID, int ledState); //ledID:0-3 ledState:1 on,0 off 14 | 15 | private: 16 | static int m_fd; 17 | 18 | signals: 19 | 20 | 21 | public slots: 22 | static void turnAllOn(); 23 | static void turnAllOff(); 24 | }; 25 | 26 | #endif // LEDS_H 27 | -------------------------------------------------------------------------------- /FriendlyARM6410/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w(argc,argv); 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /FriendlyARM6410/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include "leds.h" 4 | #include "buttons.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#include //下面两个和 同时存在会报错 ? 11 | //#include 12 | #include 13 | 14 | 15 | MainWindow::MainWindow(QWidget *parent) : 16 | QMainWindow(parent), 17 | ui(new Ui::MainWindow) 18 | { 19 | 20 | } 21 | 22 | MainWindow::MainWindow(int argc, char** argv, QWidget *parent) : 23 | QMainWindow(parent), 24 | ui(new Ui::MainWindow) 25 | { 26 | this->argc = argc; //maybe used 27 | this->argv = argv; 28 | ui->setupUi(this); 29 | 30 | wday[0]="Sun";wday[1]="Mon";wday[2]="Tue"; 31 | wday[3]="Wed";wday[4]="Thu";wday[5]="Fri";wday[6]="Sat"; 32 | 33 | weather = new Weather(this); 34 | connect(weather,SIGNAL(dataUpdate()),this,SLOT(weatherUpdate())); 35 | 36 | //定时器,每隔一段时间更新天气信息 37 | QTimer* updateWeatherTimer = new QTimer(this); 38 | connect(updateWeatherTimer,SIGNAL(timeout()),this,SLOT(getCityWeather())); 39 | updateWeatherTimer->start(1200000); 40 | this->getCityWeather(); 41 | 42 | //更新时间 43 | QTimer* timeTimer = new QTimer(this); 44 | connect(timeTimer,SIGNAL(timeout()),this,SLOT(updateTime())); 45 | timeTimer->start(1000); 46 | 47 | //界面显示 48 | this->setWindowState(Qt::WindowFullScreen); 49 | this->setWindowTitle("xcorpio"); 50 | ui->comboBox->insertItems(0,QStyleFactory::keys()); 51 | ui->comboBox->setCurrentIndex(ui->comboBox->count()-1); //设置为最后一个样式 52 | 53 | //按键 54 | Buttons* button = new Buttons(this); 55 | connect(button,SIGNAL(buttonsClicked(bool*)),this,SLOT(dealButtons(bool*))); 56 | 57 | //蜂鸣器 58 | pwm = new PWM(this); 59 | 60 | //VNCServer 61 | vncServer = new VNCServer(this->argc,this->argv,this); 62 | 63 | //语音识别 64 | srProcess = new QProcess(this); 65 | srProcess->setReadChannel(QProcess::StandardOutput); 66 | connect(srProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(parseSpeech())); 67 | connect(srProcess,SIGNAL(error(QProcess::ProcessError)),this,SLOT(processError(QProcess::ProcessError))); 68 | 69 | //远程摄像头 70 | rCamera = new RemoteCamera(this); 71 | } 72 | 73 | MainWindow::~MainWindow() 74 | { 75 | delete ui; 76 | if(vncServer){ 77 | rfbShutdownServer(vncServer->server,true); 78 | vncServer->quit(); 79 | vncServer->wait(1000); 80 | } 81 | if(srProcess->state() != QProcess::NotRunning){ 82 | srProcess->close(); 83 | srProcess->waitForFinished(1000); 84 | } 85 | rCamera->closeCamera(); 86 | rCamera->wait(1000); 87 | } 88 | 89 | void MainWindow::on_checkBox_led1_stateChanged(int arg1) 90 | { 91 | if(arg1 == Qt::Unchecked){ 92 | Leds::setLedState(0,0); 93 | }else if(arg1 == Qt::Checked){ 94 | Leds::setLedState(0,1); 95 | } 96 | } 97 | 98 | void MainWindow::on_checkBox_led2_stateChanged(int arg1) 99 | { 100 | if(arg1 == Qt::Unchecked){ 101 | Leds::setLedState(1,0); 102 | }else if(arg1 == Qt::Checked){ 103 | Leds::setLedState(1,1); 104 | } 105 | } 106 | 107 | void MainWindow::on_checkBox_led3_stateChanged(int arg1) 108 | { 109 | if(arg1 == Qt::Unchecked){ 110 | Leds::setLedState(2,0); 111 | }else if(arg1 == Qt::Checked){ 112 | Leds::setLedState(2,1); 113 | } 114 | } 115 | 116 | void MainWindow::on_checkBox_led4_stateChanged(int arg1) 117 | { 118 | if(arg1 == Qt::Unchecked){ 119 | Leds::setLedState(3,0); 120 | }else if(arg1 == Qt::Checked){ 121 | Leds::setLedState(3,1); 122 | } 123 | } 124 | 125 | void MainWindow::on_pushButton_clicked() 126 | { 127 | ::system("kill -s STOP `pidof led-player`"); 128 | } 129 | 130 | void MainWindow::on_pushButton_3_clicked() 131 | { 132 | qDebug()<name(); 133 | ::system("speak -vzh '今天是晴天!'"); 134 | } 135 | 136 | void MainWindow::on_pushButton_4_clicked() 137 | { 138 | weather->speakWeather(); 139 | } 140 | 141 | void MainWindow::on_pushButton_5_clicked() 142 | { 143 | qDebug()<name(); 144 | qDebug()<tm_hour; 155 | //int hour = QTime::currentTime().hour(); 156 | QString day; 157 | if(hour < 18){ 158 | day = "day"; 159 | }else{ 160 | day = "night"; 161 | } 162 | QString weatherIconFile = "images/icon/"+day+"/"+weather->citys.value(QString::fromUtf8("西安市")).value("state1").toString()+".png"; 163 | qDebug()<labelWeatherIcon->setPixmap(QPixmap(weatherIconFile)); 165 | ui->label_humidity->setText(weather->citys.value(QString::fromUtf8("西安市")).value("humidity").toString()); 166 | ui->label_statedetail->setText(weather->citys.value(QString::fromUtf8("西安市")).value("stateDetailed").toString()); 167 | int temlow = weather->citys.value(QString::fromUtf8("西安市")).value("tem1").toString().toInt(); 168 | int temHigh = weather->citys.value(QString::fromUtf8("西安市")).value("tem2").toString().toInt(); 169 | if(temlow > temHigh){ 170 | int tmp = temHigh; 171 | temHigh = temlow; 172 | temHigh = tmp; 173 | } 174 | ui->label_tmphigh->setText(QString::number(temHigh)); 175 | ui->label_temlow->setText(QString::number(temlow)); 176 | ui->label_time->setText(weather->citys.value(QString::fromUtf8("西安市")).value("time").toString()); 177 | ui->label_tmpnow->setText(weather->citys.value(QString::fromUtf8("西安市")).value("temNow").toString()); 178 | ui->label_windstate->setText(weather->citys.value(QString::fromUtf8("西安市")).value("windState").toString()); 179 | } 180 | 181 | void MainWindow::getCityWeather() 182 | { 183 | weather->getCityWeather("xian"); 184 | } 185 | 186 | void MainWindow::updateTime() 187 | { 188 | time_t timep; 189 | struct tm *p; 190 | time(&timep); 191 | p = localtime(&timep); 192 | ui->label_curtime->setText(QString("%1:%2:%3").arg(p->tm_hour).arg(p->tm_min).arg(p->tm_sec)); 193 | ui->label_date->setText(QString("%1-%2-%3 %4").arg(p->tm_year+1900).arg(p->tm_mon+1).arg(p->tm_mday).arg(wday[p->tm_wday])); 194 | //ui->label_curtime->setText(QTime::currentTime().toString()); 195 | //ui->label_date->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd")); 196 | } 197 | 198 | void MainWindow::dealButtons(bool *on) 199 | { 200 | ui->checkBox_1->setChecked(on[0]); 201 | ui->checkBox_2->setChecked(on[1]); 202 | ui->checkBox_3->setChecked(on[2]); 203 | ui->checkBox_4->setChecked(on[3]); 204 | ui->checkBox_5->setChecked(on[4]); 205 | ui->checkBox_6->setChecked(on[5]); 206 | ui->checkBox_7->setChecked(on[6]); 207 | ui->checkBox_8->setChecked(on[7]); 208 | if(on[0]){//按键1按下 209 | 210 | } 211 | if(on[1]){//按键2按下 212 | 213 | } 214 | if(on[2]){//按键3按下 215 | 216 | } 217 | if(on[3]){//按键4按下 218 | 219 | } 220 | if(on[4]){//按键5按下 221 | 222 | } 223 | if(on[5]){//按键6按下 224 | 225 | } 226 | if(on[6]){//按键7按下 227 | 228 | } 229 | if(on[7]){//按键8按下 230 | 231 | } 232 | } 233 | 234 | void MainWindow::parseSpeech() 235 | { 236 | char buf[1024]; 237 | int ret; 238 | while((ret = srProcess->readLine(buf, sizeof(buf))) != -1 && ret != 0) { 239 | QString tmp(buf); 240 | if(tmp.startsWith("sentence1: ")){ 241 | tmp = tmp.section(" ",1,1).section(" ",0,0); 242 | qDebug()<<""<speakWeather(); 252 | }else if(QString::compare(tmp,"PLAY MUSIC",Qt::CaseInsensitive) == 0){ 253 | qDebug()<<"command : "<<"PLAY MUSIC"; 254 | 255 | } 256 | } 257 | } 258 | } 259 | 260 | void MainWindow::processError(QProcess::ProcessError error) 261 | { 262 | switch (error) { 263 | case QProcess::FailedToStart: 264 | qDebug()<<"QProcess::FailedToStart"; 265 | break; 266 | case QProcess::Crashed: 267 | qDebug()<<"QProcess::Crashed"; 268 | break; 269 | case QProcess::Timedout: 270 | qDebug()<<"QProcess::Timedout"; 271 | break; 272 | case QProcess::WriteError: 273 | qDebug()<<"QProcess::WriteError"; 274 | break; 275 | case QProcess::ReadError: 276 | qDebug()<<"QProcess::ReadError"; 277 | break; 278 | default: 279 | qDebug()<<"QProcess::UnknownError"; 280 | break; 281 | } 282 | } 283 | 284 | void MainWindow::on_pushButton_6_clicked() 285 | { 286 | exit(0); 287 | } 288 | 289 | void MainWindow::on_comboBox_currentIndexChanged(const QString &style) 290 | { 291 | qApp->setStyle(QStyleFactory::create(style)); 292 | } 293 | 294 | void MainWindow::on_pushButton_pwm_clicked() 295 | { 296 | if(pwm == NULL){ 297 | return; 298 | } 299 | if(ui->pushButton_pwm->isChecked()){ 300 | ui->pushButton_pwm->setText(QString::fromUtf8("关闭")); 301 | pwm->setFreq(ui->spinBox->value()); 302 | }else{ 303 | ui->pushButton_pwm->setText(QString::fromUtf8("打开")); 304 | pwm->stopPWM(); 305 | } 306 | } 307 | 308 | void MainWindow::on_spinBox_valueChanged(int arg1) 309 | { 310 | if(pwm == NULL) return; 311 | if(ui->pushButton_pwm->isChecked()){ 312 | pwm->setFreq(arg1); 313 | } 314 | } 315 | 316 | void MainWindow::on_horizontalSlider_valueChanged(int value) 317 | { 318 | //改变屏幕亮度 319 | ::system(QString("echo %1 > /dev/backlight-1wire").arg(value).toLatin1()); 320 | } 321 | 322 | void MainWindow::on_pushButton_7_clicked() 323 | { 324 | if(!vncServer->isRunning()){ 325 | vncServer->start(); 326 | } 327 | } 328 | 329 | void MainWindow::on_pushButton_8_clicked() 330 | { 331 | this->vncServer->stopServer(); 332 | } 333 | 334 | void MainWindow::on_pushButton_9_clicked() 335 | { 336 | if(srProcess->state() == QProcess::NotRunning){ 337 | QString program = "julius"; 338 | QStringList arguments; 339 | arguments<<"-C"<<"friend.jconf"; 340 | srProcess->start(program,arguments); 341 | } 342 | } 343 | 344 | void MainWindow::on_pushButton_10_clicked() 345 | { 346 | if(srProcess->state() != QProcess::NotRunning){ 347 | srProcess->close(); 348 | } 349 | } 350 | 351 | void MainWindow::on_pushButton_11_clicked() 352 | { 353 | rCamera->openCamera(); 354 | } 355 | 356 | void MainWindow::on_pushButton_12_clicked() 357 | { 358 | rCamera->closeCamera(); 359 | } 360 | 361 | void MainWindow::on_tabWidget_currentChanged(int index) 362 | { 363 | if(index != 3){ 364 | rCamera->stopPreview(); 365 | }else if(index == 3 && rCamera->isRunning()){ 366 | rCamera->restorePreview(); 367 | } 368 | } 369 | -------------------------------------------------------------------------------- /FriendlyARM6410/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include "weather.h" 7 | #include "pwm.h" 8 | #include "vncserver.h" 9 | #include "remotecamera.h" 10 | 11 | 12 | namespace Ui { 13 | class MainWindow; 14 | } 15 | 16 | class MainWindow : public QMainWindow 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit MainWindow(QWidget *parent = 0); 22 | MainWindow(int argc,char** argv,QWidget *parent = 0); 23 | ~MainWindow(); 24 | 25 | private slots: 26 | void on_checkBox_led1_stateChanged(int arg1); 27 | 28 | void on_checkBox_led2_stateChanged(int arg1); 29 | 30 | void on_checkBox_led3_stateChanged(int arg1); 31 | 32 | void on_checkBox_led4_stateChanged(int arg1); 33 | 34 | void on_pushButton_clicked(); 35 | 36 | void on_pushButton_3_clicked(); 37 | 38 | void on_pushButton_4_clicked(); 39 | 40 | void on_pushButton_5_clicked(); 41 | 42 | void on_pushButton_6_clicked(); 43 | 44 | void on_comboBox_currentIndexChanged(const QString &style); 45 | 46 | void on_pushButton_pwm_clicked(); 47 | 48 | void on_spinBox_valueChanged(int arg1); 49 | 50 | 51 | void on_horizontalSlider_valueChanged(int value); 52 | 53 | void on_pushButton_7_clicked(); 54 | 55 | void on_pushButton_8_clicked(); 56 | 57 | void on_pushButton_9_clicked(); 58 | 59 | void on_pushButton_10_clicked(); 60 | 61 | void on_pushButton_11_clicked(); 62 | 63 | void on_pushButton_12_clicked(); 64 | 65 | void on_tabWidget_currentChanged(int index); 66 | 67 | public slots: 68 | void weatherUpdate(); 69 | void getCityWeather(); 70 | void updateTime(); 71 | void dealButtons(bool* on); 72 | void parseSpeech(); 73 | void processError(QProcess::ProcessError error); 74 | 75 | private: 76 | Ui::MainWindow *ui; 77 | int argc; 78 | char** argv; 79 | QString wday[7]; 80 | Weather * weather; 81 | PWM* pwm; 82 | VNCServer* vncServer; 83 | QProcess* srProcess; 84 | RemoteCamera* rCamera; 85 | }; 86 | 87 | #endif // MAINWINDOW_H 88 | -------------------------------------------------------------------------------- /FriendlyARM6410/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 480 10 | 272 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | false 18 | 19 | 20 | 21 | QTabWidget::pane { 22 | border-top: 2px solid #C2C7CB; 23 | position: absolute; 24 | top: -0.7em; 25 | /* border-image: url(images/bg.jpg);*/ 26 | border-image: url(:/images/bg.jpg); 27 | } 28 | 29 | QTabWidget::tab-bar { 30 | alignment: left; 31 | } 32 | 33 | QTabBar::tab { 34 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, 35 | stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, 36 | stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); 37 | border: 2px solid #C4C4C3; 38 | border-bottom-color: #C2C7CB; 39 | border-top-left-radius: 4px; 40 | border-top-right-radius: 4px; 41 | min-width: 8ex; 42 | } 43 | 44 | QTabBar::tab:selected, QTabBar::tab:hover { 45 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, 46 | stop: 0 #fafafa, stop: 0.4 #f4f4f4, 47 | stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); 48 | } 49 | 50 | QTabBar::tab:selected { 51 | border-color: #9B9B9B; 52 | border-bottom-color: #C2C7CB; 53 | } 54 | 55 | QPushButton{ 56 | background-color: rgba(100,225,100,100); 57 | border-style: outset; 58 | border-width: 1px; 59 | border-radius: 5px; 60 | border-color: rgba(255,255,255,30); 61 | color: rgba(0,0,0,100); 62 | padding: 2px; 63 | } 64 | 65 | QPushButton:hover{ 66 | background-color: rgba(100,255,100,150); 67 | border-color: rgba(255,255,255,200); 68 | color: (0,0,0,200); 69 | } 70 | 71 | QPushButton:pressed{ 72 | background-color: rgba(100,255,100,200); 73 | border-color: rgba(255,255,255,30); 74 | border-style: inset; 75 | color: rgba(0,0,0,100); 76 | } 77 | 78 | 79 | */ 80 | 81 | 82 | 83 | 84 | 85 | 5 86 | 87 | 88 | 1 89 | 90 | 91 | 3 92 | 93 | 94 | 1 95 | 96 | 97 | 1 98 | 99 | 100 | 101 | 102 | Qt::NoFocus 103 | 104 | 105 | 106 | 107 | 108 | QTabWidget::North 109 | 110 | 111 | QTabWidget::Rounded 112 | 113 | 114 | 3 115 | 116 | 117 | Qt::ElideNone 118 | 119 | 120 | true 121 | 122 | 123 | 124 | 125 | 126 | 127 | 天气 128 | 129 | 130 | 131 | 132 | 330 133 | 170 134 | 71 135 | 27 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 225 145 | 173 146 | 32 147 | 148 | 149 | 150 | 151 | 152 | 153 | 100 154 | 225 155 | 100 156 | 157 | 158 | 159 | 160 | 161 | 162 | 225 163 | 173 164 | 32 165 | 166 | 167 | 168 | 169 | 170 | 171 | 225 172 | 173 173 | 32 174 | 175 | 176 | 177 | 178 | 179 | 180 | 100 181 | 225 182 | 100 183 | 184 | 185 | 186 | 187 | 188 | 189 | 100 190 | 225 191 | 100 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 225 201 | 173 202 | 32 203 | 204 | 205 | 206 | 207 | 208 | 209 | 100 210 | 225 211 | 100 212 | 213 | 214 | 215 | 216 | 217 | 218 | 225 219 | 173 220 | 32 221 | 222 | 223 | 224 | 225 | 226 | 227 | 225 228 | 173 229 | 32 230 | 231 | 232 | 233 | 234 | 235 | 236 | 100 237 | 225 238 | 100 239 | 240 | 241 | 242 | 243 | 244 | 245 | 100 246 | 225 247 | 100 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 225 257 | 173 258 | 32 259 | 260 | 261 | 262 | 263 | 264 | 265 | 100 266 | 225 267 | 100 268 | 269 | 270 | 271 | 272 | 273 | 274 | 225 275 | 173 276 | 32 277 | 278 | 279 | 280 | 281 | 282 | 283 | 225 284 | 173 285 | 32 286 | 287 | 288 | 289 | 290 | 291 | 292 | 100 293 | 225 294 | 100 295 | 296 | 297 | 298 | 299 | 300 | 301 | 100 302 | 225 303 | 100 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | Qt::NoFocus 312 | 313 | 314 | color: rgb(225, 173, 32); 315 | 316 | 317 | 播报天气 318 | 319 | 320 | 321 | 322 | 323 | 10 324 | 90 325 | 131 326 | 121 327 | 328 | 329 | 330 | background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0)); 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 180 340 | 80 341 | 123 342 | 111 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 最低气温: 359 | 360 | 361 | 362 | 363 | 364 | 365 | 16 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 最高气温: 377 | 378 | 379 | 380 | 381 | 382 | 383 | 20 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 当前温度: 395 | 396 | 397 | 398 | 399 | 400 | 401 | color: rgb(189, 45, 45); 402 | 403 | 404 | 19 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 350 416 | 20 417 | 111 418 | 22 419 | 420 | 421 | 422 | 423 | 424 | 425 | color: rgba(204, 204, 204, 150); 426 | 427 | 428 | update: 429 | 430 | 431 | 432 | 433 | 434 | 435 | color: rgba(204, 204, 204, 150); 436 | 437 | 438 | 19:00 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 310 448 | 80 449 | 121 450 | 50 451 | 452 | 453 | 454 | 455 | 456 | 457 | 东南风小于三级 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 湿度: 467 | 468 | 469 | 470 | 471 | 472 | 473 | color: rgb(178, 57, 57); 474 | 475 | 476 | 64% 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 10 488 | 10 489 | 131 490 | 31 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 12 499 | 500 | 501 | 502 | color: rgb(57, 56, 221); 503 | 504 | 505 | 西安市 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 14 514 | 515 | 516 | 517 | color: rgb(215, 61, 61); 518 | 519 | 520 | 22:00:00 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 230 530 | 20 531 | 111 532 | 20 533 | 534 | 535 | 536 | color: rgba(204, 204, 204, 150); 537 | 538 | 539 | 2014-10-19 Sun 540 | 541 | 542 | 543 | 544 | 545 | 灯光 546 | 547 | 548 | 549 | 550 | 10 551 | 30 552 | 66 553 | 108 554 | 555 | 556 | 557 | 558 | 559 | 560 | true 561 | 562 | 563 | Qt::NoFocus 564 | 565 | 566 | Led1 567 | 568 | 569 | true 570 | 571 | 572 | 573 | 574 | 575 | 576 | Qt::NoFocus 577 | 578 | 579 | Led2 580 | 581 | 582 | 583 | 584 | 585 | 586 | Qt::NoFocus 587 | 588 | 589 | Led3 590 | 591 | 592 | 593 | 594 | 595 | 596 | Qt::NoFocus 597 | 598 | 599 | Led4 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 330 609 | 20 610 | 99 611 | 27 612 | 613 | 614 | 615 | SayHello 616 | 617 | 618 | 619 | 620 | 621 | 100 622 | 60 623 | 99 624 | 27 625 | 626 | 627 | 628 | 编码 629 | 630 | 631 | 632 | 633 | 634 | 200 635 | 60 636 | 231 637 | 27 638 | 639 | 640 | 641 | 642 | 643 | 644 | 100 645 | 90 646 | 99 647 | 27 648 | 649 | 650 | 651 | stop 652 | 653 | 654 | 655 | 656 | 657 | 200 658 | 90 659 | 241 660 | 27 661 | 662 | 663 | 664 | 665 | 666 | 667 | 220 668 | 20 669 | 99 670 | 27 671 | 672 | 673 | 674 | PushButton 675 | 676 | 677 | 678 | 679 | 680 | 20 681 | 170 682 | 421 683 | 26 684 | 685 | 686 | 687 | 688 | 689 | 690 | Switchs: 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | Qt::NoFocus 700 | 701 | 702 | 1 703 | 704 | 705 | 706 | 707 | 708 | 709 | Qt::NoFocus 710 | 711 | 712 | 2 713 | 714 | 715 | 716 | 717 | 718 | 719 | Qt::NoFocus 720 | 721 | 722 | 3 723 | 724 | 725 | 726 | 727 | 728 | 729 | Qt::NoFocus 730 | 731 | 732 | 4 733 | 734 | 735 | 736 | 737 | 738 | 739 | Qt::NoFocus 740 | 741 | 742 | 5 743 | 744 | 745 | 746 | 747 | 748 | 749 | Qt::NoFocus 750 | 751 | 752 | 6 753 | 754 | 755 | 756 | 757 | 758 | 759 | Qt::NoFocus 760 | 761 | 762 | 7 763 | 764 | 765 | 766 | 767 | 768 | 769 | Qt::NoFocus 770 | 771 | 772 | 8 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 命令 784 | 785 | 786 | 787 | 788 | 350 789 | 10 790 | 99 791 | 27 792 | 793 | 794 | 795 | Exit 796 | 797 | 798 | 799 | 800 | 801 | 10 802 | 20 803 | 171 804 | 29 805 | 806 | 807 | 808 | 809 | 810 | 811 | Style: 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 10 824 | 160 825 | 181 826 | 70 827 | 828 | 829 | 830 | 831 | 832 | 833 | 蜂鸣器 : 频率 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | Qt::NoFocus 843 | 844 | 845 | 打开 846 | 847 | 848 | true 849 | 850 | 851 | false 852 | 853 | 854 | 855 | 856 | 857 | 858 | 1 859 | 860 | 861 | 250000 862 | 863 | 864 | 1 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 210 876 | 180 877 | 231 878 | 31 879 | 880 | 881 | 882 | 883 | 884 | 885 | color: rgb(33, 238, 199); 886 | 887 | 888 | 屏幕亮度: 889 | 890 | 891 | 892 | 893 | 894 | 895 | 10 896 | 897 | 898 | 127 899 | 900 | 901 | 100 902 | 903 | 904 | Qt::Horizontal 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 210 914 | 30 915 | 99 916 | 27 917 | 918 | 919 | 920 | VNCServer 921 | 922 | 923 | 924 | 925 | 926 | 210 927 | 60 928 | 99 929 | 27 930 | 931 | 932 | 933 | StopVNC 934 | 935 | 936 | 937 | 938 | 939 | 340 940 | 60 941 | 99 942 | 27 943 | 944 | 945 | 946 | SRStart 947 | 948 | 949 | 950 | 951 | 952 | 340 953 | 100 954 | 99 955 | 27 956 | 957 | 958 | 959 | SRStop 960 | 961 | 962 | 963 | 964 | 965 | 远程摄像头 966 | 967 | 968 | 969 | 970 | 146 971 | 10 972 | 328 973 | 248 974 | 975 | 976 | 977 | QFrame::Box 978 | 979 | 980 | QFrame::Raised 981 | 982 | 983 | 2 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 10 993 | 40 994 | 98 995 | 71 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | OpenCamera 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | CloseCamera 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | -------------------------------------------------------------------------------- /FriendlyARM6410/pwm.cpp: -------------------------------------------------------------------------------- 1 | #include "pwm.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | PWM::PWM(QObject *parent) : 10 | QObject(parent) 11 | { 12 | m_fd = ::open("/dev/pwm",O_RDONLY); 13 | if(m_fd < 0){ 14 | qDebug()<<"open /dev/pwm failed!"; 15 | return; 16 | } 17 | } 18 | 19 | PWM::~PWM() 20 | { 21 | ::close(m_fd); 22 | } 23 | 24 | void PWM::setFreq(int freq) 25 | { 26 | ::ioctl(m_fd,1,freq); 27 | } 28 | 29 | void PWM::stopPWM() 30 | { 31 | ::ioctl(m_fd,0); 32 | } 33 | -------------------------------------------------------------------------------- /FriendlyARM6410/pwm.h: -------------------------------------------------------------------------------- 1 | #ifndef PWM_H 2 | #define PWM_H 3 | 4 | #include 5 | 6 | class PWM : public QObject 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit PWM(QObject *parent = 0); 11 | ~PWM(); 12 | 13 | signals: 14 | 15 | public slots: 16 | void setFreq(int freq); 17 | void stopPWM(); 18 | private: 19 | int m_fd; 20 | 21 | }; 22 | 23 | #endif // PWM_H 24 | -------------------------------------------------------------------------------- /FriendlyARM6410/remotecamera.cpp: -------------------------------------------------------------------------------- 1 | #include "remotecamera.h" 2 | #include "convert.h" 3 | #include "lcd.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | static int force_exit = 0; 22 | 23 | static int my_protocol_callback(struct libwebsocket_context* context, 24 | struct libwebsocket* wsi, 25 | enum libwebsocket_callback_reasons reason, 26 | void* user, void* in, size_t len) 27 | { 28 | switch(reason){ 29 | 30 | case LWS_CALLBACK_ESTABLISHED: 31 | qDebug()<<"New Connection."; 32 | break; 33 | case LWS_CALLBACK_SERVER_WRITEABLE: 34 | qDebug()<<"server wirteable."; 35 | break; 36 | case LWS_CALLBACK_RECEIVE: 37 | qDebug()<<"Got:"<<(char*)in; 38 | break; 39 | case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: 40 | qDebug()<<"filter protocol."; 41 | break; 42 | case LWS_CALLBACK_CLIENT_ESTABLISHED: 43 | qDebug()<<"Client has connected"; 44 | break; 45 | case LWS_CALLBACK_CLIENT_RECEIVE: 46 | //qDebug()<<"Client Rx("< 1.0){ 99 | fps = count; 100 | count = 0; 101 | memcpy((char*)&then,(char*)&now,sizeof(struct timeval)); 102 | } 103 | 104 | //================== 105 | 106 | int t = QTime::currentTime().msec(); 107 | QImage img = QImage(320,240,QImage::Format_ARGB32); 108 | qt_convert_NV21_to_ARGB32((uchar*)in,(quint32*)img.bits(),320,240); 109 | img = img.convertToFormat(QImage::Format_RGB16); 110 | for(int i=0;i<240;++i){ 111 | memcpy(fb_addr, img.bits(), 320*240*2); //写到fb2 112 | } 113 | t = QTime::currentTime().msec() - t; 114 | if(t<0) t+=1000; 115 | fprintf(stderr,"fb need time: %d ms fps: %03d\r", t, fps); //120ms 116 | } 117 | 118 | void RemoteCamera::openCamera() 119 | { 120 | if(!this->isRunning()){ 121 | m_fd2 = open(FB_DEV_NAME2, O_RDWR | O_NDELAY); 122 | if (m_fd2 >= 0) { 123 | s3c_win_info_t fb_info_to_driver; 124 | fb_info_to_driver.Bpp = 16; //BPP 125 | fb_info_to_driver.LeftTop_x = 150; 126 | fb_info_to_driver.LeftTop_y = 30; 127 | fb_info_to_driver.Width = 320; 128 | fb_info_to_driver.Height = 240; 129 | 130 | int fb_size = fb_info_to_driver.Width * fb_info_to_driver.Height * 2; // RGB565 131 | fb_addr = (char *) mmap(0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd2, 0); 132 | if (fb_addr == NULL) { 133 | ::close(m_fd2); 134 | m_fd2 = -1; 135 | qDebug("mmap fb2 failed!"); 136 | return ; 137 | } 138 | 139 | if (ioctl(m_fd2, SET_OSD_INFO, &fb_info_to_driver) == -1) { 140 | qDebug("SET_OSD_INFO fb2 failed!"); 141 | } 142 | 143 | if (ioctl(m_fd2, SET_OSD_START) == -1) { 144 | qDebug("SET_OSD_START fb2 failed!"); 145 | } 146 | } else { 147 | qDebug("open fb2 failed!"); 148 | } 149 | 150 | //start thread 151 | this->start(); 152 | force_exit = 0; 153 | } 154 | } 155 | 156 | void RemoteCamera::closeCamera() 157 | { 158 | if(context){ 159 | force_exit = 1; 160 | } 161 | if(m_fd2){ 162 | if (ioctl(m_fd2, SET_OSD_STOP) == -1) { 163 | qDebug("SET_OSD_STOP fb2 failed!"); 164 | } 165 | } 166 | } 167 | 168 | void RemoteCamera::stopPreview() 169 | { 170 | if(m_fd2){ 171 | if (ioctl(m_fd2, SET_OSD_STOP) == -1) { 172 | qDebug("SET_OSD_STOP fb2 failed!"); 173 | } 174 | } 175 | } 176 | 177 | void RemoteCamera::restorePreview() 178 | { 179 | if (ioctl(m_fd2, SET_OSD_START) == -1) { 180 | qDebug("SET_OSD_START fb2 failed!"); 181 | } 182 | } 183 | 184 | void RemoteCamera::run() 185 | { 186 | context = NULL; 187 | wsi = NULL; 188 | int n = 0; 189 | int opts = 0; 190 | const char* iface = NULL; 191 | int syslog_options = LOG_PID | LOG_PERROR; 192 | 193 | struct lws_context_creation_info info; 194 | 195 | memset(&info,0,sizeof(info)); 196 | //signal(SIGINT, sighandler); 197 | 198 | //only try to log things according to our debug_level 199 | setlogmask(LOG_UPTO(LOG_DEBUG)); 200 | openlog("lwsts",syslog_options,LOG_DAEMON); 201 | 202 | //tell the library what debug level to emit and to send it to syslog 203 | info.port = CONTEXT_PORT_NO_LISTEN; //as a client 204 | info.iface = iface; 205 | info.protocols = protocols; 206 | info.extensions = libwebsocket_get_internal_extensions(); 207 | info.ssl_cert_filepath = NULL; 208 | info.ssl_private_key_filepath = NULL; 209 | info.gid = -1; 210 | info.uid = -1; 211 | info.options = opts; 212 | 213 | context = libwebsocket_create_context(&info); 214 | qDebug()<<"Create context finished."; 215 | 216 | //connect server 217 | wsi = libwebsocket_client_connect(context,address,port,0,"/",address,"origin",NULL,-1); 218 | if(!wsi){ 219 | qDebug()<<"connect server failed."; 220 | return; 221 | } 222 | 223 | n = 0; 224 | while ( n>=0 && !force_exit) { 225 | //it does the polling and if threr is no transmission it returns after 50 ms. 226 | n = libwebsocket_service(context,50); 227 | } 228 | 229 | qDebug()<<"libwebsocket context will destroy"; 230 | libwebsocket_context_destroy(context); 231 | 232 | lwsl_notice("libwebsockets-test-server exit cleanky \n"); 233 | 234 | closelog(); 235 | } 236 | 237 | -------------------------------------------------------------------------------- /FriendlyARM6410/remotecamera.h: -------------------------------------------------------------------------------- 1 | #ifndef REMOTECAMERA_H 2 | #define REMOTECAMERA_H 3 | 4 | #include 5 | #include 6 | 7 | class RemoteCamera : public QThread 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit RemoteCamera(QObject *parent = 0); 12 | static void drawFb(void* in); 13 | signals: 14 | 15 | public slots: 16 | void openCamera(); 17 | void closeCamera(); 18 | void stopPreview(); 19 | void restorePreview(); 20 | 21 | // QThread interface 22 | protected: 23 | void run(); 24 | 25 | public: 26 | struct libwebsocket_context* context; 27 | struct libwebsocket* wsi; 28 | }; 29 | 30 | #endif // REMOTECAMERA_H 31 | -------------------------------------------------------------------------------- /FriendlyARM6410/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | themes/default.qss 4 | images/bg.jpg 5 | 6 | 7 | -------------------------------------------------------------------------------- /FriendlyARM6410/speakthread.cpp: -------------------------------------------------------------------------------- 1 | #include "speakthread.h" 2 | #include 3 | 4 | SpeakThread::SpeakThread(QObject *parent) : 5 | QThread(parent) 6 | { 7 | } 8 | 9 | SpeakThread::SpeakThread(QString words) 10 | { 11 | this->words = words; 12 | } 13 | 14 | void SpeakThread::run() 15 | { 16 | QString res =QString("speak -vzh+f3 -p 80 -s 150 '").append(words).append("'"); 17 | qDebug()< 5 | 6 | class SpeakThread : public QThread 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit SpeakThread(QObject *parent = 0); 11 | SpeakThread(QString words); 12 | 13 | signals: 14 | 15 | public slots: 16 | 17 | 18 | // QThread interface 19 | protected: 20 | void run(); 21 | 22 | private: 23 | QString words; 24 | }; 25 | 26 | #endif // SPEAKTHREAD_H 27 | -------------------------------------------------------------------------------- /FriendlyARM6410/themes/default.qss: -------------------------------------------------------------------------------- 1 | QTabWidget::pane { 2 | border-top: 2px solid #C2C7CB; 3 | position: absolute; 4 | top: -0.7em; 5 | border-image: url(images/bg.jpg); 6 | } 7 | 8 | QTabWidget::tab-bar { 9 | alignment: left; 10 | } 11 | 12 | QTabBar::tab { 13 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, 14 | stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, 15 | stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); 16 | border: 2px solid #C4C4C3; 17 | border-bottom-color: #C2C7CB; /* same as the pane color */ 18 | border-top-left-radius: 4px; 19 | border-top-right-radius: 4px; 20 | min-width: 8ex; 21 | } 22 | 23 | QTabBar::tab:selected, QTabBar::tab:hover { 24 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, 25 | stop: 0 #fafafa, stop: 0.4 #f4f4f4, 26 | stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); 27 | } 28 | 29 | QTabBar::tab:selected { 30 | border-color: #9B9B9B; 31 | border-bottom-color: #C2C7CB; /* same as pane color */ 32 | } 33 | 34 | QPushButton{ 35 | background-color: rgba(100,225,100,100); 36 | border-style: outset; 37 | border-width: 1px; 38 | border-radius: 5px; 39 | border-color: rgba(255,255,255,30); 40 | color: rgba(0,0,0,100); 41 | padding: 2px; 42 | } 43 | 44 | QPushButton:hover{ 45 | background-color: rgba(100,255,100,150); 46 | border-color: rgba(255,255,255,200); 47 | color: (0,0,0,200); 48 | } 49 | 50 | QPushButton:pressed{ 51 | background-color: rgba(100,255,100,200); 52 | border-color: rgba(255,255,255,30); 53 | border-style: inset; 54 | color: rgba(0,0,0,100); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /FriendlyARM6410/vncserver.cpp: -------------------------------------------------------------------------------- 1 | #include "vncserver.h" 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl); //按键事件 8 | static void mouseEvent(int buttonMask, int x, int y, rfbClientPtr cl); //鼠标事件 9 | //static rfbBool checkPasswd(struct _rfbClientRec *cl, const char *encryptedPassWord, int len); //检查密码 10 | static rfbNewClientAction newClientHook(rfbClientPtr cl); //新客户端连接 11 | static void clientGone(rfbClientPtr cl); //客户端断开连接 12 | static void displayHook(rfbClientRec *c); //before a framebuffer update send 13 | 14 | int fps; //帧数 15 | 16 | /* Here we create a structure so that every client has it's own pointer */ 17 | 18 | typedef struct ClientData { 19 | rfbBool oldButton; 20 | int oldx,oldy; 21 | } ClientData; 22 | 23 | VNCServer::VNCServer(QObject *parent) : 24 | QThread(parent) 25 | { 26 | } 27 | 28 | VNCServer::VNCServer(int argc, char **argv, QObject *parent) : 29 | QThread(parent) 30 | { 31 | this->argc = argc; 32 | this->argv = argv; 33 | this->picture_timeout = 1.0/15.0; //15帧每秒,如果可以 34 | this->width = QApplication::desktop()->width(); 35 | this->height = QApplication::desktop()->height(); 36 | 37 | 38 | #ifdef ARM_LINUX //嵌入式 depth 是 16 位 16-bit RGB format (5-6-5) 39 | this->bpp = 2; 40 | server = rfbGetScreen(&this->argc,this->argv,width,height,5,3,bpp); 41 | #elif defined DESKTOP 42 | this->bpp = 4; 43 | server = rfbGetScreen(&this->argc,this->argv,width,height,8,3,bpp); 44 | #endif 45 | if(!server){ 46 | qDebug()<<"get vnc screen failed!"; 47 | return; 48 | } 49 | server->alwaysShared = true; 50 | server->desktopName = "X-AI"; 51 | server->ptrAddEvent = mouseEvent; 52 | server->kbdAddEvent = keyEvent; 53 | server->newClientHook = newClientHook; 54 | server->displayHook = displayHook; 55 | server->authPasswdData = (void*)"passwd"; //存放加密密码的文件 56 | //server->passwordCheck = checkPasswd; 57 | 58 | //http server 59 | server->httpDir = "/www/vnc-webclients"; 60 | server->httpEnableProxyConnect = true; 61 | 62 | //frameBuffer 横向扫描 63 | server->frameBuffer = (char*)malloc(width*height*bpp); 64 | 65 | } 66 | 67 | void VNCServer::stopServer() 68 | { 69 | if(rfbIsActive(server)){ 70 | rfbShutdownServer(server,true); 71 | } 72 | } 73 | 74 | int VNCServer::timeToTakePicture() 75 | { 76 | static struct timeval now={0,0}, then={0,0}; 77 | double elapsed, dnow, dthen; 78 | 79 | gettimeofday(&now,NULL); 80 | 81 | dnow = now.tv_sec + (now.tv_usec/1000000.0); 82 | dthen = then.tv_sec + (then.tv_usec/1000000.0); 83 | elapsed = dnow - dthen; 84 | 85 | if(elapsed > this->picture_timeout) 86 | memcpy((char*)&then,(char*)&now,sizeof(struct timeval)); 87 | 88 | return elapsed > this->picture_timeout; 89 | } 90 | 91 | int VNCServer::takePicture() 92 | { 93 | //实践:QImage和FrameBuffer中的像素数据,和libvnc中不同,红蓝要互换位置,QImage 为Format_RGB32,Vinagre使用JPEG压缩,不互换位置的可以正常显示 94 | #ifdef DESKTOP 95 | QImage img = qApp->primaryScreen()->grabWindow(0).toImage(); //QImage::Format_RGB32 96 | u_int32_t* f = (u_int32_t*)img.bits(); 97 | for(int i=0;i>16 | ((f[i] & 0x0000ff00)) | ((f[i] & 0x000000ff))<<16; //0xffBBGGRR 99 | } 100 | #elif defined ARM_LINUX 101 | QImage img = QImage(QDirectPainter::frameBuffer(),width,height,QImage::Format_RGB16); 102 | img = img.convertToFormat(QImage::Format_RGB555); //转换成VNC支持的格式 103 | u_int16_t* f = (u_int16_t*)img.bits(); 104 | for(int i=0;i>10 | ((f[i] & 0b0000001111100000)) | ((f[i] & 0b0000000000011111))<<10; //0b0(blue)(green)(red) 106 | } 107 | #endif 108 | if(!img.isNull() && img.byteCount()>0){ 109 | memcpy(server->frameBuffer,img.bits(),width*height*bpp); 110 | }else{ 111 | qDebug()<<"get image failed!!\r"; 112 | return false; 113 | } 114 | return true; 115 | } 116 | 117 | static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl) 118 | { 119 | qDebug()<<"key event ==> "<<" down:"<host; 120 | #ifdef ARM_LINUX 121 | if(key == XK_BackSpace){ 122 | QWSServer::sendKeyEvent(key,Qt::Key_Backspace,Qt::NoModifier,down,false); 123 | }else if(key>=0x20 && key<0x100){ 124 | QWSServer::sendKeyEvent(key,key,Qt::NoModifier,down,false); 125 | } 126 | QWidget* w = qApp->focusWidget(); 127 | if(w){ 128 | w->update(); 129 | } 130 | #endif 131 | } 132 | 133 | static void mouseEvent(int buttonMask, int x, int y, rfbClientPtr cl) 134 | { 135 | 136 | ClientData* cd = (ClientData*)cl->clientData; 137 | #ifdef ARM_LINUX 138 | if(buttonMask){ //buttonMask 0:没有按键 1:鼠标左键 2:鼠标中间 4:鼠标右键 8:向上滚轮 16:向下滚轮 139 | if(buttonMask == cd->oldButton ){//MouseMove 140 | //QWSServer::sendMouseEvent(QPoint(x,y),QWSServer::MouseMove); //此事件太多影响效率 141 | qDebug()<<"mouse move event ==> "<<" button:"<host; 142 | }else{//MousePress 143 | // if(buttonMask == 1){ 144 | // QWSServer::sendMouseEvent(QPoint(x,y),Qt::LeftButton); 145 | // }else if(buttonMask == 2){ 146 | // QWSServer::sendMouseEvent(QPoint(x,y),Qt::MidButton); 147 | // }else if(buttonMask == 4){ 148 | // QWSServer::sendMouseEvent(QPoint(x,y),Qt::RightButton); 149 | // } 150 | QWSServer::sendMouseEvent(QPoint(x,y),QWSServer::MouseRelease); 151 | qDebug()<<"mouse press event ==> "<<" button:"<host; 152 | } 153 | }else{ 154 | if(cd->oldButton){//MouseRelease 155 | QWSServer::sendMouseEvent(QPoint(x,y),QWSServer::MousePress); 156 | qDebug()<<"mouse release event ==> "<<" button:"<oldButton<<" x:"<host; 157 | }else{//mouse hang 158 | QCursor::setPos(x,y); 159 | //qDebug()<<"mouse hang event ==> "<<" button:"<host; 160 | } 161 | } 162 | QWidget* w = qApp->focusWidget(); //更新使显示效果 163 | if(w){ 164 | w->update(); 165 | } 166 | #endif 167 | cd->oldx = x; cd->oldy = y; cd->oldButton = buttonMask; 168 | rfbDefaultPtrAddEvent(buttonMask,x,y,cl); 169 | } 170 | 171 | 172 | static rfbNewClientAction newClientHook(rfbClientPtr cl) 173 | { 174 | cl->clientData = (void*)calloc(sizeof(ClientData),1); 175 | cl->clientGoneHook = clientGone; 176 | qDebug()<<"newClientHool --> authPasswdData: "<<(char*)cl->screen->authPasswdData; 177 | qDebug()<<"decry pass: "<screen->authPasswdData); 178 | return RFB_CLIENT_ACCEPT; 179 | } 180 | 181 | //和默认检测相同 182 | //rfbBool checkPasswd(struct _rfbClientRec *cl, const char *encryptedPassWord, int len){ 183 | // qDebug()<<"checkPasswd --> checking the password!"<<" encryptedpasswd:"<screen->authPasswdData); 187 | 188 | // if(!passwd) { 189 | // rfbErr("Couldn't read password file: %s\n",cl->screen->authPasswdData); 190 | // return(FALSE); 191 | // } 192 | // qDebug()<<"checkPassws --> get passwd : "<authChallenge, passwd); 194 | 195 | // /* Lose the password from memory */ 196 | // for (i = strlen(passwd); i >= 0; i--) { 197 | // passwd[i] = '\0'; 198 | // } 199 | 200 | // free(passwd); 201 | 202 | // if (memcmp(cl->authChallenge, encryptedPassWord, len) != 0) { 203 | // rfbErr("authProcessClientMessage: authentication failed from %s\n", 204 | // cl->host); 205 | // return(FALSE); 206 | // } 207 | // for(int i=0;iauthChallenge[i],16)<<" = "<clientData); 216 | cl->clientData = NULL; 217 | } 218 | 219 | static void displayHook(rfbClientRec *c) 220 | { 221 | static struct timeval now={0,0}, then={0,0}; 222 | static int count = 0; 223 | double elapsed, dnow, dthen; 224 | 225 | gettimeofday(&now,NULL); 226 | 227 | dnow = now.tv_sec + (now.tv_usec/1000000.0); 228 | dthen = then.tv_sec + (then.tv_usec/1000000.0); 229 | elapsed = dnow - dthen; 230 | 231 | //计算帧数 232 | count++; 233 | if(elapsed > 1.0){ 234 | fps = count; 235 | count = 0; 236 | memcpy((char*)&then,(char*)&now,sizeof(struct timeval)); 237 | } 238 | //fprintf(stderr,"Picture to %s (%03d fps)\r", c->host, fps); 239 | } 240 | 241 | void VNCServer::run() 242 | { 243 | long usec; 244 | //初始化服务 245 | rfbInitServer(server); 246 | qDebug()<<"bpp:"<serverFormat.bitsPerPixel 247 | <<" depth:"<serverFormat.depth 248 | <<" bigEndian:"<serverFormat.bigEndian 249 | <<" trueColour:"<serverFormat.trueColour 250 | <<" redMax:"<serverFormat.redMax 251 | <<" greenMax:"<serverFormat.greenMax 252 | <<" blueMax:"<serverFormat.blueMax 253 | <<" deferUpdateTime:"<deferUpdateTime; 254 | 255 | //循环处理事件 256 | while(rfbIsActive(server)){ 257 | if(timeToTakePicture()){ 258 | if(takePicture()){ 259 | rfbMarkRectAsModified(server,0,0,width,height); 260 | } 261 | } 262 | usec = server->deferUpdateTime * 1000; 263 | rfbProcessEvents(server,usec); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /FriendlyARM6410/vncserver.h: -------------------------------------------------------------------------------- 1 | #ifndef VNCSERVER_H 2 | #define VNCSERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef ARM_LINUX 14 | #include 15 | #include 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | extern int fps; //帧数 25 | 26 | class VNCServer : public QThread 27 | { 28 | Q_OBJECT 29 | public: 30 | explicit VNCServer(QObject *parent = 0); 31 | VNCServer(int argc,char** argv,QObject *parent = 0); 32 | void stopServer(); 33 | signals: 34 | 35 | 36 | public slots: 37 | 38 | 39 | private: 40 | int argc; 41 | char** argv; 42 | 43 | int timeToTakePicture(); //根据时间是否该截图 44 | int takePicture(); //填充framebuffer 45 | 46 | public: 47 | rfbScreenInfoPtr server; 48 | double picture_timeout; //每帧的时间 49 | int width; //显示宽高 50 | int height; 51 | int bpp; //每像素字节数 52 | 53 | // QThread interface 54 | protected: 55 | void run(); 56 | }; 57 | 58 | #endif // VNCSERVER_H 59 | -------------------------------------------------------------------------------- /FriendlyARM6410/weather.cpp: -------------------------------------------------------------------------------- 1 | #include "weather.h" 2 | #include "speakthread.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | Weather::Weather(QObject* parent):QObject(parent = 0) 10 | { 11 | manager = new QNetworkAccessManager(this); 12 | connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); 13 | } 14 | 15 | Weather::~Weather() 16 | { 17 | delete manager; 18 | } 19 | 20 | void Weather::getCityWeather(QString city) 21 | { 22 | QString weatherUrl="http://flash.weather.com.cn/wmaps/xml/"+city+".xml"; 23 | qDebug()<<"url: "<get(QNetworkRequest(QUrl(weatherUrl))); 25 | } 26 | 27 | QString Weather::getWeatherString() 28 | { 29 | qDebug()<name(); 30 | if(!citys.contains(QString::fromUtf8("西安市"))){ 31 | return "无法获得 天气信息!"; 32 | } 33 | 34 | //西安市 多云转阴, 最高气温 十6度,最低气温 2十5度, 当前温度 2十4度, 东北风小于3级, 东风 2级, 湿度 百分之5十6 35 | QString humidity = citys.value(QString::fromUtf8("西安市")).value("humidity").toString(); 36 | QString stateDetailed = citys.value(QString::fromUtf8("西安市")).value("stateDetailed").toString(); 37 | QString windState = citys.value(QString::fromUtf8("西安市")).value("windState").toString(); 38 | QString windDir = citys.value(QString::fromUtf8("西安市")).value("windDir").toString(); 39 | QString windPower = citys.value(QString::fromUtf8("西安市")).value("windPower").toString(); 40 | int temH = citys.value(QString::fromUtf8("西安市")).value("tem2").toString().toInt(); 41 | int temL = citys.value(QString::fromUtf8("西安市")).value("tem1").toString().toInt(); 42 | if(temH < temL){ 43 | int t = temL; 44 | temL = temH; 45 | temH = t; 46 | } 47 | QString tmp = QString("西安市 "); 48 | tmp.append(stateDetailed.toUtf8()).append(",最高温度 ") 49 | .append(getSpeachNum(temH)) 50 | .append("度,最低温度 ") 51 | .append(getSpeachNum(temL)) 52 | .append("度,当前温度 ") 53 | .append(getSpeachNum(citys.value(QString::fromUtf8("西安市")).value("temNow").toString().toInt())) 54 | .append("度,") 55 | .append(windState.toUtf8()) 56 | .append(", ") 57 | .append(windDir.toUtf8()) 58 | .append(windPower.toUtf8()) 59 | .append(", 湿度 百分之") 60 | .append(getSpeachNum(humidity.left(humidity.size()-1).toInt())); 61 | return tmp; 62 | } 63 | 64 | QString Weather::getSpeachNum(int num) 65 | { 66 | QString ret; 67 | //范围为 -99 ~ 99 68 | if(num > 0){ 69 | if(num>10){ 70 | if(num>19){ 71 | ret.append(QString::number(num/10)).append("十"); 72 | if(num%10 != 0){ 73 | ret.append(QString::number(num%10)); 74 | } 75 | }else{ 76 | ret.append("十"); 77 | if(num%10 != 0){ 78 | ret.append(QString::number(num%10)); 79 | } 80 | } 81 | }else if(num < 10){ 82 | ret = QString(num); 83 | }else{ 84 | ret = QString("十"); 85 | } 86 | }else if(num < 0){ 87 | if(num < -10){ 88 | if(num < -19){ 89 | ret.append("零下").append(QString::number(num/-10)).append("十"); 90 | if(num%10 != 0){ 91 | ret.append(QString::number(num%10)); 92 | } 93 | }else{ 94 | ret.append("零下").append("十"); 95 | if(num%10 != 0){ 96 | ret.append(QString::number(num%10)); 97 | } 98 | } 99 | }if(num > -10){ 100 | ret.append("零下").append(QString::number(num%-10)); 101 | }else{ 102 | ret.append("零下十"); 103 | } 104 | }else{ 105 | ret = "零"; 106 | } 107 | qDebug()<start(); 116 | } 117 | 118 | void Weather::replyFinished(QNetworkReply *reply) 119 | { 120 | QXmlStreamReader reader; 121 | reader.setDevice(reply); 122 | //如果没有读到文件的结尾,且没有出现错误 123 | while (! reader.atEnd()) { 124 | //读取下一个记号,它返回记号的类型 125 | QXmlStreamReader::TokenType type = reader.readNext(); 126 | //根据记号的类型来进行不同的输出 127 | if(type == QXmlStreamReader::StartDocument){ 128 | qDebug()<<"startDocument:"<"; 132 | if(reader.attributes().hasAttribute("dn")){ 133 | day = reader.attributes().value("dn").toString(); 134 | } 135 | if(reader.attributes().hasAttribute("cityname")){ 136 | qDebug()<"; 142 | } 143 | if(type == QXmlStreamReader::Characters && ! reader.isWhitespace()){ 144 | qDebug()<<"text:"<deleteLater(); 153 | } 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /FriendlyARM6410/weather.h: -------------------------------------------------------------------------------- 1 | #ifndef WEATHER_H 2 | #define WEATHER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class QNetworkReply; 9 | class QNetworkAccessManager; 10 | 11 | class Weather: public QObject 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit Weather(QObject* parent = 0); 16 | ~ Weather(); 17 | 18 | QString getWeatherString(); //把天气信息转换成字符串 19 | QString getSpeachNum(int num); //例 25 =》》 二十五 20 | signals: 21 | void dataUpdate(); //信息更新发送 22 | 23 | public slots: 24 | void speakWeather(); //播放天气声音 25 | void getCityWeather(QString city); 26 | 27 | private slots: 28 | void replyFinished(QNetworkReply *reply); 29 | 30 | // QThread interface 31 | protected: 32 | void run(); 33 | 34 | private: 35 | QNetworkAccessManager * manager; 36 | public: 37 | QString day; //day or night 38 | QMap citys; 39 | 40 | }; 41 | 42 | #endif // WEATHER_H 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FriendlyARM6410 2 | 3 | 4 | 基于FriendlyARM6410平台的嵌入式Qt程序:实时天气信息,远程vnc控制,远程监视摄像头,语音控制,语音输出TTS 5 | --------------------------------------------------------------------------------