Время работы по включению и выключению

Kakmyc
Offline
Зарегистрирован: 15.01.2018

nik182 пишет:

Кто нибудь мне объяснит зачем переменные объявляют bool a = digitalRead(5); или static uint32_t timer=millis(); ? Я понимаю когда памяти совсем в обрез, но это же микроконтроллер. У него нет операционной системы. У него крутится одна программа и экономия на спичках может привести к непоняткам особенно у новичков при выходе за область видимости? Особенно со интересно со static - в чем цимус? Можно все переменные объявить глобально. Размер программы практически не изменится. 

Ну глобальные переменные они нехорошие и злые, листай потом ищи где они.
А static uint32_t , где используется , там и объявляется и извне его крутить никто не будет

ard-20
Offline
Зарегистрирован: 05.10.2020

Kakmyc пишет:
Зачем столько мусора ? Прерывания, переход через ноль и прочее. static uint32_t timer=millis(); if(есть сигнал фазы){timer=millis();} if(millis()-timer>=5000){//фазы не было 5 секунд} Херню какую-то напридумывали. А сигнал фазы можно чем угодно смотреть:переход через 0, трансформатор тока, БП туда повесить на 5в,оптрон прикрутить и тд и тп

попробовал так. Как только millis()-timer>=5000 он начинает выводить постоянно ERR ERR ERR

volatile uint32_t fuseA_fail,fuseB_fail,fuseC_fail;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);
PCIFR=PCIFR; PCICR=(1<<PCIE2); 
PCMSK2=(1<<PCINT23)|(1<<PCINT22)|(1<<PCINT21); // пины 5.6.7 на прерывание
unsigned long timer = 0; // Переменная для хранения времени
 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
{timer = millis();}
if(millis()-timer>=5000)
{Serial.println("ERR");}
}

 

ard-20
Offline
Зарегистрирован: 05.10.2020

##

nik182
Offline
Зарегистрирован: 04.05.2015

Гриша пишет:

ну, да вам бы пока с глобальными разобраться, потом в область видимости вникать. с таким-то кодом :) на 10 строк

Ну а по делу? В коде на 10 строк тоже можно нарваться на область видимости. Было уже на форуме. Даже тема как то так называлась - почему иногда не срабатывает условие? 

Гриша
Offline
Зарегистрирован: 27.04.2014

пост 104 правильно и будет так делать пока строка 17 выполняется... при каждом проходе будет это делать вы ведь его не ограничили, ничем 

Гриша
Offline
Зарегистрирован: 27.04.2014

nik182 пишет:

Гриша пишет:

ну, да вам бы пока с глобальными разобраться, потом в область видимости вникать. с таким-то кодом :) на 10 строк

Ну а по делу? В коде на 10 строк тоже можно нарваться на область видимости. Было уже на форуме. Даже тема как то так называлась - почему иногда не срабатывает условие? 

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

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

Гриша
Offline
Зарегистрирован: 27.04.2014

к примеру 

for (int i= 0; i==5; i++)
или
int i;
for (i=0; i==5; i++)

использовать глобально - ну я даже не знаю

ard-20
Offline
Зарегистрирован: 05.10.2020

###

ard-20
Offline
Зарегистрирован: 05.10.2020

Гриша пишет:

к примеру 

for (int i= 0; i==5; i++)
или
int i;
for (i=0; i==5; i++)

использовать глобально - ну я даже не знаю

Сейчас пробую

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ard-20 пишет:

Kakmyc пишет:
Зачем столько мусора ? Прерывания, переход через ноль и прочее. static uint32_t timer=millis(); if(есть сигнал фазы){timer=millis();} if(millis()-timer>=5000){//фазы не было 5 секунд} Херню какую-то напридумывали. А сигнал фазы можно чем угодно смотреть:переход через 0, трансформатор тока, БП туда повесить на 5в,оптрон прикрутить и тд и тп

попробовал так. Как только millis()-timer>=5000 он начинает выводить постоянно ERR ERR ERR

volatile uint32_t fuseA_fail,fuseB_fail,fuseC_fail;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);
PCIFR=PCIFR; PCICR=(1<<PCIE2); 
PCMSK2=(1<<PCINT23)|(1<<PCINT22)|(1<<PCINT21); // пины 5.6.7 на прерывание
unsigned long timer = 0; // Переменная для хранения времени
 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
{timer = millis();}
if(millis()-timer>=5000)
{Serial.println("ERR");}
}

 

