Этюды для начинающих: blink и без delay, и без millis

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

Что Вы понимаете под словом "отказывается"? 

zilk
Offline
Зарегистрирован: 09.08.2017

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

Что Вы понимаете под словом "отказывается"? 

Отказывается - это имеется ввиду не записывает состояние порта 2 в порт 1.

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

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

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

Что Вы понимаете под словом "отказывается"? 

отказывается согласно моему запрету.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

zilk, ваша ошибка в том, что PINB & (1 << 2) читает не "0" или "1",  а "вес" бита. Т.е. 0,1,2,4, итд. Вариантов решения несколько, попробуте самостоятельно придумать.

zilk
Offline
Зарегистрирован: 09.08.2017

dimax пишет:

zilk, ваша ошибка в том, что PINB & (1 << 2) читает не "0" или "1",  а "вес" бита. Т.е. 0,1,2,4, итд. Вариантов решения несколько, попробуте самостоятельно придумать.

Спасибо за ответ!

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

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

zilk пишет:

Отказывается - это имеется ввиду не записывает состояние порта 2 в порт 1.

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

Когда так говорят, обычно приводят скетч, который "не записывает состояние порта 2 в порт 1", причём полностью - делается пример на 5 строк и приводится. При этом делаются пояснения, что именно и куда Вы планируете писать (что у Вас за порт 2 и что за порт 1), а также какой у Вас контроллер. А так ... Господь Вас знает что у Вас там куда и чего не записывает.

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

Из того огрызка, что Вы привели, создаётся впечатление, что Вы (если у Вас 328-ая) пытаетесь скопировать значение с цифрового пина 10 в цифровой пин 11 (если я чего не напутал). В любом случае давайте скетч и пояснения.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

zilk пишет:

Конструкция типа   PORTB |= (PINB & (1 << 2)) << 1 работать отказывается.

А требования выдвинула? Типа там "зарплата на уровне других конструкций скетча" или "допустить навального до выборов" ... чего ей надо-то, чего не работает?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Ворота пишет:

"допустить навального до выборов" ... чего ей надо-то, чего не работает?

навального к выборам нельзя допускать - хохлы Кубань заберут, а на Дальнем Востоке устроят японско-китайскую гражданскую войну. О_О

zilk
Offline
Зарегистрирован: 09.08.2017

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

void setup() {
ВОПРОС = Как записать содержимое бита
         одного регистра в другой;
}

void loop() {
  if (ЕСТЬ ЧТО СКАЗАТЬ) {
    switch (ОТВЕТ) {
        case ЗНАЮ:
          printf (ПРАВИЛЬНЫЙ ОТВЕТ);
          break;
        case НЕЗНАЮ:
          printf ("НЕ ЗНАЮ");
          break;
        default:
          goto NAH;
    }
    return 0;
  }
  NAH:
  rm -rf /;
  shutdown 0;
}

Если же и этот код вам не под силу, то совет один - бросайте это дело программирование, это не ваше.

И обратитесь к психоаналитику, возможно еще не поздно...

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

zilk пишет:

Для умников типа "Ворота" (дубовые, не?) и прочих клапауциев

А для тупых, типа меня, может всё-таки скетч приведёдте и остальное (см. мой пост #156 выше)? Впрочем, я не настаиваю, если Вам это не нужно, то мне и подавно :))))

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

zilk пишет:

Для умников типа "Ворота" (дубовые, не?) и прочих клапауциев

О_О а, вот сейчас реально обидно было - почему "Клапауций" с маленькой буквы и без кавычек?

*я тебе ещё припомню эти знаки неуважения.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

zilk пишет:

Для умников типа "Ворота" (дубовые, не?) и прочих клапауциев

А для тупых, типа меня, может всё-таки скетч приведёдте и остальное (см. мой пост #156 выше)? Впрочем, я не настаиваю, если Вам это не нужно, то мне и подавно :))))

Евгений Петрович, да достань ты свой хрустальный шар жеж )))

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

ua6em пишет:

Евгений Петрович, да достань ты свой хрустальный шар жеж )))

я осудил и запретил порочную практику хрустально-шаровой магии на форуме.

zilk
Offline
Зарегистрирован: 09.08.2017

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

А для тупых, типа меня, может всё-таки скетч приведёдте и остальное (см. мой пост #156 выше)? Впрочем, я не настаиваю, если Вам это не нужно, то мне и подавно :))))

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

С уважением...

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

ua6em пишет:

Евгений Петрович, да достань ты свой хрустальный шар жеж )))

А у меня нету. Я вот тут присмотрел один, так жаба душит! Подарил бы кто.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

ua6em пишет:

Евгений Петрович, да достань ты свой хрустальный шар жеж )))

А у меня нету. Я вот тут присмотрел один, так жаба душит! Подарил бы кто.

у меня нету, у меня только такие )))

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Подскажите, как можно это использовать в измерении времени между импульсами? Сейчас у меня всё реализовано черех millis()

  timer = millis();
  if ( pulse )
  {
    if ( ( timer - pulseTime ) > minPulseDuration 
      && ( timer - pulseTime ) < firstPulseDuration )
    {      
      pulseCount++;
    }
    pulseTime = timer;
    pulse = false;
  }

