Редактирование библиотеки. Структура "this"

forfrends
Offline
Зарегистрирован: 24.02.2015

Всем привет!

Есть библиотека https://github.com/darkbyte-ru/SA818 Хочу ее отредактировать "под себя". Вот содержимое файлов:

SA818.cpp

/*
	SA818.cpp - SA818U/SA818V Communication Library.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	For a full copy of the GNU General Public License, 
	see <http://www.gnu.org/licenses/>.
*/

#include "Arduino.h"
#include "SA818.h"
#include <stdio.h>
#include <Stream.h>
#include <avr/wdt.h>

//#define DEBUG 1

SA818::SA818(SomeSerial *serial, uint8_t PIN_PTT, uint8_t PIN_PD, uint8_t PIN_HL, uint8_t PIN_AMP = 0)
{
	this->serial = serial;
	//this->serial->begin(9600);

	this->PTT_PIN = PIN_PTT;
	this->PD_PIN = PIN_PD;
	this->HL_PIN = PIN_HL;
	this->AMP_PIN = PIN_AMP;

	pinMode(this->PTT_PIN, OUTPUT);
	pinMode(this->PD_PIN, OUTPUT);
	pinMode(this->HL_PIN, OUTPUT);
	if(this->AMP_PIN){
		pinMode(this->AMP_PIN, OUTPUT);
		digitalWrite(this->AMP_PIN, LOW);
	}

	digitalWrite(this->PTT_PIN, HIGH);
	digitalWrite(this->PD_PIN, HIGH);
	digitalWrite(this->HL_PIN, LOW);
}

uint8_t SA818::readSerialTimeout()
{
	uint8_t readed = false;
	unsigned long timeout = millis();
	while (millis() - timeout < 500) {
		delay(100);
		wdt_reset();
		while (this->serial->available() > 0) {
#ifdef DEBUG			
			Serial.write(this->serial->read());
#else
			this->serial->read();
#endif			
			readed = true;
		}
		if (readed == true)break;
	}
#ifdef DEBUG			
	if(!readed){
		Serial.println("Read timeout");
	}
#endif			
	return readed;
}

uint8_t SA818::begin()
{
	//not a commmand, but for sure
	this->serial->print("AT\r\n");
	delay(500);

	for(uint8_t r = 0; r<5; r++){
		this->serial->print("AT+DMOCONNECT\r\n");
		if(this->readSerialTimeout()){
			//got +DMOCONNECT:0<CR><LF>
			return true;
		}
	}
	return false;
}

uint8_t SA818::setPower(uint8_t is_high)
{
	//HL to ground - low power, HL float - high power
	if(is_high){
		pinMode(this->HL_PIN, INPUT);
	}else{
		pinMode(this->HL_PIN, OUTPUT);
	}
	digitalWrite(this->HL_PIN, LOW); //for sure
}

uint8_t SA818::setConfig(uint8_t bw, char* tx_f, char* rx_f, char* tx_ctcss, char* rx_ctcss, uint8_t squelch)
{
	// Set PTT off, so we can communicate with the uC.
	// Delay for a bit, to finish TX
	digitalWrite(this->PTT_PIN, HIGH);
	delay(100); 

	for(uint8_t r=0; r<5; r++){
		this->serial->print("AT+DMOSETGROUP=");
		this->serial->print(bw); // 0/1
		this->serial->print(",");
		this->serial->print(tx_f);//134-174/400-480, format to 415.1250
		this->serial->print(",");
		this->serial->print(rx_f);//format to 415.1250
		this->serial->print(",");
		this->serial->print(tx_ctcss);//format to 0000
		this->serial->print(",");
		this->serial->print(squelch); // <= 8
		this->serial->print(",");
		this->serial->print(rx_ctcss);
		this->serial->print("\r\n");

		if(this->readSerialTimeout()){
			return true;
		}
	}

	return false;
}

uint8_t SA818::setVolume(uint8_t volume)
{
	// Set PTT off, so we can communicate with the uC.
	// Delay for a bit, to finish TX
	digitalWrite(this->PTT_PIN, HIGH); 
	delay(100);

	if(volume>8) volume = 8;

	//sprintf(this->buffer,"AT+DMOSETVOLUME=%1d\r\n",this->volume);
	this->serial->print("AT+DMOSETVOLUME=");
	this->serial->print(volume);
	this->serial->print("\r\n");

	return this->readSerialTimeout();
}

uint8_t SA818::setFilters(boolean preemph, boolean highpass, boolean lowpass)
{
	// Set PTT off, so we can communicate with the uC.
	// Delay for a bit, to finish TX
	digitalWrite(this->PTT_PIN, HIGH); 
	delay(100);

	//sprintf(this->buffer,"AT+SETFILTER=%1d,%1d,%1d\r\n",this->preemph,this->highpass,this->lowpass);
	//this->serial->print(this->buffer);

	this->serial->print("AT+SETFILTER=");
	this->serial->print(preemph);
	this->serial->print(",");
	this->serial->print(highpass);
	this->serial->print(",");
	this->serial->print(lowpass);
	this->serial->print("\r\n");


	//return true; //must be +DMOSETFILTER: X (X=0->ok, X=1-fail)
	return this->readSerialTimeout();
}