А что мешает добавить флаг ?

static boolean flag=0;
if(digitalRead(5)==HIGH){timer=millis();}else flag=1;
if(millis()-timer>=5000&&flag==1){Serial.println("ERROR");flag=0;}

ard-20
Offline
Зарегистрирован: 05.10.2020

добавил флаг

А что мешает добавить флаг ?

static boolean flag=0;
if(digitalRead(5)==HIGH){timer=millis();}else flag=1;
if(millis()-timer>=5000&&flag==1){Serial.println("ERROR");flag=0;}

int a;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);

unsigned long timer = 0; // Переменная для хранения времени
 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
  {timer = millis();}
else {a=1;}


if ( millis()-timer>=5000 && a==1 )
   {Serial.println("ERR");
   a=0;
   }
   }

в итоге то же 

ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
 
b707
Offline
Зарегистрирован: 26.05.2017

а так

int a;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);

unsigned long timer = 0; // Переменная для хранения времени
 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
  {timer = millis(); a = 0;}
else if (millis()-timer<5000) {a=1;}


if ( (millis()-timer>=5000) && (a==1 ))
   {Serial.println("ERR");
   a=0;
   }
   }

 

ard-20
Offline
Зарегистрирован: 05.10.2020

 то же

 
ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
ERR
 
b707
Offline
Зарегистрирован: 26.05.2017

ard-20 пишет:

 то же

 

я там выше поправил, пробуйте  еще

 

ard-20
Offline
Зарегистрирован: 05.10.2020

получается весь void loop пока (millis()-timer>=5000) сериал порт печатает циклически и флаг постоянно в 1 становится

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Это тролль походу

b707
Offline
Зарегистрирован: 26.05.2017

ard-20 пишет:

получается весь void loop пока (millis()-timer>=5000) сериал порт печатает циклически и флаг постоянно в 1 становится

получается. Ну что, новый код из сообщения 113 работает?

b707
Offline
Зарегистрирован: 26.05.2017

Kakmyc пишет:
Это тролль походу

я или ТС? :)

Kakmyc
Offline
Зарегистрирован: 15.01.2018

b707 пишет:

Kakmyc пишет:
Это тролль походу

я или ТС? :)


ТС.
Не может код из #112
Такое выводить

b707
Offline
Зарегистрирован: 26.05.2017

Kakmyc пишет:
Не может код из #112 Такое выводить

легко.

обьяснить как?

ard-20
Offline
Зарегистрирован: 05.10.2020

так работает 

А как теперь после всех изменений вывести время когда нет сигнала?

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

b707 пишет:

Kakmyc пишет:
Не может код из #112 Такое выводить

легко.

обьяснить как?

Если ШИМ с частотой ниже 0,19Гц подавать на вход.
То с интервалом >5 секунд разве что

Хотя нет.
Накосячил .
else не нужен.
Надо ;
if(digitalRead(5)==HIGH){timer=millis();a=1;}

b707
Offline
Зарегистрирован: 26.05.2017

ard-20 пишет:

так работает 

И это все??? а где цветы и овации?:))

Цитата:
А как теперь после всех изменений вывести время когда нет сигнала?

а вы этого в заказе не указывали

b707
Offline
Зарегистрирован: 26.05.2017

Kakmyc пишет:
Если ШИМ с частотой ниже 0,19Гц подавать на вход. То с интервалом >5 секунд разве что

ерунду пишете.

Если фаза пропала и не появилась, код из 112 подождет пять секунд и начнет печатать ERR с частотой оборота ЛУП. И будет печатать до тех, пока фаза не появится опять.

Как это происходит - могу построчно обьяснить. Но думаю вы сами догадаетесь

Kakmyc
Offline
Зарегистрирован: 15.01.2018

b707 пишет:

Kakmyc пишет:
Если ШИМ с частотой ниже 0,19Гц подавать на вход. То с интервалом >5 секунд разве что

ерунду пишете.

Если фаза пропала и не появилась, код из 112 подождет пять секунд и начнет печатать ERR с частотой оборота ЛУП. И будет печатать до тех, пока фаза не появится опять.

Как это происходит - могу построчно обьяснить. Но думаю вы сами догадаетесь

