Ещё раз вопрос по dely() от чайника - поясните пожалуйста...

koko
Offline
Зарегистрирован: 19.11.2012

Здравствуйте!
Подскажите пожалуйста, каким образом можно реализовать программу (на самом деле стандартную для робототехники), считывающую информацию с датчиков и выдающую в зависимости от полученной информации команды на исполнительные механизмы.
Есть следующая  проблема (для моего понимания):
1. Подключаю один светодиод и пишу программу для того, чтобы он мигал 1 раз в секунду - работает, 2 раза в секунду - работает и т.д. Однако при подключении нескольких светодиодов на разные выходы они работают не синхронно (и даже не с теми задержками которые заданы) а ждут отработки команды delay для каждого предыдущего (в последовательности команд) светодиода, причём в это время все остальные процессы тоже "ждут" когда закончится очередной цикл "мигания" очередного светодиода.
2. Каким образом можно (если это возможно) реализовать одновременную работу, в данном случае синхронное мигание (с кратной частотой относительно первого светодиода), нескольких (2-3)  светодиодов? В данном случае, если необходимо постоянно считывать данные с датчиков и одновременно организовать мигание светодиода с циклом 5 секунд, то вся система будет останавливаться и ждать 5 сек. пока не отработает delay для светодиода...?
Подскажите пожалуйста, где моя ошибка?!
 

Zapek@n
Offline
Зарегистрирован: 16.02.2012

Вот это посмотрите http://arduino.ru/tutorials/BlinkWithoutDelay

step962
Offline
Зарегистрирован: 23.05.2011

И размножьте этот кусок

  if(currentMillis - previousMillis[i] > interval[i]) {
    // сохраняем время последнего переключения
    previousMillis[i] = currentMillis; 
 
    // если светодиод не горит, то зажигаем, и наоборот
    if (ledState[i] == LOW)
      ledState[i] = HIGH;
    else
      ledState[i] = LOW;
 
    // устанавливаем состояния выхода, чтобы включить или выключить светодиод
    digitalWrite(ledPin[i], ledState[i]);

для каждого своего управляемого объекта.

Либо в цикл заверните.

koko
Offline
Зарегистрирован: 19.11.2012

БОЛЬШОЕ СПАСИБО!

Дошло)))

koko
Offline
Зарегистрирован: 19.11.2012

Голову сломал уже (((

1. Один светодиод работает (на 13 пине)  правильно.

2. Вставляю второй блок (на другой пин - 8) работают оба но неправильно: на 13 мигает на 8 горит постоянно.

3. Меняю местами - первым по очереди 8 пин, вторым 13 пин: 8 теперь работает правильно а 13 постоянно горит.

ПОЧЕМУ ТАК??????!!! В ЧЕМ ОШИБКА???

/* Blink without Delay */
int ledState = LOW;
long previousMillis;       
long currentMillis;
long interval = 1000;         
void setup()
 {
  pinMode(13, OUTPUT);   
  pinMode(8, OUTPUT);
  previousMillis = 0;   
 }  
void loop()
     {
          currentMillis = millis();
          if(currentMillis - previousMillis > interval)
               {
              previousMillis = currentMillis;
              if (ledState == LOW)
                   ledState = HIGH;
              else
                   ledState = LOW;
              digitalWrite(13, ledState);
               }
          if(currentMillis - previousMillis > interval)
               {
              previousMillis = currentMillis;
              if (ledState == LOW)
                   ledState = HIGH;
              else
                   ledState = LOW;
              digitalWrite(8, ledState);
               }
     }
maksim
Offline
Зарегистрирован: 12.02.2012

Для каждого светодиода должны быть свои переменные ledStatepreviousMillis и interval

И я бы на вашем месте сделал бы так

int interval_1 = 1000; 
int interval_2 = 500; 
unsigned long newMillis_1, newMillis_2;       

void setup()
{
  pinMode(13, OUTPUT);   
  pinMode(8, OUTPUT); 
}  
void loop()
{
  if(millis() > newMillis_1)
  {
    digitalWrite(13, !digitalRead(13));
    newMillis_1 = millis() + interval_1;
  }

  if(millis() > newMillis_2)
  {
    digitalWrite(8, !digitalRead(8));
    newMillis_2 = millis() + interval_2;
  }
}

 

maksim
Offline
Зарегистрирован: 12.02.2012
koko
Offline
Зарегистрирован: 19.11.2012

ВСЕ РАБОТАЕТ!

СПАСИБО!

И красивее как-то)))