void SA818::powerDown(uint8_t powerdown)
{
	digitalWrite(this->PTT_PIN, HIGH);
	digitalWrite(this->PD_PIN, powerdown);
}

void SA818::changeMode(uint8_t mode)
{
	digitalWrite(this->PTT_PIN, mode);
	if(this->AMP_PIN){
		digitalWrite(this->AMP_PIN, !mode);
	}
}

void SA818::setModeTX(){
	this->changeMode(SA_MODE_TX);
}

void SA818::setModeRX(){
	this->changeMode(SA_MODE_RX);
}

SA818.h

/*
    SA818.h - SA818U/SA818V Communication Library.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    For a full copy of the GNU General Public License, 
    see <http://www.gnu.org/licenses/>.
*/

#ifndef SA818_h
#define SA818_h

#include <SomeSerial.h>
#include <Stream.h>

#define SA_BANDWIDTH_12_5KHZ	0
#define SA_BANDWIDTH_25KHZ		1

#define SA_CTCSS_OFF	"0000"
#define SA_SQUELCH_OFF	0

#define SA_POWER_LOW	0
#define SA_POWER_HIGH	1

#define SA_VOLUME_MIN	0
#define SA_VOLUME_DEFAULT	4
#define SA_VOLUME_MAX	8

#define SA_FILTER_OFF	0
#define SA_FILTER_ON	1

#define SA_POWER_OFF	0
#define SA_POWER_ON		1

#define SA_MODE_TX		0
#define SA_MODE_RX		1

class SA818 {
    public:
        SA818(SomeSerial *serial, uint8_t PIN_PTT, uint8_t PIN_PD, uint8_t PIN_HL, uint8_t PIN_AMP = 0);

        uint8_t begin();
        uint8_t setConfig(uint8_t bw, char* tx_f, char* rx_f, char* tx_ctcss, char* rx_ctcss, uint8_t squelch);
        uint8_t setVolume(uint8_t volume);
        uint8_t setPower(uint8_t is_high);
		uint8_t setFilters(boolean preemph, boolean highpass, boolean lowpass);

		void powerDown(uint8_t powerdown);
		void changeMode(uint8_t mode);

		void setModeTX();
		void setModeRX();

    private:
        //Stream *serial;
        //NewSoftSerial *serial;
        SomeSerial *serial;
	
        uint8_t PTT_PIN, PD_PIN, HL_PIN, AMP_PIN;

		uint8_t readSerialTimeout();

        //char buffer[60];
};
#endif

Файл примера SA818_Basic.ino:

/*
    DRA818_Basic - Basic example of how to use the DRA818 Configuration Library

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    For a full copy of the GNU General Public License,
    see <http://www.gnu.org/licenses/>.
*/

#include "SA818.h"

//
// IO Definitions
//
#define PIN_AMP     3  // Direct control of output PA (need hardware mod)
#define PIN_HL      4  // High/Low power pin (Input - HIGH, OutputLow - Low)
#define PIN_MIC     5  // DAC pin for tone out
#define PIN_PTT     7  // PTT pin. This is active low.
#define PIN_PD      8  // Power Down pin. This need to start low, then be set high before programming.

//Comment to use hardware Serial instead
#include <SomeSerial.h>
#define SOFTSERIAL 1

#ifdef SOFTSERIAL
#define SA_RXD 9
#define SA_TXD 6
SomeSerial serial(SA_RXD, SA_TXD);
#else
SomeSerial serial(&Serial);
#endif

// Instantiate the DRA818 Control Object, using the SoftwareSerial interface.
SA818 radio(&serial, PIN_PTT, PIN_PD, PIN_HL, PIN_AMP);

void setup()
{
  // Initialise Serial interface.
#ifdef SOFTSERIAL
  Serial.begin(115200);
  Serial.println("Init");
#endif  
  serial.begin(9600);
  radio.begin();
  radio.setConfig(SA_BANDWIDTH_12_5KHZ, "144.3500", "144.3500", SA_CTCSS_OFF, SA_CTCSS_OFF, SA_SQUELCH_OFF);
  radio.setPower(SA_POWER_LOW);
  //radio.setVolume(SA_VOLUME_DEFAULT);
  //radio.setFilters(SA_FILTER_OFF, SA_FILTER_OFF, SA_FILTER_OFF);
  pinMode(PIN_AMP, OUTPUT);


}

