Проблемы с millis HELP

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Приветствую, помогите разобраться

 

У меня есть 3 сигнала с трех пинов Ардуины. нужно чтобы два стартовали одновременно, как только прерывание выставит флажок, 3 сигнал начинается после завершения одного из сигналов и потом  ожидание когда опять сработает флаг от прерывания. Но даже вот такие попытки у  меня с тем же millis в Proteus показывают полную хрень...

Все что касается пhtывания и второго сигнала я оставил за скобками как комментарий, потому что даже одиy сигнал не заканчивается как нужно. если смотреть  d Ptoteus

 

u
unsigned long myTimer1;
unsigned long myTimer2;

bool keyOn1;
bool keyOn2;




       
              const int pinIn = 3;              
              const int pinOut1 = 13; // ключ на включение транформатора (+)
              const int pinOut2 = 12; //ключ сброса энергии положительной волны на конденсатор
                 int pinOut3 = 11; //светодиодный индикатор
                 int pinOut4 = 10; //ключ слива энергии из конденсатора
                 int pinSensor = 9; //закрепляем пин 11 за щелевым датчиком
                 int pinSTART = 8; //кнопк запуска цикла
                                             //присваем выходным ножкам значения      

            // volatile boolean  intFlag = false;
       //задаём прерыванию низкий уровень 
// часть кода для функции прерывания


void setup()
{

             pinMode(3, INPUT);          // 2 пин с подтяжкой к VCC
             pinMode(pinOut1, OUTPUT);          // определяем выходные пины
             pinMode(pinOut2, OUTPUT);          // определяем выходные пины
             pinMode(pinOut3, OUTPUT);          // определяем выходные пины
             pinMode(pinOut4, OUTPUT);          // определяем выходные пины
             // attachInterrupt(1, blink1,FALLING);

                 keyOn1 =  false;
                 keyOn2 =  false;
     
}


 void loop(){ 

 if (digitalRead(pinIn) == HIGH) {
    
           
                      
                  digitalWrite(pinOut1, HIGH);
                  keyOn1 = true;
                  myTimer1 = millis();  
                    
                        //digitalWrite(pinOut2, HIGH);
                        //keyOn2 = true;
                         //myTimer2 = micros();  
                  }
                  
                                 if(keyOn1)
                                   if (millis()-myTimer1 > 5) {
                                     digitalWrite(pinOut1, LOW);
                                        keyOn1 = false; 
                                         // intFlag==false;
                                        }

                                    // if(keyOn2)
                                     //  if (micros()-myTimer2 >= 1000) {
                                      //    digitalWrite(pinOut2, LOW);
                                      //       keyOn2 = false; }
        
                                              

   }                                
          
  //             void blink1()
//{
//  intFlag = true;
//  }            
                                                

 

                                                   

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018


 if (digitalRead(pinIn) == HIGH) {
    
           
                      
                  digitalWrite(pinOut1, HIGH);
                  keyOn1 = true;
                  myTimer1 = millis();  
                    
                        //digitalWrite(pinOut2, HIGH);
                        //keyOn2 = true;
                         //myTimer2 = micros();  
                  }
                  
                                 if(keyOn1)
                                   if (millis()-myTimer1 > 5) {
                                     digitalWrite(pinOut1, LOW);
                                        keyOn1 = false; 
                                         // intFlag==false;
                                        }

 

Здесь у меня сигнал должен начаться и закончится через 5мСек, но он согласно Proteus  заканчивается не по таймеру а вместе с входным сигналом

https://photos.app.goo.gl/CcnsWC7nAU9F4jwC8

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nafanja пишет:

Приветствую, помогите разобраться

Хорошо, будем разбираться.

Цитата:

 

У меня есть 3 сигнала с трех пинов Ардуины.

Что значит "есть"? Они входняе для Ардуино или, наоборот, Ардуина должна их сформировать на своих выходах?

И что собой представляют эти сигналы?

- определенный уровень сигнала (LOW или HIGH),

- изменение уровня (переход от LOW к HIGH и обратно),

- цифровые данные в последовательном коде,

- синхронизация для последовательного кода,

- сигнал некоторой частоты (определяющая - частота),

- сигнал некоторой частоты (определяющая - скважность),

- ...

Цитата:

нужно чтобы два стартовали одновременно,

Что значит "стартовали"?

Цитата:

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

Такие задачи решаются при помощи конечного автомата. Т.е. заводите переменную - состояние этого автомата и затем переводите эту переменную в очередное состояние в зависимости от текущего состояния и наличия различных внешних воздействий (приход того или иного сигнала, аппаратное прерывание, нажатие кнопки, истечение интервала времени и т.п.)

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

 Спасибо. что подключились)

                              
               
                 int pinOut1 = 13; // ключ на включение транформатора (+)
                 int pinOut2 = 12; //ключ сброса энергии положительной волны на конденсатор
                 int pinOut3 = 11; //светодиодный индикатор
                 int pinOut4 = 10; //ключ слива энергии из конденсатора
                 int pinSensor = 9; //закрепляем пин 11 за щелевым датчиком
                 int pinSTART = 8; //кнопк запуска цикла

 

Три ключа в цикле.
Первые два должны включится. как только на вход через прерывание зашел сигнал
 
pinMode(2, INPUT_PULLUP);          // 2 пин с подтяжкой к VCC
             pinMode(pinOut1, OUTPUT);          // определяем выходные пины
             pinMode(pinOut2, OUTPUT);          // определяем выходные пины
             pinMode(pinOut3, OUTPUT);          // определяем выходные пины
             pinMode(pinOut4, OUTPUT);          // определяем выходные пины
             attachInterrupt(0, blink1,FALLING);
     

буду очень признателен - если дадите пример от которого плясать

 

 

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

по сути входной сигнал заставил отработать три выхода (три ключа) и ждать опять сигнала со входа...

пытаюсь через millis, но логика вроде бы ясна. но результат показывает обратное)

sadman41
Offline
Зарегистрирован: 19.10.2016

Для чего задействовано прерывание в таком ненагруженном скетче?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nafanja, если речь о "разобраться", Вы бы все-таки ответили на вопросы из сообщения №2.

И еще на один: коль скоро в обсуждении появился новый термин "ключ", хотелось бы узнать, что именно Вы под этим термином подразумеваете?

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Приветствую. 

Вопрос прерывания -: побаиваюсь пропусков.

Но сам скетч больше. Это я уже довел его до примитива, потому что millis в proteus не отрабатывают даже при простой нажатой кнопке. Под руками пока нет генератора, чтобы подать сигнал на вход и наблюдать картину.

Но сам по себе proteus 7 и виртуальная ардуина показывают. само прерывание с делеем отработает нормально. а вот миллис даже по кнопке не срабатывает. 

Т.е. сигнал начался, но он не заканчивается как прописано в 5 миллисекунд.

На вход поступает сигнал в 5 Герц 9меандр) скважность 50%.

Upper
Offline
Зарегистрирован: 23.06.2020

nafanja пишет:

Здесь у меня сигнал должен начаться и закончится через 5мСек, но он согласно Proteus  заканчивается не по таймеру а вместе с входным сигналом

По коду, он должен закончится через 5 мс ПОСЛЕ ОКОНЧАНИЯ входного сигнала.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Есть внешний тактовый генератор, сейчас ока 5 Герц частота и скважность50% (планирую увеличить до 50 Герц.)

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

Подскажите - как вставить картинку?

 

 

 

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Вопрос тогда - это врет Зroteus?

сейчас я сделал полный откат до минимума в скетче, чтобы проверить что не так. Один из вариfнтов - наверное просто выставить в миллис несколько секунд и посмотреть как это будет срабатывать от простой кнопки. Но в протеусе сам сигнал работает синхронно с кнопкой ...И это только пока на одном сигнале. пока понять почему так показывает Proteus - не могу понять.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

 

[/quote]

Такие задачи решаются при помощи конечного автомата. Т.е. заводите переменную - состояние этого автомата и затем переводите эту переменную в очередное состояние в зависимости от текущего состояния и наличия различных внешних воздействий (приход того или иного сигнала, аппаратное прерывание, нажатие кнопки, истечение интервала времени и т.п.)

[/quote]

Не совсем понял), не могли бы вы немного расжевать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nafanja пишет:
заканчивается не по таймеру а вместе с входным сигналом

А Вы чего хотели? До тех пор, пока Вы держите кнопку, условие "if (digitalRead(pinIn) == HIGH) " будет истинным и Ваш сигнал будет "включаться" снова и снова.

Добавьте туда проверку на то, что сигнал в данный момент не включён, станет легче.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Похоже что пока с одним пином заработало и даже с прерыванием, теперь остается понять будет ли работать второй выходной пин

 

unsigned long myTimer1;
unsigned long myTimer2;

bool keyOn1;
bool keyOn2;




       
              const int pinIn = 3;              
              const int pinOut1 = 13; // ключ на включение транформатора (+)
              const int pinOut2 = 12; //ключ сброса энергии положительной волны на конденсатор
                 int pinOut3 = 11; //светодиодный индикатор
                 int pinOut4 = 10; //ключ слива энергии из конденсатора
                 int pinSensor = 9; //закрепляем пин 11 за щелевым датчиком
                 int pinSTART = 8; //кнопк запуска цикла
                                             //присваем выходным ножкам значения      

             volatile boolean  intFlag = false;
       //задаём прерыванию низкий уровень 
// часть кода для функции прерывания


void setup()
{

             pinMode(3, INPUT_PULLUP);          // 2 пин с подтяжкой к VCC
             pinMode(pinOut1, OUTPUT);          // определяем выходные пины
             pinMode(pinOut2, OUTPUT);          // определяем выходные пины
             pinMode(pinOut3, OUTPUT);          // определяем выходные пины
             pinMode(pinOut4, OUTPUT);          // определяем выходные пины
              attachInterrupt(1, blink1,FALLING);

                 keyOn1 =  false;
                 keyOn2 =  false;
     
}


 void loop(){ 

 if (intFlag==true) {
 //if (digitalRead(pinIn) == LOW) {
    
         
                      
                  digitalWrite(pinOut1, HIGH);
                  keyOn1 = true;
                  myTimer1 = millis();  
                     
                        digitalWrite(pinOut2, HIGH);
                        keyOn2 = true;
                         myTimer2 = micros();  
                  }
                  
                                 if(keyOn1)
                                   if (millis()-myTimer1 > 2000) {
                                     digitalWrite(pinOut1, LOW);
                                        keyOn1 = false; 
                                          
                                        }

                                     if(keyOn2)
                                       if (millis()-myTimer2 >= 10000) {
                                          digitalWrite(pinOut2, LOW);
                                             keyOn2 = false; 
                                                intFlag=false; }
                                              

   }                                
          
               void blink1()
{
  intFlag = true;
  }            

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nafanja пишет:

 

Цитата:

Такие задачи решаются при помощи конечного автомата. Т.е. заводите переменную - состояние этого автомата и затем переводите эту переменную в очередное состояние в зависимости от текущего состояния и наличия различных внешних воздействий (приход того или иного сигнала, аппаратное прерывание, нажатие кнопки, истечение интервала времени и т.п.)

Не совсем понял), не могли бы вы немного расжевать?

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

 

И еще: ответов на свои вопросы я так и не получил, а потому не усматриваю Вашей заинтересованности в том, чтобы "разобраться".

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

До сих пор не могу как изображение вставить...

Опишу тогда словами.

Сигнал. который приходит на вход - меандр. Его частота 50 ерц. Ширин импульса примерно 10 мСек.

Стартовый импульс для срабатывания двух выходных пинов по переднему входному фронту...Получилось ли ответить?

 

Вот ссылка на то как приходят импульсы на вход https://photos.app.goo.gl/bT4f6R4iuVPQhj827

Вот так должны срабатывать импульсы или выходные пины, данныe из LTSpice

1.PULSE(0 5 0 10n 10n 5m 10m)

2.PULSE(0 5 4m 10n 10n 6m 10m)

3. PULSE(0 5 0 10n 10n 4m 10m)

https://photos.app.goo.gl/xHbzjtomzJHDnWN48

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

ЕвгенийП пишет:

nafanja пишет:
заканчивается не по таймеру а вместе с входным сигналом

А Вы чего хотели? До тех пор, пока Вы держите кнопку, условие "if (digitalRead(pinIn) == HIGH) " будет истинным и Ваш сигнал будет "включаться" снова и снова.

Добавьте туда проверку на то, что сигнал в данный момент не включён, станет легче.

Спасибо). а как это сделать?

В прерывании указывается фронт. а вот как быть с выхоными сигналами. которые как бы наползают во вреvени друг на друга мне непонятно. пытаюсь осилить millis. Но с Proteus это понимание пока не приходит.

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nafanja пишет:
Спасибо). а как это сделать?

Вы это уже сделали в последней версии. Через зад, но сделали.

Знаете, Ваша проблема (самая главная) даже не в незнании, а в крайне халатном отношении к коду. Так, как Вы пишете, у Вас никогда толком не будет получаться. Чтобы писать так нагло, как это делаете Вы, и это работало, нужно иметь ахренительную квалификацию.

Посмотрите сами на свой код (имею в виду стартовое сообщение темы). Как он отформатирован? Такое форматирование отражает вложенность частей и общую логику? Оно помогает понимать, что происходит? Я вот, пока внимательно не присмотрелся (и не напрягся) считал, что if из строки №56 находится внутри if'а из строки #43! А они оказывается независимы! Так какого ж хера Вы строку №56 (и всё рядом) так вправо задвинули? Для того, чтобы засрать мозги себе и остальным? Другой причины не вижу.

Далее, что именно полезного сообщает нам комментарий в строке #28? Там просто приводится третий пин в состояние INPUT. А в комментарии почему-то написано, что второй пин приводится в состояние INPUT_PULLUP. зачем в комментарии враньё? Для того, чтобы засрать мозги себе и остальным? Другой причины не вижу.

А что полезного нам сообщают комментарии в строках №№ 29-32? Там есть полезная информация? А если нет, то нахрена это написано? ? Для того, чтобы засрать мозги себе и остальным? Другой причины не вижу.

И такого много. Вы сделали ВСЁ, чтобы в Вашей программе никто не мог разобраться и в первую очередь Вы сами. Так не программируют.

Если какой-то идиот сказал Вам, что красиво выравнивать и внятно комментировать нужно только при сдаче заказчику, а "себе и так пойдёт", пошлите этого деятеля на юх и посоветуйте ему ежедневно носить обувь, которая натирает ноги, а удобную надевать только по праздникам, если надо идти "в приличное место".

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

Что касается советов коллеги по автомату и моего совета проверять состояние (что есть частный случай того, что посоветовал он), то здесь на форуме есть подробные объяснения как это делается (например) - изучайте.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018


unsigned long myTimer1;
unsigned long myTimer2;

bool keyOn1;
bool keyOn2;




       
              const int pinIn = 3;              
              const int pinOut1 = 13; // ключ на включение транформатора (+)
              const int pinOut2 = 12; //ключ сброса энергии положительной волны на конденсатор
                
              int pinOut4 = 10; //ключ слива энергии из конденсатора
                
              volatile boolean  intFlag = false; //присваиваем низкре значение для функции прерывания
      


void setup()
{

             pinMode(3, INPUT_PULLUP);          // 2 пин с подтяжкой к VCC
             pinMode(pinOut1, OUTPUT);          // определяем выходные пины
             pinMode(pinOut2, OUTPUT);          // определяем выходные пины
            
             pinMode(pinOut4, OUTPUT);          // определяем выходные пины
             attachInterrupt(1, blink1,FALLING); //значения для прерывания

                 keyOn1 =  false;
                 keyOn2 =  false;
     
}


 void loop(){ 

 if (intFlag==true) {
      
                               
                  digitalWrite(pinOut1, HIGH); //включаем пин 1
                  keyOn1 = true;               //поднимаем флажок 1
                  myTimer1 = millis();         //обнуляем таймер 1
                     
                  digitalWrite(pinOut2, HIGH); ////включаем пин 2
                  keyOn2 = true;               //поднимаем флажок 2
                  myTimer2 = micros();         //обнуляем таймер 2
                        intFlag=false; // закрываем флажок от функции прерввания
                  }
                  
                               if(keyOn1)
                               if (millis()-myTimer1 > 2000) { //отсчитываем 200- мСек
                                   digitalWrite(pinOut1, LOW); //выкелючаем пин 1
                                   keyOn1 = false; }           //флажок 1 опускаем
                                          
                                        
                               
                               if(keyOn2)
                                if (millis()-myTimer2 >= 10000) { //отсчитываем 10000- мСек
                                    digitalWrite(pinOut2, LOW);   //выкелючаем пин 2
                                    keyOn2 = false;               //флажок 2 опускаем
                                     }         
                                            

   }                                
          
               void blink1()
{
  intFlag = true; //получили на вход 3 сигнал и прерыванием ушли в цикл прерывания
                  //поднимаем влажок и переходим в основной цикл
  }            

 

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Сейчас я выложил код с прерыванием.

предыстория была такова, что я инициировал одно движение и мы подбили человека помочь нам провести эксперимент. Сам эксперимент можно было бы организовать так, ЧТОБЫ ИЗБАВИТЬСЯ ОТ МИКРОКОНТРОЛЛЕРА,  сделав все на TL494 и на этом успокоится...Но в коллективе человек вызвался использовать STM32 и при этом отказался, сославшись на то, что у меня в загашнике одна Ардиунка припасена. но выяснилось. что он Ардуинами не владеет. Вот как обычно мне и приходится разгребаться. Но из-за настырности заднюю включать неохота и хотелось бы разобраться в этой теме, коль время своей жизни у жуже стал с этим связываться.

 

поскольку я связался с Proteus и поьратил кучу ночей из-за своего тугодумья над темой millis пришлось перечитывать все. что попадалось на глаза и пытаться это приспособить к совей цели.

Что касается написания - то я перепробовал тысячи итераций) но решил все же обратиться к комьюнити за помощью. вдруг у меня настолько бенадежен)

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nafanja, Вы приходите на форум, чтобы выговориться? Вам общения не хватает?

Ваш пост №18 выложен через час после поста №17. Почему Ваш пост №18 не приведен в соответствие с рекомендациями из №17?

Почему Вы вообще не отвечаете на вопросы, которые Вам задают, и не выполняете рекомендации?

Какова цель Вашего пребывания на форуме?

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Я сейчас работаю без выходных и в перерывах между пытаюсь ответить.

Давайте по порядку. Возможно вы что-то понимаете, я не совсем. последний  скетч я постарался привести в порядок. потому что были к нему вопросы...

Andriano я вам отвечал на вопрос как мог. И что собой представляют эти сигналы?

- определенный уровень сигнала (LOW или HIGH),

- изменение уровня (переход от LOW к HIGH и обратно),

- цифровые данные в последовательном коде,

- синхронизация для последовательного кода,

- сигнал некоторой частоты (определяющая - частота),

- сигнал некоторой частоты (определяющая - скважность),

 

Я лично вам привел данные из LTSpic. чтобы вы получили представления за чем и как идут сигналы. Скинул скрин генератора из Proteusa в котором я гонял Arduino. если я что-то не ответил - дайте мне знать.

Вот скриншот из LTSpice три ключа работают от трех задающих генераторах, которым должна выступать Ардуина

https://photos.app.goo.gl/S7LXFcdjb4uGySPn6

https://photos.app.goo.gl/S7LXFcdjb4uGySPn6

1) время задержки срабатывания сигнала

2) время импульса

3) период 

 

SLKH
Offline
Зарегистрирован: 17.08.2015

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

есть у меня чувство (возможно, неверное), что задачка совсем примитивная. Но я её не понимаю - ни текста, ни картинок.

И ещё: не надо так писать: "pinMode(3, INPUT_PULLUP);          // 2 пин ..."

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nafanja пишет:

Я сейчас работаю без выходных и в перерывах между пытаюсь ответить.

Видите ли, ответ обычно требует некоторого обдумывания. Если у Вас нет времени понять вопрос и обдумать ответ, лучше совсем не отвечайте. Отложите вопросы на форум до того времени, когда сможете с ним плодотворно работать.

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

Цитата:

Давайте по порядку. Возможно вы что-то понимаете, я не совсем. последний  скетч я постарался привести в порядок. потому что были к нему вопросы...

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

Нет, Вы действительно так считаете, или просто "не было времени"?

Цитата:

Andriano я вам отвечал на вопрос как мог. И что собой представляют эти сигналы?

- определенный уровень сигнала (LOW или HIGH),

- изменение уровня (переход от LOW к HIGH и обратно),

- цифровые данные в последовательном коде,

- синхронизация для последовательного кода,

- сигнал некоторой частоты (определяющая - частота),

- сигнал некоторой частоты (определяющая - скважность),

Я лично вам привел данные из LTSpic.

Разве я Вас что-то спрашивал о LTSpice?

Цитата:

Вот скриншот из LTSpice...

Скриншота не вижу. Вижу какие-то ссылки. На этом форуме размещать относящуюся к теме информацию на внешних ресурсах считается дурным тоном.

Если Вы нуждаетесь в помощи, потратьте время на то, чтобы не создавать лишних сложностей тому, кто пытается Вам помочь. А ссылки на то, что у Вас не хватает на это времени, лично я рассматриваю как некорректное поведение.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Скетч перезалил

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018
Выше я попробовал изложить свою версию. может так получится мне пояснить.

Давайте я попробую пояснить все проще.

Есть некий синхроимпульс на входную ножку, от которой начинается отсчет времени.

Есть два пина, которые выставляют высокое значения одновременно, но заканчиваются они не одновременно.

Первый выходной сигнал на ножке заканчивает раньше и от него стартует третий сигнал на выход.

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

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018


     START                                     STOP
                 1==============================1
        1================1                      1
        1        1       1                      1 
        1        1       1                      1
        1        1       1                      1
========1        1       1===========================


        111111111111
        1          1
        1          1  
        1          1
========1          1================================== 

Вот попытка пояснить как должны располагаться три импульса на трех пинах у Ардуино.

Загружать скрины не получается мне сюда, подскажите плиз.

SLKH
Offline
Зарегистрирован: 17.08.2015

nafanja пишет:



     START                                     STOP
                 1==============================1
        1================1                      1
        1        1       1                      1 
        1        1       1                      1
        1        1       1                      1
========1        1       1===========================


        111111111111
        1          1
        1          1  
        1          1
========1          1================================== 

Вот попытка пояснить как должны располагаться три импульса на трех пинах у Ардуино.

один хрен непонятно

Цитата:
Загружать скрины не получается мне сюда, подскажите плиз.

 http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/pesochnitsa-novichok-prochti , "Вставка изображений"

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nafanja пишет:

>Давайте я попробую пояснить все проще.

Нет, давайте я попробую.

Читаю 

1. Свой пост №17
2. Ваш пост №18
3. Пост andriano #20 и #23
4. и, наконец, Ваш пост #24

Ну, ведь как был if из строки №73 сдвинут вправо, так и остался.

Вот скажите, у Вас настолько нет времени, что Вы не можете нажать Ctrl+T ??????

Или Вы просто издеваетесь над нами?

Давайте так, если Вы работаете круглыми сутками и не в состоянии читать, что Вам пишут, не в состоянии вставить картинку, и не в состоянии даже нажать Ctrl+T, давайте Вы оставите это дело до той поры, когда Вы сможете уделять этому занятию достаточно времени, чтобы хоть клавишу нажать. А пока не тратьте ни своё время, ни наше.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

/*ULTRA 26.06.2021

*/

unsigned long myTimer1;
unsigned long myTimer2;
unsigned long myTimer4;
unsigned long myTimerStopPeriod;

bool keyOn1;
bool keyOn2;
bool keyOff4;
bool keyStopperiod;





const int pinIn = 3;
const int pinOut1 = 13; // ключ на включение транформатора (+)
const int pinOut2 = 12; //ключ сброса энергии положительной волны на конденсатор

int pinOut4 = 10; //ключ слива энергии из конденсатора

volatile boolean  intFlag = false; //присваиваем низкре значение для функции прерывания



void setup()
{

  pinMode(3, INPUT_PULLUP);          // 3 пин с подтяжкой к VCC
  pinMode(pinOut1, OUTPUT);          // определяем выходные пины
  pinMode(pinOut2, OUTPUT);          // определяем выходные пины

  pinMode(pinOut4, OUTPUT);          // определяем выходные пины
  attachInterrupt(1, blink1, FALLING); //значения для прерывания

  keyOn1   = false;
  keyOn2   = false;
  keyOff4  = false;
  keyStopperiod = false;


}


void loop() {

  if (intFlag == true) {


    digitalWrite(pinOut1, HIGH); //включаем пин 1
    keyOn1 = true;               //поднимаем флажок 1
    myTimer1 = millis();         //обнуляем таймер 1

    digitalWrite(pinOut2, HIGH); ////включаем пин 2
    keyOn2 = true;               //поднимаем флажок 2
    myTimer2 = millis();         //обнуляем таймер 2

    digitalWrite(pinOut4, LOW);  //отключаем пин 4 ??? нужен ли эта команда, если у нас пин 4 не горит на время паузы
    //??? нужен ли эта команда, если у нас пин 4 не горит на время паузы
    keyOff4 = true;              //поднимаем флажок 4
    myTimer4 = millis();         //обнуляем таймер 4

    keyStopperiod = true;               //этот таймер и цикл завершает весь период работы выходных пинов
    myTimerStopPeriod = millis();


    intFlag = false; // закрываем флажок от функции прерввания
  }

  //имеет три выходных ножки, 1 и 2 включаютсся от точки Старта
  // ночка 4 отсчитыввает от точки старта паузу и включается до
  // окончания периода. который един для всех и составляет 10 Сек


  if (keyOn1)
    if (millis() - myTimer1 > 2000) { //отсчитываем 2000 мСек
      digitalWrite(pinOut1, LOW); //выкелючаем пин 1
      keyOn1 = false;
    }           //флажок 1 опускаем

  //сейчас временно выставляем значения в миллис и большого значения
  //чтобыиметь возможность протестировать

  if (keyOn2)
    if (millis() - myTimer2 >= 6000) { //отсчитываем 6000- мСек
      digitalWrite(pinOut2, LOW);   //выключаем пин 2
      keyOn2 = false;
    }              //флажок 2 опускаем


  if (keyOff4)
    if (millis() - myTimer4 >= 3000)   { //отсчитываем паузу от общего старта
      digitalWrite(pinOut4, HIGH);      //включаем пин4
      keyOff4 = false;
      keyStopperiod = true;
    }   //выствляем фдажок до полной остановки периода в 10 Сек

  if (keyStopperiod)
    if (millis() - myTimerStopPeriod >= 10000) {
      digitalWrite(pinOut4, LOW);
      keyStopperiod = false;
    }


}

void blink1()
{
  intFlag = true; //получили на вход 3 сигнал и прерыванием ушли в цикл прерывания
  //поднимаем влажок и переходим в основной цикл
}


nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

На вход МК поступает тактовый сигнал, с некой периодичностью.

Мне нужно, чтобы МК выдал три сигнала, т.е. каждый на каждую из 3 ножек.

Эти три сигнала по одному на ножку распределен во времени. Стоит вопрос - как это сделать?

Если бы они одновременно начинались и заканчивались или каждый друг за другом - я бы использовал delay и на этом все закончил. Но ни каждый во времени идут по разному

sadman41
Offline
Зарегистрирован: 19.10.2016

Используйте несколько мелких дилеев

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Вот три генератора, которые планируется сделать на Ардуино. Я подчеркнул красным данные из LTSpice.

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Намекаю: после дилея не обязательно деактивировать один из выходов, можно оставить его активным ещё на один дилей.

mifar
Offline
Зарегистрирован: 07.04.2021

Если я правильно понял ТС хочет получить нечто подобное

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018
ОГРОМНОЕ СПАСИБО

void setup() {
  // put your setup code here, to run once:
pinMode (12, OUTPUT);
pinMode (11, OUTPUT);
pinMode (10, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite (12, HIGH);
digitalWrite (10, HIGH);
delay (4);
digitalWrite (12, LOW);

  digitalWrite (11, HIGH);
 delay (2);
 digitalWrite (10, LOW);
    delay (5);
  digitalWrite (11, LOW);
}

}

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

СПАСИБО)))

Сколько мне пришлось перерыть в интернете)...А ларчик так просто для моего случая открывался)

 

Еще раз спасибо всем

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Приветствую. Попробовал переписать код через delay. При работе с Proteus если использовать генерацию с запуском от функции прерывания по флагу как бы работает. 

Похоже, что не синхронно, потому что сам ноут слабоват.

Попробовал написать такой код и Proteus ни как не реагирует. И тут может быть или мой ноут уже не в состоянии что-то показывать или что-то с кодом. Хотелось бы узнать, если какие-то ошибки от более опытных. Жду щупов под осциллограф, чтобы запустить в живую и пробовать запускать.

int pinIn = 3;    // вход для функции прерывания, принимающий тактовые импульсы
const int pinSensor = 4;// вход для подключения щелевого датчика
const int pinStart = 5 ;// старт кнопка
int pinOut1 = 13; // ключ на включение трансформатора
int pinOut2 = 12; // ключ сброса энергии индуктивности на конденсатор
int pinLed3 = 11; // пин индикатора ожидания между ш.датчиком к началу
int pinOut4 = 10; // ключ слива энергии из конденсатора

volatile boolean  intFlag = false; //присваиваем низкре значение для функции прерывания

bool flagWork;    // флаг входа в рабочий цикл (генерирования)
bool flagOut;    // флаг выхода из цикла
bool flagStart;  //флаг старта при кнопкеСТАРТ



// переменные
int pinsensorState = LOW;         // переменная для хранения состояния щелевого датчика
int pinstartState = LOW;         // переменная для хранения состояния кнопки  старта


void setup()
{

  pinMode(3, INPUT_PULLUP);          // 2 пин с подтяжкой к VCC
  pinMode(pinOut1, OUTPUT);          // определяем выходные пины
  pinMode(pinOut2, OUTPUT);          // определяем выходные пины
  pinMode(pinLed3, OUTPUT);          // определяем выход светдиодного индикатора
  pinMode(pinOut4, OUTPUT);          // определяем выходные пины
  attachInterrupt(1, blink1, FALLING); //значения для прерывания

  flagWork = false;
  flagOut = false;
  flagStart = false;
}

void loop() {

  pinstartState = digitalRead(pinStart);
  // считываем значения с кнопки старта

  pinsensorState = digitalRead(pinSensor);
  // считываем значения с входа щелевого датчика

  if (pinstartState == HIGH) {    //если на кнопке СТАРТ высокое значение
    do {
      flagStart = true;           //поднимаем флажок старта до тех пор
    }
    while (pinsensorState = HIGH); // пока не включится щелевой датчик

  }


  if (flagWork == true) { //если поднят флажок входа в цикл
    flagWork = false;
    if (flagStart == HIGH) { // если поднят флаг при вкл.кнопки СТАРТ

      if (intFlag == true) { //флажок для срабатывания прерывания
        intFlag = false;     //опустили флажок прерывания





        for (int counter = 1 ; counter <= 2; counter = counter + 1) {

          //функция на 10 мСек для повторения цикла два раза на 20 мСек
          //т.е. сработал тактовый импульс и мы прорутили генерацию два раза
          //сейчас время выставлено примерно

          digitalWrite (13, HIGH); // Транс
          digitalWrite (10, HIGH); // вкл С
          delay (4);
          digitalWrite (10, LOW);  // выкл С

          digitalWrite (12, HIGH);//пин L
          delay (2);
          digitalWrite (13, LOW); //транс
          delay (4);
          digitalWrite (12, LOW);  //пин L
          flagOut = true; //выходим из цикла
        }
        if (flagOut)
          flagOut = false;
        if (pinsensorState = HIGH) { //если щелевой датчик включен
          digitalWrite(pinLed3, HIGH); //включаем светодиод
          flagWork = false;
        }
        else {
          (flagWork = true);
        }
        // если щелевой датчик не сработал опять
        //возвращаемся в рабочий цикл генерации



      }
    }
  }

}
void blink1()

{
  intFlag = true; //получили на вход 3 тактовый сигнал и
  //поднимаем влажок и переходим в основной цикл
  //далее проаливаемся в цикл генерации
}

 

mifar
Offline
Зарегистрирован: 07.04.2021

Что это за картинка? Этот код не рабочий и не может выдавать ничего. Вообще.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

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

Добавил кнопку старта в PinMode


pinMode(3, INPUT);          // 3 пин с подтяжкой к VCC
  pinMode(5, INPUT);          // 5 пин кнопка СТАРТ с подтяжкой к подтяжкой к VCC
  pinMode(pinOut1, OUTPUT);          // определяем выходные пины
  pinMode(pinOut2, OUTPUT);          // определяем выходные пины
  pinMode(pinLed3, OUTPUT);          // определяем выход светдиодного индикатора
  pinMode(pinOut4, OUTPUT);          // определяем выходные пины
  attachInterrupt(1, blink1, RISING); //значения для прерывания

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

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Строка 054 после старта как может сработать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:
Строка 054 после старта как может сработать?

Нормально сработает. А вот строки №№55-98, те да - те хренушки.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Это то, что показывает мне при таком исполнении кода


/*ULTRA 26.06.2021

*/

int pinIn = 3;    // вход для функции прерывания, принимающий тактовые импульсы

int pinOut1 = 13; // ключ на включение транформатора
int pinOut2 = 12; // ключ сброса энергии индуктивности на конденсатор
int pinLed3 = 11; // пин индиактора ожидания между ш.датчиком к началу
int pinOut4 = 10; // ключ слива энергии из конденсатора

volatile boolean  intFlag = false; //присваиваем низкре значение для функции прерывания


void setup()
{

  pinMode(3, INPUT);          // 2 пин с подтяжкой к VCC
  pinMode(pinOut1, OUTPUT);          // определяем выходные пины
  pinMode(pinOut2, OUTPUT);          // определяем выходные пины
  pinMode(pinLed3, OUTPUT);
  pinMode(pinOut4, OUTPUT);          // определяем выходные пины
  attachInterrupt(1, blink1, RISING); //значения для прерывания

 }

void loop() {


  

  if (intFlag == true) { //флажок для срабатывания прерывания
    intFlag = false;     //опустили флажок прерывания
   
        for (int counter = 1 ; counter <= 2; counter = counter + 1) {

          //функция на 10 мСек для повторения цикла два раза на 20 мСек
          //т.е. сработал тактовый импульс и мы прорутили генерацию два раза
          //сейчас время выставлено примерно

          digitalWrite (13, HIGH); // Транс
          digitalWrite (10, HIGH); // вкл С
          delay (4);
          digitalWrite (10, LOW);  // выкл С

          digitalWrite (12, HIGH);//пин L
          delay (2);
          digitalWrite (13, LOW); //транс
          delay (4);
          digitalWrite (12, LOW);  //пин L
        }
      
}
}
void blink1()

{
  intFlag = true; //получили на вход 3 тактовый сигнал и
  //поднимаем влажок и переходим в основной цикл
  //далее проаливаемся в цикл генерации
}









 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Как ввести возможность остановить все датчиком до тех пор пока не нажму кнопку СТАРТ - вот тут не хватает мозга...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nafanja пишет:

Как ввести возможность остановить все датчиком до тех пор пока не нажму кнопку СТАРТ - вот тут не хватает мозга...

Варианта, минимум, два:

1. Циклом while.

2. Отключить прерывание от таймера, повесить прерывание на кнопку и усыпить контроллер.

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Вот что я нашел на просторах интернета. Никогда не использовал это. Поэтому вопрос про усыпление.

 

Также прерывание можно отключить при помощи функции 

detachInterrupt(pin)

, где pin – опять же номер прерывания. А ещё можно глобально запретить прерывания функцией 

noInterrupts()

 и снова разрешить их при помощи 

interrupts()

. Аккуратнее с ними! 

noInterrupts()

 остановит также прерывания таймеров, и у вас “сломаются” все функции времени и генерация ШИМ

Вот так можно ли организовать усыпление таймера?


/*ULTRA 26.06.2021

*/

volatile boolean  intFlag = false; //присваиваем низкре значение для функции прерывания



int pinIn = 3;    // вход для функции прерывания, принимающий тактовые импульсы
const int pinSensor = 4;// вход для подключения щелевого датчика
const int pinStart = 5 ;// старт кнопка

int pinOut1 = 13; // ключ на включение транформатора
int pinOut2 = 12; // ключ сброса энергии индуктивности на конденсатор
int pinLed3 = 11; // пин индиактора ожидания между ш.датчиком к началу
int pinOut4 = 10; // ключ слива энергии из конденсатора

// переменные
int pinsensorState = LOW;         // переменная для хранения состояния щелевого датчика
int pinstartState = LOW;         // переменная для хранения состояния кнопки  старта



void setup()
{

  pinMode(3, INPUT);          // 3 пин с подтяжкой к VCC
  pinMode(4, INPUT);          // 4 пин щелевой датчик
  pinMode (5, INPUT);         // 5 пин для кнопки СТАРТ
  pinMode(pinOut1, OUTPUT);          // определяем выходные пины
  pinMode(pinOut2, OUTPUT);          // определяем выходные пины
  pinMode(pinLed3, OUTPUT);
  pinMode(pinOut4, OUTPUT);          // определяем выходные пины
  attachInterrupt(1, blink1, RISING); //значения для прерывания

}

void loop() {

  pinstartState = digitalRead(pinStart);
  // считываем значения с кнопки старта

  pinsensorState = digitalRead(pinSensor);
  // считываем значения с входа щелевого датчика

  if (pinstartState == HIGH) {    //если на кнопке СТАРТ высокое значение
    interrupts();
  }             // Изменяем режим кнопки

  if (pinsensorState == HIGH) {   //если щелевой датчик включен
    noInterrupts();
  } // обнуляем значение


  if (intFlag == true) { //флажок для срабатывания прерывания
    intFlag = false;     //опустили флажок прерывания

    for (int counter = 1 ; counter <= 2; counter = counter + 1) {

      //функция на 10 мСек для повторения цикла два раза на 20 мСек
      //т.е. сработал тактовый импульс и мы прорутили генерацию два раза
      //сейчас время выставлено примерно

      digitalWrite (13, HIGH); // Транс
      digitalWrite (10, HIGH); // вкл С
      delay (4);
      digitalWrite (10, LOW);  // выкл С

      digitalWrite (12, HIGH);//пин L
      delay (2);
      digitalWrite (13, LOW); //транс
      delay (4);
      digitalWrite (12, LOW);  //пин L

    }
  }

}
void blink1()

{
  intFlag = true; //получили на вход 3 тактовый сигнал и
  //поднимаем влажок и переходим в основной цикл
  //далее проаливаемся в цикл генерации
}









 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Proteus показал, что пока на пин 5 не пришел сигнал noInterrupt Ардуино генерит сигналы на выходных ножках.

Если подключаю генератор с частотой 1 секунда шим 50% к пин 4 куда должен подключаться щелевой датчик и должна отключаться прерывание то генерация не происходит вообще...

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

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Сделал два генератора. который заменяет щелевой датчик, который подает сигнал на отключение прерывания. кнопка СТАРТ срабатывает на включение и вот такая получается модуляция

mifar
Offline
Зарегистрирован: 07.04.2021

nafanja пишет:

Можно ли считать эту симуляцию корректной,

Нет, нельзя. Хватит уже использовать метод тыка. Сделайте то что вам говорили. Распишите нормальным языком чего вы хотите, нарисуйте свои входные и выходные сигналы на листочке. Лично я уже из ваших пояснений  https://www.youtube.com/watch?v=vlUe8ciyh4w

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Включаем кнопку СТАРТ. которая есть пин 5. Запускается цикл генерации сигналов по aлажку от прерывания. прерывание происходит аппаратное на 3 пине. туда приходит тактовый сигнал с частотой 50 Герц.

Как только сработал щелевой датчик 4 пин, нам нужно отключить генерацию или усыпить прерывание. В скетче я попробjвал сделать noInterrups

Кнопку СТАРТ  я прикрутил к interrupts, чтобы разбудить апаратное прерывание.

Как только поднимается флажок прерывание я повторяю пичку импульсов два раз через функцию FOR

volatile boolean  intFlag = false; //присваиваем низкре значение для функции прерывания



int pinIn = 3;    // вход для функции прерывания, принимающий тактовые импульсы
const int pinSensor = 4;// вход для подключения щелевого датчика
const int pinStart = 5 ;// старт кнопка

int pinOut1 = 13; // ключ на включение транформатора
int pinOut2 = 12; // ключ сброса энергии индуктивности на конденсатор
int pinLed3 = 11; // пин индиактора ожидания между ш.датчиком к началу
int pinOut4 = 10; // ключ слива энергии из конденсатора

// переменные
int pinsensorState = LOW;         // переменная для хранения состояния щелевого датчика
int pinstartState = LOW;         // переменная для хранения состояния кнопки  старта



void setup()
{

  pinMode(3, INPUT);          // 3 пин с подтяжкой к VCC
  pinMode(4, INPUT);          // 4 пин щелевой датчик
  pinMode (5, INPUT);         // 5 пин для кнопки СТАРТ
  pinMode(pinOut1, OUTPUT);          // определяем выходные пины
  pinMode(pinOut2, OUTPUT);          // определяем выходные пины
  pinMode(pinLed3, OUTPUT);
  pinMode(pinOut4, OUTPUT);          // определяем выходные пины
  attachInterrupt(1, blink1, RISING); //значения для прерывания

}

void loop() {

  pinstartState = digitalRead(pinStart);
  // считываем значения с кнопки старта

  pinsensorState = digitalRead(pinSensor);
  // считываем значения с входа щелевого датчика

  if (pinstartState == HIGH) {    //если на кнопке СТАРТ высокое значение
    interrupts();
  }             // Изменяем режим кнопки

  if (pinsensorState == HIGH) {   //если щелевой датчик включен
    noInterrupts();
  } // обнуляем значение


  if (intFlag == true) { //флажок для срабатывания прерывания
    intFlag = false;     //опустили флажок прерывания

    for (int counter = 1 ; counter <= 2; counter = counter + 1) {

      //функция на 10 мСек для повторения цикла два раза на 20 мСек
      //т.е. сработал тактовый импульс и мы прорутили генерацию два раза
      //сейчас время выставлено примерно

      digitalWrite (13, HIGH); // Транс
      digitalWrite (10, HIGH); // вкл С
      delay (4);
      digitalWrite (10, LOW);  // выкл С

      digitalWrite (12, HIGH);//пин L
      delay (2);
      digitalWrite (13, LOW); //транс
      delay (4);
      digitalWrite (12, LOW);  //пин L

    }
  }

}
void blink1()

{
  intFlag = true; //получили на вход 3 тактовый сигнал и
  //поднимаем влажок и переходим в основной цикл
  //далее проаливаемся в цикл генерации
}

 

nafanja
nafanja аватар
Offline
Зарегистрирован: 20.06.2018

Сейчас вопрос такой, можно ли снять аппаратное прерывание через noInterrupts одним нажатием и навсегда.

Из литературы - это глобальное снятие. Если так, значит Proteus показывает все верно.

void loop() {

  pinstartState = digitalRead(pinStart);
  // считываем значения с кнопки старта

  pinsensorState = digitalRead(pinSensor);
  // считываем значения с входа щелевого датчика

  if (pinstartState == HIGH) {    //если на кнопке СТАРТ высокое значение
    interrupts();
  }             // Изменяем режим кнопки

  if (pinsensorState == HIGH) {   //если щелевой датчик включен
    noInterrupts();
  } // обнуляем значение