Subversion Repositories Projects

Rev

Rev 170 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
170 KeyOz 1
/***************************************************************************
2
 *   Copyright (C) 2008 by Manuel Schrape                                  *
3
 *   manuel.schrape@gmx.de                                                 *
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation; either version 2 of the License.        *
8
 *                                                                         *
9
 *   This program is distributed in the hope that it will be useful,       *
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12
 *   GNU General Public License for more details.                          *
13
 *                                                                         *
14
 *   You should have received a copy of the GNU General Public License     *
15
 *   along with this program; if not, write to the                         *
16
 *   Free Software Foundation, Inc.,                                       *
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18
 ***************************************************************************/
19
 
20
#include <QtGui>
21
 
22
#include <QLineEdit>
23
#include <QString>
24
#include <QTimer>
25
#include <QIcon>
26
#include <QToolButton>
27
#include <QSpinBox>
28
 
29
#include "mktool.h"
30
#include "dlg_Config.h"
31
#include "dlg_Motortest.h"
32
#include "dlg_Preferences.h"
33
#include "../global.h"
34
#include "../ToolBox.h"
35
 
36
#include <stdlib.h>
37
 
38
MKTool::MKTool()
39
{
40
    setupUi(this);
41
 
42
    Settings = new cSettings;
43
 
44
    init_Arrays();
45
    init_GUI();
46
 
47
    init_Objects();
48
    init_Connections();
49
 
50
    init_Plot();
51
}
52
 
53
void MKTool::init_GUI()
54
{
55
    setWindowTitle(QA_NAME + " v" + QA_VERSION);
56
 
57
    // Tab mit Debug-Elementen verbergen
58
    tab_Main->removeTab(5);
59
 
60
    // Settings-Tab hinzufügen.
61
    f_Settings = new wdg_Settings( this );
62
    tab_Main->insertTab ( 2, f_Settings, "FC-Settings");
63
    tab_Main->widget(2)->setObjectName("Tab_2");
64
 
65
    // Develop - Nicht gebrauchte sachen abschalten.
66
    ac_StartServer->setVisible(false);
67
    box_Flugdaten->hide();
68
    box_System->hide();
69
    pb_SettingsReset->hide();
70
    pb_Flash->hide();
71
    rb_NC->hide();
72
 
73
    // Zusätzliche Widgets in die Toolbar.
74
    toolBar->addWidget(lb_Port);
75
    toolBar->addWidget(le_Port);
76
    toolBar->addSeparator();
77
//    toolBar->addWidget(cb_Hardware);
78
 
79
    lb_Status->setText("Hallo bei QMK-Groundstation...!!!");  
80
 
81
#ifdef _EEEPC_
82
    toolBar->hide();
83
    lb_Status->hide();
84
#endif
85
 
86
    resize(Settings->GUI.Size);
87
    move(Settings->GUI.Point);
88
 
89
    if (Settings->GUI.isMax)
90
    {
91
        showMaximized();
92
    }
93
 
94
    // Analoglabels anzeigen
95
    for (int a = 0; a < MaxAnalog; a++)
96
    {
97
        lb_Analog[a]->setText(Settings->Analog1.Label[a]);
98
    }
99
 
100
    // Kopie der Tabs anlegen
101
    for (int b = 0; b < 6; b++)
102
    {
103
        TabWidgets[b] = tab_Main->widget(b);
104
    }
105
 
106
    // Ausgeblendete Tabs ausblenden
107
    for (int c = 0; c < 6; c++)
108
    {
109
        if (Settings->GUI.TabViews[c] == false)
110
        {
111
            QString TabName = QString("Tab_%1").arg(c);
112
 
113
            for (int d = 0; d < tab_Main->count(); d++)
114
            {
115
                if (tab_Main->widget(d)->objectName() == TabName)
116
                {
117
                    tab_Main->removeTab(d);
118
                }
119
            }
120
        }
121
    }
122
 
123
    ac_View0->setChecked(Settings->GUI.TabViews[0]);
124
    ac_View1->setChecked(Settings->GUI.TabViews[1]);
125
    ac_View2->setChecked(Settings->GUI.TabViews[2]);
126
    ac_View3->setChecked(Settings->GUI.TabViews[3]);
127
    ac_View4->setChecked(Settings->GUI.TabViews[4]);
128
    ac_View5->setChecked(Settings->GUI.TabViews[5]);
129
 
130
    le_Port->setText(Settings->TTY.Port);
131
 
132
    cb_ShowMSG->setChecked(Settings->GUI.Term_Info);
133
    cb_ShowData->setChecked(Settings->GUI.Term_Data);
134
    cb_ShowAlways->setChecked(Settings->GUI.Term_Always);
135
}
136
 
137
void MKTool::init_Objects()
138
{
139
    // QTimer-Instanzen
140
    Ticker = new QTimer(this);
141
 
142
    // Seriell-Port
143
    serialPort = new ManageSerialPort;
144
 
145
    // QFile-Instanz (Log-Datei)
146
    CSVFile = new QFile("");
147
 
148
    // Senden erlauben (Warum auch immer)
149
    AllowSend = true;
150
}
151
 
