Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ср дек 27, 2023 15:18:53
Имеется: устройство из Ардуино Нано, 5 в реле, SIM900A и концевика(в макете кнопки пулл-ап). Код (почти, с костылями
) работает - по звонку поднимает трубку, слушает ДТМФ и по 1 вкл/выкл реле. По нажатию кнопки делает звонок на номер ХХХХХХ, проблема в том, что звонок делает бесконечно! Как ограничиться одним звонком? for (int count = 0; count < 1; count++) не смог прикрутить, неделю только изучаю это всё, скомпилирован из нескольких чужих кодов. Поиск по запросу "как выполнить
часть кода в цикле только 1 раз" пока(пока) не помог.
Спойлер
- Код:
#include <SoftwareSerial.h>
String numberCall_1 = "ХХХХХХХХХХХХ"; // Номер абонента №1 для звонка
const int RX = 2; // назначаем Rx Arduino на pin 2
const int TX = 3; // назначаем Тx Arduino на pin 3
SoftwareSerial MySerial(RX, TX);
#define pinSensor_0 8 // объявляем pin 8 Arduino входом для концевика
const int RELAY_1 = 6; // назначаем управление реле на pin 6
//Переменные для хранения входящих данных
String buff;
String dtmf;
boolean relay1_st = false; // Выставляем высокий уровень(выключаем реле)т.к. кнопка PULL-UP
boolean is_call = false; // Звонок (Логический (булевый) тип данных)
uint8_t flagSensor_0 = 0;
void setup()
{
pinMode(pinSensor_0, INPUT); // назначаем 8 пин на вход сигнала
pinMode(RELAY_1, OUTPUT); // назначаем 6 пин на выход сигнала
digitalWrite(RELAY_1, LOW); // устанавливаем реле в выкл сотояние
Serial.begin(9600);
MySerial.begin(9600);
Serial.println(F("Подключение GSM модуля SIM800L")); // вывод в монитор порта
delay(5000); // Задержка в 5 секунд
MySerial.println(F("AT")); // вывод в монитор порта Подключаемся к режиму AT для настройки скорости обмена данными
delay(500);
MySerial.println(F("AT+DDET=1")); // вывод в монитор порта Включение DTMF(тонального набора)
delay(500);
}
void loop()
{
while (MySerial.available())
{
buff = MySerial.readString();
Serial.println(buff);
if (is_call = true) // Если вызов прошёл
{
if (int index = buff.indexOf("+DTMF:") > -1 ) // Ищем первое совпадение. Если не -1 значит нашли.
{
index = buff.indexOf(":"); // Ищем :
dtmf = buff.substring(index + 1, buff.length()); // Возвращает подстроку в строке
dtmf.trim(); // обрезает все пробелы в начале и конце указанной строки.
Serial.println("dtmf: " + dtmf); // Выводит полученное значение
State();
}
if (buff.indexOf("NO CARRIER") > -1)
{
MySerial.println(F("ATH")); // вывод в монитор порта Повесить трубку/ разорвать соединение
is_call = false;
}
}
if (buff.indexOf("RING") > -1) // Входящий звонок
{
delay(2000);
MySerial.println(F("ATA")); // вывод в монитор порта Ответ на звонок
is_call = true;
}
}
while (Serial.available())
{
MySerial.println(Serial.readString());
}
if (flagSensor_0 == 0 && digitalRead(pinSensor_0) == 0) flagSensor_0 = 1;
if (flagSensor_0 == 1)
{
String command;
command = "ATD+" + numberCall_1 + ";";
MySerial.println(command);
delay(20000);
MySerial.println("ATH");
delay(180000);
asm volatile ("jmp 0x0000");
}
if (flagSensor_0 == 2 && digitalRead(pinSensor_0) != 0) flagSensor_0 = 0;
}
void State() {
if (dtmf == "1") {
relay1_st = !relay1_st;
digitalWrite(RELAY_1, relay1_st); // Включаем или выключаем реле 1
}
}
Ср дек 27, 2023 16:03:05
создай какой-нить флаг uze_zvonil, присвой ему ноль.
пере набором номера проверь, равен ли он нулю, если да, набери номер и присвой флагу 1
- Код:
unsigned char uze_zvonil = 0;
..................
if (!uze_zvonil)
{
call_number(xxxxxxxx);
uze_zvonil = 1;
}
Ср дек 27, 2023 17:42:05
Угу - а потом? Ему же в цикле надо остаться для дальнейшего мониторинга , я так понимаю ?
По какому-то условию надо потом будет флаг обратно переключить.
Ср дек 27, 2023 18:10:28
Ну да, надо остаться в цикле, т.е. остановить выполнение части кода.
PS: Аа, понял про "остаться в цикле" - эту часть кода(звонок по срабатыванию кнопки) можно и не продолжать) так как нажат физический концевик и надо топать его проверять, а чтобы телефон в это время не верещал - прикручен ресет asm volatile и дилей(в это время реле включено, пока не сработает ресет, к этой части кода вопросов нет, кроме неграмотности и корявости, возможно)))учусь только.. Главное - чтобы ус-во делало только один звонок, а не звонило через каждую минуту примерно, пока не разберусь с концевиком.
Через флаги не получилось, что-то неправильно, видимо, намудрил, надо разбираться. Здесь то, что связано со звонком по кнопке и флагами-
Спойлер
- Код:
while (Serial.available())
{
MySerial.println(Serial.readString());
}
if (flagSensor_0 == 0 && digitalRead(pinSensor_0) == 0) flagSensor_0 = 1;
if (flagSensor_0 == 1)
{
String command;
command = "ATD+" + numberCall_1 + ";";
MySerial.println(command);
delay(20000);
MySerial.println("ATH");
delay(180000);
asm volatile ("jmp 0x0000");
}
if (flagSensor_0 == 2 && digitalRead(pinSensor_0) != 0) flagSensor_0 = 0;
}
Оно-то и так уже работает, но всё-таки - хочется разобраться и сделать правильно. asm volatile ("jmp 0x0000"); и дилей 3 минуты прикрутил как временную меру
Ср дек 27, 2023 20:50:05
Вот поэтому и проектируют сначала алгоритмическую модель программы.
По ней гораздо легче логику взаимодействия смотреть.
Чт дек 28, 2023 00:57:39
По какому-то условию надо потом будет флаг обратно переключить.
ТС не озвучивал. Требовалось однократное - нате.
Чт дек 28, 2023 08:35:17
По одной капле воды - как там говорил Шерлок Холмс...
Чт дек 28, 2023 08:58:29
или как в старой сказке про купца и двух его работников, один из которых получал значительно больше денег, потому что думать умел наперёд.
Чт дек 28, 2023 12:56:02
Мог бы кто-нибудь из заглядывающих в тему проверить код в1 сообщении? Бот РОЕ, кстати, сколько ни просил, написал только один рабочий код - нажатие кнопки и однократный звонок, и в коде звонок вынесен за цикл, но условие звонка в цикле. Мне не помогло.
Спойлер
- Код:
#include <SoftwareSerial.h>
SoftwareSerial sim800l(2, 3);
int buttonPin = 8;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
sim800l.begin(9600);
}
void loop() {
if(digitalRead(buttonPin) == LOW) {
callNumber();
}
}
void callNumber() {
sim800l.println("ATD+ххххххххххххх;");
delay(20000);
sim800l.println("ATH");
}
Чт дек 28, 2023 13:06:12
Сказано же:
Муркиз писал(а):проектируют сначала алгоритмическую модель программы.
А тут не видно алгоритма, тут видно какие-то дёрганья и метанья. Сроки горят, что ли? Не лучше ли спокойно построить алгоритм, вырисовать его блок-схемами, можно даже специально ради этого Дракон освоить
https://drakon.su/ благо, год его настаёт. Параллельно изучить программирование. И учиться мыслить как программист, на языке программирования в соответствие алгоритму. И всё наладится.
А ответ с флагом я дал правильный. И
Муркиз дал правильное к нему замечание, что флаг надо где-то ещё сбросить, но где?
Чт дек 28, 2023 13:11:09
А где ? И каким приемом - зависит от алгоритма работы - а тут, кроме предположений, ничего нельзя однозначно определить.
А решать неопределенность - очень неблагодарная задача.
Чт дек 28, 2023 13:25:33
я всё же посмотрел код в 1сообщении...
там есть такая строчка:
- Код:
if (flagSensor_0 == 2 && digitalRead(pinSensor_0) != 0) flagSensor_0 = 0;
она никогда не выполняется, потому что во всей программе есть ещё только flagSensor_0 = 1; (ну и при инициализации flagSensor_0 = 0;)
То есть, флаг-то уже есть, но он как устанавливается в 1 здесь:
- Код:
if (flagSensor_0 == 0 && digitalRead(pinSensor_0) == 0) flagSensor_0 = 1;
так всегда и равен единице
Добавлено after 8 minutes 46 seconds:итого, если выкинуть всё лишнее, то имеем:
- Код:
...
uint8_t flagSensor_0 = 0;
...
void loop()
{
...
if (flagSensor_0 == 0 && digitalRead(pinSensor_0) == 0) flagSensor_0 = 1;
if (flagSensor_0 == 1)
{
String command;
command = "ATD+" + numberCall_1 + ";";
MySerial.println(command);
delay(20000);
MySerial.println("ATH");
delay(180000);
asm volatile ("jmp 0x0000");
}
if (flagSensor_0 == 2 && digitalRead(pinSensor_0) != 0) flagSensor_0 = 0;
}
если asm volatile ("jmp 0x0000"); - это типа ресета, то вообще феерично: всё это условие
- Код:
if (flagSensor_0 == 0 && digitalRead(pinSensor_0) == 0) flagSensor_0 = 1;
if (flagSensor_0 == 1)
{
рискует выполнятся абсолютно всегда, если digitalRead(pinSensor_0) == 0
ну а следующее за ним if (flagSensor_0 == 2 не выполняется никогда, выше уже говорил.
Добавлено after 1 minute 35 seconds:зачем делать ресет-то? очень странный подход...
Чт дек 28, 2023 13:27:09
Долго объяснять, зачем ресет. Например, ус-во не отвечает и не звонит после нажатия кнопки. Но реле продолжает быть вкл, что есть необх. минимум), поэтому ресет=костыль, писал же уже про них. Да, да, да - это решается по-другому, но не мной сейчас))) Про то, что с флагами пока не разобрался - тоже писал
Неопределенности нет - есть уже работающее ус-во и код, есть конкретная проблема - цикличный звонок вместо однократного, всё. Алгоритмы, логика, развитие - это всё потом, весной) Это приносящее пользу ус-во для своего дом. пользования на скорую руку
от нуба, какие сроки)пока так.
Последний раз редактировалось
Вик30 Чт дек 28, 2023 13:33:14, всего редактировалось 1 раз.
Чт дек 28, 2023 13:28:49
Из шаблона это было скорее всего взято , а там это было заложено для аварийного прерывания модуля.
Чт дек 28, 2023 13:37:53
Из шаблона это было скорее всего взято , а там это было заложено для аварийного прерывания модуля.
блин, вы как будто только себя читаете)
надо топать его проверять, а чтобы телефон в это время не верещал -.... asm volatile ("jmp 0x0000"); и дилей 3 минуты прикрутил как временную меру
Чт дек 28, 2023 13:41:27
с таким ресетом никакие флаги не помогут. они ж всегда сбрасываются.
Добавлено after 1 minute 55 seconds:Я придумал! надо флаги хранить снаружи. чтобы ресет их не мог сбросить. например, в еепром, или релюшку самозащелкивающуюся
Последний раз редактировалось
Martian Чт дек 28, 2023 13:42:00, всего редактировалось 1 раз.
Чт дек 28, 2023 13:41:58
с таким ресетом никакие флаги не помогут. они ж всегда сбрасываются.
можно, конечно, написать капсом и красным - "костыль, временно", но, скорее всего, правилами запрещено...
Чт дек 28, 2023 13:42:57
и? ну напиши капсом и красным, что изменится-то? работать будет? если временно - убирай, зачем он, если он сьрасывает все флаги и код заново выполняется, хотя не нужно, чтобы заново выполнялся. От чего он костыль? Что за проблема была, которую он решал? Ардуино зависала?
Чт дек 28, 2023 14:09:58
Ну уберу, дело 15 сек, флаги остались, а цикл весь!!! выполняется заново, цикл. бесконечный дозвон, в чем и проблема, поэтому и дилей итд. Не в них проблема(хотя какую проблему они решают - написано мной тремя сообщ. выше и не раз, хз, зависание ли это, раз сим900 продолжает звонить), хватит о них уже. Как, чем остановить выполнение части кода(цикла) - рабочих и вообще примеров и решений не нашел, только типа "loop" оставить пустым, а программу поместить в setup, если надо выполнить один раз. Не мой случай. Да, надо изучать, вникать, пробовать, что и буду делать по возможности.
Чт дек 28, 2023 15:19:59
рабочих и вообще примеров и решений не нашел
про конечные автоматы почитайте. все правильно про флаги - по команде взводите флаг, по флагу звонок (именно по флагу, а не по команде), после выполнения звонка сбрасываете флаг - все
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.