#1 2025-02-24 14:29:02

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Потрібна допомога в редагуванні скетчу для реле часу

Потрібна допомога в редагуванні скетчу, оскільки для мене тема з ардуіно нова,не можу сам впоратися тому прошу про допомогу
Суть проблеми,є 4 канальний модуль реле часу на базі ардуінки про міні,і є готовий скетч під це діло,але проблема заключається в тому що при подачі сигналу реле часу працює циклічно,тобто реле умовно відпрацювало 5 секунд а сигнал поступає нерозривно більше 5 секунд і реле часу спрацьовує знову а потрібно щоб незалежно від часу на який подається сигнал реле відпрацювало умовно 5 секунд і відключилось до моменту поки не буде наступного сигналу, якщо хтось зможе допогти буду дуже вдячний
Прикріпив архів з усіма даними по модулю

IO22C04-4-Channel-Pro-mini-PLC-Board.rarIO22C04-4-Channel-Pro-mini-PLC-Board.rar

Неактивний

#2 2025-02-24 14:36:07

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

Дивитись код всередині архіву неспортивно wink Акби воно на гітхабі було, з синтаксисом..
Спробую вгадати.
Ви в циклі міряєте логічний рівень на якомусь піні. Якщо там 1 - запускаєте якийсь процес довжиною 5 сек. Коли процес закінчується - там знову все ще 1.
Рішення таке: треба порвінювати рівень який зараз з попереднім рівнем; якщо вони відрізняються, тоді щось робити.

Неактивний

#3 2025-02-24 15:10:09

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

проблема в тому що сигнал буде дуже різним по часу і більшим ніж час роботи реле
прикріплю скріни з кодом

Неактивний

#4 2025-02-24 15:11:18

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

Bezymjannyjj.pngBezymjannyjj2.pngBezymjannyjj7.pngBezymjannyjj6.pngBezymjannyjj5.pngBezymjannyjj4.pngBezymjannyjj3.png

Неактивний

#5 2025-02-24 15:21:57

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

uint_8t prev_value;
void setup()
{
 prev_value = digitalRead(somePin);
}
void loop()
{
uint8_t new_value = digitalRead(somePin);
if (new_value != prev_value)
{
 prev_value = new_value;
do_some_shit();
}
}

Десь так.
Якщо треба щоб воно реагувало не на будь яку зміну сигналу, а лише на ввімкнення - добавте ще один if, я впевнений, все вийде wink
Якщо треба вміти ловити сигнал під час роботи 5 секундної функції, значить треба робити інакше. На перериваннях, наприклад.

Неактивний

#6 2025-02-24 15:26:23

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

дуже дякую.зараз спробую прописати і перевірю як все працює

Неактивний

#7 2025-02-24 15:32:10

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

Намалюйте на папірці діаграму входного сигналу і все вам стане ясно wink

Неактивний

#8 2025-02-24 15:54:46

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Потрібна допомога в редагуванні скетчу для реле часу

Maikl123 пише:

є готовий скетч під це діло

В тому скетчі одразу впадає в очі як мінімум один баг: TubeDisplay4Bit() виконується в контексі переривання і читає та пише int relay*_time_left. В loop() ці змінні також модифікуються без будь-якої синхронізації.

Також uchar OneSecondCnt як глобальна змінна ініціалізована нулем, потім

  OneSecondCnt--;
  if(OneSecondCnt==0) ...

Тобто переходить через переповнення - навряд чи так було спеціально задумано.

Ще купа інших недоліків у тому коді, але про них поки промовчу.

Maikl123 пише:

але проблема заключається в тому що при подачі сигналу реле часу працює циклічно,тобто реле умовно відпрацювало 5 секунд а сигнал поступає нерозривно більше 5 секунд і реле часу спрацьовує знову а потрібно щоб незалежно від часу на який подається сигнал реле відпрацювало умовно 5 секунд і відключилось до моменту поки не буде наступного сигналу

Так у вас умова вмикання реле - це низький рівень на вході:

if (digitalRead(INPUT1)==LOW) { ... digitalWrite(j1, HIGH);digitalWrite(led, HIGH); } ...

А умова вимикання - закінчення відліку лічильника

if (relay1_time_left>0) { ... } else { digitalWrite(j1, LOW); relay1_display = relay1_delay_time;}

Як сказано у коментарі вище, потрібно перемикати стан не по значенню рівня на вході, а по факту зміни цього рівня.
Але мені здається, набагато легше буде написати нормально з нуля, чим виправляти той "готовий" гів код.

Остання редакція dimich (2025-02-24 16:06:48)

Неактивний

#9 2025-02-24 15:57:35

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Потрібна допомога в редагуванні скетчу для реле часу

