Знающие помогите, с продолжительностью импульса на реле

TTIIMMAA
Offline
Зарегистрирован: 09.02.2017

Здравствуйте Всем, прошу помощи по коду, видимо я еще очень далек от этого

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

Код для примера

/* Энкодер */
enum { ENC_PIN1 = 2, ENC_PIN2 = 3 };

void setup()
{
 pinMode(ENC_PIN1, INPUT);
 pinMode(ENC_PIN2, INPUT);
 
 Serial.begin(9600);
}

/* Функция декодирования кода Грея, взятая с Википедии.
* Принимает число в коде Грея, возвращает обычное его представление.
*/
unsigned graydecode(unsigned gray)
{
 unsigned bin;

 for (bin = 0; gray; gray >>= 1)
    bin ^= gray;

 return bin;
}

void loop()
{
 static uint8_t previous_code = 0; // предыдущий считанный код
 
 /* gray_code - считанное с энкодера значение
  * code - декодированное значение
  */
 uint8_t gray_code = digitalRead(ENC_PIN1) | (digitalRead(ENC_PIN2) << 1),
         code = graydecode(gray_code);
 
 /* Если считался нуль, значит был произведён щелчок ручкой энкодера */
 if (code == 0)
 {
   /* Если переход к нулю был из состояния 3 - ручка вращалась
    * по часовой стрелке, если из 1 - против.
    */
   if (previous_code == 3)
     Serial.println("->");
   else if (previous_code == 1)
     Serial.println("<-");
 }
 
 /* Сохраняем код и ждём 1 мс - вполне достаточно опрашивать энкодер
  * не более 1000 раз в секунду.
  */
 previous_code = code;
 delay(1);
}

При повороте по часовой прибавлять время , а против Убавлять, Какая нужна переменная? 

Также не пойму как кнопку вставить в программу

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну лучше воспользоваться таким кодом. Скетч здесь. https://yadi.sk/d/aeYxE17v3Dhusf

Головной файл выкладываю сюда 

