Почему переменные разного типа???
- Войдите на сайт для отправки комментариев
Сб, 20/01/2018 - 20:22
Посмотрел образец кода http://arduino.ru/tutorials/BlinkWithoutDelay
Вот он:
/* Blink without Delay
2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
*/
const int ledPin = 13; // номер выхода, подключенного к светодиоду
// Variables will change:
int ledState = LOW; // этой переменной устанавливаем состояние светодиода
long previousMillis = 0; // храним время последнего переключения светодиода
long interval = 1000; // интервал между включение/выключением светодиода (1 секунда)
void setup() {
// задаем режим выхода для порта, подключенного к светодиоду
pinMode(ledPin, OUTPUT);
}
void loop()
{
// здесь будет код, который будет работать постоянно
// и который не должен останавливаться на время между переключениями свето
unsigned long currentMillis = millis();
//проверяем не прошел ли нужный интервал, если прошел то
if(currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// устанавливаем состояния выхода, чтобы включить или выключить светодиод
digitalWrite(ledPin, ledState);
}
}
Мне непонятно, почему previousMillis типа long, а currentMillis unsigned long? Это ведь не одно и то же? Верно? А там есть строка:
previousMillis = currentMillis;
Будет ли это работать правильно?
Будет, но только в пределах long.
unior_develope, будет ли это работать правильно, зависит от того, как Вы будете это использовать.
В очень многих случаях присваивание величинам одного типа значений переменных другого работает правильно.
Но не всегда.
Главное - понимать, что происходит при таком присваивании.
Мне непонятно, почему previousMillis типа long, а currentMillis unsigned long? Это ведь не одно и то же? Верно? А там есть строка:
Будет ли это работать правильно?
Мне вот непонятно, зачем вообще currentMillis в данном случае. millis()-previousMillis>interval, делает тоже самое и экономит четыре байта оперативки. Это из разряда использования int для назначении пинов.
Не. тогда нужно два вызова millis(). А они иногда разные результаты будут давать что на интервале скажется, для мигания светодиода раз в сек конечно пофиг, но в общем случае плохо. Если уж про экономию - заменить лонги на не лонги.
По теме. Сочитать в выражениях знаковое и беззнаковое - плохой стиль и потенциальный источник неприятных ошибок. Компилятор варнинг обычно выдает.
Не. тогда нужно два вызова millis(). А они иногда разные результаты будут давать что на интервале скажется, для мигания светодиода раз в сек конечно пофиг, но в общем случае плохо. Если уж про экономию - заменить лонги на не лонги.
Я ведь написал, для "конкретного". Да и для подавляющего большинства домашних поделок. Обычное домашнее применение - интервал опроса датчиков или вывода чего то, а считает-выведет через 10 секунд или 10,001сек разницы уже никакой. Если нужны действительно точные тайминги с миллисом вроде никто и не заморачивается. Вчера померил на своей программе луп, а там везде 0 миллисов. А он и динамически символ формирует, и строку из прогмемов на семисегментники, и ДС-ку опрашивает, и часы, и ИР слушает, и температуру держит. Честно говоря, даже не представляю ситуацию, где эта погрешность может сказаться (в бытовом применении). ИМХО.
Там дело не в длине лопа, даже очень быстрый лоп иногда будет попадать в ситуацию когда при первом его вызове, в проверке, он вернет N, а в следующем, в присвоении уже, N+1. Так по 1мс терятся будет.
Если писать аккуратно, то и на милисе тайминги точные как кварц позволит выйдут. По опыту уход до 2-3сек/час. А аккуратность вобщем - писать
previousMillis += 1000, да прерывания не запрещать надолго.//чера померил на своей программе луп, а там везде 0 миллисов.
То неверно мерили. Среднее не катит. Посмотреть глазками сотню отсчетов тоже. Стройте гистаграмму, намного интересней все будет. Массив в котором в ячейке 0 кол-во лупов выполненых за 0мс, в 1 - за 1мс и т.д. сколько памяти не жалко, в последней ячейке (например 100) - кол-во лупов выполненых за 100 и более мс. В каждом лупе как длительность померили делаем +1 в соответствующую ячейку. Дайте коду поработать, например 100000 циклов, затем смотрите результат и думайте.
ПС. таки нашел кусок своего кода для этого. Там еще и максимально длинный лоп ищет и еще коечего делает.
#define SIZE_HISTOGRAMM_LOOP 16 word HistogrammaLoopTime[SIZE_HISTOGRAMM_LOOP]; //последний элемент - максимальная длительность /* Формируем новое системное время для текущего цикла, собираем статистику загрузки, определяем короткий цикл для запуска */ boolean GetNewTime(word* Timer) { word T=millis(); word i=T-*Timer; { if(i>SIZE_HISTOGRAMM_LOOP-2) i=SIZE_HISTOGRAMM_LOOP-2; HistogrammaLoopTime[i]++; if(i>HistogrammaLoopTime[SIZE_HISTOGRAMM_LOOP-1]) HistogrammaLoopTime[SIZE_HISTOGRAMM_LOOP-1]=i; if(!HistogrammaLoopTime[i]) { memset(HistogrammaLoopTime, 0, SIZE_HISTOGRAMM_LOOP*2); } } *Timer=T; return i==0; }Ну ладно, ладно, обманул.((( Гистограмм не строил, сегодня на микросе погонял. Массовые штучные замеры, все двузначные микросы, в глазах рябят, примерно с интервалом опроса DS-ки 2,7 и 5,6мС единичные проскакивают. Похоже запрос и считывание.
Если не поленюсь потом, попробую посчитать, сейчас она меня уже достала со своим меню на табло из двух семисегментников, завершать пора.))))