152
void MKTool::init_Connections()
153
{
154
    // Seriel-Port Empfang
155
    connect(serialPort, SIGNAL(newDataReceived(const QByteArray &)), this, SLOT(slot_newDataReceived(const QByteArray &)));
156
 
157
    // Serielle Verbundung öffnen / schließen
158
    connect(ac_ConnectTTY, SIGNAL(triggered()), this, SLOT(slot_OpenPort()));
159
 
160
    // Buttons Settings lesen / schreiben
161
    connect(f_Settings->pb_Read,   SIGNAL(clicked()), this, SLOT(slot_GetFCSettings()));
162
    connect(f_Settings->pb_Write,  SIGNAL(clicked()), this, SLOT(slot_SetFCSettings()));
163
 
164
    // LCD auf / ab
165
    connect(pb_LCDup,   SIGNAL(clicked()), this, SLOT(slot_LCD_UP()));
166
    connect(pb_LCDdown, SIGNAL(clicked()), this, SLOT(slot_LCD_DOWN()));
167
 
168
    // Actions
169
    connect(ac_Config,       SIGNAL(triggered()), this, SLOT(slot_ac_Config()));
170
    connect(ac_Preferences,  SIGNAL(triggered()), this, SLOT(slot_ac_Preferences()));
171
    connect(ac_Motortest,    SIGNAL(triggered()), this, SLOT(slot_ac_Motortest()));
172
    connect(ac_MehrDaten,    SIGNAL(triggered()), this, SLOT(slot_ac_MehrDaten()));
173
    connect(ac_KeineDaten,   SIGNAL(triggered()), this, SLOT(slot_ac_KeineDaten()));
174
    connect(ac_GetLabels,    SIGNAL(triggered()), this, SLOT(slot_ac_GetLabels()));
175
 
176
    // Plotter starten / scrollen
177
    connect(scroll_plot,     SIGNAL(valueChanged(int)), this, SLOT(slot_ScrollPlot(int)));
178
    connect(ac_StartPlotter, SIGNAL(triggered()), this, SLOT(slot_ac_StartPlotter()));
179
 
180
    // Tabs ein & ausblenden
181
    connect(ac_View0,        SIGNAL(triggered()), this, SLOT(slot_ac_View()));
182
    connect(ac_View1,        SIGNAL(triggered()), this, SLOT(slot_ac_View()));
183
    connect(ac_View2,        SIGNAL(triggered()), this, SLOT(slot_ac_View()));
184
    connect(ac_View3,        SIGNAL(triggered()), this, SLOT(slot_ac_View()));
185
    connect(ac_View4,        SIGNAL(triggered()), this, SLOT(slot_ac_View()));
186
    connect(ac_View5,        SIGNAL(triggered()), this, SLOT(slot_ac_View()));
187
 
188
    // firmeware Updateen / flashen
189
    connect(pb_Update,   SIGNAL(clicked()), this, SLOT(slot_pb_Update()));
190
    connect(pb_HexFile,  SIGNAL(clicked()), this, SLOT(slot_pb_HexFile()));
191
 
192
    // CVS-Record starten / stoppen
193
    connect(ac_RecordCSV,  SIGNAL(triggered()), this, SLOT(slot_RecordCSV()));
194
 
195
    // Timer-Events
196
    connect(Ticker,   SIGNAL(timeout()),       SLOT(slot_Ticker()));
197
 
198
    // Seitenwechsel
199
    connect(tab_Main,             SIGNAL(currentChanged(int)), this, SLOT(slot_TabChanged(int)));
200
    connect(f_Settings->tab_Par,  SIGNAL(currentChanged(int)), this, SLOT(slot_TabChanged(int)));
201
 
202
    // About QMK & About-QT Dialog einfügen
203
    connect(ac_About, SIGNAL(triggered()), this, SLOT(slot_ac_About()));
204
    menu_Help->addAction(trUtf8("Über &Qt"), qApp, SLOT(aboutQt()));
205
}
206
 
207
void MKTool::init_Arrays()
208
{
209
    lb_Analog[0]  = lb_A_0;
210
    lb_Analog[1]  = lb_A_1;
211
    lb_Analog[2]  = lb_A_2;
212
    lb_Analog[3]  = lb_A_3;
213
    lb_Analog[4]  = lb_A_4;
214
    lb_Analog[5]  = lb_A_5;
215
    lb_Analog[6]  = lb_A_6;
216
    lb_Analog[7]  = lb_A_7;
217
    lb_Analog[8]  = lb_A_8;
218
    lb_Analog[9]  = lb_A_9;
219
    lb_Analog[10] = lb_A_10;
220
    lb_Analog[11] = lb_A_11;
221
    lb_Analog[12] = lb_A_12;
222
    lb_Analog[13] = lb_A_13;
223
    lb_Analog[14] = lb_A_14;
224
    lb_Analog[15] = lb_A_15;
225
    lb_Analog[16] = lb_A_16;
226
    lb_Analog[17] = lb_A_17;
227
    lb_Analog[18] = lb_A_18;
228
    lb_Analog[19] = lb_A_19;
229
    lb_Analog[20] = lb_A_20;
230
    lb_Analog[21] = lb_A_21;
231
    lb_Analog[22] = lb_A_22;
232
    lb_Analog[23] = lb_A_23;
233
    lb_Analog[24] = lb_A_24;
234
    lb_Analog[25] = lb_A_25;
235
    lb_Analog[26] = lb_A_26;
236
    lb_Analog[27] = lb_A_27;
237
    lb_Analog[28] = lb_A_28;
238
    lb_Analog[29] = lb_A_29;
239
    lb_Analog[30] = lb_A_30;
240
    lb_Analog[31] = lb_A_31;
241
}
242
 
243
void MKTool::init_Plot()
244
{
245
    NextPlot = 0;
246
 
247
    qwtPlot->setCanvasBackground(QColor(QRgb(0x00000000)));
248
 
249
    qwtPlot->insertLegend(new QwtLegend(), QwtPlot::RightLegend);
250
 
251
    QwtPlotGrid *Grid = new QwtPlotGrid();
252
    Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
253
 
254
    Grid->attach(qwtPlot);
255
 
256
    qwtPlot->setAxisScale(QwtPlot::xBottom,0,Settings->Data.Plotter_Count,0);
257
 
258
    for (int a = 0; a < MaxAnalog; a++)
259
    {
260
        Plot[a] = new QwtPlotCurve(Settings->Analog1.Label[a]);
261
        Plot[a]->setPen(QPen(QColor(Def_Colors[a])));
262
        Plot[a]->setRenderHint(QwtPlotItem::RenderAntialiased);
263
 
264
        if (Settings->Analog1.PlotView[a])
265
            Plot[a]->attach(qwtPlot);
266
    }
267
    qwtPlot->replot();
268
}
269
 
270
 
