SIM900 и Arduino

Viktor5252
Offline
Зарегистрирован: 21.04.2021
#include <Keypad.h>       // Подключаем библиотеку 
#include <LiquidCrystal.h>  // Подключаем библиотеку 
#include <SoftwareSerial.h>
// Создать объект программного последовательного порта для связи с SIM900
// Tx и Rx SIM900 подключены к выводам 7 и 8 Arduino
SoftwareSerial SIMModule(7, 8);
LiquidCrystal lcd(12, 11, 10, 6, 5, 4); 
byte zamokcl[8]={0,14,17,17,31,27,27,31};
byte zamokop[8]={ 14,17,17,1,31,27,27,31};
const byte ROWS = 4; // 4 строки
const byte COLS = 4; // 4 столбца
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
}; 
String number="+7";
byte rowPins[ROWS] = {A5,A4,A3,A2}; // пины строк
byte colPins[COLS] = {A0,A1,2,3};      // пины столбцов
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char a, cmp_com, bit_ok;

void setup()
{ 
    lcd.begin(16, 2);  // Инициализирует LCD 16x2
    lcd.print("Init SIM");
    pinMode(9,OUTPUT);
    digitalWrite(9,HIGH);
    delay(1000);
    digitalWrite(9,LOW);
    lcd.createChar(4, zamokcl);
    lcd.createChar(5, zamokop);
    Serial.begin(9600);        // скорость обмена с терминалом
    SIMModule.begin(9600); // Начать последовательную связь Arduino и SIM900
    lcd.setCursor(0,0);       // поставить курсор LCD на первую строку и первый символ
    SIMModule.println("AT");
    updateSerial();

    lcd.print("Press * to start");
}


void loop()
{   
   updateSerial(); 
    char key = keypad.getKey(); //получить символ с нажатой клавиши
    if (key && number.length()<12){PrepareNumber(key);}
    else if (number.length()==12)
    {
        if (key=='D'){PrepareNumber(key);}
        if (key == 'A'){StartCall();}
    }
      
}

void StartCall()
{
    SIMModule.println("AT+CPAS\r\n");
    int8_t s = SIMModule.read();
    Serial.println(s);
    if(SIMModule.read()==2)
    {
    SIMModule.println("ATA\r\n");
    }
    String call = "ATD"+number+";\r\n";
    Serial.println(call);
    SIMModule.println(call);
    lcd.clear();
    lcd.print("Calling");
    lcd.setCursor(0,1); 
    lcd.print(number); 
  
}
/****
DEBUG
****/

void updateSerial()
{
  delay(50);
  while (Serial.available()) 
  {
    // Пересылка того, что было получено с аппаратного последовательного порта, 
    // на программный последовательный порт
    SIMModule.write(Serial.read());

  }
  while(SIMModule.available()) 
  {
    // Пересылка того, что было получено с программного последовательного порта, 
    // на аппаратный последовательный порт
    Serial.write(SIMModule.read());
  }
}

void PrepareNumber(char key)
{
  byte oz = 100;
    switch (key)
    {
      
        case '*':
            number="+7";
            delay(oz);
            break;
        case '1':
            number+="1";
            delay(oz);
            break;
        case '2':
            number+="2";
            delay(oz);
            break;
        case '3':
            number+="3";
            delay(oz);
            break;
        case '4':
            number+="4";
            delay(oz);
            break;
        case '5':
            number+="5";
            delay(oz);
            break;
        case '6':
            number+="6";
            delay(oz);
            break;
        case '7':
            number+="7";
            delay(oz);
            break;
        case '8':
            number+="8";
            delay(oz);
            break;
        case '9':
            number+="9";
            delay(oz);
            break;
        case '0':
            number+="0";
            delay(oz);
            break;
        case 'D':
            delay(oz);
            if (number.length()==2) return;
            String subnam =""; 
            for(int i=0;i<number.length()-1;i++)
            {
                subnam+=number[i];
            }
            number=subnam;
            break;
    }
    
    UpdateDisplay();
}

