шим и сервопривод конфликт.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

Прошу прощения если было, ткните носом.

Строю кораблик для завоза прикорма. управление от РУ машинки киоша трех канальное, ардуино нано, драйвер моторов пока на HG7881, моторов два, и две сервы для сброса прикорма.

драйвера подключены

#define mot1_F 5 // выходы на драйвер
#define mot1_R 6
#define mot2_F 9 // выходы на драйвер
#define mot2_R 10
 
сервы 
 
servo1.attach (15);
servo2.attach (14);
 
написан/стырен обработчик сигналов с приемника для рулежки/езды на прерываниях второй и третьей ноги.
 
типа
 
void gaz_ppm() {    // PPM read interrupt
 ct = micros(); // read current time
 ms_gaz=ct-lt; // ms = current time - last time
 lt=ct; // last time
 if(ms_gaz>2200)  // fix time bug 
   ms_gaz=tmp;        // fix time bug
   tmp=ms_gaz;        // fix time bug

и обработка третьего канала для управления двумя сервами

ch1 = pulseIn(pulse1_pin1, HIGH, 25000);
  
  if (ch1 < 1000) servo1.write(180); else servo1.write(0);
  if (ch1 > 2000) servo2.write(180); else servo2.write(0);
 
по одельности в коде все работает. 
работа серв меня устраивает.
работа двигателей тоже (вперед,назад, повороты, раздрай)
в библиотеке SERVO сказано что при ее использовании "На контроллерах отличных от Mega использование библиотеки отключает возможность использовать выходы 9 и 10 в режиме ШИМ даже если привод не подключен к этим выводам"
Есть альтернативная библиотека SERVO2 , аналогичная штатной библиотеке, с ее помощью удалось крутить моторы и к сожалению только одну серву из двух. 
библиотека серво я так понял использует TIMER1 для своих нужд , он же используется для ШИМ, если возможность переключить таймер , и как это сделать?
 
 
 
sadman41
Offline
Зарегистрирован: 19.10.2016

Servo.h  использует таймеры #1, #3, #4 и #5, т.е. 16-битные таймеры. У 328-го МК (Arduino Nano) 16-битный таймер только один - #1. Так что переключить вы ничего никуда не сможете.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

а какое решение проблемы пожете подсказать, сменить ардуинку?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

" Катер из потолочки " читали?

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

Лично я бы начал крутить сервы без библиотеки.

Для поворота им нужно на протяжении некоторого времени подавать импульс, продолжительность которого пропорциональна углу поворота. Для разных моделей он отличается, однако Servo.h пользуется такими: 544мкс для поворота на 0 и 2400мкс для поворота на 180. Если вам удерживать их не надо, то, думаю, что для вашей задачи даже блокирующий код с delay() подойдёт. Синяя SG90 у меня на столе проворачивается на 180 за 0.5сек максимум.

 

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

А чем не устраивают другие ШИМ-пины? 3 и 11? Используйте их, чего Вы прицепились к 9 и 10?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Лично я бы купил Турнигу и забыл про Ардуину.
Ищите FlySky er9x
Кстати в этой, старой , стоит Атмега64 стоит и софт конфигуратора чудесный есть - er9x eePe.
Можно хоть летать, хоть на экскаваторе работать.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

нашел такой код


#define MIN 600 // минимальное положение сервы 
#define MAX 2400 // максимальное положение сервы 
#define STEP_ADD 10 //шаг сервы на 1 градус 
#define SERVO_1 13 //управляющий выход для первой сервы 
int step_on = (MAX-MIN)/2+MIN; //среднее положение сервы 
void setup()  
{  
pinMode(SERVO_1, OUTPUT);  
Serial.begin(115200); 
}  
void loop()  
{  
  if (Serial.available() > 0)  step_on=(Serial.read())*10;                           
      servo(step_on, SERVO_1); 
} 
void servo(int stepe, int ServoPin) 
{ 
  if(stepe > MAX)stepe = MAX;  
  if(stepe < MIN)stepe = MIN;  
    digitalWrite(ServoPin, HIGH);  
    delayMicroseconds(stepe);  
    digitalWrite(ServoPin, LOW);  
    delay(20-(stepe/1000)); 
}  

изменил строку

 if (Serial.available() > 0)  step_on=(Serial.read())*10;   

на step_on=  значения подставлял от 0 до 180

но чего то он не работает

 

 

 

 

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

ЕвгенийП пишет:

А чем не устраивают другие ШИМ-пины? 3 и 11? Используйте их, чего Вы прицепились к 9 и 10?

int rul = 2; //PPM in for INT1 канал руля
int gaz = 3; //PPM in for INT2 канал газа
 
для работы драйвера HG7881 нужно четыре пина с шим , для плавной регулировки хода.
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

sadman41 пишет:
......Если вам удерживать их не надо.......

Серве не надо всегда подавать сигнал,
она будет стоять без сигнала в последнем положении.
Даже команда в библиотеке есть: detatch

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

купить каждый может ))), а эту выкинуть? а зачем тогда мудрить что то, когда можно готовый кораблик за 40 к взять!

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