271
// Ticker-Event
272
///////////////
273
void MKTool::slot_Ticker()
274
{
275
    if (TickerDiv)
276
        TickerDiv = false;
277
    else
278
        TickerDiv = true;
279
 
280
    for (int a = 0; a < MaxTickerEvents; a++)
281
    {
282
        if (TickerEvent[a] == true)
283
        {
284
            switch(a)
285
            {
286
                case 0 :
287
                    if (TickerDiv)
288
                    {
289
                        QByteArray Temp(LastSend.toUtf8());
290
                        serialPort->sendData(Temp);
291
                    }
292
                break;
293
                case 1 :
294
                    TX_Data[0] = 0;
295
                    send_Data('p', ADDRESS_FC, TX_Data, 0, false);
296
                break;
297
                case 2 :
298
                    if (cb_LCD->isChecked())
299
                    {
300
                        TX_Data[0] = LCD_Page;
301
                        TX_Data[1] = 0;
302
                        send_Data('l', ADDRESS_ALL, TX_Data, 1, true);
303
                    }
304
                break;
305
                case 3 :
306
                    if (ac_MehrDaten->isChecked())
307
                    {
308
                        TX_Data[0] = Settings->Data.Debug_Fast / 10;
309
                        send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
310
                    }
311
                    else
312
                    {
313
                        TX_Data[0] = Settings->Data.Debug_Slow / 10;
314
                        send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
315
                    }
316
                break;
317
            }
318
        }
319
    }
320
}
321
 
322
 
323
// Slots der Actions (Menüpunkte, Buttons)
324
//////////////////////////////////////////
325
void MKTool::slot_ac_Motortest()
326
{
327
    dlg_Motortest *f_Motortest = new dlg_Motortest(this);
328
 
329
    connect(f_Motortest, SIGNAL(updateMotor(int, int, int, int)), this, SLOT(slot_Motortest(int, int, int, int)));
330
 
331
    if (f_Motortest->exec()==QDialog::Accepted)
332
    {
333
    }
334
 
335
    disconnect(f_Motortest, 0,0,0);
336
    slot_Motortest(0,0,0,0);
337
}
338
 
339
void MKTool::slot_Motortest(int Motor1, int Motor2, int Motor3, int Motor4)
340
{
341
    TX_Data[0] = Motor1;
342
    TX_Data[1] = Motor2;
343
    TX_Data[2] = Motor3;
344
    TX_Data[3] = Motor4;
345
    send_Data('t', ADDRESS_FC, TX_Data, 4, false);
346
}
347
 
348
void MKTool::slot_ac_Config()
349
{
350
    set_Analog Old_Analog1;
351
 
352
    Old_Analog1 = Settings->Analog1;
353
 
354
    dlg_Config *f_Config = new dlg_Config(this);
355
    f_Config->set_Settings(Settings, Mode.ID);
356
 
357
    if (f_Config->exec()==QDialog::Accepted)
358
    {
359
        Settings = f_Config->get_Settings();
360
        Settings->write_Settings_Analog(Mode.ID);
361
 
362
        // Plotter neu einrichten
363
        if (Old_Analog1.PlotView != Settings->Analog1.PlotView)
364
        {
365
            config_Plot();
366
        }
367
 
368
        // CVS-Datei neu anlegen.
369
        if ((CSVFile->isOpen()) && (Old_Analog1.LogView != Settings->Analog1.LogView))
370
        {
371
            slot_RecordCSV();
372
            slot_RecordCSV();
373
        }
374
 
375
    }
376
}
377
 
378
void MKTool::slot_ac_Preferences()
379
{
380
    dlg_Preferences *f_Preferences = new dlg_Preferences(this);
381
 
382
    Settings->TTY.Port = le_Port->text();
383
    f_Preferences->set_Settings(Settings);
384
 
385
    if (f_Preferences->exec()==QDialog::Accepted)
386
    {
387
        Settings = f_Preferences->get_Settings();
388
        Settings->write_Settings();
389
        le_Port->setText(Settings->TTY.Port);
390
        config_Plot();
391
    }
392
}
393
 
394
void MKTool::slot_ac_StartPlotter()
395
{
396
    if (ac_StartPlotter->isChecked())
397
    {
398
        ac_StartPlotter->setText("Stop Plotter");
399
        pb_StartPlotter->setText("Stop Plotter");
400
    }
401
    else
402
    {
403
        ac_StartPlotter->setText("Start Plotter");
404
        pb_StartPlotter->setText("Start Plotter");
405
    }
406
}
407
 
408
void MKTool::slot_ac_View()
409
{
410
    int Aktive;
411
 
412
    QAction *Action = (QAction*)sender();
413
 
414
    if (Action->objectName() == QString("ac_View0"))
415
        Aktive = 0;
416
    if (Action->objectName() == QString("ac_View1"))
417
        Aktive = 1;
418
    if (Action->objectName() == QString("ac_View2"))
419
        Aktive = 2;
420
    if (Action->objectName() == QString("ac_View3"))
421
        Aktive = 3;
422
    if (Action->objectName() == QString("ac_View4"))
423
        Aktive = 4;
424
    if (Action->objectName() == QString("ac_View5"))
425
        Aktive = 5;
426
 
427
    QString TabName = QString("Tab_%1").arg(Aktive);
428
 
429
    if (!Action->isChecked())
430
    {
431
        for (int a = 0; a < tab_Main->count(); a++)
432
        {
433
            if (tab_Main->widget(a)->objectName() == TabName)
434
            {
435
                tab_Main->removeTab(a);
436
            }
437
        }
438
 
439
//        Action->setChecked(false);
440
    }
441
    else
442
    {
443
//        Action->setChecked(true);
444
        tab_Main->insertTab(Aktive, TabWidgets[Aktive], Action->text());
445
    }
446
}
447
 
448
void MKTool::slot_ac_MehrDaten() // DONE 0.71g
449
{
450
    if (!ac_KeineDaten->isChecked())
451
    {
452
        if (ac_MehrDaten->isChecked())
453
        {
454
            TX_Data[0] = Settings->Data.Debug_Fast / 10;
455
            send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
456
        }
457
        else
458
        {
459
            TX_Data[0] = Settings->Data.Debug_Slow / 10;
460
            send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
461
        }
462
    }
463
}
464
 