Уже.
Смотрите выше

b707
Offline
Зарегистрирован: 26.05.2017

del

ard-20
Offline
Зарегистрирован: 05.10.2020

Спасибо всем кто помогал. Бурные  аплодисменты и овации.   

Пытаюсь делать дальше.

 

ard-20
Offline
Зарегистрирован: 05.10.2020

b707 пишет:

del

Вот блин одни чудеса. Как же это решить. Я запутался в край.

 

b707
Offline
Зарегистрирован: 26.05.2017

ard-20 пишет:

Вот блин одни чудеса. Как же это решить. Я запутался в край.

Что опять не так? Вроде решили уже. Аж два варианта...

ard-20
Offline
Зарегистрирован: 05.10.2020

Теперь работает

int a;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);

unsigned long timer = 0; // Переменная для хранения времени
 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
  {timer = millis(); a = 1;}

if ( (millis()-timer>=5000) && (a==1 ))
   {Serial.println("ERR");
   a=0;
   }
   }

 

b707
Offline
Зарегистрирован: 26.05.2017

ard-20 - любую программисткую задачку можно решить бесчисленным набором вариантов

ard-20
Offline
Зарегистрирован: 05.10.2020

Тут как только милис набегут больше timer выдаст ошибку . Но как посчитать сколько не было фазы используя эти данные?

ard-20
Offline
Зарегистрирован: 05.10.2020

Даю отсутствие сигнала 7 сек а выводит 5 почему?

int a,b;
unsigned long time_A;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);

unsigned long timer = 0; // Переменная для хранения времени

 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
  {timer = millis(); a = 1;}

if (digitalRead(5) == LOW)
  {time_A = millis()-timer; b=1;}
  

if ((millis()-timer>=5000)&&(a==1)&&(b==1))
   {Serial.println("ERR");
   Serial.println(time_A/1000);
   a=0;
   b=0;
   }
   }

 

Гриша
Offline
Зарегистрирован: 27.04.2014

1) как только у нас произошло событие мы запомнили время начала события

2) проверяем что событие длится дольше чем.... что-то делаем и выводим в порт. обнулять событие будем?

3) выводим в порт время с начала события, а дальше варианты а) каждые Х сек пока событие не закончится б) даже если событие закончилось выводим сколько длилось и когда началось... в) вариантов масса - как хотите так и творите.

 

Гриша
Offline
Зарегистрирован: 27.04.2014

1) как только у нас произошло событие мы запомнили время начала события

2) проверяем что событие длится дольше чем.... что-то делаем и выводим в порт. обнулять событие будем?

3) выводим в порт время с начала события, а дальше варианты а) каждые Х сек пока событие не закончится б) даже если событие закончилось выводим сколько длилось и когда началось... в) вариантов масса - как хотите так и творите.

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Думаю одну часть кода за ТС написали, на этом стоит останвиться

ard-20
Offline
Зарегистрирован: 05.10.2020

timer начало события 

милис конец события LOW 

time_A = millis()-timer;время LOW / Задаю 7 а выводит 5

 

Гриша
Offline
Зарегистрирован: 27.04.2014

ard-20 пишет:

timer начало события 

милис конец события LOW 

time_A = millis()-timer;время LOW / Задаю 7 а выводит 5

 

а покажи, в каком месте ты вычисляешь это время?

ard-20
Offline
Зарегистрирован: 05.10.2020
int a,b;
unsigned long time_A;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);

unsigned long timer = 0; // Переменная для хранения времени

 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
  {timer = millis(); a = 1;}

if (digitalRead(5) == LOW)
  {time_A = millis()-timer; b=1;}
  

if ((millis()-timer>=5000)&&(a==1)&&(b==1))
   {Serial.println("ERR");
   Serial.println(time_A/1000);
   a=0;
   b=0;
   }
   }

 вот {time_A = millis()-timer; b=1;}

20 строка

ard-20
Offline
Зарегистрирован: 05.10.2020
 Выводит
5
ERR
5
ERR
4
ERR
5
ERR
4
ERR
 
ard-20
Offline
Зарегистрирован: 05.10.2020

сделал по аналогии теперь время выводит от 0 до 7 в ком порт длинной линейкой

int a,b;
unsigned long time_A;
void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);

unsigned long timer = 0; // Переменная для хранения времени

 Serial.begin(9600);
}  