trembo пишет:
Серве не надо всегда подавать сигнал, она будет стоять без сигнала в последнем положении. Даже команда в библиотеке есть: detatch

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

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

Alecs_2000 пишет:

int rul = 2; //PPM in for INT1 канал руля
int gaz = 3; //PPM in for INT2 канал газа
 

Здесь что-то не так, на 3-ем пине ШИМ есть, а на втором - нет, А Вы их используете одинаково. Так нужен ШИМ для PPM или нет?

Alecs_2000 пишет:

для работы драйвера HG7881 нужно четыре пина с шим , для плавной регулировки хода.

И прекрасно - 5, 6, 3 и 11 - первый таймер никак не задействован. Что мешает?

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

с дуней одной кнопкой или серией кнопок через резисторы можно творить чудеса, ИМХО, например открывать крышку сброса прикорма оч. медленно или очень быстро, включить выключить свет. .... два раза нажал, один раз коротко, нажал по держал.

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Alecs_2000 пишет:

купить каждый может ))), а эту выкинуть? а зачем тогда мудрить что то, когда можно готовый кораблик за 40 к взять!


Тогда я не понял.
У вас уже есть аппаратура?
Какой модели?
Обычно один пин управляет одним устройством: сервой, мотором......
При этом сигнал - это не включено-выключено.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

на 2 и 3 пине есть прерывание которое используется для захвата ппм сигнала, кусок кода в первом сообщении, 5,6 ноги используются для плавного запуска двигателей вперед, 9 и 10 соответственно назад. 

вот весь код.

 

// PPM read from receiver
 
int rul = 2; //PPM in for INT1 канал руля
int gaz = 3; //PPM in for INT2 канал газа
 
int bind = 12; //настройка
 
#define mot1_F 5 // выходы на драйвер
#define mot1_R 6
#define mot2_F 9 // выходы на драйвер
#define mot2_R 10
 
//const int LED=13; // Контакт 10 для подключения светодиода
//const int BUTTON=2; // Контакт 2 для подключения кнопки
//int tekButton = LOW; // Переменная для сохранения текущего состояния кнопки
//int prevButton = LOW; // Переменная для сохранения предыдущего состояния
 
#define dlay 500
#define pulse1_pin1 19
//#define pulse1_pin2 18
 
int ch1 = 0;
int ch2 = 0;
long toRead = 0;
 
 
volatile unsigned long lt, ct, ms_rul,ms_gaz,tmp, lt1, ct1,  tmp1, maxgaz, mingaz, maxrul, minrul ;
 
volatile  unsigned long sr_rul, sr_gaz, dv_f1, dv_r1, dv_f2, dv_r2,lp,p, mz;
#include <Servo2.h>
Servo2 servo1;
Servo2 servo2;
 
void setup(){
  pinMode(rul, INPUT);
  pinMode(gaz, INPUT);
servo1.attach (15);
 servo2.attach (14);
 servo1.write(0);
 servo2.write(0);
  
//  pinMode(bind,) 
 
pinMode(mot1_F, OUTPUT);
pinMode(mot1_R, OUTPUT);
pinMode(mot2_F, OUTPUT);
pinMode(mot2_R, OUTPUT);
 
 
 
  
 digitalWrite (rul, HIGH);  digitalWrite (gaz, HIGH);      //Pull-up pin
  
 attachInterrupt(0, rul_ppm, CHANGE);   attachInterrupt(1, gaz_ppm, CHANGE);
  
  
maxgaz=2100; // настраиваемая переменная движение вперед;  
mingaz=850; // настраиваемая переменная движение назад;
maxrul=2000; // настраиваемая переменная движения правого поворота
minrul=900; // настраиваемая переменная движение левого поворота 
 
sr_rul=1488; // положение нейтрали руля
sr_gaz=1480; // положение нейтрали газа
 
mz=20;
 
pinMode(pulse1_pin1, INPUT);
//  pinMode(pulse1_pin2, INPUT);
 
 
 
Serial.begin(9600); 
 
 
 
}
 