465
void MKTool::slot_ac_KeineDaten() // DONE 0.71g
466
{
467
    if (ac_KeineDaten->isChecked())
468
    {
469
        TickerEvent[3] = false;
470
        TX_Data[0] = 0;
471
        send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
472
    }
473
    else
474
    {
475
        // Wenn MK3MAG dann andauernd Daten neu anfragen.
476
        if (Mode.ID == ADDRESS_MK3MAG)
477
            TickerEvent[3] = true;
478
 
479
        if (ac_MehrDaten->isChecked())
480
        {
481
            TX_Data[0] = Settings->Data.Debug_Fast / 10;
482
            send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
483
        }
484
        else
485
        {
486
            TX_Data[0] = Settings->Data.Debug_Slow / 10;
487
            send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
488
        }
489
    }
490
}
491
 
492
void MKTool::slot_ac_About()
493
{
494
    QMessageBox::about(this, trUtf8(("Über ")) + QA_NAME, QA_ABOUT);
495
}
496
 
497
void MKTool::slot_ac_GetLabels() // DONE 0.71g
498
{
499
    TX_Data[0] = 0;
500
    send_Data('a', ADDRESS_ALL, TX_Data, 1, true);
501
}
502
 
503
 
504
//  Daten-Plotter
505
/////////////////
506
void MKTool::update_Plot()
507
{
508
    for (int a = 0; a < MaxAnalog; a++)
509
    {
510
        Plot[a]->setData(aID,aData[a],NextPlot - 1);
511
    }
512
 
513
    if ((NextPlot > Settings->Data.Plotter_Count))
514
    {
515
        scroll_plot->setMaximum(NextPlot - Settings->Data.Plotter_Count);
516
    }
517
 
518
    if ((scroll_plot->value() == NextPlot - (Settings->Data.Plotter_Count + 1)))
519
    {
520
        qwtPlot->setAxisScale(QwtPlot::xBottom,NextPlot - Settings->Data.Plotter_Count,NextPlot,0);
521
        scroll_plot->setValue(NextPlot - Settings->Data.Plotter_Count);
522
    }
523
 
524
    qwtPlot->replot();
525
}
526
 
527
void MKTool::config_Plot()
528
{
529
//    qDebug("Plotter rekonfiguriert..!!");
530
    qwtPlot->setAxisScale(QwtPlot::xBottom,0,Settings->Data.Plotter_Count,0);
531
 
532
    for (int a = 0; a < MaxAnalog; a++)
533
    {
534
        Plot[a]->detach();
535
        Plot[a]->setPen(QPen(QColor(Def_Colors[a])));
536
 
537
        if (Settings->Analog1.PlotView[a])
538
        {
539
            Plot[a]->setTitle(Settings->Analog1.Label[a]);
540
            Plot[a]->attach(qwtPlot);
541
        }
542
    }
543
    qwtPlot->replot();
544
}
545
 
546
void MKTool::slot_ScrollPlot(int Pos)
547
{
548
    qwtPlot->setAxisScale(QwtPlot::xBottom,Pos,Pos + Settings->Data.Plotter_Count,0);
549
    qwtPlot->replot();
550
}
551
 
552
 