Maikl123 пише:

прикріплю скріни з кодом

Не робіть так. Ви б ще аудіоповідомлення з кодом надиктували.

Неактивний

#10 2025-02-24 16:39:33

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

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

Неактивний

#11 2025-02-24 16:45:55

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

цей код писав не я,купив готовий модуль 4 канального реле часу під ардуінку цей скетч був у комплекті як "заводський" тому так,є схема модуля якщо потрібно

Неактивний

#12 2025-02-24 16:53:35

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

Так у вас умова вмикання реле - це низький рівень на вході:

if (digitalRead(INPUT1)==LOW) { ... digitalWrite(j1, HIGH);digitalWrite(led, HIGH); } ...

А умова вимикання - закінчення відліку лічильника

if (relay1_time_left>0) { ... } else { digitalWrite(j1, LOW); relay1_display = relay1_delay_time;}

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

Неактивний

#13 2025-02-24 16:57:34

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

Як сказано у коментарі вище, потрібно перемикати стан не по значенню рівня на вході, а по факту зміни цього рівня.
Але мені здається, набагато легше буде написати нормально з нуля, чим виправляти той "готовий" гів код.


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

Неактивний

#14 2025-02-24 16:59:28

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

Ну я в же один раз пропонував використовувати не низький рівень, а перехід з високого рівня в низький.

Неактивний

#15 2025-02-24 17:03:18

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

if (digitalRead(INPUT1)==LOW)

uint8_t new_value = digitalRead(somePin);
if (new_value != prev_value)
{
 prev_value = new_value;
do_some_shit()uint8_t new_value = digitalRead(somePin);
if (new_value != prev_value)
{
 prev_value = new_value;
 if (new_value == LOW)
    need_start = true;
};
}
if (need_start) {need_start = false;...}

Неактивний

#16 2025-02-24 17:41:13

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

jokeR пише:

Ну я в же один раз пропонував використовувати не низький рівень, а перехід з високого рівня в низький.


але питання як це організувати,я не можу подати високий рівень у вигляді сигналу,оскільки там не 5в і ардуінка не переварить а щось кардинально міняти по технічці не хотілося б

Неактивний

#17 2025-02-24 18:14:19

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

ну я ж код написав..

Неактивний

#18 2025-02-24 18:26:48

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Потрібна допомога в редагуванні скетчу для реле часу

Maikl123 пише:

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

У вас є вхід з двома станами: низький / високий рівень (можливий брязкіт контактів поки до уваги не берем).
Є вихід з двома станами: реле вимкнене / увімкнене.
Є внутрішній стан таймера: активний / неактивний.

Це вже дає 8 можливих комбінацій (частина з них потім редукується). Для початку намалюйте діаграму або таблицю переходів. Для кожного переходу визначте умову (стан входу, стан таймера), а також дії, які мають виконатись (увімкнути/вимкнути реле, запустити таймер і т.п.).

Поки реле увімкнене, повторний перехід з високого на низький рівень на вході має перезапускати таймер? Чи стан вхіду має значення тільки після вимкнення реле?

Неактивний

#19 2025-02-24 18:39:24

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

jokeR пише:

ну я ж код написав..


пробував попередній варіан в різних варіаціях нічого не виходить,якщо не важко напишіть на коді один приклад конкретний

/*---Segment Display Screen----
--A--
F---B
--G--
E---C
--D--
__  __   __  __
|__||__|.|__||__|
|__||__|'|__||__|
----------------------*/   


#include "FlexiTimer2.h"
#define uchar unsigned char
#define uint  unsigned int

int display_dat;
int key_value;

const int led = 13;

//Pin connected to latch of Digital Tube Module
const int latch = 8;
//Pin connected to click of Digital Tube Module
const int clock = 9;
//Pin connected to data of Digital Tube Module
const int data = 7;

const int K1 = 2;
const int K2 = 3;
const int K3 = 4;
const int K4 = 5;

const int INPUT1 = A1;
const int INPUT2 = A0;
const int INPUT3 = A3;
const int INPUT4 = A2;

const int j1 = 10;
const int j2 = 11;
const int j3 = 12;
const int j4 = 6;

int relay1_delay_time = 5;//1-9999 seconds,Modify the number change the delay time
int relay2_delay_time = 5;//1-9999 seconds,Modify the number change the delay time
int relay3_delay_time = 5;//1-9999 seconds,Modify the number change the delay time
int relay4_delay_time = 5;//1-9999 seconds,Modify the number change the delay time

int relay1_time_left;
int relay2_time_left;
int relay3_time_left;
int relay4_time_left;

int relay1_display;
int relay2_display;
int relay3_display;
int relay4_display;



