Весы, Тара. Сыпем в тару песок(или другое сыпучее). При определённом насыпанном весе останавливается программа, а так же включается зуммер и лампа. Освобождаем весы. Устанавливаем новую тару. Нажимаем кнопку (чем запускаем далее скетч ). Пробовал с прерываниями - не получилось. Начинающий я... Подскажете что не так делаю? Прерывания скетча нет. Не останавливается и кнопка мёртвая. Кнопка с антидребезгом (с резистором). Флаги вроде поставил ... как у Алексагайвера в 16 уроке... Код (C++): // HX711 к Arduino pin 4->CLK 5->DAT 5V->VCC GND->GND //дИСПЛЕЙ 1602 и oled VCC — 5V GND — GND SDA — A4 SCL — A5 // The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine. #include <LiquidCrystal_I2C.h> #include "HX711.h" //This library can be obtained here http://librarymanager/All#Avia_HX711 } void dvigatel_1() {} void dvigatel_2() {}
Почитайте документацию к attachInterrupt, пожалуйста. И посмотрите, что значит первый параметр, и как надо его правильно использовать. И ответьте на вопрос - какая у вас плата? И ещё: в обработчике прерывания - не стоит работать с Serial, да и вообще - делать что-то тяжёлое.
Уно. А как тогда остановить, чтобы по кнопке опять начинался? У меня ещё там будет порядочно... примерно столько же.
Всё правильно у меня - на 3 пин при цифре 1. interrupt – номер вызываемого прерывания (стандартно 0 – для 2-го пина, для платы Ардуино Уно 1 – для 3-го пина), Но Работало же всё со скетчем блинк (стандартный в примерах)..нажал на кнопку - светодиоды помигали и остановились. ..Нажал кнопку ..помигали и остановились.
Здесь-то всё работает! Код (C++): volatile boolean flag; void setup() { Serial.begin(9600); pinMode(3, INPUT_PULLUP); pinMode(7, OUTPUT); attachInterrupt(1, oled, FALLING); } void loop() { if (flag) { oled(); Serial.println("Interrupt!"); flag = 0; } } void oled(){ flag = 1; digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); }
Ещё раз: Wiring НЕ ГАРАНТИРУЕТ, что номер прерывания 1 - будет для пина номер 3. Именно поэтому в документации описано, что правильно получать номер прерывания вызовом digitalPinToInterrupt. По поводу "здесь-то всё работало": прочитайте, пж, про прерывания поподробней, и поймёте, что "здесь-то всё работало" - это до поры, до времени, т.к. пример - выхолощенный. Повторюсь: функция-обработчик прерывания - должна быть как можно короче, идеально - в ней просто устанавливать флаг, и всё. Я вам указал одну из причин, почему может не работать - использование Serial внутри обработчика прерывания. Пример, приведённый вами выше, как пример вида "здесь-то всё работает" - очень, очень плохой пример того, как надо работать с прерываниями. И который ведёт к неизбежным косякам в мало-мальски приличном по объёму проекте.
Это ужасный пример, который, может и работает, но следовать ему абсолютно не стоит. - Не надо использовать функцию для преваниния в Loop - Не надо использовать библиотеки в прерывании (в вашем случае lcd) - Желательно не использовать Serial.print. Иногда допустимо использовать Serial.print в прерывании для отладки с помощью вывода коротких (1-2 символа) собщений, но в окончательном варианте лучше их убрать. - Не надо использовать в прерывании delay() или ждать пока изменения millis() - И вообще не надо допускать длительных действий в прерывании.
lcd у тебя через I2C. Ему нужны свои прерывания. Если ты вызываешь его в обработчике, он может просто навечно повиснуть в ожидании прерывания.
Странный пример, такое впечатление, что просто недоделанный. Мигание и в прерывании, и после, по флагу из loop() запускается. А антидребезг за счет delay отрабатывает. А так уже не так страшно: Код (C++): volatile boolean flag; void setup() { Serial.begin(9600); pinMode(3, INPUT_PULLUP); pinMode(7, OUTPUT); attachInterrupt(1, oled, FALLING); } void loop() { if (flag) { blink(); Serial.println("Interrupt!"); flag = 0; } } void oled(){ flag = 1; } void blink(){ digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); }
Из любопытства зашел, посмотрел. Нет у Гайвера этого мигания, а в прерывании - только взведение флага. Так что не от Гайвера этот кошмар.
Абсолютно не стоит..Согласен с Вами. Я пытаться программировать начал только только, может месяц как.. Это не гайверовский пример, этот кошмар я сам на его примере прерываний накропал с блинком симбиоз.(Уж как получилось). Поэтому, пока ещё не понимая как сделать так как в первом посте написал и выложил всё сюда дабы спросить помощи, хоть какой.. Вот и так ..прошу помочь.. или здесь как на форуме Arduino ru тоже посылают на... "иди учись" (даже ради 2-3 проектов). А что надо делать?
Ну я же исправил ваш ужасный вариант, на более приемлемый в посте #10 Просто то, что Вы хотите получить, нужно делать иначе. То, что у Вас в первом скетче - нужно переписывать полностью. Там не просто ошибки, там построение программы абсолютно не соответствует вашей задаче. Попробуйте сначала научиться просто измерять вес и выводить его на дисплей в loop(), без всяких прерываний и кнопок, начните с этого. Чтобы отображались изменения веса при наполнении тары. Дальше научитесь зажигать лампу и включать зуммер при достижении нужного значения. Оставьте пока прерывания и кнопку. Это пока не для Вас. Как только сможете зажигать лампу и включать зуммер при достижении нужного веса можно будет перейти и к кнопке. Начните с исправления этого, тут все просто исправить: Код (C++): for (int i = 0; i < 3; i ++) // усредняем показания, считав значения датчика 10 раз { units = + scale.get_units(), 3; // суммируем показания 10 замеров }
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данных передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания.
Ну что значит не работают. Миллис, например, можно вызывать и сколько угодно раз, просто он всегда будет возвращать одно и то же значение которое было на момент срабатывания прерывания. delay() зависнет, но если перед его вызовом разрешить глобальные прерывания (sei), то будет работать, просто это 1- плохой стиль 2- ваше прерывание сможет прервать другое прерывание (с другим вектором)
Его не было смысла править - это просто дерьмовый вариант за 5 минут склепал чисто для примера что работает. Это всё уже давно сделал и прежде чем пост написать игрался неделю. Даже останавливается при достижении нужного веса. но как только снимаю вес с весов - начинает опять работать движок*(светиться светодиод и зуммер орать, поэтому зуммер отключил.) Чего тут править можно? Ну вместо 3 замеров сделать 10...ну 20... в результате медленнее стало меняться число на экране... Код (C++): for (int i = 0; i < 20; i ++) // усредняем показания, считав значения датчика 10 раз { units = + scale.get_units(), 20; // суммируем показания 10 замеров } .Может формула не та?... так брал её вот здесь в спойлере. Спойлер: вот здесь https://wiki.iarduino.ru/page/hx_711_with_tenzo/ Или имеете в виду что не там цифру поставил - надо было в скобках? А зачем "+" перед "scale.get_units"?