void loop() 
{
  // Key the PTT on and off repeatedly.
  radio.setModeTX();
  delay(3000);

  radio.setModeRX();
  delay(3000);
}

Первое, что хочу сделать, это избавиться от SomeSerial, так как буду подключать именно через физический Serial (D0 и D1), и программный Serial использовать не буду. Прошивка в микроконтроллер будет заливаться через программатор по SPI. 

Второе: мне не понятно применение структуры "this->" так как с подобным раньше не сталкивался. Вот часть кода из SA818.cpp:

SA818::SA818(SomeSerial *serial, uint8_t PIN_PTT, uint8_t PIN_PD, uint8_t PIN_HL, uint8_t PIN_AMP = 0)
{
	this->serial = serial;
	//this->serial->begin(9600);

	this->PTT_PIN = PIN_PTT;
	this->PD_PIN = PIN_PD;
	this->HL_PIN = PIN_HL;
	this->AMP_PIN = PIN_AMP;
...

В файле SA818.h есть объявление переменных:

uint8_t PTT_PIN, PD_PIN, HL_PIN, AMP_PIN;

То получается здесь глобальной переменной PTT_PIN присваивается значение PIN_PTT, которое мы указали при вызове функции SA818? Я правильно понял? 

По поводу замены Serial. Можно ли

this->serial->print(bw);

заменить на:

Serial.print(bw);

Ну и саму инициализацию Serial:

this->serial = serial;

Заменить на:

Serial.begin(9600);

 

b707
Онлайн
Зарегистрирован: 26.05.2017

forfrends - вот если вы в классах - ни в зуб ногой - нафига лезете редактировать библиотеки?

Тем более что нет никакой нужды избавляться от SomeSerial, чтобы работать с аппаратным Сериалом. SomeSerial - специальный класс, позволяющий использовать как аппаратный, так и программный Сериал в одной и той же переменной.

forfrends пишет:

То получается здесь глобальной переменной PTT_PIN присваивается значение PIN_PTT, которое мы указали при вызове функции SA818? Я правильно понял?

тут нет никаких глобальных переменных,

uint8_t PTT_PIN, PD_PIN, HL_PIN, AMP_PIN;

в файле SA818.h - это члены класса SA818

Строчка

this->PTT_PIN = PIN_PTT;

инициализирует переменную текущего экземпляра параметром конструктора. Указатель this-> как раз указывает на текущий экземпляр, хотя в данном случае, если я не ошибаюсь, this не обязателен, вот так вот будет работать ровно так же:

PTT_PIN = PIN_PTT;

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Што за SomeSerial?
Я бы его в объявлениях на что-нить более вышеиерархичное типа Stream* заменил и капец.

b707
Онлайн
Зарегистрирован: 26.05.2017

sadman41 пишет:
Што за SomeSerial? Я бы его в объявлениях на что-нить более вышеиерархичное типа Stream* заменил и капец.

можно и так, но если ТС все это затеял только ради того, чтобы заменить софтовый сериал на аппаратный - то проще оставить этот SomeSerial и вообще ничего не менять, библиотека и так поддерживает оба сериала

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

forfrends пишет:
мне не понятно применение структуры "this->"
Объяснение тянет страниц на 10-20. Так что лучше Вам взять нормальную книгу по С++ и прочитать что такое классы и как они устроены.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Есть у меня одна библиотека от Pavel Milanes, там как раз наоборот - использует Serial,
а хотелось бы SoftwareSerial, просил его поправить, вроде говорит несложно, сделаю
и уже более года как делает )))

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

ua6em пишет:

Есть у меня одна библиотека от Pavel Milanes, там как раз наоборот - использует Serial,
а хотелось бы SoftwareSerial, просил его поправить, вроде говорит несложно, сделаю
и уже более года как делает )))

Так за год и самому можно было бы уже раз 10 поправить

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

asam пишет:

ua6em пишет:

Есть у меня одна библиотека от Pavel Milanes, там как раз наоборот - использует Serial,
а хотелось бы SoftwareSerial, просил его поправить, вроде говорит несложно, сделаю
и уже более года как делает )))

Так за год и самому можно было бы уже раз 10 поправить

я же в программировании диодиком поморгать в основном, чужое там спионерить и использовать в своём коде, а библиотеки кромсать пока не мой удел, DetSimen подсказал, но пока далёк от понимания

смотрю пример SomeSerial, кто сможет пояснить в чем разница инициализации софтовых портов?

#ifndef SOME_SERIAL_NOT_SUPPORT_SOFTWARE_SERIAL
// arm boards and esp32 do not support SoftwareSerial
SomeSerial mySoftSerial1(10, 11); // RX, TX

SoftwareSerial mySoftwareSerial(8, 9); //RX, TX
SomeSerial mySoftSerial2(&mySoftwareSerial);
#endif

 

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018

Тс про this-> можешь тут почитать;
https://goo-gl.su/jUR3WSfE