void UpdateDisplay()
{
    lcd.clear();
    lcd.print("Ha6op HoMepa:");
    lcd.setCursor(0,1);
    lcd.print(number);
}

Доброго времени суток, подскажите, как организовать правильное считывание ответа от SIM900 по типу команды "AT+CPAS" , в ответ получаем "+CPAS: 0 OK"(ок на второй строке) по сути необходима лишь цифра , которая находится в конце первой строки ( в некоторых случаях две цифры через запятую). Вчера весь вечер листал интернет , но так и не понял как это сделать (необходимо периодически узнавать есть ли входящий звонок или разговаривают ли в данный момент через него)

rkit
Offline
Зарегистрирован: 23.11.2016

sscanf

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

Если возникают такие вопросы, то почему не взять готовую библиотеку для SIM900? Благо, их девать некуда хороших и разных. Вот только первые три результата поиска

1. https://github.com/amperka/gprs-shield
2. https://github.com/MarcoMartines/GSM-GPRS-GPS-Shield
3. https://iarduino.ru/file/112.html

Разбирать строку руками и чтобы при этом ещё и не остановить намертво всё остальное - не так-то просто. Если Вы хотите этому научиться, то, конечно, но будьте готовы - эта задача займёт от месяца и больше (хотя, само по себе, полезно).

Viktor5252
Offline
Зарегистрирован: 21.04.2021

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

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

А можно ли к

int8_t s = SIMModule.read();

заменить на

String s1=String(SIMModule.read());

А потом проверять ее методами класса String?

 

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

Alexey_Rem пишет:

А можно ли к

int8_t s = SIMModule.read();

заменить на

String s1=String(SIMModule.read());

А потом проверять ее методами класса String?

Можно всё, но не так.

Судя по вопросам, которые ТС задаёт (и не только в этой теме), он не понимает в этом НИ ХРЕНА, а потому, меньше чем за несколько месяцев ему этого не сделать. Никак.

Viktor5252

вариантов у Вас два - найти готовое или заказать за деньги. Других вариантов нет. 

Хотя, есть ещё один вариант - отказаться пока от защиты диплома, продолжить обучение и таки чему-нибудь научиться, а тогда уж всё сделать и защитить диплом, но Вы же не считаете это вариантом, правда?

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП, это уже другой человек.

Лето, дача, шашлыки - понимаю... ))

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

sadman41 пишет:
это уже другой человек.

Виноват :-(((

Сейчас поправлю пост

sadman41 пишет:

Лето, дача, шашлыки - понимаю... ))

У меня нет дачи. Шашлыки я жарю во дворе своего дома возле беседки - вот в этом сезоне купил большой стационарный мангал с крышей и всеми делами.

А крышу мне сегодня снесли два письма, которые по е-мэйлу пришли. Одно от Илона Маска, а второе от Исуса Христа. В обоих предлагается срочно ознакомиться с предложением, которое изменит мою жизнь к лучшему и ответить на него. Само предложение приложено и имеет иконку Adobe Reader и название VIPOnlyUniqueProposal.PDF.exe Предлагается просто кликнуть на него, оно откроется, изучить и срочно, до конца дня, ответить.

Я вот всё думаю, в детстве мне даже сраный Дед Мороз на письма не отвечал, а тут такое счастье сразу привалило - и Христос, и Маск по своей инициативе мне написали. Чем заслужил? Откуда такая карма?

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Спрашиваю для себя на будущее. На текущий момент моего разумения я использовал бы такое решение или просто парсил массив s[], что тут не так?

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

Alexey_Rem пишет:
что тут не так?
Вы напишите полностью, тогда и поговорим. А то, что Вы сейчас написали

String s1=String(SIMModule.read());

ну, и и какой в этом смысл? Получили байт, запихали в String, получите новый - этот затрётся, дальше-то что? 

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Спасибо

andyparker
Offline
Зарегистрирован: 20.12.2020

Лучше уж тогда так:

String data = "";
while (SIM900.available()) {
  data += String(SIM900.read());
}
// parsing