Некорректная отработка кода

iconini13ya
Offline
Зарегистрирован: 04.04.2021
Здравствуйте, подскажите пожалуйста - вопрос очень прост. У меня есть функция, выполняющаяся в setup - simSetup(), и в ней выполняется функция 1 sendSMS() скорее всего я тупой - или колеса не едут, но почему-то код из sendSMS() выполняется раньше, чем simSetup(). Т.е нарушается последовательность исполнения кода. Я студент + новичок поэтому предполагаю (на основе знаний из других языков программирования), что проблема может быть в потоках, хотя не особо знаю как потоки реализованы в arduino. Пруф о том, что код sendSMS() выполняется раньше

 
#define CH_NUM 0x60   // номер канала, должен совпадать с передатчиком (датчик)

// УРОВЕНЬ МОЩНОСТИ ПЕРЕДАТЧИКА
// На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
#define SIG_POWER RF24_PA_MAX

// СКОРОСТЬ ОБМЕНА
// На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
// должна быть одинакова на приёмнике и передатчике!
// при самой низкой скорости имеем самую высокую чувствительность и дальность!!
// ВНИМАНИЕ!!! enableAckPayload (основная функция обмена данными) НЕ РАБОТАЕТ НА СКОРОСТИ 250 kbps!
#define SIG_SPEED RF24_1MBPS
//--------------------- НАСТРОЙКИ ----------------------

//--------------------- БИБЛИОТЕКИ ---------------------
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10
#include "SoftwareSerial.h" //библиотека для создания сериал порта на любом пине
SoftwareSerial SIM800(2,3);   
//--------------------- БИБЛИОТЕКИ ---------------------

//--------------------- ПЕРЕМЕННЫЕ ----------------------
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte callbackData[3];         // массив принятых данных
byte Data[4]; //массив отправляемых данных
byte pipeNo; //Байтовая переменная хранения номера трубы для отправки
struct Sensor { //Переменная типа struct для хранения данных о датчике
  byte id;
  byte type;
  byte data;
};
Sensor cashDataToSend;
//--------------------- ПЕРЕМЕННЫЕ ----------------------

void setup() {
  pinMode(4,OUTPUT);
  Serial.begin(9600); //открываем порт для связи с ПК
  radioSetup();
  simSetup();
//  writeMainPhone(520534351);
//  writeAddPhone(114540246);
//  sendSMS("+79160910471","Hi,this is the ansver from arduino");
//  delay(10000);

//  for(int i =0; i<54; i++){
////    writeNewSensorSettings(0,1,mySensor);
////    clearSensorById(i);
////    delay(200);
//   Serial.print("Info "); Serial.println(eeprom_read_byte(i));
//   delay(5);
//  }
}
int bustatus;
void loop() {

//  sendSMS("+79520534351","Hi,this is the ansver from arduino");
//  delay(500);

 if (SIM800.available())           // Ожидаем прихода данных (ответа) от модема...
    Serial.write(SIM800.read());    // ...и выводим их в Serial
 if (Serial.available())           // Ожидаем команды по Serial...
    SIM800.write(Serial.read());    // ...и отправляем полученную команду модему 
 if(radio.available()){
  Serial.println("Читаю");
  radio.read(&callbackData, sizeof(callbackData));
  if(callbackData[0]==0){
    Serial.println("Новенький");
    radio.stopListening();
    Serial.println("Перестал читать");
    writeNewSensorSettings(callbackData[1],callbackData[2],cashDataToSend);
    Data[0]= callbackData[0];
    Data[1]= callbackData[1];
    Data[2]= cashDataToSend.id;
    Data[3]= cashDataToSend.type;
    Serial.print("Новый id"); Serial.println(Data[2]);
    Serial.print("Новый type"); Serial.println( Data[3]);
    while(radio.write(Data, sizeof(Data)) == false){
      Serial.println("Пишу");
      delay(50);
      }
    Serial.println("Отправил");  
    radio.startListening();
    Serial.println("Начинаю слушать");
    }
  }  

  if(Serial.available()){
    bustatus=Serial.parseInt();
    Serial.print(bustatus);
    switch(bustatus){
      case 2:
        Serial.print("Я на лоу");
        digitalWrite(4,LOW);
        break;
      case 1:
        Serial.print("Я на хай");
        digitalWrite(4,HIGH);
        break;
      }
    }
}

