Товарищи!!! Помогите допилить код! Немного)))

Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

Имеется: устройство из Ардуино Нано, 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
  }
}
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

создай какой-нить флаг uze_zvonil, присвой ему ноль.
пере набором номера проверь, равен ли он нулю, если да, набери номер и присвой флагу 1

Код: Выделить всё

unsigned char uze_zvonil = 0;

..................

if (!uze_zvonil)
{
   call_number(xxxxxxxx);
   uze_zvonil = 1;
}
Аватара пользователя
Муркиз
Друг Кота
Сообщения: 25758
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Муркиз »

Угу - а потом? Ему же в цикле надо остаться для дальнейшего мониторинга , я так понимаю ?

По какому-то условию надо потом будет флаг обратно переключить.
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

Ну да, надо остаться в цикле, т.е. остановить выполнение части кода.
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 минуты прикрутил как временную меру
Аватара пользователя
Муркиз
Друг Кота
Сообщения: 25758
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Муркиз »

Вот поэтому и проектируют сначала алгоритмическую модель программы.

По ней гораздо легче логику взаимодействия смотреть.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

[uquote="Муркиз",url="/forum/viewtopic.php?p=4522849#p4522849"]По какому-то условию надо потом будет флаг обратно переключить.[/uquote] ТС не озвучивал. Требовалось однократное - нате.
Аватара пользователя
Муркиз
Друг Кота
Сообщения: 25758
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Муркиз »

По одной капле воды - как там говорил Шерлок Холмс...
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

или как в старой сказке про купца и двух его работников, один из которых получал значительно больше денег, потому что думать умел наперёд.
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

Мог бы кто-нибудь из заглядывающих в тему проверить код в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");
  
}
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

Сказано же:
Муркиз писал(а):проектируют сначала алгоритмическую модель программы.
А тут не видно алгоритма, тут видно какие-то дёрганья и метанья. Сроки горят, что ли? Не лучше ли спокойно построить алгоритм, вырисовать его блок-схемами, можно даже специально ради этого Дракон освоить https://drakon.su/ благо, год его настаёт. Параллельно изучить программирование. И учиться мыслить как программист, на языке программирования в соответствие алгоритму. И всё наладится.

А ответ с флагом я дал правильный. И Муркиз дал правильное к нему замечание, что флаг надо где-то ещё сбросить, но где? :dont_know:
Аватара пользователя
Муркиз
Друг Кота
Сообщения: 25758
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Муркиз »

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

А решать неопределенность - очень неблагодарная задача.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

я всё же посмотрел код в 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:
зачем делать ресет-то? очень странный подход...
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

Долго объяснять, зачем ресет. Например, ус-во не отвечает и не звонит после нажатия кнопки. Но реле продолжает быть вкл, что есть необх. минимум), поэтому ресет=костыль, писал же уже про них. Да, да, да - это решается по-другому, но не мной сейчас))) Про то, что с флагами пока не разобрался - тоже писал

Неопределенности нет - есть уже работающее ус-во и код, есть конкретная проблема - цикличный звонок вместо однократного, всё. Алгоритмы, логика, развитие - это всё потом, весной) Это приносящее пользу ус-во для своего дом. пользования на скорую руку Изображениеот нуба, какие сроки)пока так.
Последний раз редактировалось Вик30 Чт дек 28, 2023 13:33:14, всего редактировалось 1 раз.
Аватара пользователя
Муркиз
Друг Кота
Сообщения: 25758
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Муркиз »

Из шаблона это было скорее всего взято , а там это было заложено для аварийного прерывания модуля.
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

[uquote="Муркиз",url="/forum/viewtopic.php?p=4523209#p4523209"]Из шаблона это было скорее всего взято , а там это было заложено для аварийного прерывания модуля.[/uquote]блин, вы как будто только себя читаете)
[uquote="Вик30",url="/forum/viewtopic.php?p=4522863#p4522863"]надо топать его проверять, а чтобы телефон в это время не верещал -.... asm volatile ("jmp 0x0000"); и дилей 3 минуты прикрутил как временную меру[/uquote]
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

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

Добавлено after 1 minute 55 seconds:
Я придумал! надо флаги хранить снаружи. чтобы ресет их не мог сбросить. например, в еепром, или релюшку самозащелкивающуюся :)))
Последний раз редактировалось Martian Чт дек 28, 2023 13:42:00, всего редактировалось 1 раз.
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

[uquote="Martian",url="/forum/viewtopic.php?p=4523223#p4523223"]с таким ресетом никакие флаги не помогут. они ж всегда сбрасываются.[/uquote]
можно, конечно, написать капсом и красным - "костыль, временно", но, скорее всего, правилами запрещено...
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Martian »

и? ну напиши капсом и красным, что изменится-то? работать будет? если временно - убирай, зачем он, если он сьрасывает все флаги и код заново выполняется, хотя не нужно, чтобы заново выполнялся. От чего он костыль? Что за проблема была, которую он решал? Ардуино зависала?
Вик30
Родился
Сообщения: 12
Зарегистрирован: Ср июл 05, 2023 11:22:59

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Вик30 »

Ну уберу, дело 15 сек, флаги остались, а цикл весь!!! выполняется заново, цикл. бесконечный дозвон, в чем и проблема, поэтому и дилей итд. Не в них проблема(хотя какую проблему они решают - написано мной тремя сообщ. выше и не раз, хз, зависание ли это, раз сим900 продолжает звонить), хватит о них уже. Как, чем остановить выполнение части кода(цикла) - рабочих и вообще примеров и решений не нашел, только типа "loop" оставить пустым, а программу поместить в setup, если надо выполнить один раз. Не мой случай. Да, надо изучать, вникать, пробовать, что и буду делать по возможности.
Morroc
Друг Кота
Сообщения: 19494
Зарегистрирован: Чт фев 20, 2014 18:57:55

Re: Товарищи!!! Помогите допилить код! Немного)))

Сообщение Morroc »

[uquote="Вик30",url="/forum/viewtopic.php?p=4523240#p4523240"]рабочих и вообще примеров и решений не нашел[/uquote]
про конечные автоматы почитайте. все правильно про флаги - по команде взводите флаг, по флагу звонок (именно по флагу, а не по команде), после выполнения звонка сбрасываете флаг - все
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Ответить

Вернуться в «Arduino»