553
// Firmeware-Update
554
///////////////////
555
void MKTool::slot_pb_Update()
556
{
557
    QString Device;
558
    QString Hardware;
559
 
560
    if (rb_FC->isChecked())
561
    {
562
        Device   = "m644";
563
        Hardware = "FlightCtrl";
564
    }
565
    else if (rb_MK3MAG->isChecked())
566
    {
567
        Device   = "m168";
568
        Hardware = "MK3MAG";
569
    }
570
    else if (rb_BL->isChecked())
571
    {
572
        Device   = "m8";
573
        Hardware = "BL-Ctrl";
574
    }
575
 
576
    QString Message = "Firmeware-Datei \n\n";
577
    Message = Message + le_HexFile->text() + "\n\n";
578
    Message = Message + "an " + Hardware + trUtf8(" mit AVRDUDE - Seriel & Bootloader über ") + le_Port->text() + trUtf8(" übertragen?\n");
579
 
580
    if (le_HexFile->text() == "")
581
    {
582
        QMessageBox::warning(this, QA_NAME, trUtf8("Bitte Firmeware-Datei wählen."), QMessageBox::Ok);
583
    }
584
    else if (QMessageBox::warning(this, QA_NAME, Message, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
585
    {
586
        QString Programm = "avrdude" ;
587
 
588
        QStringList Argumente;
589
 
590
        Update = new QProcess();
591
 
592
        if (serialPort->isOpen())
593
        {
594
            slot_OpenPort();
595
        }
596
 
597
        Argumente << "-P";
598
        Argumente << le_Port->text();
599
        Argumente << "-p";
600
        Argumente << Device;
601
        Argumente << "-c";
602
        Argumente << "butterfly";
603
        Argumente << "-b";
604
        Argumente << "57600";
605
        Argumente << "-U";
606
        Argumente << "flash:w:" + le_HexFile->text();
607
 
608
//    QString Programm = "/home/Manuel/bin/avrdude -p m644 -P /dev/ttyS0 -c butterfly -b 57600 -U flash:w:/home/Manuel/Documents/Mikrokopter/Firmeware/FlightCtrl/Flight-Ctrl_MEGA644_V0_71h.hex";
609
 
610
        te_Shell->setText(""); // Ausgabefenster säubern
611
 
612
        connect(Update, SIGNAL(readyReadStandardOutput()), this, SLOT(slot_UpdateShell()) );
613
        connect(Update, SIGNAL(readyReadStandardError()), this, SLOT(slot_UpdateShell()) );
614
 
615
        Update->start(Programm, Argumente); // Programmaufruf
616
    }
617
}
618
 
619
void MKTool::slot_UpdateShell()
620
{
621
    QByteArray Output;
622
 
623
    Output = Update->readAllStandardError(); // Shellausgabe an Variable
624
    te_Shell->moveCursor(QTextCursor::End,  QTextCursor::MoveAnchor);
625
    te_Shell->insertPlainText(QString::fromUtf8(Output));
626
 
627
    Output = Update->readAll();
628
    te_Shell->moveCursor(QTextCursor::End,  QTextCursor::MoveAnchor);
629
    te_Shell->insertPlainText(QString::fromUtf8(Output));
630
}
631
 
632
void MKTool::slot_pb_HexFile()
633
{
634
    QString FileName = QFileDialog::getOpenFileName(this,trUtf8(("Firmeware-Datei wählen")),"",
635
                                tr("Intel Hex(*.hex);;Alle Dateien (*)"));
636
    if (!FileName.isEmpty())
637
    {
638
        le_HexFile->setText(FileName);
639
    }
640
}
641
 
642
 
643
// Wechsel der Tabs erkennen
644
void MKTool::slot_TabChanged(int Tab) // DONE 0.71g
645
{
646
    Tab = Tab;
647
    if (tab_Main->count() != 0)
648
    {
649
        if ((tab_Main->currentWidget()->objectName() == QString("Tab_2")) && (f_Settings->tab_Par->currentIndex() == 1))
650
        {
651
            TX_Data[0] = 0;
652
            send_Data('p', ADDRESS_FC, TX_Data, 0, true);
653
 
654
            Ticker->setInterval(500);
655
            TickerEvent[1] = true;
656
        }
657
        else
658
        {
659
            Ticker->setInterval(2000);
660
            TickerEvent[1] = false;
661
        }
662
 
663
        if ((tab_Main->currentWidget()->objectName() == QString("Tab_4")))
664
        {
665
            TX_Data[0] = 0;
666
            TX_Data[1] = 0;
667
            send_Data('l', ADDRESS_ALL, TX_Data, 1, true);
668
 
669
            Ticker->setInterval(500);
670
            TickerEvent[2] = true;
671
        }
672
        else
673
        {
674
            Ticker->setInterval(2000);
675
            TickerEvent[2] = false;
676
        }
677
    }
678
}
679
 
680
// LCD-Seiten weiterschalten
681
void MKTool::slot_LCD_UP() // DONE 0.71g
682
{
683
    if (LCD_Page == LCD_MAX_Page)
684
        TX_Data[0] = 0;
685
    else
686
        TX_Data[0] = LCD_Page + 1;
687
 
688
    TX_Data[1] = 0;
689
    send_Data('l', ADDRESS_ALL, TX_Data, 1, true);
690
}
691
 
692
void MKTool::slot_LCD_DOWN() // DONE 0.71g
693
{
694
    if (LCD_Page == 0)
695
        TX_Data[0] = LCD_MAX_Page;
696
    else
697
        TX_Data[0] = LCD_Page - 1;
698
 
699
    TX_Data[1] = 0;
700
    send_Data('l', ADDRESS_ALL, TX_Data, 1, true);
701
}
702
 
703
// Settings aus MK lesen / in MK schreiben
704
void MKTool::slot_GetFCSettings() // DONE 0.71g
705
{
706
    TX_Data[0] = f_Settings->sb_Set->value();
707
    TX_Data[1] = 0;
708
    send_Data('q', ADDRESS_FC, TX_Data, 1);
709
}
710
 
711
void MKTool::slot_SetFCSettings() // DONE 0.71g
712
{
713
    char *TX_Data2 = f_Settings->GetFCSettings();
714
 
715
    send_Data('s', ADDRESS_FC, TX_Data2, MaxParameter + 2, false);
716
}
717
 
718
 
719
// Save GUI-Preferences
720
///////////////////////
721
void MKTool::set_Preferences()
722
{
723
    Settings->GUI.TabViews.setBit(0, ac_View0->isChecked());
724
    Settings->GUI.TabViews.setBit(1, ac_View1->isChecked());
725
    Settings->GUI.TabViews.setBit(2, ac_View2->isChecked());
726
    Settings->GUI.TabViews.setBit(3, ac_View3->isChecked());
727
    Settings->GUI.TabViews.setBit(4, ac_View4->isChecked());
728
    Settings->GUI.TabViews.setBit(5, ac_View5->isChecked());
729
 
730
    Settings->GUI.Term_Info   = cb_ShowMSG->isChecked();
731
    Settings->GUI.Term_Data   = cb_ShowData->isChecked();
732
    Settings->GUI.Term_Always = cb_ShowAlways->isChecked();
733
    Settings->GUI.Term_Send   = cb_ShowSend->isChecked();
734
    Settings->GUI.isMax       = isMaximized();
735
    Settings->GUI.Size        = size();
736
    Settings->GUI.Point       = pos();
737
 
738
    Settings->TTY.Port = le_Port->text();
739
}
740
 
741
 
742
// Debug-Daten anzeigen und Aufzeichnen
743
///////////////////////////////////////
744
void MKTool::write_CSV()
745
{
746
    QTextStream Out(CSVFile);
747
    for (int a=0; a<MaxAnalog; a++)
748
    {
749
        if (Settings->Analog1.LogView[a])
750
        {
751
            Out << AnalogData[a];
752
            if (a < MaxAnalog - 1)
753
                Out << ';';
754
        }
755
    }
756
    Out << "\n";
757
}
758
 
759
void MKTool::slot_RecordCSV() // DONE 0.71g
760
{
761
    if (!CSVFile->isOpen())
762
    {
763
        QString Filename = Settings->DIR.Logging + Mode.Hardware + " - " + QDate::currentDate().toString(("yyyy-MM-dd")) + " -- " + QTime::currentTime().toString("hh-mm") + ".csv";
764
 
765
        CSVFile = new QFile(Filename);
766
        if (!CSVFile->exists())
767
        {
768
            CSVFile->open(QIODevice::Append | QIODevice::Text);
769
 
770
            QTextStream Out(CSVFile);
771
 
772
            for (int a = 0; a < MaxAnalog; a++)
773
            {
774
                if (Settings->Analog1.LogView[a])
775
                {
776
                    Out << Settings->Analog1.Label[a];
777
 
778
                    if (a < MaxAnalog - 1)
779
                        Out << ';';
780
                }
781
            }
782
            Out << "\n";
783
        }
784
        else
785
        {
786
            CSVFile->open(QIODevice::Append | QIODevice::Text);
787
        }
788
 
789
        pb_Record->setIcon(ToolBox::Icon(6));
790
        pb_Record->setText("CSV Stop");
791
        ac_RecordCSV->setIcon(ToolBox::Icon(6));
792
        ac_RecordCSV->setText("CSV Stop");
793
    }
794
    else
795
    {
796
        CSVFile->close();
797
        pb_Record->setIcon(ToolBox::Icon(7));
798
        pb_Record->setText("CSV Aufzeichnen");
799
        ac_RecordCSV->setIcon(ToolBox::Icon(7));
800
        ac_RecordCSV->setText("CSV  Aufzeichnen");
801
    }
802
}
803
 
804
void MKTool::show_DebugData()
805
{
806
    if (CSVFile->isOpen())
807
    {
808
        write_CSV();
809
    }
810
 
811
    if (ac_StartPlotter->isChecked())
812
    {
813
        aID[NextPlot] = NextPlot;
814
 
815
        for (int a = 0; a < MaxAnalog; a++)
816
        {
817
            aData[a][NextPlot] = AnalogData[a];
818
        }
819
        NextPlot++;
820
 
821
        if ((tab_Main->currentWidget()->objectName() == QString("Tab_1")))
822
            update_Plot();
823
    }
824
 
825
    le_A_0->setText(QString("%1").arg(AnalogData[0]));
826
    le_A_1->setText(QString("%1").arg(AnalogData[1]));
827
    le_A_2->setText(QString("%1").arg(AnalogData[2]));
828
    le_A_3->setText(QString("%1").arg(AnalogData[3]));
829
    le_A_4->setText(QString("%1").arg(AnalogData[4]));
830
    le_A_5->setText(QString("%1").arg(AnalogData[5]));
831
    le_A_6->setText(QString("%1").arg(AnalogData[6]));
832
    le_A_7->setText(QString("%1").arg(AnalogData[7]));
833
    le_A_8->setText(QString("%1").arg(AnalogData[8]));
834
    le_A_9->setText(QString("%1").arg(AnalogData[9]));
835
    le_A_10->setText(QString("%1").arg(AnalogData[10]));
836
    le_A_11->setText(QString("%1").arg(AnalogData[11]));
837
    le_A_12->setText(QString("%1").arg(AnalogData[12]));
838
    le_A_13->setText(QString("%1").arg(AnalogData[13]));
839
    le_A_14->setText(QString("%1").arg(AnalogData[14]));
840
    le_A_15->setText(QString("%1").arg(AnalogData[15]));
841
    le_A_16->setText(QString("%1").arg(AnalogData[16]));
842
    le_A_17->setText(QString("%1").arg(AnalogData[17]));
843
    le_A_18->setText(QString("%1").arg(AnalogData[18]));
844
    le_A_19->setText(QString("%1").arg(AnalogData[19]));
845
    le_A_20->setText(QString("%1").arg(AnalogData[20]));
846
    le_A_21->setText(QString("%1").arg(AnalogData[21]));
847
    le_A_22->setText(QString("%1").arg(AnalogData[22]));
848
    le_A_23->setText(QString("%1").arg(AnalogData[23]));
849
    le_A_24->setText(QString("%1").arg(AnalogData[24]));
850
    le_A_25->setText(QString("%1").arg(AnalogData[25]));
851
    le_A_26->setText(QString("%1").arg(AnalogData[26]));
852
    le_A_27->setText(QString("%1").arg(AnalogData[27]));
853
    le_A_28->setText(QString("%1").arg(AnalogData[28]));
854
    le_A_29->setText(QString("%1").arg(AnalogData[29]));
855
    le_A_30->setText(QString("%1").arg(AnalogData[30]));
856
    le_A_31->setText(QString("%1").arg(AnalogData[31]));
857
}
858
 
859
 
860
// Seriel-Port Bereich, Befehle senden und Daten empfangen
861
//////////////////////////////////////////////////////////
862
 
863
// Neues Datenpacket empfangen -> Verarbeiten
864
void MKTool::new_RXData(sRxData RX) // DONE 0.71g
865
{
866
 
867
    if (LastSend.length() > 2)
868
    {
869
    }
870
 
871
    int HardwareID = RX.Input[1] - 'a';
872
 
873
    switch(HardwareID)
874
    {
875
        case ADDRESS_FC :
876
            switch(RX.Input[2])
877
            {
878
                // Stick-Belegung der Fernsteuerung
879
                case 'P' : // DONE 0.71g
880
                    if (ToolBox::Decode64(RX))
881
                    {
882
                        f_Settings->pb_K1->setValue(ToolBox::Data2Int(RX.Decode,  2,true));
883
                        f_Settings->pb_K2->setValue(ToolBox::Data2Int(RX.Decode,  4,true));
884
                        f_Settings->pb_K3->setValue(ToolBox::Data2Int(RX.Decode,  6,true));
885
                        f_Settings->pb_K4->setValue(ToolBox::Data2Int(RX.Decode,  8,true));
886
                        f_Settings->pb_K5->setValue(ToolBox::Data2Int(RX.Decode, 10 ,true));
887
                        f_Settings->pb_K6->setValue(ToolBox::Data2Int(RX.Decode, 12,true));
888
                        f_Settings->pb_K7->setValue(ToolBox::Data2Int(RX.Decode, 14,true));
889
                        f_Settings->pb_K8->setValue(ToolBox::Data2Int(RX.Decode, 16,true));
890
                    }
891
                break;
892
                // Settings lesen
893
                case 'Q' : // DONE 0.71g
894
                    if (ToolBox::Decode64(RX))
895
                    {
896
                        TickerEvent[0] = false;
897
 
898
                        if (RX.Decode[1] == VERSION_SETTINGS)
899
                        {
900
                            int Settings_ID = RX.Decode[0];
901
                            for (int a = 0; a < MaxParameter; a++)
902
                            {
903
                                FCSettings[a] = RX.Decode[a + 2];
904
                            }
905
                            //show_ParameterSet(Settings_ID);
906
                            f_Settings->show_FCSettings(Settings_ID, FCSettings);
907
                        }
908
                        else
909
                        {
910
                            f_Settings->pb_Read->setDisabled(true);
911
                            f_Settings->pb_Write->setDisabled(true);
912
 
913
                            QMessageBox::warning(this, QA_NAME,
914
                                   "Versionen inkompatibel. \nParameterbearbeitung nicht moeglich.", QMessageBox::Ok);
915
                        }
916
                    }
917
                break;
918
                // Settings geschrieben
919
                case 'S' : // DONE 0.71g
920
                    TickerEvent[0] = false;
921
                break;
922
            }
923
 
924
        case ADDRESS_NC :
925
            switch(RX.Input[2])
926
            {
927
                // Navigationsdaten
928
                case 'O' : // NOT DONE 0.12h
929
                    if (ToolBox::Decode64(RX))
930
                    {
931
                    }
932
                break;
933
            }
934
//        case ADDRESS_MK3MAG :
935
 
936
        default :
937
            switch(RX.Input[2])
938
            {
939
                // LCD-Anzeige
940
                case 'L' : // DONE 0.71g
941
                    if (ToolBox::Decode64(RX))
942
                    {
943
                        int LCD[150];
944
                        memcpy(LCD,RX.Decode, sizeof(RX.Decode));
945
 
946
                        LCD_Page     = RX.Decode[0];
947
                        LCD_MAX_Page = RX.Decode[1];
948
 
949
                        le_LCD0->setText(ToolBox::Data2QString(LCD,2,22));
950
                        le_LCD1->setText(ToolBox::Data2QString(LCD,22,42));
951
                        le_LCD2->setText(ToolBox::Data2QString(LCD,42,62));
952
                        le_LCD3->setText(ToolBox::Data2QString(LCD,62,82));
953
 
954
                        TickerEvent[0] = false;
955
                    }
956
                break;
957
                // Analoglabels
958
                case 'A' : // DONE 0.71g
959
                    if (ToolBox::Decode64(RX))
960
                    {
961
                        int Position = RX.Decode[0];
962
                        if (Position != 31)
963
                        {
964
                            Settings->Analog1.Label[Position] = ToolBox::Data2QString(RX.Decode,1,17).trimmed();
965
                            if (Settings->Analog1.Label[Position] == "")
966
                            {
967
                                Settings->Analog1.Label[Position] = "A-" + QString("%1").arg(Position);
968
                            }
969
                            Position ++;
970
                            TX_Data[0] = Position;
971
                            send_Data('a', ADDRESS_ALL, TX_Data, 1, true);
972
                        }
973
                        if (Position == 31)
974
                        {
975
                            for (int a = 0; a < MaxAnalog; a++)
976
                            {
977
                                lb_Analog[a]->setText(Settings->Analog1.Label[a]);
978
                            }
979
                            Settings->Analog1.Version = Mode.Version;
980
                            Settings->write_Settings_AnalogLabels(HardwareID);
981
                            config_Plot();
982
                        }
983
                    }
984
                break;
985
                // Debug-Daten
986
                case 'D' : // DONE 0.71g
987
                    if (ToolBox::Decode64(RX))
988
                    {
989
                        for (int i = 0; i < MaxAnalog; i++)
990
                        {
991
                            AnalogData[i] = ToolBox::Data2Int(RX.Decode, (i * 2) + 2);
992
                        }
993
                        show_DebugData();
994
                    }
995
                break;
996
                // Version
997
                case 'V' : // DONE 0.71h
998
                    if (ToolBox::Decode64(RX))
999
                    {
1000
                        TickerEvent[0] = false;
1001
 
1002
                        Mode.ID            = HardwareID;
1003
                        Mode.VERSION_MAJOR = RX.Decode[0];
1004
                        Mode.VERSION_MINOR = RX.Decode[1];
1005
                        Mode.VERSION_PATCH = RX.Decode[4];
1006
                        Mode.VERSION_SERIAL_MAJOR = RX.Decode[2];
1007
                        Mode.VERSION_SERIAL_MINOR = RX.Decode[3];
1008
 
1009
                        Mode.Hardware   = HardwareType[Mode.ID];
1010
                        Mode.Version    = QString("%1").arg(RX.Decode[0]) + "." + QString("%1").arg(RX.Decode[1]) + QString(RX.Decode[4] + 'a');
1011
 
1012
                        setWindowTitle(QA_NAME + " v" + QA_VERSION + " - " + Mode.Hardware + " " + Mode.Version);
1013
 
1014
                        if (Mode.VERSION_SERIAL_MAJOR != VERSION_SERIAL_MAJOR)
1015
                        {
1016
                                AllowSend = false;
1017
                                QMessageBox::warning(this, QA_NAME,
1018
                                   "Serielles Protokoll Inkompatibel. \nBitte neue Programmversion installieren,", QMessageBox::Ok);
1019
                        }
1020
 
1021
                        TX_Data[0] = Settings->Data.Debug_Slow / 10;
1022
                        send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
1023
 
1024
                        // Wenn MK3MAG dann andauernd Daten neu anfragen.
1025
                        if (Mode.ID == ADDRESS_MK3MAG)
1026
                        {
1027
                            TickerEvent[3] = true;
1028
                        }
1029
 
1030
                        // Wenn FlightCtrl dann Settings abfragen.
1031
                        if (Mode.ID == ADDRESS_FC)
1032
                        {
1033
                            {
1034
                                TX_Data[0] = 0xff;
1035
                                TX_Data[1] = 0;
1036
                                send_Data('q', ADDRESS_FC, TX_Data, 1);
1037
                            }
1038
                        }
1039
                        // Wenn nicht Lesen und Schreiben der Settings deaktivieren.
1040
                        else
1041
                        {
1042
                                f_Settings->pb_Read->setDisabled(true);
1043
                                f_Settings->pb_Write->setDisabled(true);
1044
                        }
1045
 
1046
                        Settings->read_Settings_Analog(HardwareID);
1047
                        Settings->read_Settings_AnalogLabels(HardwareID);
1048
 
1049
                        if (Settings->Analog1.Version != Mode.Version)
1050
                        {
1051
                            lb_Status->setText("Analoglabel-Version unterschiedlich. Lese Analoglabels neu aus.");
1052
                            slot_ac_GetLabels();
1053
                        }
1054
                        else
1055
                        for (int a = 0; a < MaxAnalog; a++)
1056
                        {
1057
                            lb_Analog[a]->setText(Settings->Analog1.Label[a]);
1058
                        }
1059
                        config_Plot();
1060
                    }
1061
                break;
1062
            }
1063
    }
1064
}
1065
 
1066
// Neue Daten an der Schnittstelle
1067
void MKTool::slot_newDataReceived(const QByteArray &dataReceived) // DONE 0.71g
1068
{
1069
    const char *RXt;
1070
    RXt = dataReceived.data();
1071
    int a = 0;
1072
 
1073
    while (RXt[a] != '\0')
1074
    {
1075
        if (RXt[a] == '\r')
1076
        {
1077
            while ((RxData.String.length() > 1) && (RxData.String.at(1) == '#'))
1078
            {
1079
                RxData.String.remove(0,1);
1080
            }
1081
 
1082
            if (ToolBox::check_CRC(RxData.String))
1083
            {
1084
                RxData.Input = RxData.String.toLatin1().data();
1085
                new_RXData(RxData);
1086
 
1087
                if ((cb_ShowData->isChecked()) && ((tab_Main->currentWidget()->objectName() == QString("Tab_3")) || (cb_ShowAlways->isChecked())))
1088
                {
1089
                    te_RX->moveCursor(QTextCursor::End,  QTextCursor::MoveAnchor);
1090
//                    te_RX->insertPlainText(" > " + RxData.String + '\r');
1091
                    te_RX->insertHtml("<span style=\"color:#00008b;\">" + RxData.String + "<br /></span>");
1092
                }
1093
            }
1094
            else
1095
            {
1096
                if ((cb_ShowMSG->isChecked()) && ((tab_Main->currentWidget()->objectName() == QString("Tab_3")) || (cb_ShowAlways->isChecked())))
1097
                {
1098
                    te_RX->moveCursor(QTextCursor::End,  QTextCursor::MoveAnchor);
1099
//                    te_RX->insertPlainText(" > " + RxData.String + '\r');
1100
                    te_RX->insertHtml("<span style=\"color:#008b00;\">" + RxData.String + "<br /></span>");
1101
                }
1102
            }
1103
            RxData.String = QString("");
1104
        }
1105
        else
1106
        {
1107
            {
1108
                RxData.String = RxData.String + QString(RXt[a]);
1109
            }
1110
        }
1111
        a++;
1112
    }
1113
}
1114
 
1115
// Seriellen Port öffnen
1116
void MKTool::slot_OpenPort()
1117
{
1118
    if (serialPort->isOpen())
1119
    {
1120
        TX_Data[0] = Settings->Data.Debug_Off / 10;
1121
        send_Data('d', ADDRESS_ALL, TX_Data, 1, false);
171 KeyOz 1122
        sleep(1);
170 KeyOz 1123
        TX_Data[0] = 0;
1124
        TX_Data[1] = 0;
1125
        TX_Data[2] = 0;
1126
        TX_Data[3] = 0;
1127
        send_Data('t', ADDRESS_FC, TX_Data, 4, false);
1128
        serialPort->close();
1129
        pb_Open->setText("Verbinden");
1130
        ac_ConnectTTY->setText("Verbinden");
1131
        pb_Open->setIcon(ToolBox::Icon(9));
1132
        ac_ConnectTTY->setIcon(ToolBox::Icon(9));
1133
 
1134
        Ticker->stop();
1135
    }
1136
    else
1137
    {
1138
        serialPort->setPort(le_Port->text()); //Port
1139
 
1140
        serialPort->setBaudRate(BAUD57600); //BaudRate
1141
        serialPort->setDataBits(DATA_8); //DataBits
1142
        serialPort->setParity(PAR_NONE); //Parity
1143
        serialPort->setStopBits(STOP_1); //StopBits
1144
        serialPort->setFlowControl(FLOW_OFF); //FlowControl
1145
 
1146
        serialPort->setTimeout(0, 10);
1147
        serialPort->enableSending();
1148
        serialPort->enableReceiving();
1149
 
1150
        serialPort->open();
1151
        if (serialPort->isOpen())
1152
        {
1153
            serialPort->receiveData();
1154
 
1155
            send_Data('v', ADDRESS_ALL, TX_Data, 0, true);
1156
 
1157
            pb_Open->setText("Trennen");
1158
            ac_ConnectTTY->setText("Trennen");
1159
            pb_Open->setIcon(ToolBox::Icon(8));
1160
            ac_ConnectTTY->setIcon(ToolBox::Icon(8));
1161
 
1162
            Ticker->start(2000);
1163
        }
1164
    }
1165
}
1166
 
1167
// Daten senden
1168
void MKTool::send_Data(char CMD, int Address, char Data[150],unsigned int Length, bool Resend) // DONE 0.71g
1169
{
1170
    if (serialPort->isOpen() && AllowSend)
1171
    {
1172
        QString TX_Data = ToolBox::Encode64(Data, Length);
1173
 
1174
        TX_Data = QString("#") + (QString('a' + Address)) + QString(CMD) + TX_Data;
1175
 
1176
//    qDebug(TX_Data.toLatin1().data());
1177
 
1178
        TX_Data = ToolBox::add_CRC(TX_Data) + '\r';
1179
 
1180
//    qDebug(TX_Data.toLatin1().data());
1181
 
1182
        if (Resend)
1183
        {
1184
            LastSend = TX_Data;
1185
            TickerEvent[0] = true;
1186
        }
1187
 
1188
        QByteArray Temp(TX_Data.toUtf8());
1189
        serialPort->sendData(Temp);
1190
 
1191
        if (cb_ShowSend->isChecked())
1192
        {
1193
            te_RX->moveCursor(QTextCursor::End,  QTextCursor::MoveAnchor);
1194
            te_RX->insertHtml("<span style='color:#8b0000;'>" + TX_Data + "<br /></span>");
1195
        }
1196
    }
1197
}
1198
 
1199
 
1200
// Programm beenden
1201
///////////////////
1202
 
1203
MKTool::~MKTool()
1204
{
1205
//    qDebug(" Programm Ende ..!! ");
1206
    if (serialPort->isOpen())
1207
    {
1208
        serialPort->close();
1209
    }
1210
 
1211
    set_Preferences();
1212
    Settings->write_Settings();
1213
 
1214
    if (CSVFile->isOpen())
1215
    {
1216
        CSVFile->close();
1217
    }
1218
}