Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить

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

Ср дек 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
  }
}

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

Ср дек 27, 2023 16:03:05

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

Код:
unsigned char uze_zvonil = 0;

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

if (!uze_zvonil)
{
   call_number(xxxxxxxx);
   uze_zvonil = 1;
}

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

Ср дек 27, 2023 17:42:05

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

По какому-то условию надо потом будет флаг обратно переключить.

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

Ср дек 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 минуты прикрутил как временную меру

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

Ср дек 27, 2023 20:50:05

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

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

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

Чт дек 28, 2023 00:57:39

По какому-то условию надо потом будет флаг обратно переключить.
ТС не озвучивал. Требовалось однократное - нате.

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

Чт дек 28, 2023 08:35:17

По одной капле воды - как там говорил Шерлок Холмс...

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

Чт дек 28, 2023 08:58:29

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

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

Чт дек 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");
 
}

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

Чт дек 28, 2023 13:06:12

Сказано же:

Муркиз писал(а):проектируют сначала алгоритмическую модель программы.


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

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

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

Чт дек 28, 2023 13:11:09

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

А решать неопределенность - очень неблагодарная задача.

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

Чт дек 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:
зачем делать ресет-то? очень странный подход...

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

Чт дек 28, 2023 13:27:09

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

Неопределенности нет - есть уже работающее ус-во и код, есть конкретная проблема - цикличный звонок вместо однократного, всё. Алгоритмы, логика, развитие - это всё потом, весной) Это приносящее пользу ус-во для своего дом. пользования на скорую руку Изображениеот нуба, какие сроки)пока так.
Последний раз редактировалось Вик30 Чт дек 28, 2023 13:33:14, всего редактировалось 1 раз.

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

Чт дек 28, 2023 13:28:49

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

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

Чт дек 28, 2023 13:37:53

Из шаблона это было скорее всего взято , а там это было заложено для аварийного прерывания модуля.
блин, вы как будто только себя читаете)
надо топать его проверять, а чтобы телефон в это время не верещал -.... asm volatile ("jmp 0x0000"); и дилей 3 минуты прикрутил как временную меру

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

Чт дек 28, 2023 13:41:27

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

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

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

Чт дек 28, 2023 13:41:58

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

можно, конечно, написать капсом и красным - "костыль, временно", но, скорее всего, правилами запрещено...

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

Чт дек 28, 2023 13:42:57

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

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

Чт дек 28, 2023 14:09:58

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

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

Чт дек 28, 2023 15:19:59

рабочих и вообще примеров и решений не нашел

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