проблема в том, что функция millis() переполнит переменную unsigned long через 50 дней, судя по описанию, а устройство в данном конкретном случае рассчитано на длительную круглосуточную работу.

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

Вам нужно измерять один интервал длительность более, чем 50 дней (25 на самом деле)? Или интервалы короткие, просто Вас беспокоит, что он может попасть на переполнение?

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

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

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

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

  if ( pulseCount > 0 && ( timer - pulseTime ) > pulseDuration )
  {
    ...do something;
    pulseCount = 0;
  }

интервалы

int firstPulseDuration = 200;
int pulseDuration = 100;
int minPulseDuration = 50;

 

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

Вы не ответили на мой вопрос. Вам нужны интервалы длинее 25 дней или интервалы короткие? Какие интервалы у Вас?

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

дописал ответ выше :)

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

Ну, тогда у Вас нет проблем. Чем Вам помешает переполнение? Ничем абсолютно, даже не парьтесь. Вот если бы Вы вместо

timer - pulseTime > minPulseDuration

сделали бы

pulseTime + minPulseDuration < timer

тогда, да. Была бы проблема. А так её нет и бороться не с чем.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

ЕвгенийП пишет:
Вам нужно измерять один интервал длительность более, чем 50 дней (25 на самом деле)?

почему 25 дней? ровно 4294967296 - 1 одна миллисекунда интервалы можно крутить.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Да, понял вас, действительно, при переполнении, хотя вероятность крайне низка, что устройство будет передавать импульсы и в этот момент таймер переполнится, будет просто отрицательное значение, сравниваться с положительным, что-то я сильно нервничаю, устройсто просто сильно ответственное, с деньгами работает, нельзя пропустить ни одного импульса! :)

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

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

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Перфетционизм во всем, unsigned long это непозволительная роскош в виде целых 4-х байт в динамической памяти контроллера! Я и без этого найду, куда этот байты пристроить :)

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

cyber-jet пишет:

что-то я сильно нервничаю

Давайте сделаем так. Я покажу Вам технику проверки этого дела - т.е. технику вызова переполнения в любой удобный момент, чтобы Вы могли испытать свою программу на переполнение не ожидая два месяца, а прямо здесь и сецчас. Только уговор, Вы не просите меня объяснить почему переполнение Вам не мешает. Эта тема обсасывалась на форуме 100500 раз и у меня на неё уже аллергия. Значит, приём для проверки я Вам показываю, а вот почему оно Вам не помешало - Вы ищете по форуму без меня.

Счётчик миилиса называется timer0_millis. Он инициализируется нулём. Если присвоить ему достаточно большое число, то переполнение может наступить очень скоро.

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

Поскольку переполнение чере 5 секунд, а интервалы двухсекундные, переполнение обязательно попадёт на интервал.

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

//////////////////////////////////////////////////////////////////////
//
// Сделано так, чтобы millis() переполнился через 5 секунд после старта
// программа же отсчитывает двухсекундные интревалы (в функции make2SecondsInterval)
// Так что переполнение millis  придётся на середину интервала
// Запускаем и смотрим на происходящую "катастрофу"
//
template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }
extern volatile unsigned long timer0_millis;

static void make2SecondsInterval(void) {
	uint32_t startTime = millis(), currentMillis;
	while ((currentMillis = millis()) - startTime < 2000ul);
	Serial << " start: " << startTime << "\nmillis: " << currentMillis <<
	        "\ndiffer: " << (currentMillis - startTime) << "\n---\n";
}

void setup (void) {
	Serial.begin(115200);
	timer0_millis = UINT32_MAX - 5000ul;	// millis переполнится через 5 секунд
	// Отсчитываем 5 двухсекундных интервалов
	for (int i=0; i < 5; i++) make2SecondsInterval();
}

void loop(void) {}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

cyber-jet пишет:

Перфетционизм во всем, unsigned long это непозволительная роскош в виде целых 4-х байт в динамической памяти контроллера! 

храни сбережения с чарах - половина в отрицательных значениях, вторую в положительных. фиг инфляция такие сбережения сожрёт.

cyber-jet пишет:

будет просто отрицательное значение, сравниваться с положительным, что-то я сильно нервничаю, устройсто просто сильно ответственное, с деньгами работает :)

смотри, что бы тебе банкнотами с отрицательными номиналами не начали платить - как сдачу с отрицательных ржублей давать будешь? О_О

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

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

Вы не просите меня объяснить почему переполнение Вам не мешает. Эта тема обсасывалась на форуме 100500 раз и у меня на неё уже аллергия.

Евгений, судя по тому как вы расписываете всё хладнокровно  никакой аллергии у вас нет :) У меня от темы очередного чайника про переполнение миллис примерно такое лицо:

 

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Мне не нужно ни чего объяснять по поводу переполнения, потому что это конкретная функция. Мне не понятно как поведет себя сравнение между переменными с жесткой типизацией и с разными типами. В данном случае это разность unsigned long, которая может быть отрицательной, сравнивается с положительной int.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