/* class_do_Encoder_KY_040.ino https://yadi.sk/d/aeYxE17v3Dhusf
  #1 энкодер  CLK->2 (CLK_PIN)
               DT->3 (DT_PIN)
               SW->4 (SW_PIN)
  Принцип кода:В сериал отправляется действие на энкодере.
*/
//#1 энкодер
#include "Cl_do_Encoder_KY_040.h"
const byte CLK_pin = 2;
const byte DT_pin = 3;
const byte SW_pin = 4;
Cl_do_Encoder_KY_040 Encoder; // ( CLK,DT,SW )создать энкодер на пинах 2,3,4
void func_SW(void) {
  Serial.println("Press SW");
}
void func_plus(void) {
  Serial.println("Turn +");
}
void func_minus(void) {
  Serial.println("Turn -");
}
void setup() {
  Serial.begin(9600);
  //#1 энкодер
  Encoder.setup(CLK_pin, DT_pin, SW_pin);
}
void loop() {
  //#1 энкодер
  Encoder.loop(& func_SW , & func_plus, & func_minus );
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А вот пример таймера на реле https://yadi.sk/d/WKaKvxrX3APTwN

Опять же Головной файл 

/* class_time_relay.ino  https://yadi.sk/d/WKaKvxrX3APTwN
  #1 реле ->13 
  #2 кнопка ->2
  Принцип кода:нажал 1 раз реле вкл на опред время. Замечение: вкл можно только когда выкл, иначе вкл будут не учтены.
*/
//#1 реле
#include "Cl_time_relay.h"
const byte relay_pin = 13;
Cl_time_relay T_Relay1;  //создать по времени отключ реле на пине 13
void func() {
  T_Relay1.ON();
}
//#2 кнопка
#include "Cl_do_btn.h"
const byte btn1_pin = 2;
Cl_do_btn Do_1; // создать кнопку на пине 2
void setup() {
  //#1 реле
  T_Relay1.setup(relay_pin, 0, 10000);// (пин,логика,время relay ON)
  //#2 кнопка
  Do_1.setup(btn1_pin);
}
void loop() {
  //#1 реле
  T_Relay1.loop();
  //#2 кнопка
  Do_1.loop(& func);
}

 

TTIIMMAA
Offline
Зарегистрирован: 09.02.2017

qwone пишет:

Ну лучше воспользоваться таким кодом. Скетч здесь. https://yadi.sk/d/aeYxE17v3Dhusf

Головной файл выкладываю сюда 

/* class_do_Encoder_KY_040.ino https://yadi.sk/d/aeYxE17v3Dhusf
  #1 энкодер  CLK->2 (CLK_PIN)
               DT->3 (DT_PIN)
               SW->4 (SW_PIN)
  Принцип кода:В сериал отправляется действие на энкодере.
*/
//#1 энкодер
#include "Cl_do_Encoder_KY_040.h"
const byte CLK_pin = 2;
const byte DT_pin = 3;
const byte SW_pin = 4;
Cl_do_Encoder_KY_040 Encoder; // ( CLK,DT,SW )создать энкодер на пинах 2,3,4
void func_SW(void) {
  Serial.println("Press SW");
}
void func_plus(void) {
  Serial.println("Turn +");
}
void func_minus(void) {
  Serial.println("Turn -");
}
void setup() {
  Serial.begin(9600);
  //#1 энкодер
  Encoder.setup(CLK_pin, DT_pin, SW_pin);
}
void loop() {
  //#1 энкодер
  Encoder.loop(& func_SW , & func_plus, & func_minus );
}

 

 

Воспользовался этим кодом, в какую сторону я бы не крутил энкодер Мониторинг порта показывает 

Turn +

и редко проскакивает если аккуратно крутить Turn -

Может быть я схему собрал не правильно

Прикрепляю схему, на схеме за место энкодера изображен потенциометр , не обращайте внимание, и кнопку я вывел отдельно, резисторы 10кОм

 
xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

qwone пишет:

А вот пример таймера на реле https://yadi.sk/d/WKaKvxrX3APTwN

Опять же Головной файл 

/* class_time_relay.ino  https://yadi.sk/d/WKaKvxrX3APTwN
  #1 реле ->13 
  #2 кнопка ->2
  Принцип кода:нажал 1 раз реле вкл на опред время. Замечение: вкл можно только когда выкл, иначе вкл будут не учтены.
*/
//#1 реле
#include "Cl_time_relay.h"
const byte relay_pin = 13;
Cl_time_relay T_Relay1;  //создать по времени отключ реле на пине 13
void func() {
  T_Relay1.ON();
}
//#2 кнопка
#include "Cl_do_btn.h"
const byte btn1_pin = 2;
Cl_do_btn Do_1; // создать кнопку на пине 2
void setup() {
  //#1 реле
  T_Relay1.setup(relay_pin, 0, 10000);// (пин,логика,время relay ON)
  //#2 кнопка
  Do_1.setup(btn1_pin);
}
void loop() {
  //#1 реле
  T_Relay1.loop();
  //#2 кнопка
  Do_1.loop(& func);
}

 

Понимаете ли, код

void loop() {
  //#1 реле
  T_Relay1.loop();
  //#2 кнопка
  Do_1.loop(& func);
}

вводит в ступор даже продвинутого человека, как бы вы в двух словах, объяснили это ТС ?

я понимаю, что это ваш стиль и т.д.

просто читал тут на форуме тему про два loop в скече, не от вас ли оно ?

какой то arduino wiring++ получается.

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну понятно. У меня под модуль Encoder_KY_040 заточен. Там резисторы на CLK и DIR на питание висят. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

xDriver пишет:

просто читал тут на форуме тему про два loop в скече, не от вас ли оно ?

Есть программа FLProg, которая рисует код под Ардуино. Хотя он очень кривой, он работает. Да и писать для новичков с помощью него проще.  В некотором смысле мой стиль это ответ на такое решение. Собирать программу из обычных рабочих модулей. Ну проще подкинуть в скетч пару классов и добавить модуль.loop(); и модуль.setup(); И все.

Но кто же может подумать, что народ делает подтяжку резистором к земле. Да так никто не делает. Это как правосторонее движение.  Ведь физически можно ездить по левой стороне, хотя не рекомендуется, так как тогда можно врезаться во встречную машину.

TTIIMMAA
Offline
Зарегистрирован: 09.02.2017

Получается мне нужно попробовать подтянуть резистором к 5V ?

просто схема с подтяжкой к земле работала с кодом который я указал в первом посте

TTIIMMAA
Offline
Зарегистрирован: 09.02.2017

Посмотрель схему Encoder KY 040, я все понял

Картинки по запросу Encoder_KY_040

Соберу схему так, думаю все будет работать. Но к сожалению я так и не понял для чего нужна кнопка SW,  какое действие она выполняет так и не понятно, или она просто прописана как пин ? ведь в коде нет, Пина на реле, и про время импульса тоже. Помогите пожалуйста как прописать это все. 

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

TTIIMMAA пишет:

Соберу схему так, думаю все будет работать. Но к сожалению я так и не понял для чего нужна кнопка SW,  какое действие она выполняет так и не понятно, или она просто прописана как пин ? ведь в коде нет, Пина на реле, и про время импульса тоже. Помогите пожалуйста как прописать это все. 

В Encoder KY 040  кнопка это просто надавить на ось и будет щелчок. Если у вас нет такого энкодера, то можно  на тот пин подключить внешнюю кнопку. Просто земля-> кнопка -> пин. Подтяжка на+5 В программная.

Цитата:

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

Составляет программы на FLProg армянчик , там же он показавает как это делать. Разумеется немного не академическое объяснение, но хотя бы ход и методы понятны.  Может и там найдете ваше решение. Вот только много у него видео.

https://www.youtube.com/channel/UCZ2a-GXoEFH8W34vq5ob7Kw

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скетч здесь https://yadi.sk/d/tI3tYixH3Dpk3H

головной файл выкладываю

/* to_TTIIMMAA.ino https://yadi.sk/d/tI3tYixH3Dpk3H
  #1 реле ->13 (relay_pin)
  #2 энкодер  CLK->2 (CLK_pin)
               DT->3 (DT_pin)
  #3           SW->4 (SW_pin)
  Принцип кода:энкодером + - регулируем импульс длину
               кнопкой отправляем импульс
*/
//#1 реле
#include "Cl_time_relay.h"
const byte relay_pin = 13;
Cl_time_relay T_Relay1;  //создать по времени отключ реле на пине 13
const uint32_t time_ON_max = 10000; // максимум 10 сек
const uint32_t time_ON_min = 100; // максимум 0,10 сек
const uint32_t time_ON_step = 100; // шаг изменения 0,10 сек
//#2 энкодер
#include "Cl_do_Encoder_KY_040.h"
const byte CLK_pin = 2;
const byte DT_pin = 3;
const byte SW_pin = 4;
Cl_do_Encoder_KY_040 Encoder; // ( CLK,DT,SW )создать энкодер на пинах 2,3,4
void func_SW(void) {
  T_Relay1.ON();
}
void func_plus(void) {
  T_Relay1.time_ON += time_ON_step;
  if (T_Relay1.time_ON > time_ON_max)T_Relay1.time_ON = time_ON_max;
  Serial.print("time_ON = ");
  Serial.println(T_Relay1.time_ON);
}
void func_minus(void) {
  T_Relay1.time_ON -= time_ON_step;
  if (T_Relay1.time_ON < time_ON_min)T_Relay1.time_ON = time_ON_min;
  Serial.print("time_ON = ");
  Serial.println(T_Relay1.time_ON);
}
void setup() {
  Serial.begin(9600);
  //#1 реле
  T_Relay1.setup(relay_pin, 0);// (пин,логика)
  //#2 энкодер
  Encoder.setup(CLK_pin, DT_pin, SW_pin);
}
void loop() {
  //#1 реле
  T_Relay1.loop();
  //#2 энкодер
  Encoder.loop(& func_SW , & func_plus, & func_minus );
}

 

TTIIMMAA
Offline
Зарегистрирован: 09.02.2017

Спасибо большое, вроде все понятно, А можно ли это код засунуть в FLProg и посмотреть как это выглядит?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

FLProg не пользуюсь. Хотя там легче составлять скетчи для новичков, но там код ну очень тяжело читаем. Так что без меня.

saleksey
Offline
Зарегистрирован: 11.02.2017

Механические энкодеры как и обычные кнопки обладают дребезгом контактов, чтоб от него избавиться можно добавить между контакатами А, В и корпусом по конденсатору 100нФ(так же как и резисторы но к корпусу)

пример кода обработки энкодера, не помню где взял, на авторство не претендую

int pinA = A3;  // номер вывода, подключенный к CLK енкодера
int pinB = A2;  // номер вывода контроллера, подключенный к DT енкодера
int encoderPosCount = 0; 
int pinALast;  
int aVal;
boolean bCW;

void setup() { 
  pinMode (pinA,INPUT);
  pinMode (pinB,INPUT);
  /* Считываем значение на выводе A и запоминаем его как последнее значение на этом выводе */
  pinALast = digitalRead(pinA);   
  Serial.begin (9600);
} 

void loop() { 
  aVal = digitalRead(pinA);
  if (aVal != pinALast){ // проверка на изменение значения на выводе А по сравнению с предыдущим запомненным, что означает, что вал повернулся
    // а чтобы определить направление вращения, нам понадобится вывод В.
    if (digitalRead(pinB) != aVal) {  // Если вывод A изменился первым - вращение по часовой стрелке
      encoderPosCount ++;
      bCW = true;
    } else {// иначе B изменил свое состояние первым - вращение против часовой стрелки
      bCW = false;
      encoderPosCount--;
    }
    Serial.print ("clock: ");
    if (bCW){
      Serial.println ("+");
    }else{
      Serial.println("-");
    }
    Serial.print("pos: ");
    Serial.println(encoderPosCount);
  } 
  pinALast = aVal;
} 

PS: Если реле электромеханическое не используйте его в ШИМ режиме - просто угробите, используйте полевик

TTIIMMAA
Offline
Зарегистрирован: 09.02.2017

qwone пишет:

Скетч здесь https://yadi.sk/d/tI3tYixH3Dpk3H

головной файл выкладываю

/* to_TTIIMMAA.ino https://yadi.sk/d/tI3tYixH3Dpk3H
  #1 реле ->13 (relay_pin)
  #2 энкодер  CLK->2 (CLK_pin)
               DT->3 (DT_pin)
  #3           SW->4 (SW_pin)
  Принцип кода:энкодером + - регулируем импульс длину
               кнопкой отправляем импульс
*/
//#1 реле
#include "Cl_time_relay.h"
const byte relay_pin = 13;
Cl_time_relay T_Relay1;  //создать по времени отключ реле на пине 13
const uint32_t time_ON_max = 10000; // максимум 10 сек
const uint32_t time_ON_min = 100; // максимум 0,10 сек
const uint32_t time_ON_step = 100; // шаг изменения 0,10 сек
//#2 энкодер
#include "Cl_do_Encoder_KY_040.h"
const byte CLK_pin = 2;
const byte DT_pin = 3;
const byte SW_pin = 4;
Cl_do_Encoder_KY_040 Encoder; // ( CLK,DT,SW )создать энкодер на пинах 2,3,4
void func_SW(void) {
  T_Relay1.ON();
}
void func_plus(void) {
  T_Relay1.time_ON += time_ON_step;
  if (T_Relay1.time_ON > time_ON_max)T_Relay1.time_ON = time_ON_max;
  Serial.print("time_ON = ");
  Serial.println(T_Relay1.time_ON);
}
void func_minus(void) {
  T_Relay1.time_ON -= time_ON_step;
  if (T_Relay1.time_ON < time_ON_min)T_Relay1.time_ON = time_ON_min;
  Serial.print("time_ON = ");
  Serial.println(T_Relay1.time_ON);
}
void setup() {
  Serial.begin(9600);
  //#1 реле
  T_Relay1.setup(relay_pin, 0);// (пин,логика)
  //#2 энкодер
  Encoder.setup(CLK_pin, DT_pin, SW_pin);
}
void loop() {
  //#1 реле
  T_Relay1.loop();
  //#2 энкодер
  Encoder.loop(& func_SW , & func_plus, & func_minus );
}

 

Спасибо вам большое что уделили для меня время , что написали для меня пример, принцип я вроде как понял, пока юзаю, пробую два индикатора семисегментных, точнее пока думаю как можно прикрепить