Arduino - общие обсуждения

Вопросы и ответы связанные с цифровым управлением, аналоговой автоматикой и их элементами
Сообщение
Автор
shalex
Сообщения: 285
Зарегистрирован: Сб июн 06, 2015 3:26 pm
Благодарил (а): 23 раза
Поблагодарили: 10 раз

Re: Arduino - общие обсуждения

#71 Непрочитанное сообщение shalex »

Федюнь писал(а):if(digitalRead(timer_ledPIN) == HIGH && (results.value == 0xFCA418D1 ))digitalWrite(ledPin_3, HIGH); //это код кнопки №3
if(digitalRead(timer_ledPIN) == HIGH && (results.value == 0xAFD97D5 ))digitalWrite(ledPin_4, HIGH); //это код кнопки №4

irrecv.resume();

}
SoftwareServo::refresh();
}


Я понял что надо так сделать.Правильно я понял?
Серва по прежнему не реагирует ни на какую кнопку.Как в первый раз на большой скорости перевелась в крайнее положение так там и стоит.
Надо чтобы SoftwareServo::refresh(); вызывался в каждом цикле loop

Однако, вернулись к тому, с чего начали - отладочный порт нужен как воздух.

Федюнь
Сообщения: 1430
Зарегистрирован: Вс фев 19, 2012 7:18 am
Имя: Фарид
Откуда: Узбекистан Ташкент
Контактная информация:

Re: Arduino - общие обсуждения

#72 Непрочитанное сообщение Федюнь »

Вобшем мы с товаришем списались и повыравнивали программу.

#include <SoftwareServo.h> // подключаем библиотеку для Servo
#include <IRremote.h> // подключаем СКАЧЕННУЮ библиотеку IRremote для ИК пульта

int RECV_PIN = 2; //вход ИК инфракрасного приемника (32H-Atmega168)
IRrecv irrecv(RECV_PIN);
decode_results results;

SoftwareServo servo_1; //даём имена servo
SoftwareServo servo_2;

//Pin для светодиодов,светодиоды для визуального контроля за процессом
int ledPin_1 = 15; //PIN 15, на Arduino Uno, Atmega328 (A1)(24H-Atmega168)
int ledPin_2 = 16; // (25Н-Atmega168)
int ledPin_3 = 17; // (26H-Atmega168)
int ledPin_4 = 18; // (27H-Atmega168)
int ledPin_14 = 14; //индикация таймера //PIN 14, на Arduino Uno, Atmega328 (A0) (23H-Atmega168)

int a_1;// промежуточная переменная для хранения (увеличенного диапазона от 0 до 30000)значений (увеличения или уменьшения)PWM,
int a_2;// с последующей конвертации в переменную(val) диапазон градусов поворота доступных для servo.

//переменные для конвертации (увеличенного диапазона значений от 0 до 30000) (a_1;),(a_2;),в значения требуемые для поворота servo.
int val_1;
int val_2;
int speed_PWM;//переменная для (увеличения или уменьшения)скорости поворота servo.
unsigned long eventTime=0;//переменная для (увеличения или уменьшения)скорости поворота servo.
bool leds[4] = {0,0,0,0};

void setup() {
irrecv.enableIRIn(); // включить ИК приёмник
servo_1.attach(9); // серво подключён на цифровой вход (pin 9) (13H-Atmega168)
servo_2.attach(10); // серво подключён на цифровой вход (pin 10) (14H-Atmega168)

pinMode(ledPin_1, OUTPUT);
pinMode(ledPin_2, OUTPUT);
pinMode(ledPin_3, OUTPUT);
pinMode(ledPin_4, OUTPUT);
pinMode(ledPin_14, OUTPUT);

digitalWrite(ledPin_1, LOW);
digitalWrite(ledPin_2, LOW);
digitalWrite(ledPin_3, LOW);
digitalWrite(ledPin_4, LOW);
digitalWrite(ledPin_14, LOW);

a_1=1;
a_2=1;

speed_PWM=100;//Чем меньше значение тем меньше скорость
}