cyber-jet пишет:
В данном случае это разность unsigned long, которая может быть отрицательной, сравнивается с положительной int.
  Вот объясните как безнаковая лонг может быть отрицательной. Вот ответьте мне ,сколько беременность у мужика? Вот и я не знаю. Но задавать такой вопрос я соответсвующих форумах постесняюсь. Не хочу выглядить лишний раз идиотом. 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

cyber-jet пишет:

разность unsigned long, которая может быть отрицательной

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

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Можно стесняться, когда знаешь чего стеснятся. А вы знаете, что в JS переменная может принимать одно несколько разных логических состояний? Например NaN, undefined, false и все они будут разными, но в свою очередь отрицательными, а в php вообще не важно там условие if ( var ) будет неверным во многих случаях, так как там типизация не жесткая. А чему тогда будет равно вычитание unsigned long var = 0 из другого числа такого-же типа. Сейчас конечно-же я запустил нужный тестовый скетч и проверил.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

cyber-jet пишет:

Сейчас конечно-же я запустил нужный тестовый скетч и проверил.

скетч сюда публикуй, бо я так подозреваю, что ты - тупой троляка 

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Клапауций 112 пишет:

больше всего меня прикалывают бессмысленные утырки...

вы тут случайно не перепутали ни чего?

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

cyber-jet пишет:

 разность unsigned long, которая может быть отрицательной

Вы живетё в каком-то странном мире, в котором взможны вещи, невозможные по определению.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017
int pulseCount = 0;
int firstPulseDuration = 200;
int pulseDuration = 100;
int minPulseDuration = 50;

unsigned long pulseTime = 0;
unsigned long timer;

volatile boolean pulse = false;

void setup()
{  
  Serial.begin ( 9600 );
  attachInterrupt ( 0, ifPulse, FALLING );
}
void loop()
{
  timer = millis();
  if ( pulseCount > 0 && ( timer - pulseTime ) > pulseDuration )
  {
    Serial.print ( pulseCount );
    pulseCount = 0;
  }
  if ( pulse )
  {
    if ( ( timer - pulseTime ) > minPulseDuration 
      && ( timer - pulseTime ) < firstPulseDuration )
    {      
      pulseCount++;
    }
    pulseTime = timer;
    pulse = false;
  }
}
void ifPulse()
{
  pulse = true;
}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

ну, а комментарии к скетчу - ниггер-Пушкин будет писать?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ты тут не в Яву попал, а в С++ вляпался. 

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

cyber-jet, а к чему последний скетч?

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Вот реальная ситуация с переполнением, вероятность этого конечно крайне мала, но возможна, когда серия получаемых импульсов попадет на обнуление millis(), тогда условие ( timer - pulseTime ) > minPulseDuration выдаст false и импульс не засчитается. Но это дело поправимое, понадобится одно условие на конкретный частный случай.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

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

cyber-jet, а к чему последний скетч?

Крайне нервный человек, камментом выше, попросил предоставить :)

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

cyber-jet пишет:

когда серия получаемых импульсов попадет на обнуление millis(), тогда условие ( timer - pulseTime ) > minPulseDuration выдаст false и импульс не засчитается. 

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

Если таки .... приведите пример в цирах, когда у Вас что-то там произойдёт.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

ЕвгенийП: подсмотрел у вас вот это - UINT32_MAX, попробовал вычесть из нуля, получил единицу, вопросов больше не имею. В общем переполнение и обнуление это вообще не проблема :)

Спасибо.

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

Только осторожнее. Это не проблема для вычитания, но проблема для сложения. Так, как у Вас - правильно. Я уже писал об этом выше.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

В описании не написано, что unsigned long -1 будет равно его максимальному значению, понимание этого всё прояснило.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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

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

  // count timers
  unsigned long ctmr = (long(millis() / 1000));
  if ((timerSec > 4294900) && (ctmr < 100)) {
    timerSec = 0;
  }

 

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

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

Итак, имеется скетч

void setup (void) {
	Serial.begin(115200);
	int a = <вставьте сюда число>;
	if (a != 0 && a == -a) Serial.println("What the fuck?!?");
	Serial.println("That's all! No more fun!");
}

void loop(void) {}

Необходимо подставить в указанное место число (получится, например, int a = 10;) такое, чтобы в монитор порта вывелось сообщение "What the fuck?!?".

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

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

andycat пишет:

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

Коту делать нехрен, он ....

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

andycat пишет:

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

Это лишнее, потому что из переписки выше понятно, что разность любых unsigned long будет корректной, вот вам скетч для примера, моделирующего переполнение и обнуление millis(), и нужно высчитать интервал:

unsigned long a = 10;
unsigned long b = UINT32_MAX - 10;

void setup() {
  Serial.begin ( 115200 );
  Serial.print( a - b );
}

Выдаст 21. Почему не 20? Ответ очевиден, я думаю :)