kopia lustrzana https://github.com/dgatf/Oscilloscope
Update to v0.3
rodzic
78d468c5e0
commit
6b27a3a53d
|
@ -1,6 +1,6 @@
|
||||||
# Oscilloscope Serial
|
# Oscilloscope Serial
|
||||||
|
|
||||||
An oscilloscope application that reads the values at serial port generated by an Arduino board and based on the value of the analog pin A0
|
An oscilloscope application that reads the values at serial port generated by an Arduino board and based on the value of the analog pin A0 (A5 for Leonardo)
|
||||||
|
|
||||||
<p align="center"><img src="./images/img1.png" width="600"><br>
|
<p align="center"><img src="./images/img1.png" width="600"><br>
|
||||||
<i>Main window</i><br><br></p>
|
<i>Main window</i><br><br></p>
|
||||||
|
@ -17,7 +17,7 @@ Flash _oscilloscope_. In the Oscilloscope app configure the serial port. By defa
|
||||||
|
|
||||||
You can connect any signal up to 5 volts to the analog pin A0. For signals over 5V a voltage divider is needed.
|
You can connect any signal up to 5 volts to the analog pin A0. For signals over 5V a voltage divider is needed.
|
||||||
|
|
||||||
For ATmega boards it is defined a PWM signal at pin OC1B. To test the Oscilloscope app connect pin OC1B to pin A0
|
For ATmega boards it is defined a PWM signal at pin OC1B. To test the Oscilloscope app connect pin OC1B to pin A0/A5
|
||||||
Adjust PWM signal with PWM_FREQ and PWM_DUTY. Default is 1000Hz, 50% duty.
|
Adjust PWM signal with PWM_FREQ and PWM_DUTY. Default is 1000Hz, 50% duty.
|
||||||
|
|
||||||
Pin OC1B location:
|
Pin OC1B location:
|
||||||
|
@ -43,6 +43,9 @@ Supported OS:
|
||||||
|
|
||||||
## Change log:
|
## Change log:
|
||||||
|
|
||||||
|
v0.3
|
||||||
|
- Minor fixes
|
||||||
|
|
||||||
[v0.2](https://github.com/dgatf/Oscilloscope/releases/tag/v0.2)
|
[v0.2](https://github.com/dgatf/Oscilloscope/releases/tag/v0.2)
|
||||||
- Upgrade to qml gui
|
- Upgrade to qml gui
|
||||||
- Add csv export
|
- Add csv export
|
||||||
|
|
|
@ -1,31 +1,209 @@
|
||||||
#define serial Serial
|
#define serial Serial
|
||||||
|
|
||||||
/* PWM signal */
|
/* PWM signal */
|
||||||
#define PWM_FREQ 1000 // HZ (1000HZ=1ms)
|
#define PWM_FREQ 20000 // HZ (1000HZ=1ms)
|
||||||
#define PWM_DUTY 0.5 // %/100
|
#define PWM_DUTY 0.5 // %/100
|
||||||
|
|
||||||
|
/* Capture buffer */
|
||||||
|
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__)
|
||||||
|
#define BUFFER_LEN 1500
|
||||||
|
#endif
|
||||||
|
#if defined(__AVR_ATmega32U4__)
|
||||||
|
#define BUFFER_LEN 2000
|
||||||
|
#endif
|
||||||
|
#if defined(__AVR_ATmega2560__)
|
||||||
|
#define BUFFER_LEN 5000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Data bits */
|
||||||
|
#define DATABITS 8 // 8, (4), 1
|
||||||
|
|
||||||
|
/* ADC Prescaler */
|
||||||
|
#define PRESCALER 32 // 32, 16, 8, (4)
|
||||||
|
|
||||||
|
/* Mode */
|
||||||
|
#define REALTIME 0
|
||||||
|
#define CAPTURE 1
|
||||||
|
#define MODE REALTIME // REALTIME, CAPTURE
|
||||||
|
|
||||||
#define MS_TO_COMP(SCALER) (F_CPU / (SCALER * 1000.0))
|
#define MS_TO_COMP(SCALER) (F_CPU / (SCALER * 1000.0))
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_AVR)
|
volatile bool isBufferFull = false;
|
||||||
|
volatile uint8_t buffer[BUFFER_LEN];
|
||||||
|
|
||||||
ISR(ADC_vect) {
|
void (*ADC_vect_handlerP)() = NULL;
|
||||||
|
|
||||||
|
ISR(ADC_vect)
|
||||||
|
{
|
||||||
|
if (ADC_vect_handlerP)
|
||||||
|
ADC_vect_handlerP();
|
||||||
|
/*static uint16_t contByte = 0;
|
||||||
|
buffer[contByte] = ADCH;
|
||||||
|
if (contByte == BUFFER_LEN)
|
||||||
|
{
|
||||||
|
isBufferFull = true;
|
||||||
|
contByte = 0;
|
||||||
|
ADCSRA &= ~_BV(ADIE);
|
||||||
|
|
||||||
|
}
|
||||||
|
contByte++;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Capture */
|
||||||
|
|
||||||
|
void capture_8b()
|
||||||
|
{
|
||||||
|
static uint16_t contByte = 0;
|
||||||
|
buffer[contByte] = ADCH;
|
||||||
|
if (contByte == BUFFER_LEN)
|
||||||
|
{
|
||||||
|
isBufferFull = true;
|
||||||
|
contByte = 0;
|
||||||
|
ADCSRA &= ~_BV(ADIE);
|
||||||
|
|
||||||
|
}
|
||||||
|
contByte++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void capture_4b()
|
||||||
|
{
|
||||||
|
static uint16_t contByte = 0;
|
||||||
|
static bool newByte = false;
|
||||||
|
if (newByte)
|
||||||
|
{
|
||||||
|
buffer[contByte] |= (ADCH & 0xF0);
|
||||||
|
contByte++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
buffer[contByte] = ADCH >> 4;
|
||||||
|
if (contByte == BUFFER_LEN)
|
||||||
|
{
|
||||||
|
isBufferFull = true;
|
||||||
|
contByte = 0;
|
||||||
|
ADCSRA &= ~_BV(ADIE);
|
||||||
|
|
||||||
|
}
|
||||||
|
newByte = !newByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
void capture_1b()
|
||||||
|
{
|
||||||
|
static uint16_t contByte = 0;
|
||||||
|
static uint8_t data = 0;
|
||||||
|
static uint8_t contBit = 0;
|
||||||
|
data |= (ADCH & 0x80);
|
||||||
|
contBit++;
|
||||||
|
if (contBit == 8)
|
||||||
|
{
|
||||||
|
buffer[contByte] = data;
|
||||||
|
contBit = 0;
|
||||||
|
contByte++;
|
||||||
|
}
|
||||||
|
if (contByte == BUFFER_LEN)
|
||||||
|
{
|
||||||
|
isBufferFull = true;
|
||||||
|
contByte = 0;
|
||||||
|
ADCSRA &= ~_BV(ADIE);
|
||||||
|
}
|
||||||
|
data >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Realtime */
|
||||||
|
|
||||||
|
void realtime_8b()
|
||||||
|
{
|
||||||
serial.write((uint8_t)ADCH);
|
serial.write((uint8_t)ADCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void realtime_4b()
|
||||||
serial.begin(1000000);
|
{
|
||||||
|
static uint8_t data = 0;
|
||||||
|
static bool sendByte = false;
|
||||||
|
if (sendByte)
|
||||||
|
serial.write(data | (ADCH & 0xF0));
|
||||||
|
else
|
||||||
|
data = ADCH >> 4;
|
||||||
|
sendByte = !sendByte;
|
||||||
|
|
||||||
/* ADC init
|
}
|
||||||
Capture time: F_CPU / ADC_PRESCALER / 13 ADC TICKS:
|
|
||||||
Prescaler 32: 1.6M / 32 / 13 = 76923 -> 1 / 38461 = 26 us
|
void realtime_1b()
|
||||||
Prescaler 16: 1.6M / 16 / 13 = 76923 -> 1 / 76923 = 13 us (this is too fast for some devices)
|
{
|
||||||
|
static uint8_t data = 0;
|
||||||
|
static uint8_t cont;
|
||||||
|
data |= (ADCH & 0x80);
|
||||||
|
cont++;
|
||||||
|
if (cont == 8)
|
||||||
|
{
|
||||||
|
serial.write(data);
|
||||||
|
data = 0;
|
||||||
|
cont = 0;
|
||||||
|
}
|
||||||
|
data >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendData()
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < BUFFER_LEN; i++) {
|
||||||
|
while (!serial.availableForWrite());
|
||||||
|
serial.write(buffer[i]);
|
||||||
|
}
|
||||||
|
isBufferFull = false;
|
||||||
|
delay(2000);
|
||||||
|
ADCSRA |= _BV(ADIE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
/*
|
||||||
|
ADC init
|
||||||
|
Capture time: F_CPU / ADC_PRESCALER / 13 ADC TICKS: (1 byte at 1000000 = 10us)
|
||||||
|
Prescaler 32: 1.6M / 32 / 13 = 38461 -> 1 / 38461 = 26 us -> realtime 8 data bits
|
||||||
|
Prescaler 16: 1.6M / 16 / 13 = 76923 -> 1 / 76923 = 13 us -> realtime 4 data bits
|
||||||
|
Prescaler 8: 1.6M / 8 / 13 = 153846 -> 1 / 153846 = 6.5 us -> capture
|
||||||
|
Prescaler 4: 1.6M / 4 / 13 = 307692-> 1 / 307692 = 3.25 us -> too fast
|
||||||
|
Prescaler 2: 1.6M / 2 / 13 = 615385-> 1 / 615385 = 1.62 us -> too fast
|
||||||
*/
|
*/
|
||||||
|
switch (PRESCALER)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS1);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS1) | _BV(ADPS0);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
ADMUX = _BV(REFS0) | _BV(ADLAR);
|
ADMUX = _BV(REFS0) | _BV(ADLAR);
|
||||||
//ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2); // prescaler 16
|
|
||||||
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS0); // prescaler 32
|
|
||||||
ADCSRB = 0;
|
ADCSRB = 0;
|
||||||
ADCSRA |= _BV(ADSC);
|
ADCSRA |= _BV(ADSC);
|
||||||
|
|
||||||
|
if (MODE == REALTIME)
|
||||||
|
{
|
||||||
|
serial.begin(1000000, SERIAL_8N1);
|
||||||
|
if (DATABITS == 8)
|
||||||
|
ADC_vect_handlerP = realtime_8b;
|
||||||
|
if (DATABITS == 4)
|
||||||
|
ADC_vect_handlerP = realtime_4b;
|
||||||
|
if (DATABITS == 1)
|
||||||
|
ADC_vect_handlerP = realtime_1b;
|
||||||
|
}
|
||||||
|
if (MODE == CAPTURE)
|
||||||
|
{
|
||||||
|
serial.begin(115200, SERIAL_8N1);
|
||||||
|
if (DATABITS == 8)
|
||||||
|
ADC_vect_handlerP = capture_8b;
|
||||||
|
if (DATABITS == 4)
|
||||||
|
ADC_vect_handlerP = capture_4b;
|
||||||
|
if (DATABITS == 1)
|
||||||
|
ADC_vect_handlerP = capture_1b;
|
||||||
|
}
|
||||||
|
|
||||||
/* PWM signal is available at pin OC1B. To test the Oscilloscope app connect pin OC1B to pin A0
|
/* PWM signal is available at pin OC1B. To test the Oscilloscope app connect pin OC1B to pin A0
|
||||||
Adjust PWM signal with PWM_FREQ and PWM_DUTY. Default: PWM 1000Hz, 50% DUTY
|
Adjust PWM signal with PWM_FREQ and PWM_DUTY. Default: PWM 1000Hz, 50% DUTY
|
||||||
Pin OC1B:
|
Pin OC1B:
|
||||||
|
@ -38,36 +216,25 @@ void setup() {
|
||||||
#else
|
#else
|
||||||
DDRB |= _BV(DDB2);
|
DDRB |= _BV(DDB2);
|
||||||
#endif
|
#endif
|
||||||
DDRB |= _BV(DDB2);
|
|
||||||
TCCR1A = _BV(WGM11) | _BV(WGM10);
|
TCCR1A = _BV(WGM11) | _BV(WGM10);
|
||||||
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11); // scaler 8
|
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11); // scaler 8
|
||||||
TCCR1A |= _BV(COM1B1);
|
TCCR1A |= _BV(COM1B1);
|
||||||
|
|
||||||
|
// PWM signal
|
||||||
OCR1A = 1000.0 / PWM_FREQ * MS_TO_COMP(8);
|
OCR1A = 1000.0 / PWM_FREQ * MS_TO_COMP(8);
|
||||||
OCR1B = PWM_DUTY * OCR1A;
|
OCR1B = PWM_DUTY * OCR1A;
|
||||||
|
|
||||||
|
/* // sinus signal (1Hz)
|
||||||
|
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // scaler 1
|
||||||
|
OCR1A = 1000.0 / 38000 * MS_TO_COMP(8);
|
||||||
|
OCR1B = PWM_DUTY * OCR1A;*/
|
||||||
|
|
||||||
|
//TIMSK1 = OCIE1A;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
if (isBufferFull)
|
||||||
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Interval between analog readings (for non ATmega boards. It has to be the same as defined in the Oscilloscope settings */
|
|
||||||
#define INTERVAL 200// microseconds (us). Minimun is 200
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
serial.begin(1000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
static uint16_t ts = 0;
|
|
||||||
if ((uint16_t)micros() - ts > INTERVAL)
|
|
||||||
{
|
|
||||||
ts = micros();
|
|
||||||
uint8_t val = analogRead(A0) >> 2;
|
|
||||||
serial.write(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -91,7 +91,11 @@ Item {
|
||||||
ListElement { text: "5ms/d"; value: 5000 }
|
ListElement { text: "5ms/d"; value: 5000 }
|
||||||
ListElement { text: "1ms/d"; value: 1000 }
|
ListElement { text: "1ms/d"; value: 1000 }
|
||||||
ListElement { text: "500μs/d"; value: 500 }
|
ListElement { text: "500μs/d"; value: 500 }
|
||||||
|
ListElement { text: "400μs/d"; value: 400 }
|
||||||
|
ListElement { text: "300μs/d"; value: 300 }
|
||||||
|
ListElement { text: "200μs/d"; value: 200 }
|
||||||
ListElement { text: "100μs/d"; value: 100 }
|
ListElement { text: "100μs/d"; value: 100 }
|
||||||
|
ListElement { text: "50μs/d"; value: 50 }
|
||||||
}
|
}
|
||||||
currentIndex: 2
|
currentIndex: 2
|
||||||
onCurrentValueChanged: oscilloscope.setHDiv(currentValue)
|
onCurrentValueChanged: oscilloscope.setHDiv(currentValue)
|
||||||
|
|
|
@ -110,7 +110,7 @@ Item {
|
||||||
ListElement { text: "500000" }
|
ListElement { text: "500000" }
|
||||||
ListElement { text: "1000000" }
|
ListElement { text: "1000000" }
|
||||||
}
|
}
|
||||||
currentIndex: 7
|
currentIndex: 8
|
||||||
}
|
}
|
||||||
Label { text: "Data bits" }
|
Label { text: "Data bits" }
|
||||||
ComboBox {
|
ComboBox {
|
||||||
|
@ -139,7 +139,26 @@ Item {
|
||||||
SpinBox {
|
SpinBox {
|
||||||
id: interval
|
id: interval
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
value: 26
|
value: 2600
|
||||||
|
from: 0
|
||||||
|
to: 100 * 100
|
||||||
|
editable: true
|
||||||
|
|
||||||
|
property int decimals: 2
|
||||||
|
property real realValue: value / 100
|
||||||
|
|
||||||
|
validator: DoubleValidator {
|
||||||
|
bottom: Math.min(interval.from, interval.to)
|
||||||
|
top: Math.max(interval.from, interval.to)
|
||||||
|
}
|
||||||
|
|
||||||
|
textFromValue: function(value, locale) {
|
||||||
|
return Number(value / 100).toLocaleString(locale, 'f', interval.decimals)
|
||||||
|
}
|
||||||
|
|
||||||
|
valueFromText: function(text, locale) {
|
||||||
|
return Number.fromLocaleString(locale, text) * 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ Oscilloscope::Oscilloscope(qreal pixelRatio)
|
||||||
, pixmap(new QPixmap(pmWidth, pmHeight))
|
, pixmap(new QPixmap(pmWidth, pmHeight))
|
||||||
, paint(new QPainter(pixmap))
|
, paint(new QPainter(pixmap))
|
||||||
, serial(new QSerialPort())
|
, serial(new QSerialPort())
|
||||||
|
, timer(new QTimer())
|
||||||
{
|
{
|
||||||
|
connect(timer, &QTimer::timeout, this, &Oscilloscope::timeOut);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Oscilloscope::Oscilloscope(qreal pixelRatio)
|
Oscilloscope::Oscilloscope(qreal pixelRatio)
|
||||||
|
@ -39,7 +41,8 @@ Oscilloscope::Oscilloscope(qreal pixelRatio)
|
||||||
jclass classId = env->FindClass("org/qtproject/qt/UsbSerialInterface");
|
jclass classId = env->FindClass("org/qtproject/qt/UsbSerialInterface");
|
||||||
usbSerial = QAndroidJniObject(classId);
|
usbSerial = QAndroidJniObject(classId);
|
||||||
JNINativeMethod methods[] { {"sendBuffer", "([B)V", reinterpret_cast<void *>(sendBuffer)}
|
JNINativeMethod methods[] { {"sendBuffer", "([B)V", reinterpret_cast<void *>(sendBuffer)}
|
||||||
, {"sendStatus", "(ILjava/lang/String;)V", reinterpret_cast<void *>(sendStatus)} };
|
, {"sendStatus", "(ILjava/lang/String;)V", reinterpret_cast<void *>(sendStatus)}
|
||||||
|
};
|
||||||
env->RegisterNatives(classId, methods, 2);
|
env->RegisterNatives(classId, methods, 2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,7 +68,7 @@ QPixmap Oscilloscope::requestPixmap(const QString &id, QSize *size, const QSize
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
void Oscilloscope::openSerialPort(QString portName, QString baudrate, QString dataBits, QString parity, QString interval)
|
void Oscilloscope::openSerialPort(QString portName, QString baudrate, QString dataBits, QString parity, QString intervalStr)
|
||||||
{
|
{
|
||||||
connect(serial, &QSerialPort::readyRead, this, &Oscilloscope::readData);
|
connect(serial, &QSerialPort::readyRead, this, &Oscilloscope::readData);
|
||||||
serial->setPortName(portName);
|
serial->setPortName(portName);
|
||||||
|
@ -74,11 +77,11 @@ void Oscilloscope::openSerialPort(QString portName, QString baudrate, QString da
|
||||||
serial->setParity((QSerialPort::Parity)parity.toUInt());
|
serial->setParity((QSerialPort::Parity)parity.toUInt());
|
||||||
serial->setStopBits(QSerialPort::StopBits::OneStop);
|
serial->setStopBits(QSerialPort::StopBits::OneStop);
|
||||||
serial->setFlowControl(QSerialPort::FlowControl::NoFlowControl);
|
serial->setFlowControl(QSerialPort::FlowControl::NoFlowControl);
|
||||||
this->interval = interval.toUInt();
|
interval = intervalStr.toUInt() / 100.0;
|
||||||
if (serial->open(QIODevice::ReadOnly)) {
|
if (serial->open(QIODevice::ReadOnly)) {
|
||||||
status = connected;
|
status = connected;
|
||||||
emit sendStatusConn(status);
|
emit sendStatusConn(status);
|
||||||
QString message("Connected (" + portName + " " + baudrate + "bps " + interval + "μs)");
|
QString message("Connected (" + portName + " " + baudrate + "bps " + QString::number(interval) + "μs)");
|
||||||
emit sendMessage(message);
|
emit sendMessage(message);
|
||||||
} else {
|
} else {
|
||||||
status = disconnected;
|
status = disconnected;
|
||||||
|
@ -96,9 +99,9 @@ void Oscilloscope::openSerialPort(QString portName, QString baudrate, QString da
|
||||||
parity_android = parity.toUInt();
|
parity_android = parity.toUInt();
|
||||||
jstring name = env->NewStringUTF(portName.toStdString().c_str());
|
jstring name = env->NewStringUTF(portName.toStdString().c_str());
|
||||||
usbSerial.callMethod<void>
|
usbSerial.callMethod<void>
|
||||||
("openConnection"
|
("openConnection"
|
||||||
, "(Landroid/content/Context;Ljava/lang/String;IIII)V"
|
, "(Landroid/content/Context;Ljava/lang/String;IIII)V"
|
||||||
, QtAndroid::androidContext().object(), name, baudrate.toUInt(), dataBits.toUInt(), 1, parity_android);
|
, QtAndroid::androidContext().object(), name, baudrate.toUInt(), dataBits.toUInt(), 1, parity_android);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -119,12 +122,34 @@ void Oscilloscope::closeSerialPort()
|
||||||
emit isPausedChanged(false);
|
emit isPausedChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Oscilloscope::timeOut()
|
||||||
|
{
|
||||||
|
timedOut = true;
|
||||||
|
isPixmapSent = false;
|
||||||
|
isDataStart = true;
|
||||||
|
processData(data);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
void Oscilloscope::readData()
|
void Oscilloscope::readData()
|
||||||
{
|
{
|
||||||
QByteArray data = serial->readAll();
|
if (isRealTime) {
|
||||||
if (!isPaused)
|
data = serial->readAll();
|
||||||
processData(data);
|
if (!isPaused) {
|
||||||
|
processData(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isPaused) {
|
||||||
|
timer->setSingleShot(true);
|
||||||
|
timer->start(500);
|
||||||
|
if (timedOut) {
|
||||||
|
data.clear();
|
||||||
|
timedOut = false;
|
||||||
|
}
|
||||||
|
data.append(serial->readAll());
|
||||||
|
timedOut = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void Oscilloscope::readData(const QByteArray &data)
|
void Oscilloscope::readData(const QByteArray &data)
|
||||||
|
@ -173,6 +198,10 @@ QStringList Oscilloscope::fillPortsInfo()
|
||||||
QStringList list;
|
QStringList list;
|
||||||
for (const QSerialPortInfo& info : infos) {
|
for (const QSerialPortInfo& info : infos) {
|
||||||
list.append(info.portName());
|
list.append(info.portName());
|
||||||
|
qDebug() << info.description();
|
||||||
|
qDebug() << info.manufacturer();
|
||||||
|
qDebug() << info.serialNumber();
|
||||||
|
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -180,9 +209,9 @@ QStringList Oscilloscope::fillPortsInfo()
|
||||||
QStringList Oscilloscope::fillPortsInfo()
|
QStringList Oscilloscope::fillPortsInfo()
|
||||||
{
|
{
|
||||||
QAndroidJniObject drivers = usbSerial.callObjectMethod
|
QAndroidJniObject drivers = usbSerial.callObjectMethod
|
||||||
("drivers"
|
("drivers"
|
||||||
, "(Landroid/content/Context;)Ljava/util/List;"
|
, "(Landroid/content/Context;)Ljava/util/List;"
|
||||||
, QtAndroid::androidContext().object());
|
, QtAndroid::androidContext().object());
|
||||||
QStringList list;
|
QStringList list;
|
||||||
int size = drivers.callMethod<jint>("size");
|
int size = drivers.callMethod<jint>("size");
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
@ -211,101 +240,129 @@ void Oscilloscope::processData(const QByteArray &data)
|
||||||
quint16 width = pmWidth;
|
quint16 width = pmWidth;
|
||||||
paint->setPen(QPen(QColor(signalColor), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
paint->setPen(QPen(QColor(signalColor), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||||
float xDelta = width * interval / 1000.0 / timeRange;
|
float xDelta = width * interval / 1000.0 / timeRange;
|
||||||
for (quint16 i = 0; i < data.size(); i++) {
|
static quint16 contX = 0;
|
||||||
// Find V limits
|
|
||||||
if ((quint8)data[i] > maxValue) {
|
|
||||||
maxValue = data[i];
|
|
||||||
}
|
|
||||||
if ((quint8)data[i] < minValue) {
|
|
||||||
minValue = data[i];
|
|
||||||
}
|
|
||||||
// Find triggers and signal properties
|
|
||||||
if ((quint8)data[i] - prevValue > 0) { // rising
|
|
||||||
deltaRising += (quint8)data[i] - prevValue;
|
|
||||||
deltaFalling = 0;
|
|
||||||
}
|
|
||||||
if ((quint8)data[i] - prevValue < 0) { // falling
|
|
||||||
deltaFalling += prevValue - (quint8)data[i];
|
|
||||||
deltaRising = 0;
|
|
||||||
}
|
|
||||||
prevValue = data[i];
|
|
||||||
if (((float)deltaRising) / 0xFF * 5 > triggerValue / 1000.0) {
|
|
||||||
if ((triggerType == rising || triggerType == none) && triggerCont - tsRising > 2) {
|
|
||||||
isTriggered = true;
|
|
||||||
rawFreq = triggerCont - tsRising;
|
|
||||||
rawDuty = triggerCont - tsFalling;
|
|
||||||
rawFreqAvg = 0.1 * rawFreq + 0.9 * rawFreqAvg;
|
|
||||||
rawDutyAvg = 0.1 * rawDuty + 0.9 * rawDutyAvg;
|
|
||||||
}
|
|
||||||
deltaRising = 0;
|
|
||||||
deltaFalling = 0;
|
|
||||||
tsRising = triggerCont;
|
|
||||||
}
|
|
||||||
if (((float)deltaFalling) / 0xFF * 5 > triggerValue / 1000.0) {
|
|
||||||
if (triggerType == falling && triggerCont - tsFalling > 2) {
|
|
||||||
isTriggered = true;
|
|
||||||
rawFreq = triggerCont - tsFalling;
|
|
||||||
rawDuty = triggerCont - tsRising;
|
|
||||||
rawFreqAvg = 0.1 * rawFreq + 0.9 * rawFreqAvg;
|
|
||||||
rawDutyAvg = 0.1 * rawDuty + 0.9 * rawDutyAvg;
|
|
||||||
}
|
|
||||||
deltaRising = 0;
|
|
||||||
deltaFalling = 0;
|
|
||||||
tsFalling = triggerCont;
|
|
||||||
}
|
|
||||||
triggerCont++;
|
|
||||||
// Capture
|
|
||||||
if (isCapturing) {
|
|
||||||
captureBuffer->append(data[i]);
|
|
||||||
}
|
|
||||||
// Draw new value
|
|
||||||
if (isTriggered == true || triggerType == none) {
|
|
||||||
float newxPos = oldxPos + xDelta;
|
|
||||||
qint16 newyPos = height + yZeroV - getYVal(data[i]);
|
|
||||||
// End of pixmap
|
|
||||||
if (newxPos > width) {
|
|
||||||
if (triggerType != none) {
|
|
||||||
isTriggered = false;
|
|
||||||
deltaRising = 0;
|
|
||||||
deltaFalling = 0;
|
|
||||||
}
|
|
||||||
emit sendPixmap();
|
|
||||||
|
|
||||||
if (pendingExport) {
|
if (isDataStart) {
|
||||||
savePixmap(filename);
|
oldxPos = 0;
|
||||||
pendingExport = false;
|
maxValue = 0;
|
||||||
|
minValue = 0;
|
||||||
|
drawBackground();
|
||||||
|
paint->setPen(QPen(QColor(signalColor), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||||
|
isDataStart =false;
|
||||||
|
isTriggered = false;
|
||||||
|
}
|
||||||
|
for (quint16 contByte = 0; contByte < data.size(); contByte++) {
|
||||||
|
for (quint16 contSubByte = 8 / dataBits; contSubByte > 0; contSubByte--) {
|
||||||
|
quint8 value = (data[contByte] << (contSubByte - 1) * dataBits) & ~(0xFF >> dataBits);
|
||||||
|
//quint8 value = data[contByte];
|
||||||
|
// Find V limits
|
||||||
|
if (value > maxValue) {
|
||||||
|
maxValue = value;
|
||||||
|
}
|
||||||
|
if (value < minValue) {
|
||||||
|
minValue = value;
|
||||||
|
}
|
||||||
|
// Find triggers and signal properties
|
||||||
|
if (value - prevValue > 0) { // rising
|
||||||
|
deltaRising += value - prevValue;
|
||||||
|
deltaFalling = 0;
|
||||||
|
}
|
||||||
|
if (value - prevValue < 0) { // falling
|
||||||
|
deltaFalling += prevValue - value;
|
||||||
|
deltaRising = 0;
|
||||||
|
}
|
||||||
|
prevValue = value;
|
||||||
|
if (((float)deltaRising) / 0xFF * 5 > triggerValue / 1000.0) {
|
||||||
|
if ((triggerType == rising || triggerType == none) && triggerCont - tsRising > 2) {
|
||||||
|
isTriggered = true;
|
||||||
|
rawFreq = triggerCont - tsRising;
|
||||||
|
rawDuty = triggerCont - tsFalling;
|
||||||
|
rawFreqAvg = 0.1 * rawFreq + 0.9 * rawFreqAvg;
|
||||||
|
rawDutyAvg = 0.1 * rawDuty + 0.9 * rawDutyAvg;
|
||||||
}
|
}
|
||||||
if (isCapturing) {
|
deltaRising = 0;
|
||||||
isCapturing = false;
|
deltaFalling = 0;
|
||||||
saveCsv(filename);
|
tsRising = triggerCont;
|
||||||
delete captureBuffer;
|
}
|
||||||
|
if (((float)deltaFalling) / 0xFF * 5 > triggerValue / 1000.0) {
|
||||||
|
if (triggerType == falling && triggerCont - tsFalling > 2) {
|
||||||
|
isTriggered = true;
|
||||||
|
rawFreq = triggerCont - tsFalling;
|
||||||
|
rawDuty = triggerCont - tsRising;
|
||||||
|
rawFreqAvg = 0.1 * rawFreq + 0.9 * rawFreqAvg;
|
||||||
|
rawDutyAvg = 0.1 * rawDuty + 0.9 * rawDutyAvg;
|
||||||
}
|
}
|
||||||
if (pendingCsv) {
|
deltaRising = 0;
|
||||||
isCapturing = true;
|
deltaFalling = 0;
|
||||||
pendingCsv = false;
|
tsFalling = triggerCont;
|
||||||
captureBuffer = new QByteArray(timeRange/interval+1, 0);
|
}
|
||||||
}
|
triggerCont++;
|
||||||
|
// Capture
|
||||||
if (pendingPause) {
|
if (isCapturing) {
|
||||||
pendingPause = false;
|
captureBuffer->append(value);
|
||||||
isPaused = true;
|
|
||||||
emit isPausedChanged(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
drawBackground();
|
|
||||||
paint->setPen(QPen(QColor(signalColor), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
|
||||||
newxPos = 0;
|
|
||||||
maxValue = 0;
|
|
||||||
minValue = 0;
|
|
||||||
}
|
}
|
||||||
// Draw new value
|
// Draw new value
|
||||||
else {
|
if (isTriggered == true || triggerType == none) {
|
||||||
paint->drawLine(newxPos + width * hAdjust, newyPos + height * vAdjust, oldxPos + width * hAdjust, oldyPos + height * vAdjust);
|
float newxPos = contX * xDelta;
|
||||||
|
contX++;
|
||||||
|
qint16 newyPos = height + yZeroV - getYVal(value);
|
||||||
|
// End of pixmap
|
||||||
|
if (newxPos > width) {
|
||||||
|
if (triggerType != none) {
|
||||||
|
isTriggered = false;
|
||||||
|
deltaRising = 0;
|
||||||
|
deltaFalling = 0;
|
||||||
|
}
|
||||||
|
emit sendPixmap();
|
||||||
|
if (pendingExport) {
|
||||||
|
savePixmap(filename);
|
||||||
|
pendingExport = false;
|
||||||
|
}
|
||||||
|
if (isCapturing) {
|
||||||
|
isCapturing = false;
|
||||||
|
saveCsv(filename);
|
||||||
|
delete captureBuffer;
|
||||||
|
}
|
||||||
|
if (pendingCsv) {
|
||||||
|
isCapturing = true;
|
||||||
|
pendingCsv = false;
|
||||||
|
captureBuffer = new QByteArray(timeRange/interval+1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pendingPause) {
|
||||||
|
pendingPause = false;
|
||||||
|
isPaused = true;
|
||||||
|
emit isPausedChanged(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isRealTime) {
|
||||||
|
isPixmapSent = true;
|
||||||
|
newxPos = 0;
|
||||||
|
maxValue = 0;
|
||||||
|
minValue = 0;
|
||||||
|
contX = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawBackground();
|
||||||
|
paint->setPen(QPen(QColor(signalColor), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||||
|
newxPos = 0;
|
||||||
|
maxValue = 0;
|
||||||
|
minValue = 0;
|
||||||
|
contX = 0;
|
||||||
|
}
|
||||||
|
// Draw new value
|
||||||
|
else {
|
||||||
|
paint->drawLine(newxPos + width * hAdjust, newyPos + height * vAdjust, oldxPos + width * hAdjust, oldyPos + height * vAdjust);
|
||||||
|
}
|
||||||
|
oldxPos = newxPos;
|
||||||
|
oldyPos = newyPos;
|
||||||
}
|
}
|
||||||
oldxPos = newxPos;
|
|
||||||
oldyPos = newyPos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isRealTime && !isPixmapSent)
|
||||||
|
emit sendPixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint16 Oscilloscope::getYZeroV()
|
qint16 Oscilloscope::getYZeroV()
|
||||||
|
@ -331,8 +388,8 @@ void Oscilloscope::drawBackground()
|
||||||
for (quint8 i = 0; i < 6; i++) { // horizontal lines
|
for (quint8 i = 0; i < 6; i++) { // horizontal lines
|
||||||
paint->drawLine(0, height * i / 6, width, height * i / 6);
|
paint->drawLine(0, height * i / 6, width, height * i / 6);
|
||||||
}
|
}
|
||||||
for (quint8 i = 0; i < 10; i++) { // vertical lines
|
for (quint8 i = 0; i < 11; i++) { // vertical lines
|
||||||
paint->drawLine(width * i / 10, 0, width * i / 10, height);
|
paint->drawLine(width * i / 11, 0, width * i / 11, height);
|
||||||
}
|
}
|
||||||
QFont font = paint->font();
|
QFont font = paint->font();
|
||||||
font.setPixelSize(14 * pixelRatio);
|
font.setPixelSize(14 * pixelRatio);
|
||||||
|
@ -404,8 +461,7 @@ void Oscilloscope::exportCsv(QUrl url)
|
||||||
void Oscilloscope::saveCsv(QString filename)
|
void Oscilloscope::saveCsv(QString filename)
|
||||||
{
|
{
|
||||||
QFile data(filename);
|
QFile data(filename);
|
||||||
if(data.open(QFile::WriteOnly | QFile::Truncate))
|
if(data.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||||
{
|
|
||||||
QTextStream output(&data);
|
QTextStream output(&data);
|
||||||
output << "Interval\t" + QString::number(interval) + "\n";
|
output << "Interval\t" + QString::number(interval) + "\n";
|
||||||
for (quint16 i=0; i < captureBuffer->size(); i++) {
|
for (quint16 i=0; i < captureBuffer->size(); i++) {
|
||||||
|
@ -416,11 +472,11 @@ void Oscilloscope::saveCsv(QString filename)
|
||||||
data.close();
|
data.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Oscilloscope::setIsPaused(const bool value) {
|
void Oscilloscope::setIsPaused(const bool value)
|
||||||
|
{
|
||||||
if (value == true)
|
if (value == true)
|
||||||
pendingPause = true;
|
pendingPause = true;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
pendingPause = false;
|
pendingPause = false;
|
||||||
emit isPausedChanged(false);
|
emit isPausedChanged(false);
|
||||||
|
|
|
@ -16,59 +16,132 @@
|
||||||
#ifndef OSCILLOSCOPE_H
|
#ifndef OSCILLOSCOPE_H
|
||||||
#define OSCILLOSCOPE_H
|
#define OSCILLOSCOPE_H
|
||||||
|
|
||||||
#include <QSerialPort>
|
#include <QDebug>
|
||||||
#include <QSerialPortInfo>
|
#include <QFile>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QQuickImageProvider>
|
#include <QQuickImageProvider>
|
||||||
#include <QFile>
|
#include <QSerialPort>
|
||||||
#include <QDebug>
|
#include <QSerialPortInfo>
|
||||||
|
#include <QTime>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include <QAndroidJniObject>
|
|
||||||
#include <QAndroidJniEnvironment>
|
#include <QAndroidJniEnvironment>
|
||||||
|
#include <QAndroidJniObject>
|
||||||
#include <QtAndroid>
|
#include <QtAndroid>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Oscilloscope : public QObject, public QQuickImageProvider
|
class Oscilloscope : public QObject, public QQuickImageProvider
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
//Q_PROPERTY(bool isPaused READ getIsPaused WRITE setIsPaused NOTIFY isPausedChanged)
|
// Q_PROPERTY(bool isPaused READ getIsPaused WRITE setIsPaused NOTIFY
|
||||||
|
// isPausedChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum TriggerType { none, rising, falling };
|
enum TriggerType { none, rising, falling };
|
||||||
enum Status { connected, disconnected, permission_not_granted, error_connecting, error_opening, connection_lost, driver_not_found, permission_requested };
|
enum Status {
|
||||||
|
connected,
|
||||||
|
disconnected,
|
||||||
|
permission_not_granted,
|
||||||
|
error_connecting,
|
||||||
|
error_opening,
|
||||||
|
connection_lost,
|
||||||
|
driver_not_found,
|
||||||
|
permission_requested
|
||||||
|
};
|
||||||
Q_ENUM(Status)
|
Q_ENUM(Status)
|
||||||
Q_ENUM(TriggerType)
|
Q_ENUM(TriggerType)
|
||||||
Oscilloscope(qreal pixelratio);
|
Oscilloscope(qreal pixelratio);
|
||||||
~Oscilloscope();
|
~Oscilloscope();
|
||||||
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
|
QPixmap requestPixmap(const QString &id, QSize *size,
|
||||||
Q_INVOKABLE void openSerialPort(QString portName, QString baudrate, QString dataBits, QString parity, QString interval);
|
const QSize &requestedSize) override;
|
||||||
|
Q_INVOKABLE void openSerialPort(QString portName, QString baudrate,
|
||||||
|
QString dataBits, QString parity,
|
||||||
|
QString interval);
|
||||||
Q_INVOKABLE void closeSerialPort();
|
Q_INVOKABLE void closeSerialPort();
|
||||||
Q_INVOKABLE QStringList fillPortsInfo();
|
Q_INVOKABLE QStringList fillPortsInfo();
|
||||||
Q_INVOKABLE void setBackgroundColor(const QString &color) { backgroundColor = color; drawBackground(); emit sendPixmap(); }
|
Q_INVOKABLE void setBackgroundColor(const QString &color)
|
||||||
Q_INVOKABLE void setGridColor(const QString &color) { gridColor = color; drawBackground(); emit sendPixmap(); }
|
{
|
||||||
Q_INVOKABLE void setSignalColor(const QString &color) { signalColor = color; drawBackground(); emit sendPixmap(); }
|
backgroundColor = color;
|
||||||
Q_INVOKABLE void setTextColor(const QString &color) { textColor = color; drawBackground(); emit sendPixmap(); }
|
drawBackground();
|
||||||
Q_INVOKABLE void setVDiv(const quint16 value) { vDiv = value; voltRange = value * 6 / 1000.0; yZeroV = getYZeroV(); drawBackground(); emit sendPixmap(); }
|
emit sendPixmap();
|
||||||
Q_INVOKABLE void setHDiv(const quint16 value) { hDiv = value; timeRange = value * 11 / 1000.0; drawBackground(); emit sendPixmap(); }
|
}
|
||||||
Q_INVOKABLE void setTriggerType(const quint16 value) { triggerType = (TriggerType)value; }
|
Q_INVOKABLE void setGridColor(const QString &color)
|
||||||
Q_INVOKABLE void setTriggerValue(const quint16 value) { triggerValue = value; }
|
{
|
||||||
Q_INVOKABLE void setVAdjust(const qint16 value) { vAdjust = 6/voltRange * value / 100.0; drawBackground(); emit sendPixmap(); }
|
gridColor = color;
|
||||||
Q_INVOKABLE void setHAdjust(const qint16 value) { hAdjust = 11/timeRange * value / 100.0 * 0.25; drawBackground(); emit sendPixmap(); }
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setSignalColor(const QString &color)
|
||||||
|
{
|
||||||
|
signalColor = color;
|
||||||
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setTextColor(const QString &color)
|
||||||
|
{
|
||||||
|
textColor = color;
|
||||||
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setVDiv(const quint16 value)
|
||||||
|
{
|
||||||
|
vDiv = value;
|
||||||
|
voltRange = value * 6 / 1000.0;
|
||||||
|
yZeroV = getYZeroV();
|
||||||
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setHDiv(const quint16 value)
|
||||||
|
{
|
||||||
|
hDiv = value;
|
||||||
|
timeRange = value * 11 / 1000.0;
|
||||||
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setTriggerType(const quint16 value)
|
||||||
|
{
|
||||||
|
triggerType = (TriggerType)value;
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setTriggerValue(const quint16 value)
|
||||||
|
{
|
||||||
|
triggerValue = value;
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setVAdjust(const qint16 value)
|
||||||
|
{
|
||||||
|
vAdjust = 6 / voltRange * value / 100.0;
|
||||||
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
|
Q_INVOKABLE void setHAdjust(const qint16 value)
|
||||||
|
{
|
||||||
|
hAdjust = 11 / timeRange * value / 100.0 * 0.25;
|
||||||
|
drawBackground();
|
||||||
|
emit sendPixmap();
|
||||||
|
}
|
||||||
Q_INVOKABLE void exportImage(QUrl filename);
|
Q_INVOKABLE void exportImage(QUrl filename);
|
||||||
Q_INVOKABLE void exportCsv(QUrl filename);
|
Q_INVOKABLE void exportCsv(QUrl filename);
|
||||||
Q_INVOKABLE bool getIsPaused() { return isPaused; }
|
Q_INVOKABLE bool getIsPaused()
|
||||||
|
{
|
||||||
|
return isPaused;
|
||||||
|
}
|
||||||
Q_INVOKABLE void setIsPaused(const bool value);
|
Q_INVOKABLE void setIsPaused(const bool value);
|
||||||
Q_INVOKABLE QString getVersion() { return APP_VERSION; }
|
Q_INVOKABLE QString getVersion()
|
||||||
|
{
|
||||||
|
return APP_VERSION;
|
||||||
|
}
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
static Oscilloscope *instance() { return m_instance; }
|
static Oscilloscope *instance()
|
||||||
|
{
|
||||||
|
return m_instance;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isPausedChanged(bool isPaused);
|
void isPausedChanged(bool isPaused);
|
||||||
void sendPixmap();
|
void sendPixmap();
|
||||||
void sendStatusConn(Status status);
|
void sendStatusConn(Status status);
|
||||||
void sendMessage(QString message, quint16 duration=0);
|
void sendMessage(QString message, quint16 duration = 0);
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
void receiveBuffer(const QByteArray &buffer);
|
void receiveBuffer(const QByteArray &buffer);
|
||||||
void receiveStatus(int status, const QString &msg);
|
void receiveStatus(int status, const QString &msg);
|
||||||
|
@ -76,8 +149,8 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Edge { min, max };
|
enum Edge { min, max };
|
||||||
quint16 pmHeight = 400; //230;
|
quint16 pmHeight = 400;
|
||||||
quint16 pmWidth = 800; //520;
|
quint16 pmWidth = 800;
|
||||||
quint8 maxValue = 0;
|
quint8 maxValue = 0;
|
||||||
quint8 minValue = 0;
|
quint8 minValue = 0;
|
||||||
quint16 rawFreq = 0;
|
quint16 rawFreq = 0;
|
||||||
|
@ -88,7 +161,7 @@ private:
|
||||||
bool pendingCsv = false;
|
bool pendingCsv = false;
|
||||||
bool pendingPause = false;
|
bool pendingPause = false;
|
||||||
QString filename;
|
QString filename;
|
||||||
quint16 interval = 26;
|
float interval = 26;
|
||||||
quint16 vDiv = 1000;
|
quint16 vDiv = 1000;
|
||||||
quint16 hDiv = 1000;
|
quint16 hDiv = 1000;
|
||||||
float voltRange = 1000 * 6 / 1000.0;
|
float voltRange = 1000 * 6 / 1000.0;
|
||||||
|
@ -125,9 +198,18 @@ private:
|
||||||
void savePixmap(QString filename);
|
void savePixmap(QString filename);
|
||||||
void saveCsv(QString filename);
|
void saveCsv(QString filename);
|
||||||
|
|
||||||
|
quint8 dataBits = 8;
|
||||||
|
bool isRealTime = true;
|
||||||
|
bool isPixmapSent = false;
|
||||||
|
bool isDataStart = false;
|
||||||
|
QTimer *timer;
|
||||||
|
QByteArray data;
|
||||||
|
bool timedOut = false;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
void readData();
|
void readData();
|
||||||
|
void timeOut();
|
||||||
#else
|
#else
|
||||||
void readData(const QByteArray &data);
|
void readData(const QByteArray &data);
|
||||||
#endif
|
#endif
|
||||||
|
|
Ładowanie…
Reference in New Issue