void loop() {

//если ledPin_1) ==, выставляем ограничение для переменной(a_1) до (&& a_1<30000).и Начинаем увеличивать
// значения переменной(a_1) прибавляем на значение переменной speed_PWM,
//и также выставляем ограничение при убывании (&& a_1>0)
if((leds[0]==1) && (a_1<30000)) a_1=a_1+speed_PWM;
if((leds[1]==1) && (a_1>0) ) a_1=a_1-speed_PWM;

val_1 = a_1;
val_1 = map(val_1, 0, 30000, 1, 179);//читаем значение (a_1) и конвертируем его в val_1, то бишь в значение поворота в градусах для servo.
servo_1.write(val_1); // правильно было бы конвертировать в, (от 0, до 180) градусов, но мои дешёвые servo доходя до краёв

//делаем тоже самое и для servo_2
if((leds[2]==1) && (a_2<30000)) a_2=a_2+speed_PWM;
if((leds[3]==1) && (a_2>0) ) a_2=a_2-speed_PWM;

val_2 = a_2;
val_2 = map(val_2, 0, 30000, 1, 179);
servo_2.write(val_2); //записываем значения val_2 в servo_2

if (irrecv.decode(&results)) { // здесь считываем коды от ИК пульта
if (results.value == 0x1767AF71) leds[0]=1;
if (results.value == 0x318A151 ) leds[1]=1;
if (results.value == 0xFCA418D1 ) leds[2]=1;
if (results.value == 0xAFD97D5 ) leds[3]=1;
if (results.value == 0xA54EEF0D )digitalWrite(ledPin_14, HIGH); //(A54EEF0D) это код кнопки контрастность +
if (results.value == 0x2A8D308D )digitalWrite(ledPin_14, LOW); //(2A8D308D) это код кнопки контрастность -

irrecv.resume();

}
else
{
for (int i = 0; i < 4; i++) leds=0;
}

if (leds[0]==1) digitalWrite(ledPin_1, HIGH); else digitalWrite(ledPin_1, LOW);
if (leds[1]==1) digitalWrite(ledPin_2, HIGH); else digitalWrite(ledPin_2, LOW);
if (leds[2]==1) digitalWrite(ledPin_3, HIGH); else digitalWrite(ledPin_3, LOW);
if (leds[3]==1) digitalWrite(ledPin_4, HIGH); else digitalWrite(ledPin_4, LOW);

SoftwareServo::refresh();
}

Федюнь
Сообщения: 1430
Зарегистрирован: Вс фев 19, 2012 7:18 am
Имя: Фарид
Откуда: Узбекистан Ташкент
Контактная информация:

Re: Arduino - общие обсуждения

#73 Непрочитанное сообщение Федюнь »

14 ногу я перенаправли для включения дополнительного светодиода.Желаюшие могут применить на ардуине с МК на атмега 168,думаю что влезит в атмегу 8

Федюнь
Сообщения: 1430
Зарегистрирован: Вс фев 19, 2012 7:18 am
Имя: Фарид
Откуда: Узбекистан Ташкент
Контактная информация:

Re: Arduino - общие обсуждения

#74 Непрочитанное сообщение Федюнь »

14 ногу я перенаправил для включения дополнительного светодиода.Желаюшие могут применить на ардуине с МК на атмега 168,думаю что влезит в атмегу 8

shalex
Сообщения: 285
Зарегистрирован: Сб июн 06, 2015 3:26 pm
Благодарил (а): 23 раза
Поблагодарили: 10 раз

Re: Arduino - общие обсуждения

#75 Непрочитанное сообщение shalex »

поправил немного ваш скетч, теперь он стал масштабируемым, пока не кончатся ноги на атмеге (SERVO_COUNT). что еще:
- отдельные настройки (скорость, пины для светодиодов вправо-влево, пин сервы, коды кнопок вправо-влево) для каждой сервы;
- эти настройки задаются в константе-массиве ServosSetup. оптом, так сказать и вполне наглядно ))

как работает:
- в одном цилке обрабатывается только одна серва (что должно обеспечить возможность наращивания каналов при почти такой же производительности)

Для одной сервы в каждом цикле выполняются такие действия:
- сначала опрашивается пульт
- потом определяем поведение канала и вкл/выкл диоды, если надо
- далее дерганье сервой, если надо
[Оффтопик]

Код: Выделить всё

//
// shalex. 2016
// special for Fedun
//
#include <SoftwareServo.h> 
#include <IRremote.h> 

const int RECV_PIN = 2; //вход ИК инфракрасного приемника (32H-Atmega168)

const int MIN_ANGLE = 1;
const int MAX_ANGLE = 179;
const int MIN_VAL = 0;
const int MAX_VAL = 30000;

const int SERVO_COUNT = 2;
unsigned long IR_BUTTON_DELAY = 100;

typedef struct
{
    int               pin_led_left;
    int               pin_led_right;
    int               pin_servo;
    int               pwm_speed;
    unsigned long     IR_button_code_left;
    unsigned long     IR_button_code_right;
} FedunServoSetup;

typedef struct
{
    unsigned long LastTickLeft;
    unsigned long LastTickRight;
    bool  StateLeft;
    bool  StateRight;
    int   CurrentPosition;
    SoftwareServo servo;
    
} FedunServo;