void loop()
{
  
  
 
 
 
 Serial.println();
//Serial.println(pp);
//  Serial.println(dv_f1);
//  Serial.println(dv_r1);
//Serial.println(ms_rul);
//Serial.println(map(ms_gaz,sr_gaz,maxgaz,255,0));
//Serial.println(ms_gaz);
 
 
          // движение вперед
         if (ms_gaz > sr_gaz+mz)
            {
              dv_f1=map(ms_gaz,sr_gaz-mz,maxgaz,0,255);
              dv_f2=map(ms_gaz,sr_gaz-mz,maxgaz,0,255);
            }
            else
             {
              dv_f1=0;
              dv_f2=0;
             }
                     
        // движение назад
             if (ms_gaz < sr_gaz-mz)
             {
             dv_r1=map(ms_gaz,sr_gaz+mz,mingaz,0,255);
             dv_r2=map(ms_gaz,sr_gaz+mz,mingaz,0,255);
             }
       
             else
             {
              dv_r1=0;
              dv_r2=0;
              }
           
         
         //раздрай
 
             if (ms_rul > sr_rul+mz)
                {
                  
                dv_f1= map(ms_rul,sr_rul-mz,maxrul,0,255);
                dv_r2= map(ms_rul,sr_rul-mz,maxrul,0,255);                 
                
                  }
                
             if (ms_rul < sr_rul-mz)
                {
                dv_r1= map(ms_rul,sr_rul+mz,minrul,0,255);
                dv_f2= map(ms_rul,sr_rul+mz,minrul,0,255);                 
                 }
 
 
 
 
analogWrite(mot1_F,dv_f1 );
analogWrite(mot1_R,dv_r1 );
analogWrite(mot2_F,dv_f2 );
analogWrite(mot2_R,dv_r2 );
 
 
 
if (millis() - toRead>500) 
 {
  ch1 = pulseIn(pulse1_pin1, HIGH, 25000);
  
  if (ch1 < 1000) servo1.write(180); else servo1.write(0);
  if (ch1 > 2000) servo2.write(180); else servo2.write(0);
   
 
 
//  else servo1.write(90);
 
  }
//Serial.print(ch1);
 
 
}
 
 
 
 
 
 
 
void gaz_ppm() {    // PPM read interrupt
 ct = micros(); // read current time
 ms_gaz=ct-lt; // ms = current time - last time
 lt=ct; // last time
 if(ms_gaz>2200)  // fix time bug 
   ms_gaz=tmp;        // fix time bug
   tmp=ms_gaz;        // fix time bug
}    
void rul_ppm() {    // PPM read interrupt
 ct1 = micros(); // read current time
 ms_rul=ct1-lt1; // ms = current time - last time
 lt1=ct1; // last time
 if(ms_rul>2200)  // fix time bug 
   ms_rul=tmp1;        // fix time bug
   tmp1=ms_rul;        // fix time bug
}    
 
 
Alecs_2000
Offline
Зарегистрирован: 26.02.2018

вместо библиотеки SERVO ,  эксперементировал с библиотекой SERVO2 результат , с первой сервы крутятся как надо, моторы работают не правильно, со второй библиотекой моторы крутятся адекватно, но работает только одна серва.

аппа KT-200, с добавленым третьим каналом, приемник от нее же четырех канальный.

 

 

 

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

Alecs_2000 пишет:

на 2 и 3 пине есть прерывание которое используется 

Так используйте прерывание на других пинах, чего Вы к ШИМ'овским привязались?

Alecs_2000 пишет:

 кусок кода в первом сообщении, 

Я не читал Ваш код. Вставляйте правильно, если хотите, чтобы читали.

 

 

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

ЕвгенийП пишет:

Так используйте прерывание на других пинах, чего Вы к ШИМ'овским привязались?

прошу прощения... а на других пинах прерывания есть?

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

Поторопился не указал ДУНЮ NANO  она.

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

Можно, но будет ли это для вас проще, чем крутить серву вручную, например - большой вопрос.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

не понял

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

Т.е. "да, можно на других пинах поймать прерывания"

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

А в библиотеке серво2 может кто поковыряться с ней работает корректно, но только одна серва. библиотека есть здесь в конце статьи http://wiki.amperka.ru/робототехника:сервоприводы

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

Alecs_2000 пишет:

прошу прощения... а на других пинах прерывания есть?

А то! На всех есть, кроме А6 и A7. Только attachInterrupt на них не работает. Возьмите какую-нибудь библиотеку для них и пользуйте, благо это добра (библиотек) как биоматериала за баней.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

ну так это и есть внешнее прерывание.

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

Что "это"? Вы, если хотите помощи, объясняйтесь понятнее. Я вот не понимаю в чём у Вас вообще проблема.

Вам нужно 4 ШИМ-пина. Они у Вас есть, но Вы зачем-то один из них заняли под прерывание, и из этого пальца высосали несуществующую проблему.

Я же Вам говорю, оставьте ШИМ-пины в покое и используйте для прерываний другие пины, т.к. на них тоже есть прерывания типа PCINT. Библиотек для PCINT навалом. Пользуйтесь.

В чём Ваша проблема-то? Я никак понять не могу.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

по тому что я так делал и оно работает, по тому что я не делал по другому и не представляю как это получится. в таком случае ППМ сигнал можно считать еще проще всего одной строкой на и на любой ноге. 

ch1 = pulseIn(pulse1_pin1, HIGH, 25000);

могу сильно ошибаться но, "железное" прерывание  более надежно для основной функции движеня, дабы не ездить за большой лодкой в случае подвисания ДУНИ.

Alecs_2000
Offline
Зарегистрирован: 26.02.2018

опять же можно не мудрить а купить "нормальные" регуляторы хода, многоканальную апу, несколько RC свичей, а дунку выкинуть!

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

Эта музыка будет вечной! Вы бы хоть прочитали что-нибудь, я же ссылки давал. PCINT тоже железное прерывание. Ничуть не менее железное, чем LEVEL, которым Вы пользуетесь.

Ну, впрочем, как говорила Рая Абельская: "не хочите, не ешьте". У меня и своих дел хватает.