void loop(){
static uint32_t timer=millis();
if(digitalRead(5) == HIGH)
  {timer = millis(); a = 1;}

if (digitalRead(5) == LOW)
  {time_A = millis()-timer; b=1;}

  if (b==1){
    Serial.println(time_A/1000);
    b=0;
    }

if ((millis()-timer>=5000)&&(a==1))
   {Serial.println("ERR");
   Serial.println(time_A/1000);
   a=0;

   }
   }

 

nik182
Offline
Зарегистрирован: 04.05.2015

Если соединить фазы с входами D5 D6 D7 резисторами 3 мегома ( у меня цепочки из 3 1 мегомных SMD1206) то для реакции на отключение сети можно использовать что то типа 

int tf0, tf1, tf2;

void setup() {
  Serial.begin(115200);
  if (pulseIn(5, HIGH, 5000000L) == 0) { // если нет напряжения на фазе 5 секунд пишет ошибку и пытается начать сначала.
    Serial.print("A Fail");
    return;
  };
}

void loop()
{
  if (pulseIn(5, HIGH, 1000000L) == 0) { // если нет напряжения на фазе A 1сек пишет ошибку и пытается начать сначала.
    Serial.print("A Fail");
    return;
  } else delayMicroseconds(2400); if (bitRead(PIND, 5)) { // сдвиг на середину фазы А
  tf0--;
  if (tf0 < 1) tf0++;
} else {
  tf0++; if (tf0 > 50) {  // 50 периодов сети - 1 секунда - если нет напряжения на фазе A 1 секунду пишет ошибку и пытается начать сначала.
    Serial.print("A Fail");
    return;
  };
};
delayMicroseconds(7600); if (bitRead(PIND, 6)) { // сдвиг на середину фазы В
  tf1--;
  if (tf1 < 1) tf1++;
} else {
  tf1++; if (tf1 > 50) { // 50 периодов сети - 1 секунда - если нет напряжения на фазе B 1 секунду пишет ошибку и пытается начать сначала.
    Serial.print("B Fail");
    return;
  };
};
delayMicroseconds(7600); if (bitRead(PIND, 7)) { // сдвиг на середину фазы С
  tf2--;
  if (tf2 < 1) tf2++;
} else {
  tf2++; if (tf2 > 50) { // 50 периодов сети - 1 секунда - если нет напряжения на фазе C 1 секунду пишет ошибку и пытается начать сначала.
    Serial.print("C Fail");
    return;
  };
};
}

Это только идея. В железе не проверял. Пропускает отключения напряжения меньше 1 секунды. Фазы обязательно А-5 В-6 С-7 Если наоборот, то можно использовать как реле обратного порядка чередования фаз, уменьшив время реакции до пары - тройки периодов.  Может в два раза увеличить интервал из за особенностей работы pulseIn. 

ard-20
Offline
Зарегистрирован: 05.10.2020

Подскажите  вычитаю 

timer3 = (timer2 - timer1)/1000;

6
1
4294962
 
вроде должно быт 5 а выводит 4294962
ard-20
Offline
Зарегистрирован: 05.10.2020



int a,b,c;
unsigned long time_A;
 unsigned long timer1 =0;
unsigned long timer2 =0;
unsigned long timer3 =0;