//variables
IRrecv irrecv(RECV_PIN);
decode_results results;
int CurrentServo = 0;

const FedunServoSetup ServosSetup[SERVO_COUNT] ={
  {15, 16,  9, 100, 0x1767AF71, 0x318A151},      //pin_led_left;pin_led_right;pin_servo;pwm_speed;IR_button_code_left;IR_button_code_right;
  {17, 18, 10, 100, 0xFCA418D1, 0xAFD97D5}
};
FedunServo Servos[SERVO_COUNT];

int LowAngle(int angle){
 return map(angle, MIN_VAL, MAX_VAL, MIN_ANGLE, MAX_ANGLE);    
}

void setup() {  
 Serial.begin(9600);          
 
 irrecv.enableIRIn(); // включить ИК приёмник
 
 for (int i=0 ; i < SERVO_COUNT; i++) {
   
   pinMode(ServosSetup[i].pin_led_left, OUTPUT);
   digitalWrite(ServosSetup[i].pin_led_left, LOW);
   pinMode(ServosSetup[i].pin_led_right, OUTPUT);
   digitalWrite(ServosSetup[i].pin_led_right, LOW);
   
   Servos[i].servo.attach(ServosSetup[i].pin_servo);
   Servos[i].LastTickLeft = 0;
   Servos[i].LastTickRight = 0;
   Servos[i].StateLeft = false;
   Servos[i].StateRight = false;
   Servos[i].CurrentPosition = MIN_VAL;
   Servos[i].servo.write(LowAngle(Servos[i].CurrentPosition));
 }
}

void loop() {
  
unsigned long CurrentTime = millis();

  
  CurrentServo += 1;
  if (CurrentServo > SERVO_COUNT) CurrentServo = 0;
  
  if (irrecv.decode(&results))   // здесь считываем коды от ИК пульта
    LoopIRControl(CurrentServo, results.value, CurrentTime);
    
  LoopServoStateAndLed(CurrentServo, CurrentTime);
  LoopServoMotion(CurrentServo);
  
  SoftwareServo::refresh();
}

void LoopIRControl(int servo_index, unsigned long code_value, unsigned long CurrentTime){
       if (ServosSetup[servo_index].IR_button_code_left == code_value || ServosSetup[servo_index].IR_button_code_right == code_value) {
           if (ServosSetup[servo_index].IR_button_code_left == code_value) {
               Servos[servo_index].LastTickLeft = CurrentTime;
           }
           else
               Servos[servo_index].LastTickRight = CurrentTime;
       }
}

void LoopServoMotion(int servo_index) {
  
int NewPosition = Servos[servo_index].CurrentPosition;

  if (Servos[servo_index].StateLeft) {
    if (Servos[servo_index].CurrentPosition < MAX_VAL) NewPosition = min(Servos[servo_index].CurrentPosition + ServosSetup[servo_index].pwm_speed, MAX_VAL);
  }
    else
    if (Servos[servo_index].StateRight)
      if (Servos[servo_index].CurrentPosition > MIN_VAL) NewPosition = max(Servos[servo_index].CurrentPosition - ServosSetup[servo_index].pwm_speed, MIN_VAL);
  if (NewPosition != Servos[servo_index].CurrentPosition) {
    Servos[servo_index].servo.write(LowAngle(NewPosition));
    Servos[servo_index].CurrentPosition = NewPosition;
  }
}
void LoopServ(unsigned long& LastTick, bool& state, int pin_led, unsigned long CurrentTime) {
   state = 0;
   if (LastTick != 0) {
       // led isn'n on
       if (!state) {
          digitalWrite(pin_led, HIGH);           
          state = true;
       }
       // button timeout IR_BUTTON_DELAY is ended
       if ( CurrentTime - LastTick > IR_BUTTON_DELAY) {
         if (state) {
          digitalWrite(pin_led, LOW);           
          state = false;
          LastTick = 0;
         }
       }  
   }

}
void LoopServoStateAndLed(int servo_index, unsigned long CurrentTime) {
     
   if (Servos[servo_index].LastTickLeft != 0) LoopServ(Servos[servo_index].LastTickLeft, Servos[servo_index].StateLeft, ServosSetup[servo_index].pin_led_left, CurrentTime);
     else
     if (Servos[servo_index].LastTickRight != 0) LoopServ(Servos[servo_index].LastTickRight, Servos[servo_index].StateRight, ServosSetup[servo_index].pin_led_right, CurrentTime);
}
 
 
Внимание: скетч компилируется, но не факт, что работает. отлаживать его придется самостоятельно.
Для этого скетч разбит на простые структуры, которые легко начинить Serial.print();