PS С отдельными переменными я пробовал, но что-то не доработал - все равно глючило...

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Можно сделать и так . А вообще зависит от конкретной ситуации. Можно сделать один счетчик и на основе его показаний запускать/останавливать функции.

long previousMillis = 0; 
long previousMillis2 = 0; 

 int val=0; 

 void setup()    
 { 
        
     pinMode(13, OUTPUT);         
        pinMode(8, OUTPUT);        
         
 } 

 void loop() 

 { 
     
         
      if (millis() -previousMillis >500)    
     { 
        previousMillis = millis();     
      digitalWrite(13,!digitalRead(13));
     } 
     
        if (millis() -previousMillis2 >500)    
     { 
        previousMillis2 = millis();     
      digitalWrite(8,!digitalRead(8));
     } 
    
        
        
 } 

 

koko
Offline
Зарегистрирован: 19.11.2012

Спасибо.

Я попробую и так и так...

Да, один счётчик это для меня более приемлемо.

 

 

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

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

koko
Offline
Зарегистрирован: 19.11.2012

OK!

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Я почти скопировал код maksimа. Просто сразу не посмотрел. 

GrigoriyBaranov
Offline
Зарегистрирован: 05.11.2012

koko пишет:

Здравствуйте!
Подскажите пожалуйста, каким образом можно реализовать программу (на самом деле стандартную для робототехники), считывающую информацию с датчиков и выдающую в зависимости от полученной информации команды на исполнительные механизмы.
Есть следующая  проблема (для моего понимания):
1. Подключаю один светодиод и пишу программу для того, чтобы он мигал 1 раз в секунду - работает, 2 раза в секунду - работает и т.д. Однако при подключении нескольких светодиодов на разные выходы они работают не синхронно (и даже не с теми задержками которые заданы) а ждут отработки команды delay для каждого предыдущего (в последовательности команд) светодиода, причём в это время все остальные процессы тоже "ждут" когда закончится очередной цикл "мигания" очередного светодиода.
2. Каким образом можно (если это возможно) реализовать одновременную работу, в данном случае синхронное мигание (с кратной частотой относительно первого светодиода), нескольких (2-3)  светодиодов? В данном случае, если необходимо постоянно считывать данные с датчиков и одновременно организовать мигание светодиода с циклом 5 секунд, то вся система будет останавливаться и ждать 5 сек. пока не отработает delay для светодиода...?
Подскажите пожалуйста, где моя ошибка?!
 

1)Просто переписать алгоритмы работы программы.
2)"Синхронно" можно управлять светодиодами!,но только вплоть до 1 такта выполнения команды. (1 такт = 1 / тактовая частота, uno 0,0000000625 с/такт) Соответственно пишем часть этого кода на ASM.

 

.include "m328pdef.inc"

.def time_1=r16
.def time_2=r17
.def time_3=r18

sbi 0x04,0

main:
sbi 0x05,0
rcall timeDelay_100ms
rcall delay
cbi 0x05,0
rcall timeDelay_100ms
rcall delay
rjmp main

timeDelay_100ms:
ldi time_1,0x00
ldi time_2,0x6A
ldi time_3,0x18
ret

timeDelay_10ms:
ldi time_1,0x00
ldi time_2,0x71
ldi time_3,0x02
ret

delay:
subi time_1,1
sbci time_2,0
sbci time_3,0
brcc delay
ret

 

Пример кода на asm мигающая светодиодом подключенным к 8-ому порту. Сверхточное время задержки(отставание 1 такт на полный алгоритм расчета времени); тактовая частота 16МГц - это важно для определения значений переменных. Команда sbi выставляет указанный бит регистра в состояние "1". Для одновременного изменения состояния сразу нескольких портов в одной группе следует использовать ldi .

)

 

GrigoriyBaranov
Offline
Зарегистрирован: 05.11.2012

koko пишет:

Спасибо.

Я попробую и так и так...

Да, один счётчик это для меня более приемлемо.

 

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

koko
Offline
Зарегистрирован: 19.11.2012

Спасибо - я как раз голову ломал над тем, как засинхронизировать всё это и какие поправки и куда давать...

Теперь буду разбираться, ещё раз спасибо - мне нужна точная синхронизация.