void setup() {
pinMode(5, INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
Serial.begin(9600);
/*
if (pulseIn(5, HIGH, 5000000L) == 0) { // если нет напряжения на фазе 5 секунд пишет ошибку и пытается начать сначала.
    Serial.print("A Fail");
    return;
  }
if (pulseIn(6, HIGH, 5000000L) == 0) { // если нет напряжения на фазе 5 секунд пишет ошибку и пытается начать сначала.
    Serial.print("A Fail");
    return;
  }
if (pulseIn(7, HIGH, 5000000L) == 0) { // если нет напряжения на фазе 5 секунд пишет ошибку и пытается начать сначала.
    Serial.print("A Fail");
    return;
  }*/
}  

void loop(){

while (digitalRead(5) ==HIGH)
  {timer2 = millis();

  a=1;}

while (digitalRead(5) ==LOW)
  {timer1 = millis();
  
  b=1;}

 if (a==1 && b==1 ){
 timer3 = (timer2 - timer1)/1000;
  
  Serial.println(timer1/1000);
  Serial.println(timer2/1000);
  Serial.println(timer3);
  a=0;
  b=0;
 }
   }
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ard-20, опять вы плодите переменные, и называете их совершенно безликими именами. Это прямой путь к путанице. А чем кстати не угодил вариант, что я вам в #83 написал? Он уже работает. Разве что нет сигнализации 5-секундного простоя.

ard-20
Offline
Зарегистрирован: 05.10.2020

Он сложный для меня и без Вашей помощи я в нем не разберусь 

Мне еще надо посчитать и вывести сколько не было фазы в пределах до 5 сек 

например фазы а не было 2 сек.

 

b707
Offline
Зарегистрирован: 26.05.2017

ard-20 пишет:

Подскажите  вычитаю 

timer3 = (timer2 - timer1)/1000;

6
1
4294962
 
вроде должно быт 5 а выводит 4294962

Вам dimax уже написал, почему так получается.  Если бы вы вместо timer1 дали имя faza_ON а вместо timer2 - faza_OFF. было бы очевидно, что надо вычитать timer1 - timer2. а не наоборот, как у вас

А с вашими "слепыми" именами переменных надо постоянно держать в голове. что есть что. А у вас внимательности не хватает.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ard-20 пишет:

Он сложный для меня и без Вашей помощи я в нем не разберусь . Мне еще надо посчитать и вывести сколько не было фазы в пределах до 5 сек . например фазы а не было 2 сек.

Ну так мой пример и выводит раз  в секунду состояние, сразу видно сколько не было и какой фазы. "Сигналочку" на 5 секунд нетрудно дописать.

nik182
Offline
Зарегистрирован: 04.05.2015

Схему подключения к сети можно увидеть? От неё зависит алгоритм программы. Что делает Ваша последняя реализация я вообще не понимаю. Как по мне она всегда должна выдавать число меньше 11. 

ard-20
Offline
Зарегистрирован: 05.10.2020

Схема простая с НАНО 5 6 7 пин (подаю 0 или 1) вот этим скетчем с задержками а на МЕГА 2560 принимаю 5 6 7 пином и считываю

пытаюсь вывести ERR если фазы не было 5 сек и надо вывести сколько времени вообще не было фазы.

С нано подаю

boolean state_A = 0; // Переменная для хранения состояния вывода
boolean state_B = 0; // Переменная для хранения состояния вывода
boolean state_C = 0; // Переменная для хранения состояния вывода

unsigned long new_millis_A = millis(); // Переменная для хранения времени
unsigned long new_millis_B = millis(); // Переменная для хранения времени
unsigned long new_millis_C = millis(); // Переменная для хранения времени

#define TIME_ON_A 1000  // Время в течении, которого на выводе 1
#define TIME_OFF_A 3000 // Время в течении, которого на выводе 0

#define TIME_ON_B 1000  // Время в течении, которого на выводе 1
#define TIME_OFF_B 2000 // Время в течении, которого на выводе 0

#define TIME_ON_C 2000  // Время в течении, которого на выводе 1
#define TIME_OFF_C 3000 // Время в течении, которого на выводе 0

void setup() {
  
  pinMode(5,OUTPUT); // Настраиваем вывод на выход
  pinMode(6,OUTPUT); // Настраиваем вывод на выход
  pinMode(7,OUTPUT); // Настраиваем вывод на выход
  Serial.begin(9600);
  }
void loop(){ 
  
// Управление фазой А:
  if(millis() > new_millis_A){
    state_A = !state_A;
    digitalWrite(5, state_A);
    if(state_A){
      new_millis_A = millis() + TIME_ON_A;  
    }
    else{
      new_millis_A = millis() + TIME_OFF_A; 
    }
  }

  // Управление фазой В:
   if(millis() > new_millis_B){
    state_B = !state_B;
    digitalWrite(6, state_B);
    if(state_B){
      new_millis_B = millis() + TIME_ON_B;  
    }
    else{
      new_millis_B = millis() + TIME_OFF_B; 
    }
  }

  
   // Управление фазой C:
   if(millis() > new_millis_C){
    state_C = !state_C;
    digitalWrite(7, state_C);
    if(state_C){
      new_millis_C = millis() + TIME_ON_C;  
    }
    else{
      new_millis_C = millis() + TIME_OFF_C; 
    }
  }

}