void radioSetup() {         // настройка радио модуля
  radio.begin();               // активировать модуль
  radio.setAutoAck(1);         // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);     // (время между попыткой достучаться, число попыток)
  radio.setPayloadSize(32);    // размер пакета, байт
  radio.openReadingPipe(1, address[0]);   // хотим слушать трубу 0
  radio.openWritingPipe(address[1]); 
  radio.setChannel(CH_NUM);               // выбираем канал
  radio.setPALevel(SIG_POWER);            // уровень мощности передатчика
  radio.setDataRate(SIG_SPEED);           // скорость обмена
  // должна быть одинакова на приёмнике и передатчике!
  // при самой низкой скорости имеем самую высокую чувствительность и дальность!!

  radio.powerUp();         // начать работу
  radio.startListening();  // начинаем слушать эфир, мы приёмный модуль
}

void simSetup(){
  SIM800.begin(19200);  //Скорость порта для связи Arduino с GSM модемом    
  delay(100);
  SIM800.println("AT");  
  delay(100);
  SIM800.print("AT+CMGF=1\r");
  delay(8000); 
  sendSMS("+79520534351","Hi,this is the ansver from arduino");
  }

  void sendSMS(String phone,String message) // Некорректный пример
{
    SIM800.println("AT+CMGS=\"" + phone + "\"");  // Задаем номер телефона адресата
    delay(100);
    SIM800.println(message);          // Вводим сообщение
    delay(100);
    SIM800.println((char)26);         // Уведомляем GSM-модуль об окончании ввода
    delay(100);
    SIM800.println();
                    // Ожидаем отправки
    Serial.println("отослал");
}

bool isItFreeCell(int num) {
  Serial.print("isItFreeCell() <-"); Serial.println(num) ;
  byte cash = eeprom_read_byte((uint8_t*)num);
  Serial.print("Что находится в ячейке num"); Serial.println(cash) ;
  delay(15);
  Serial.print(cash); Serial.print(" = "); Serial.print(cash); Serial.println(" ?") ;
  if (cash == 255) {
    Serial.println(" Да") ;
    return true;
  }
  else {
    Serial.println(" Нет") ;
    return false;
  }
}

void clearSensorById(int id) {
  for (int i = 10; i < 1000; i= i + 3) 
  {
    if (eeprom_read_byte((uint8_t*)i) == id) 
    {
      delay(10);
      eeprom_write_byte((byte*)i, 255);
      delay(10);
      eeprom_write_byte((byte*)i + 1, 255);
      delay(10);
      eeprom_write_byte((byte*)i + 2, 255);
      delay(10);
      break;
    }
  }
}

void writeNewSensorSettings(byte type, byte data, Sensor& CallbackData) {
  Sensor mySensor;
  mySensor.type = type;
  mySensor.data = data;
  for (int i = 10; i < 1000; i = i + 3) {
    Serial.print("i= "); Serial.println(i) ;
    if (isItFreeCell(i) == true) {
      delay(500);
      if (i==10){
         mySensor.id=1;
        }else {
         mySensor.id = eeprom_read_byte((uint8_t*)i-3)+1; //Чтение из eeprom 
          }
      Serial.print("Старый id = "); Serial.println(mySensor.id);
        Serial.print("Новый id = "); Serial.println(eeprom_read_byte((uint8_t*)i-3)) ;
      eeprom_write_block((void*)&mySensor, (int*)i, sizeof(mySensor));
      eeprom_read_block((void*)&CallbackData, (int*)i, sizeof(CallbackData)); 
      break;
    }
  }
}

void readSensorSettingsById(int id,Sensor& callbackData){
    for (int i =10;i<1000;i= i+3){
       if (eeprom_read_byte((uint8_t*)i) == id) {
        eeprom_read_block((void*)&callbackData, (int*)i, sizeof(callbackData));
      }
    }
  }
void writeMainPhone(long phomeNumber){ //long поскольку int(16 бит) -32768 до 32767 и по этим причинам не подходит для номера телефона
  int n=0;
  for(int i=5;i>0;i--){
//    Serial.println(i-n);
//    Serial.println(phomeNumber%100);
    delay(50);
    eeprom_write_byte(n, phomeNumber%100);
    delay(50);
    n++;
    phomeNumber/=100;
//    Serial.println(n);
//    Serial.println(phomeNumber);
    }
  }