/*       NO.:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 23 24 25 26 27 28     
/*Character :0,1,2,3,4,5,6,7,8,9,A, b, C, c, d, E, F, H, h, L, n, N, o, P, r, t, U, -,  ,*/
uchar  TUBE_SEG[] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa7,0xa1,0x86,0x8e,0x89,0x8b,0xc7,0xab,0xc8,0xa3,0x8c,0xaf,0x87,0xc1,0xbf,0xff};//Common anode Digital Tube Character Gallery

uchar TUBE_NUM[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//Tuble bit number

uchar dat_buf[8];

//***********************************************
// dat : Data to be displayed
// com_num :  Digital Tube Common
//***********************************************
uchar dat;
uchar com_num;
void TubeDisplayOneBit()
{
  uchar tube_dat;
  uchar bit_num;
   tube_dat = TUBE_SEG[dat]; //Common Cathode Digital Tube,bit negated
   bit_num = ~TUBE_NUM[com_num];
 
    //ground latchPin and hold low for as long as you are transmitting
     digitalWrite(latch, LOW);
     
     shiftOut(data, clock, MSBFIRST, bit_num);
     shiftOut(data, clock, MSBFIRST, tube_dat);   
     
     //return the latch pin high to signal chip that it
     //no longer needs to listen for information
     digitalWrite(latch, HIGH);
}

uchar OneSecondCnt;
void TubeDisplay4Bit(void)
{
  if(com_num<3) com_num ++;else com_num=0;
  dat = dat_buf[com_num];
  TubeDisplayOneBit();
 
  OneSecondCnt--;
  if(OneSecondCnt==0)
  {
    OneSecondCnt = 1000;
    if(relay1_time_left>0){relay1_time_left--; relay1_display = relay1_time_left;} else {digitalWrite(j1, LOW);relay1_display = relay1_delay_time;}
    if(relay2_time_left>0){relay2_time_left--; relay2_display = relay2_time_left;} else {digitalWrite(j2, LOW);relay2_display = relay2_delay_time;}
    if(relay3_time_left>0){relay3_time_left--; relay3_display = relay3_time_left;} else {digitalWrite(j3, LOW);relay3_display = relay3_delay_time;}
    if(relay4_time_left>0){relay4_time_left--; relay4_display = relay4_time_left;} else {digitalWrite(j4, LOW);relay4_display = relay4_delay_time;}
   
  }
 
  if(key_value==0) display_dat = relay1_display;
  else if(key_value==1) display_dat = relay2_display;
  else if(key_value==2) display_dat = relay3_display; 
  else  display_dat = relay4_display;
 
   dat_buf[0] = display_dat/1000;
   display_dat = display_dat%1000;
   dat_buf[1] = display_dat/100;
   display_dat = display_dat%100;
   dat_buf[2] = display_dat/10;
   dat_buf[3] = display_dat%10;
 
}

void setup() {
   //set pins to output because they are addressed in the main loop
   pinMode(led, OUTPUT);
   
   
   pinMode(latch, OUTPUT);
   pinMode(clock, OUTPUT);
   pinMode(data, OUTPUT);
   
   pinMode(K1, INPUT);
   pinMode(K2, INPUT);
   pinMode(K3, INPUT);
   pinMode(K4, INPUT);
   
   pinMode(INPUT1, INPUT);
   pinMode(INPUT2, INPUT);
   pinMode(INPUT3, INPUT);
   pinMode(INPUT4, INPUT);
   
   pinMode(j1, OUTPUT);
   pinMode(j2, OUTPUT);
   pinMode(j3, OUTPUT);
   pinMode(j4, OUTPUT);
   
  FlexiTimer2::set(5, 1.0/1000, TubeDisplay4Bit); // call every 5ms "ticks"
  FlexiTimer2::start();
 
  digitalWrite(j1, LOW);
  digitalWrite(j2, LOW);
  digitalWrite(j3, LOW);
  digitalWrite(j4, LOW);
 
  digitalWrite(INPUT1, HIGH);
  digitalWrite(INPUT2, HIGH);
  digitalWrite(INPUT3, HIGH);
  digitalWrite(INPUT4, HIGH);
 
 
  digitalWrite(K1, HIGH);
  digitalWrite(K2, HIGH);
  digitalWrite(K3, HIGH);
  digitalWrite(K4, HIGH);
 
  key_value = 0;
}

void loop() {
 
  while(1)
  {

    if(digitalRead(INPUT1)==LOW) {relay1_time_left = relay1_delay_time;digitalWrite(j1, HIGH);digitalWrite(led, HIGH);}else { digitalWrite(led, LOW);}

    if(digitalRead(INPUT2)==LOW) {relay2_time_left = relay2_delay_time;digitalWrite(j2, HIGH);digitalWrite(led, HIGH);}else { digitalWrite(led, LOW);}

    if(digitalRead(INPUT3)==LOW) {relay3_time_left = relay3_delay_time;digitalWrite(j3, HIGH);digitalWrite(led, HIGH);}else { digitalWrite(led, LOW);}

    if(digitalRead(INPUT4)==LOW) {relay4_time_left = relay4_delay_time;digitalWrite(j4, HIGH);digitalWrite(led, HIGH);}else { digitalWrite(led, LOW);}
   
    if     (digitalRead(K1)==LOW) {key_value = 0; }
    else if(digitalRead(K2)==LOW) {key_value = 1; }
    else if(digitalRead(K3)==LOW) {key_value = 2; }
    else if(digitalRead(K4)==LOW) {key_value = 3; }
  }
}

Неактивний

#20 2025-02-24 18:52:33

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 49

Re: Потрібна допомога в редагуванні скетчу для реле часу

танунафіг..

Дешевше переписати з нуля.
Стороння людина в простиню з digitalread/digitalwrite без труда не врюхає.

while(1) - можна спокійно викинути, функція loop() сама перезапускається.
FlexiTimer2 - хз що це і як воно працює, підозрюю що якась ліба з таймером. Без вивчення readme таке крпще не використовувати.

TubeDisplay4Bit - судячи з назви, щось пов"язане з дисплеєм. Але всередині там щось з секундами робиться.

В пєчьку! (ц)

Неактивний

#21 2025-02-24 18:53:07

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

У вас є вхід з двома станами: низький / високий рівень (можливий брязкіт контактів поки до уваги не берем).
Є вихід з двома станами: реле вимкнене / увімкнене.
Є внутрішній стан таймера: активний / неактивний.

Це вже дає 8 можливих комбінацій (частина з них потім редукується). Для початку намалюйте діаграму або таблицю переходів. Для кожного переходу визначте умову (стан входу, стан таймера), а також дії, які мають виконатись (увімкнути/вимкнути реле, запустити таймер і т.п.)[/quote dimich]


потрібно щоб при вході низького сигнала з датчика вмикалось реле на умовних 5 секунд навіть якщо тривалість сигналу перевищує 5 секунд щоб реле повторно не вмикалось до моменту поки не буде нового сигналу із датчика ,оскільки зараз приходить сигнал реле вмикається і працює заданий час але якщо по закінченню часу сигнал все ще поступає то реле влючається знову на той же час а потрібно щоб повторно включалось тільки при вході нового сигналу,

Неактивний

#22 2025-02-24 19:01:59

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

jokeR пише:

танунафіг..

Дешевше переписати з нуля.
Стороння людина в простиню з digitalread/digitalwrite без труда не врюхає.

while(1) - можна спокійно викинути, функція loop() сама перезапускається.
FlexiTimer2 - хз що це і як воно працює, підозрюю що якась ліба з таймером. Без вивчення readme таке крпще не використовувати.

TubeDisplay4Bit - судячи з назви, щось пов"язане з дисплеєм. Але всередині там щось з секундами робиться.

В пєчьку! (ц)


так,дисплей є

ось такий модуль

Bezymjannyjj8.png

Неактивний

#23 2025-02-24 19:04:29

Maikl123
Учасник
Зареєстрований: 2023-01-25
Повідомлень: 28

Re: Потрібна допомога в редагуванні скетчу для реле часу

dimich пише:

Поки реле увімкнене, повторний перехід з високого на низький рівень на вході має перезапускати таймер? Чи стан вхіду має значення тільки після вимкнення реле?

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

Неактивний

#24 2025-02-24 19:31:56

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Потрібна допомога в редагуванні скетчу для реле часу

Для одного реле

bool input1_prev { false };

// в loop():

bool input = (digitalRead(INPUT1)==LOW);
if (input != input1_prev) {
    if (input) {
        noInterrupts();
        relay1_time_left = relay1_delay_time;
        digitalWrite(j1, HIGH);
        Interrupts();
    }
    digitalWrite(led, input); // тут один led на 4 канала?
    input1_prev = input;
}

Щоб не дублювати код для кожного канала, зробіть масив.
Викиньте "while(1) {...}" із loop().
Можна легко обійтись без отого FlexiTimer2, воно тільки ускладнює програму.

А краще найміть спеціаліста, в якого є час і натхнення, нехай напише вам нормальний код.

Неактивний

#25 2025-02-24 20:00:53

jokeer
Гість

Re: Потрібна допомога в редагуванні скетчу для реле часу

Якщо це плата популярна, на неї повинні бути прошивки. на гітхабі пошукайте.

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму