Помогите разобраться с программой

Тема в разделе "Arduino & Shields", создана пользователем grx1a, 4 фев 2013.

  1. grx1a

    grx1a Гик

    Здравствуйте, помогите с программой пожалуйста, не могу срастить как заставить работать два цифровых выхода одновременно , какая функция в программе позволяет такое делать? . Т.е. есть рабочие программы: для мигания двух светодиодов попеременно, также есть программа для пьеза пищалки работающей в качестве сирены, и есть программа на работу PIRsensor (инфракрасный датчик движения) с цифровым выходом, все эти проги просты и по отдельности работают без проблем, но когда их пытаюсь объединить вместе работают, но ни так как хотелось бы. А хотелось бы так: При срабатывании PIR сенсора должна включится сирена вместе с мигалкой одновременно, но у меня получается только так: срабатывает PIR сенсор при этом сначала мигает мигалка, затем пищит сирена и то только на повышение частоты, а хотелось бы что бы все работало одновременно, возможно ли такое? Может у кого-нибудь есть подобный пример, или хотя бы подскажите какую функцию в данном случае можно использовать чтобы решить проблему. Вот не совсем правильно работующая программа
    //мигалка с сиреной срабатывающая от PIR Сенсора
    #define led1 12 //Красный светодиод
    #define PIRpin 10 //Сигнал с PIR Сенсора
    #define led2 11 //Синийсветодиод
    #define soundPin 8
    int pir=0; //Значение PIR Сенсора
    int val = 0;
    float wait = 0.7;
    #define time 5
    int freq = 0;

    void setup()
    {
    pinMode (soundPin,OUTPUT);
    pinMode (led1,OUTPUT);
    pinMode (led2,OUTPUT);
    pinMode(PIRpin,INPUT);
    }
    void loop()
    {
    pir=digitalRead(PIRpin);
    if(pir==HIGH)
    {val=1;
    if (val==1){
    digitalWrite(led1,HIGH);
    delay(70);
    digitalWrite(led1,LOW);
    delay(120);
    digitalWrite(led1,HIGH);
    delay(70);
    digitalWrite(led1,LOW);
    delay(250);
    digitalWrite(led2,HIGH);
    delay(70);
    digitalWrite(led2,LOW);
    delay(120);
    digitalWrite(led2,HIGH);
    delay(70);
    digitalWrite(led2,LOW);
    delay(250);}


    {for (freq = 150; freq < 1800; freq++)
    {tone(soundPin, freq, time); // Beep pin, freq, time
    delay(wait);
    }
    for (freq = 1800; freq > 150; freq--)
    {tone(soundPin, freq, time); // Beep pin, freq, time
    delay(wait);}


    }}}

     
  2. nailxx

    nailxx Официальный Нерд Администратор

    Да, это конечно возможно, но не совсем тривиально. Посмотрите на свою программу. В `loop` у вас как последовательно идут ярковыраженные отдельные мини-алгоритмы, так они и исполняются. Помните, процессор выполняет инструкции последовательно. Он не догадается, что нужно исполнение «раздвоить» и одновременно исполнять чуть-чуть «верхнего кода» и чуть-чуть «нижнего».

    Выхода два:

    1) Суровый подгон. Смешать/подогнать всё таким образом, чтобы оно происходило одновременно алгоритмически. Что-то вроде:

    Код (Text):

    int i = 0;
    for (freq = 150; freq < 1800; freq++, i++)
    {
        tone(soundPin, freq, time);
        delay(1);
     
        digitalWrite(led1, i % 70);
        digitalWrite(led2, !(i % 70));
    }
     
    for (freq = 1800; freq > 150; freq--, i++)
    {
        tone(soundPin, freq, time);
        delay(1);
     
        digitalWrite(led1, i % 70);
        digitalWrite(led2, !(i % 70));
    }
     
    2) Использовать аппаратные таймеры и прерывания для исполнения кода, который меняет состояние лампочек и пищалки ровно через то время, которое вам нужно.
     
  3. Megakoteyka

    Megakoteyka Оракул Модератор

    Первый способ не советую, потом замучаетесь код править, чтобы банально изменить мелодию)
    Либо аппаратный таймер, либо простенький программный. Старайтесь избавляться от использования функции delay() в подобных алгоритмах, она только такты жрет.
     
  4. grx1a

    grx1a Гик

    Да я понимаю что код не реальный, что программа читается процессором с верху в низ в порядке очереди, это я так для наглядности выложил, что бы понятней была суть проблемы. Конечно я могу собрать все эти три схемы без ARDUINO и все будет работать на микросхемах и других деталях, и код не нужен так как нет процессора, но при этом придется использовать много деталей что увеличит вес и габариты устройства, в некоторых случаях это не есть хорошо, весь смысл в том что бы уменьшить количество железа. Я ардуинку приобрел меньше месяца назад, в праграмировании только начинаю изучать азы, начал изучать с момента покупки, мне интересно можно ли процессору зделать две функции loop чтобы он их находил и читал одновременно например в начале программы в void setup указать что функция void loop будет не одна а несколько, и их нужно читать одновременно или что то в этом роде, по поводу функции delay я уже заметил, что для подобных ситуаций она здорово все портит
     
  5. nailxx

    nailxx Официальный Нерд Администратор

    Вы говорите о чём-то вроде потоках и процессах. Когда одному процессору некто даёт то одну задачу, то другую, то одну, то другую и так постоянно. В полноценных компьютерах этим «некто» является операционная система. Это одна из её главных ролей.

    На Arduino, как вы понимаете, ОС нет и нужно реализовывать подобные вещи самостоятельно. Однако некоторое подобие ОС удавалось создавать энтузиастам.
     
  6. Unixon

    Unixon Оракул Модератор

    Создать видимость одновременности можно и несколько проще, но нужно правильно выбрать инструмент. Никаких for(), никаких delay() внутри loop() - только сравнение с millis() или любым другим счетчиком и изменение состояния. Программа при этом будет, однако, совершенно не похожа на исходный "последовательный" вариант.
     
    nailxx нравится это.
  7. Megakoteyka

    Megakoteyka Оракул Модератор

    Функция loop() - просто обертка, в реальности Ваша программа выглядит так:
    Код (Text):
    void setup() {
    }
     
    void loop() {
    }
     
    void main() {
      setup();
      while(true)
        loop();
    }
    Т.е. вы постоянно находитесь в бесконечном цикле. Вам нужно выполнять определенные действия в определенные моменты времени - поможет таймер аппаратный или самодельный программный.
     
    Unixon нравится это.