void writeAddPhone(long phomeNumber){ //long поскольку int(16 бит) -32768 до 32767 и по этим причинам не подходит для номера телефона
  int n=0;
  for(int i=5;i>0;i--){
//    Serial.println(i-n);
//    Serial.println(phomeNumber%100);
    delay(50);
    eeprom_write_byte(n+5, phomeNumber%100);
    delay(50);
    n++;
    phomeNumber/=100;
//    Serial.println(n);
//    Serial.println(phomeNumber);
    }
  }

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я Вам уже писал, что на картинке ни хрена не видно. Если нужно вставить лог монитора порта, вставляйте его текстом, лучше тоже как код, чтобы номера строк были.

Выложите нормальный код и нормальный лог

iconini13ya
Offline
Зарегистрирован: 04.04.2021

В моем неокрепшем уму возникла догадка о том, что код сначала должен инициализироваться (в моем понимании ардуинка должна его сначала прочитать, а потом выполнить), но тогда я до конца не понимаю - почему delay(8000) начинает отрабатывать сразу. Т.е -> как только я загружаю скетч в ардуино и начинаю смотреть в порт, проходит 8 секунд и код описанный выше - исполняется одновременно. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

iconini13ya пишет:

В моем неокрепшем уму 

Мой неокрепший ум ни хрена не понял. Выложите нормально код и лог. И объясните толком в чём у Вас проблема.

iconini13ya
Offline
Зарегистрирован: 04.04.2021

Текст из порта 

отослал
AT
OK
AT+CMGF=1
OK
SMS Ready
AT+CMGS="+79520534351"
Call Ready    

Пожалуйста, перечитайте мой вопрос. На всякий случай продублирую - важную строку информации  

У меня есть функция, выполняющаяся в setup - simSetup(), и в ней выполняется функция  sendSMS() 

Сама проблема заключается в том, что- Есть функция simSetup() и в нее вложена функция sendSMS() и почему-то функция 

sendSMS() срабатывает раньше чем "Внутренности" simSetup(), хотя вложенная функция стоит после этих самых "Внутренностей". О срабатывании раньше "внутренностей" сигнализирует отправленное в сериал сообщение "отослал" - раньше, чем настройки, отправляемые по ходу кода в сериал перед ним
iconini13ya
Offline
Зарегистрирован: 04.04.2021
void simSetup(){
  SIM800.begin(19200);  //Скорость порта для связи Arduino с GSM модемом    
  delay(100);
  SIM800.println("AT");  
  delay(100);
  SIM800.print("AT+CMGF=1\r");
  delay(8000); 
  sendSMS("+79520534351","Hi,this is the ansver from arduino");
  }

  void sendSMS(String phone,String message) // Некорректный пример
{
    SIM800.println("AT+CMGS=\"" + phone + "\"");  // Задаем номер телефона адресата
    delay(100);
    SIM800.println(message);          // Вводим сообщение
    delay(100);
    SIM800.println((char)26);         // Уведомляем GSM-модуль об окончании ввода
    delay(100);
    SIM800.println();
                    // Ожидаем отправки
    Serial.println("отослал");
}

Из этого кода видно, что "отослал" должно приходить самым последним - из логики вложенности , а имеем - 

отослал

AT
OK
AT+CMGF=1
OK
SMS Ready
AT+CMGS="+79520534351"
Call Ready    
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А кто Вам сказал, что оно раньше выполняется?

Вы в simSetup что-то делаете, но ответы не печатаете и даже не вычитываете из буфера. Все ответы от модуля копятся во входном буфере SIM800. Потом Вы заходите в sendSMS в и в нём, в строке №142 печатаете слово "отослал" (его мы и виидм первым). И уже потом Вы заходите в loop и там в строках №№ 61 и 62 начинаете вычитывать их входного буфера и печатать всё, что за это время Вам наприсылал Sim800. Вот и получается, что оно печатается после слова "отослал".

iconini13ya
Offline
Зарегистрирован: 04.04.2021

Большое спасибо, ошибочку понял )