#2 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 16:56:07

Хлопці все запрацювало cool

ось...

#define NUM_READINGS 600
int average;
int outPin = 13;
int inPWM = A0;

void setup() {
  digitalWrite(outPin, LOW);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}


void loop() {
  long sum = 0;  // локальна змінна sum
  for (int i = 0; i < NUM_READINGS; i++) {      // згідно з кількістю усереднень
    sum += analogRead(A0);                        // сумуємо значення з датчика змінної sum
  }
  average = sum / NUM_READINGS;                  // знаходимо середнє арифметичне, поділивши суму на число вимірів
  Serial.println(average);                       // для прикладу виводимо в порт
  delay(1000);
 
  if (average < 22 && digitalRead(outPin) == LOW)  // умова на потрібний імпульс (шим)
   {                             
    digitalWrite(outPin, HIGH);                // робимо високий рівень
   }
   else if (average < 22 && digitalRead(outPin) == HIGH) // і якщо імпульс був раніше
   {
    digitalWrite(outPin, LOW);                  // вимикаємо 
   }
            

}

#4 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 14:30:17

jokeer пише:

Можливо. Дивіться попередження компіляції.
Але спочатку розберіться що у вас там за сигнал. Не схоже це на pwm. .

>> сигнал PWM йде приблизно зі значеннями 69-74,

що це за значення, звідки ви його взяли?

Я дивився у мониторі порта зміни при натисканні команди серво
Znmok-ekrana-2025-06-08-142635.png

#5 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 14:20:51

jokeR пише:

Трохи дивно виходить.  Ну давайте поміряємо період імпульсів.


Znmok-ekrana-2025-06-08-141812.png

#6 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 14:08:09

if (average < 20)                                  // умова на потрібний імпульс (шим)
   {                             
    digitalWrite(outPin, HIGH);                // робимо високий рівень
 
    } else  if  digitalRead(outPin,HIGH) { // i якщо імпульс був знов через деякий час , де був HIGH
  
    digitalWrite(outPin, LOW);                // вимикаємо 

Наразі не компілюється, щось с синтаксисом..

#7 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 12:50:19

jokeer пише:

щось це не схоже на pwm. Або десь земля відірвана.
Розказуйте, якщо це не секретна бімба wink

Інший пристрій це STM32F103 яка управляє сервомоторами зі зворотнім зв'язком у виді микроперемекача. Я вимикаю конектор мотора та туди ціпляюсь портом D2 (два пина: сигнал та GND)

#9 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 12:02:23

jokeR пише:

Про серву схоже вгадав wink
Ви хочете щоб кожне відкривання серви перемикало стан пристрою (щоб лампочак вмикалась і вимикалась)?


Так

#10 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 12:01:17

jokeR пише:
#define PIN_INPUT 2 // Arduino Nano - pin2 or pin3 only
#define PWM_WIDTH_FALSE 1400
#define PWM_WIDTH_TRUE 1600

unsigned long pulse_start = 0;
unsigned long pulse_width = 0;
bool state_from_pwm = false;

void catch_int()
{
   if (digitalRead(PIN_INPUT))
   {
    pulse_start = micros();
   } else {
    pulse_width = micros() - pulse_start;
    if (pulse_width < PWM_WIDTH_FALSE) 
    {
      state_from_pwm = false;
    } else if (pulse_width > PWM_WIDTH_TRUE)
    {
      state_from_pwm = true;
    };
    digitalWrite(LED_BUILTIN, state_from_pwm);
   };
}


void setup() {

  pinMode(LED_BUILTIN, OUTPUT); 
  pinMode(PIN_INPUT, INPUT);
  attachInterrupt(digitalPinToInterrupt(PIN_INPUT), catch_int, CHANGE);
  interrupts();
}

void loop() {
}

Десь так. Очікуються імпульси на вході D2. Якщо ваші 20 - це 1/20 від 50 гц, тобто 1 мс, то варто взяти за межу середину допустимого інтервалу (1.5мс), і додати гістерезис +-100 мкс, для захисту від спрацьовувань близько до межі. Сподіваюсь, вгадав.
Хоча, якщо я вгадав, то мені здається, що ваша задача вирішується і без додаткового контроллера.

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

state_from_pwm = true;

1

#11 Re: Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-08 11:41:42

jokeR пише:

Конкретно що не так з вашим кодом. Ви 500 разів підряд читаєте значення з АЦП і рахуєте середнє значення. Зазвичай так роблять, коли інтервал часу, на якому усереднюють, відомий. У вашому випадку - ні. 500 відліків - невідомо скільки мікросекунд.
Далі. АЦП вертає значення від 0 до 1024, 1024 відповідає, якщо не помиляюсь, 3.3 В. Що таке 20 незрозуміло, але це дуже близько до рівня шуму. Скоріше за все, воно ловить завади від живлення.

Згоден!

Так, замало. Але мені цього вистачає, щоб зловити команду на запуск. Нажаль осцила нема, щоб зробити точні заміри імпульсів. Ціль - Продублювати запуск умовного сервомотору, тіки з логічною одиницею або нулем.

Слухаю порт, де значення можуть бути різними від 0 до 1023. Коли інший пристрий знаходится в режимі очікування, то сигнал PWM йде приблизно зі значеннями 69-74, а коли йде команда на виконання, то маємо десь 18-21. (умовні значення). і роблю порт (13) HIGH. Через деякий час поступає таж сама команда з умовним значенням 18-20 мені потрібно зробити порт (13) LOW. При тому коді, що скинув вишче, світлодіод блимкае приблизно 4 рази, та тухне. Та якщо убрати

  } else {
  
    digitalWrite(13, LOW);
  }

світлодіод світиться постіно. Потрібно щоб він тух при подальшому, коли середне аріфмітичне (18-21) з'явиться в виборці.

#12 Програмування Arduino » Допомога з написанням коду Arduino Nano (Arduino IDE) » 2025-06-07 20:25:21

Kvins
відповідей: 30

Всім міцного!

Хлопці потребую допомоги у написанні скетчу.

Задача:
Маємо PWM сигнал з іншого пристрою, треба з нього по команді (умова (average < 20)), перетворити на логічну одиницю і якщо через деякий час  ще буде такий саме імпульс, на нуль.  Використовую порт з LED, щоб бачити як відпрацьовує логіка.

#define NUM_READINGS 500
int average;
int outPin = 13;

void setup() {
  digitalWrite(13, LOW);
  Serial.begin(9600);
}
void loop() {
  long sum = 0;                                  // локальна змінна sum
  for (int i = 0; i < NUM_READINGS; i++) {      // згідно з кількістю усереднень
    sum += analogRead(0);                        // сумуємо значення з датчика змінної sum
  }
  average = sum / NUM_READINGS;                  // знаходимо середнє арифметичне, поділивши суму на число вимірів
  Serial.println(average);                       // для прикладу виводимо в порт
  if (average < 20) {                             // умова на потрібний імпульс (шим)
  digitalWrite(outPin, HIGH);                // робимо високий рівень
 
    } else {
  
    digitalWrite(13, LOW);
  }
}

Є нюанс, справа в тому, що імпульс пробігає декілька разів і в мене, порт падає в LOW. Можливо, я все роблю не правильно, є інший алгоритм...
Підскажіть як це можна реалізувати.
Дякую! smile

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