Конфликт библиотек

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

Думаю, что отдельный.

Kraker
Offline
Зарегистрирован: 10.09.2017

В итоге получилось вот что: 


#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#define OE 7
SoftwareSerial BTSerial(0,1);
SoftwareSerial mySerial(14,2);
static const int latchPin = 12;
static const int  clockPin = 4;
static const int dataPin = 8;
static const int speed1 = 11;
static const int speed2 = 3;
static const int speed3 = 6;
static const int speed4 = 5;
int vspdLR ;
static const int servoPin = 10;
   
void setup(){
    pinMode(OE,OUTPUT);
    digitalWrite(OE,HIGH);
    BTSerial.begin(9600); 
    mySerial.begin (9600); 
	  mp3_set_serial (mySerial); 
	  mp3_set_volume (25); 
    pinMode(latchPin,OUTPUT);
    pinMode(clockPin,OUTPUT);
    pinMode(dataPin,OUTPUT);   
    pinMode(speed1,OUTPUT);
    pinMode(speed2,OUTPUT);
    pinMode(speed3,OUTPUT);
    pinMode(speed4,OUTPUT);  
    pinMode(servoPin, OUTPUT);    
    
      
}

void loop(){
    BTSerial.listen();
    if(BTSerial.available()){
        const char vcmd = (const char)BTSerial.read();
        Serial.println(vcmd);
        
    if(vcmd == 'F'){
            vforward();
        }
   else if(vcmd == 'B'){
            vbackward();
        }   
   else  if(vcmd == 'G'){
            vforwardleft();
        } 
   else  if(vcmd == 'I'){
            vforwardright();
        }   
   else if(vcmd == 'H'){
            vbackwardleft();
        }   
   else  if(vcmd == 'J'){
            vbackwardright();
        }  
   else  if(vcmd == 'S'){
            vrelease();
        }  
   else if(vcmd=='V'){
            vmp3pl1();
            }
   else if(vcmd=='v'){
            vmp3st();
        } 
   else if(vcmd=='X'){
            vmp3pl2();            
        } 
   else if(vcmd=='x'){
            vmp3st();           
        } 
   else  if (isdigit(vcmd)) vspeed (25 * (vcmd - '0'));
        
   else  if(vcmd == 'q'){

            vspeed(255);

        }         
    }
}

             // СЕРВА!

void servoPulse(int servoPin, int myAngle) 
{
  const int pulseWidth = (myAngle * 11) + 500;
  digitalWrite(servoPin, HIGH);       
  delayMicroseconds(pulseWidth);     
  digitalWrite(servoPin, LOW);        
  delay(20);                           
}
    
          // Вперед!
void  vforward(){
     vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b00100111);            
    digitalWrite(latchPin, HIGH);  
    servoPulse(10, 90); 
     
}
         // Назад!
void vbackward(){
    vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b11011000);            
    digitalWrite(latchPin, HIGH);  
    servoPulse(10, 90);  
    
}
         // Вперед и Влево!
void vforwardleft(){
    vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b00100111);            
    digitalWrite(latchPin, HIGH);  
    servoPulse(10, 120); 
    
 }
         // Вперед и Вправо!
void vforwardright(){
    vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b00100111);            
    digitalWrite(latchPin, HIGH); 
    servoPulse(10, 60);     
     
}
       //  Назад и Влево!
void vbackwardleft(){
    vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b11011000);            
    digitalWrite(latchPin, HIGH);
    servoPulse(10, 120); 
    
     
}
       // Назад и Вправо!
void vbackwardright(){
    vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b11011000);            
    digitalWrite(latchPin, HIGH);
    servoPulse(10, 60);  
     
      
}
         // Стоп!
void vrelease(){
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b00000000);            
    digitalWrite(latchPin, HIGH);    
    servoPulse(10, 90);
}
void vmp3pl1(){
    
    mp3_play(1);
    
}
void vmp3pl2(){
    
    mp3_play(2);
}
void vmp3st(){
    
    mp3_stop();
    
}
void vspeed(int spdLR){
    
        vspdLR = spdLR;
       
    analogWrite(speed1,vspdLR);
    analogWrite(speed2,vspdLR);
    analogWrite(speed3,vspdLR);
    analogWrite(speed4,vspdLR);
   
}

Где еще нужно причесать? 

и Главный вопрос куда смотреть чтобы решить вопрос с сервой и ее дерганием ?

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

Ну, а 13-ую строку чего обидели насчёт static? Всем дали, а ей не досталось? :)

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

Вы же пока напишите мне, откуда берутся команды типа 'F', 'B', 'G' и т.д. Их вводит человек или генерит какая-то программа?

Kraker
Offline
Зарегистрирован: 10.09.2017

Виноват ,исправлюсь :)

Kraker
Offline
Зарегистрирован: 10.09.2017

Команды приходят от планшета, апп Bluetooth RC controller.

Вся основа кода взята из примера для этой апп

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

Да и ещё вопрос, можно ли после строки 164 вставить: vspeed(0);?

Это имеено вопрос. Я не до конца понимаю логику, потому спрашиваю. Если можно, то мне это поможет Вам обзор усовершенствований писать.

 

Kraker
Offline
Зарегистрирован: 10.09.2017

Я правельно понимаю ,что выхотите  vspeed задать -0, тоесть значение скорости будет равно нулю. Если это так то не вижу проблем ,хотя скорей всего пропадет возможность задать начальную скорость в момент СТОП. Тоесть сначала надо будет дать команду движения , а затем выбрать скорость,а при астановке она опять скинется в ноль что не есть гуд.  Так что если я все правельно понял ,то наверное это не оптимально.

 

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

Ну, нет, так нет, обойдёмся. Я попозже напишу новый "список на 8 листов"

Kraker
Offline
Зарегистрирован: 10.09.2017

Хотелось бы не только следовать вашим рекомендациям , но и понимать что же я тут пишу. Пока я не совсем понимаю.

В любом случае Спасибо за помощь

Kraker
Offline
Зарегистрирован: 10.09.2017

По поводу vspeed , на самом деле нужно просто подавать на выходы speed1-4 разноуровневый сигнал , в зависимости от Поступающих команд с планшета.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Вопрос для гуру: зачем для глобальных объявлять static const...?

Чем просто const хуже?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Static из других файлов не виден

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

В подавляющем большинстве случаев - ничем. Но бывают редкие случаи, когда это приводит к экономии памяти.

По идее, static предполагает невозможность доступа из другого файла, а если слова  static нет, то в другом файле можно описать эту же переменную с ключевым словом extern и иметь к ней доступ.

Современный оптимизирующий компилятор, если видит глобальную константу небольшого размера со словом static, он вообще не выделяет под неё память, а вставляет литерал в код. Если же слова static нет, то он тоже вставляет литерал в код, но также и "условно" выделяет память, сообщая линкеру, что если из других файлов никто туда не лезет, то переменную можно выбросить. Что линкер обычно и делает.

Так вот, в большинстве случаев это будет именно так - её всё равно выбросят (не компилятор, так линкер) и памяти она не займёт. Но здесь всё зависит от опций компилятора и линкера. А вот если явно указано static, то выбросить её может сам компилятор, линкер о ней и не узнает. Т.е. получается, что со словом static её легче выбросить и освободить память.

Общий вывод - если доступ из других файлов не нужен, надо писать static. Хуже не будет точно, а лучше - не часто, но может и быть.

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

Kraker, ну давайте смотреть.

Во первых, вы не перенесли функции выше использования и не прдъобявили их. В каких-то версиях IDE (напримерв 1.6.5), Вас может ждать неприятный сюрприз. По правилам языка, функция должна лиюо располагаться выше, чем используется, либо быть предобъявленной выше, первого использования.

Далее. Посмотрите на строки 96-162. Там содержатся 6 одинаковых функций, которые отличаются только числовыми пераметрами. А в строка 163-171 ещё одна, которая отличается от шести предыдущих одной строкой (вернее её отсутствием).

Т.е. мы можем вместо строк 96-171 написать так:

void servoGo(const uint8_t data, const uint8_t pin, const int angle) {
	vspeed(vspdLR);
	servoStop(data, pin, angle);
}

void servoStop(const uint8_t data, const uint8_t pin, const int angle) {
	pinMode(OE, OUTPUT);
	digitalWrite(OE, LOW);
	digitalWrite(latchPin, LOW);
	shiftOut(dataPin, clockPin, MSBFIRST, data);
	digitalWrite(latchPin, HIGH);
	servoPulse(pin, angle);
}

А строки 41-61 соответсвенно заменить на:

    if (vcmd == 'F')      servoGo(0b00100111, 10, 90);	// Forward
    else if (vcmd == 'B') servoGo(0b11011000, 10, 90);	// Backward
    else if (vcmd == 'G') servoGo(0b00100111, 10, 120);	// Forward Left
    else if (vcmd == 'I') servoGo(0b00100111, 10, 60);	// Forward Right
    else if (vcmd == 'H') servoGo(0b11011000, 10, 120);	// Backward Left
    else if (vcmd == 'J') servoGo(0b11011000, 10, 60);	// Backward Right
    else if (vcmd == 'S') servoStop(0b00000000, 10, 90);	// Stop

Сделайте это и сравните размер памяти программы.

Ну, пока хватит, потом как сделаете, ещё раз посмотрим, а то изменения больно глобальны

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

case ещё более читабельным будет.

Kraker
Offline
Зарегистрирован: 10.09.2017

Наверное проскачило , но я спрашивал как предобъявить функцию, не совсем понял как это сделать.Наверное потому , что неправельно воспринемаю void.  Я  думаю что void loop  это основная программа где собственно все и крутится, а остальные расцениваю как подпрограммы ,поэтому где их обьявлять что то не понимаю :(

 

 

Kraker
Offline
Зарегистрирован: 10.09.2017

Если код который я накидал я еще как то понимаю, то с заменой от Евгения я буду разбираться оч долго,надеюсь разберусь.

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

Kraker пишет:

как предобъявить функцию

Очень просто. Выиписываете её заголовок (без тела) и ставите точку с запятой. Заголовок - это то, что до {

Например, 

// Предобъявление функции kaka
int kaka(const int a, const int b);

...........................

// Определение функции kaka
int kaka(const int a, const int b) {
	return a + b;
}

 

Kraker
Offline
Зарегистрирован: 10.09.2017
int vforward();

..................

int vforward() {
    vspeed(vspdLR);
    pinMode(OE,OUTPUT);
    digitalWrite(OE,LOW);
    digitalWrite(latchPin, LOW);  
    shiftOut(dataPin, clockPin, MSBFIRST, 0b00100111);            
    digitalWrite(latchPin, HIGH);  
    servoPulse(10, 90); 
       }

 

Я правельно понял?

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

Да.

И первую строчку повыше.

Кстати, IDE именно это и делает за Вас. Потому всё и работает. А там, где не делает, там бы Вашу программу компилятор обругал бы.

Kraker
Offline
Зарегистрирован: 10.09.2017

Ну ,он и ругается но компилирует.

 

 

 

Kraker
Offline
Зарегистрирован: 10.09.2017

Если я внесу ваши изменения ,разве будет необходимость в обьявлении их теперь?  Выже их заменили.

 

GarryC
Offline
Зарегистрирован: 08.08.2016

По поводу сервы - точно плавает длительность импульсов, а не интервал между ними ?

Kraker
Offline
Зарегистрирован: 10.09.2017

GarryC пишет:

По поводу сервы - точно плавает длительность импульсов, а не интервал между ними ?

Сейчас загружал с планшета последний вариант, длительность вроде в норме ,но есть провалы(моргание на осцицелографе), дома грузил предыдущий вариант там скакала длительность импульсов( тоесть 90 градусов длительность 15мс вроде,а уменя плавало рывками)соответственно серва дергалась.

Kraker
Offline
Зарегистрирован: 10.09.2017

Евгений а можно мне разжувать так сказать что от куда в вашем коде

void servoGo(const uint8_t data, const uint8_t pin, const int angle) {
	vspeed(vspdLR);
	servoStop(data, pin, angle);
}

void servoStop(const uint8_t data, const uint8_t pin, const int angle) {
	pinMode(OE, OUTPUT);
	digitalWrite(OE, LOW);
	digitalWrite(latchPin, LOW);
	shiftOut(dataPin, clockPin, MSBFIRST, data);
	digitalWrite(latchPin, HIGH);
	servoPulse(pin, angle);
}

 А то я немогу слепить картинку,просто копироввть неинтересно, хотся понять что где.

Где ловим сдвиговый регистр? И как работате серва если в servoPulse прописано чуть по другому?

Ну и чобственно что есть чтов этом 

const uint8_t data, const uint8_t pin, const int angle

Интуитивно понимаю вроде, но от так чтоб совсем понять, так нет

Kraker
Offline
Зарегистрирован: 10.09.2017

Вы уж простите мне мое полное незнание  но я бы понял еслиб было так( ну как понял,относительно конечно)

const uint8_t data, const uint8_t servoPin, const int myAngle

 

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

Это параметры функции, они могут называться как угодно и используются внутри функции. Посмотрите на вызовы - там параметры передаются, а внутри функции испольуются. Ну, и почитатйте что-нибудь про функции в Си

Kraker
Offline
Зарегистрирован: 10.09.2017

Доброго времени суток.

Благодаря Евгению получился у меня вот такой кодик. 

#include <PWMServo.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#define OE 7
SoftwareSerial BTSerial(0,1);
SoftwareSerial mySerial(14,2);
static const int latchPin = 12;
static const int  clockPin = 4;
static const int dataPin = 8;
static const int speed1 = 11;
static const int speed2 = 3;
static const int speed3 = 6;
static const int speed4 = 5;
int vspdLR ;
PWMServo myservo;
   
void setup(){
    pinMode(OE,OUTPUT);
    digitalWrite(OE,HIGH);
    BTSerial.begin(9600); 
    mySerial.begin (9600); 
	  mp3_set_serial (mySerial); 
	  mp3_set_volume (25); 
    pinMode(latchPin,OUTPUT);
    pinMode(clockPin,OUTPUT);
    pinMode(dataPin,OUTPUT);   
    pinMode(speed1,OUTPUT);
    pinMode(speed2,OUTPUT);
    pinMode(speed3,OUTPUT);
    pinMode(speed4,OUTPUT);   
    myservo.attach(10);
    myservo.write(90);  
          
}

void loop(){
    BTSerial.listen();
    if(BTSerial.available()){
        const char vcmd = (const char)BTSerial.read();
        Serial.println(vcmd);
        
   if (vcmd == 'F')      movement(0b00100111,  90);	// Forward
   else if (vcmd == 'B') movement(0b11011000,  90);	// Backward
   else if (vcmd == 'G') movement(0b00100111,  60);	// Forward Left
   else if (vcmd == 'I') movement(0b00100111,  120);	// Forward Right
   else if (vcmd == 'H') movement(0b11011000,  60);	// Backward Left
   else if (vcmd == 'J') movement(0b11011000,  120);	// Backward Right
   else if (vcmd == 'S') movement(0b00000000, 90);	// Stop
        
   else if(vcmd=='V'){
            vmp3pl1();
            }
   else if(vcmd=='v'){
            vmp3st();
        } 
   else if(vcmd=='X'){
            vmp3pl2();            
        } 
   else if(vcmd=='x'){
            vmp3st();           
        } 
   else  if (isdigit(vcmd)) vspeed (25 * (vcmd - '0'));
        
   else  if(vcmd == 'q'){

            vspeed(255);

        }         
    }
}
  
void movement(const uint8_t data, const int angle) {
  vspeed(vspdLR);
	pinMode(OE, OUTPUT);
	digitalWrite(OE, LOW);
	digitalWrite(latchPin, LOW);
	shiftOut(dataPin, clockPin, MSBFIRST, data);
	digitalWrite(latchPin, HIGH);
	myservo.write(angle);
}  
  
void vmp3pl1(){
    
    mp3_play(1);
    
}
void vmp3pl2(){
    
    mp3_play(2);
}
void vmp3st(){
    
    mp3_stop();
    
}
void vspeed(int spdLR){
    
        vspdLR = spdLR;
       
    analogWrite(speed1,vspdLR);
    analogWrite(speed2,vspdLR);
    analogWrite(speed3,vspdLR);
    analogWrite(speed4,vspdLR);
   
}

Проблемму с дерганием сервы решила библиотека PWMServo.h найденная на просторах форума.

Всем спасибо. 

Пойду читать про функции :)