Федюнь
Сообщения: 1430
Зарегистрирован: Вс фев 19, 2012 7:18 am
Имя: Фарид
Откуда: Узбекистан Ташкент
Контактная информация:

Re: Arduino - общие обсуждения

#76 Непрочитанное сообщение Федюнь »

Ага спасибо.И надо добавить,уникальность кода в том что можно управлять любым ИК пультом,например от старого телевизора или дивидиплеера. Предварительно считав коды кнопок и записав их в блокнот.Как считать коды кнопок думаю найти можно,на просторах интернета навалом.
Данный девайс я решил использовать для автономного управления краном.А там кому как угодно,хоть форточкой управляйте дома))))

shalex
Сообщения: 285
Зарегистрирован: Сб июн 06, 2015 3:26 pm
Благодарил (а): 23 раза
Поблагодарили: 10 раз

Re: Arduino - общие обсуждения

#77 Непрочитанное сообщение shalex »

Федюнь писал(а):Ага спасибо.И надо добавить,уникальность кода в том что можно управлять любым ИК пультом,например от старого телевизора или дивидиплеера. Предварительно считав коды кнопок и записав их в блокнот.Как считать коды кнопок думаю найти можно,на просторах интернета навалом.
Данный девайс я решил использовать для автономного управления краном.А там кому как угодно,хоть форточкой управляйте дома))))
Да, только для стрелок такой код не подойдет. Оказывается автоматизируем кран.

Снимите видео про кран, если не сложно? Интересно было бы посмотреть.

p.s. кстати, можно же приделать DCC декодер и управлять краном с помощью "штурвала" Роко-мышки, например, а не ИК-пультом )))

Аватара пользователя
И.К.С.
Сообщения: 3881
Зарегистрирован: Пн мар 17, 2008 9:57 am
Имя: Ĩ.Ĉ.Š. мӧҗҥҩ ҧрѻҫҭҩ мӥҫҭҿӄѣ Ӥ.Ҟ.Ҫ іљі Ҝѻӊҫҭѩңҭӥԋъ
Откуда: У.Г.Ж.Д. 13 верста( U.M.M.R.R 13 km)
Благодарил (а): 181 раз
Поблагодарили: 122 раза
Контактная информация:

Re: Arduino - общие обсуждения

#78 Непрочитанное сообщение И.К.С. »

Федюнь писал(а):Предварительно считав коды кнопок и записав их в блокнот.Как считать коды кнопок думаю найти можно,на просторах интернета навалом.
Блокнотик можно пропустить. Сделать режим обучения достаточно просто, можно даже найти готовый код.
HOe.N.Z? . . G.Oe.HO! ПолHOля , эNка и кое-что ещё. Люблю У.Г.Ж.Д. особенно 13 версту и вообще 1 эпоху.
Изображение
Изображение
Изображение

Федюнь
Сообщения: 1430
Зарегистрирован: Вс фев 19, 2012 7:18 am
Имя: Фарид
Откуда: Узбекистан Ташкент
Контактная информация:

Re: Arduino - общие обсуждения

#79 Непрочитанное сообщение Федюнь »

Просьба заказчика,зделать не на DCC а на другом пульте. https://www.youtube.com/watch?v=r0Y3YwxntEE

shalex
Сообщения: 285
Зарегистрирован: Сб июн 06, 2015 3:26 pm
Благодарил (а): 23 раза
Поблагодарили: 10 раз

Re: Arduino - общие обсуждения

#80 Непрочитанное сообщение shalex »

Федюнь писал(а):Просьба заказчика,зделать не на DCC а на другом пульте. https://www.youtube.com/watch?v=r0Y3YwxntEE
Интересное видео, но ни одного пульта не увидел ((
А код можете и сами поменять.

Код: Выделить всё

  if (irrecv.decode(&results))   // здесь считываем коды от ИК пульта
    LoopIRControl(CurrentServo, results.value, CurrentTime);
переделайте на

Код: Выделить всё

  
  unsigned long msg = 	MsgCode();
  if (msg != 0)   // здесь считываем коды от ИК пульта
    LoopIRControl(CurrentServo, msg, CurrentTime);
и добавьте функцию обработки получения сообщений от чего либо. под любой пульт несложно переделать.
в данном случае для того же ИК пульта.

Код: Выделить всё

unsigned long MsgCode(){

unsigned long tmp = 0;
decode_results results;

  if (irrecv.decode(&results))   // здесь считываем коды от ИК пульта
	tmp = results.value;
  return tmp;			
}

Ответить

Вернуться в «Цифровое управление, Аналоговая автоматика и их элементы»