[AJUDA] Usar substring e transformar o resultado em int

Pessoal, boa tarde! estou com dificuldades em entender o que acontece aqui no meu código.

Eu estou recebendo uma SMS por um módulo GSM, e enviando para o serial monitor.

O SMS é basicamente esse: "#vermelho45amarelo11verde37". Cada número (45, 11 e 37) vai ser utilizado como delay, para acender uma fase de um semáforo.

O problema está quando vou multiplicar esses números por 1000 para fazer o delay. O retorno que eu tenho são caracteres estranhos. Mas os números que entram na formula da conta aparecem da maneira correta.

Alguem pode me ajudar por favor???

//

// Inicio do código

//

int ledverm = 39;
int ledamar = 41;
int ledverd = 43;
int vm;
int vm1;
int vm2;
int am;
int am1;
int am2;
int vd;
int vd1;
int vd2;
String strvm1;
String strvm2;
String stram1;
String stram2;
String strvd1;
String strvd2;
void setup()
{
  Serial1.begin(19200);
  Serial.begin(19200);
  pinMode(ledverm, OUTPUT);
  pinMode(ledamar, OUTPUT);
  pinMode(ledverd, OUTPUT);
  // Configure para receber mensagens de outros dispositivos
  // Entre as equipes dar tempo para processá-los
  Serial1.print("AT+CMGF=1\r");
  delay(300);
  Serial1.print("AT+IFC=1, 1\r");
  delay(300);
  Serial1.print("AT+CPBS=\"SM\"\r");
  delay(300);
  Serial1.print("AT+CNMI=1,2,2,1,0\r");
  delay(500);
  Serial1.print("AT+CMGD=1,4");
  delay(500);
  Serial.print("AT+CMGF=1\r");
  delay(300);
  Serial.print("AT+IFC=1, 1\r");
  delay(300);
  Serial.print("AT+CPBS=\"SM\"\r");
  delay(300);
  Serial.print("AT+CNMI=1,2,2,1,0\r");
  delay(500);
  Serial.print("AT+CMGD=1,4\r");
  delay(500);
}
String currStr = "";
// A variável tem o valor True, se a linha atual é a mensagem
boolean isStringMessage = false;
void loop()
{
  if (!Serial1.available())
    return;
  char currSymb = Serial1.read();    
  if ('\r' == currSymb) {
    if (isStringMessage) {
      strvm1 = currStr.substring(9,10);
      char charvm1[strvm1.length()+1];
      strvm1.toCharArray(charvm1, sizeof(charvm1));
      int vm1 = atoi(charvm1);
      Serial.print("\rstrvm1=");Serial.print(strvm1);
      Serial.print("\rvm1=");Serial.print(vm1);
      
      strvm2 = currStr.substring(10,11);
      char charvm2[strvm2.length()+1];
      strvm2.toCharArray(charvm2, sizeof(charvm2));
      int vm2 = atoi(charvm2);
      Serial.print("\rstrvm2=");Serial.print(strvm2);
      Serial.print("\rvm2=");Serial.print(vm2);
      stram1 = currStr.substring(18,19);
      char charam1[stram1.length()+1];
      stram1.toCharArray(charam1, sizeof(charam1));
      int am1 = atoi(charam1);
      Serial.print("\rstram1=");Serial.print(stram1);
      Serial.print("\ram1=");Serial.print(am1);
      stram2 = currStr.substring(19,20);
      char charam2[stram2.length()+1];
      stram2.toCharArray(charam2, sizeof(charam2));
      int am2 = atoi(charam2);
      Serial.print("\rstram2=");Serial.print(stram2);
      Serial.print("\ram2=");Serial.print(am2);
      strvd1 = currStr.substring(25,26);
      char charvd1[strvd1.length()+1];
      strvd1.toCharArray(charvd1, sizeof(charvd1));
      int vd1 = atoi(charvd1);
      Serial.print("\rstrvd1=");Serial.print(strvd1);
      Serial.print("\rvd1=");Serial.print(vd1);
      strvd2 = currStr.substring(26,27);  
      char charvd2[strvd2.length()+1];
      strvd2.toCharArray(charvd2, sizeof(charvd2));
      int vd2 = atoi(charvd2);
      Serial.print("\rstrvd2=");Serial.print(strvd2);
      Serial.print("\rvd2=");Serial.print(vd2);      // Até aqui funciona normalmente
      
      int vm = (10*vm1 + vm2)*1000;      Serial.print("\rvm=");Serial.print(vm);       // Aqui está 
      int am = (10*am1 + am2)*1000;      Serial.print("\ram=");Serial.print(am);    //  o 
      int vd = (10*vd1 + vd2)*1000;      Serial.print("\rvd=");Serial.print(vd);           // PROBLEMA
      isStringMessage = false;
      semaforo(); // Ai quando utilizo as variáveis nesta função, não obtenho o resultado esperado.
    } 
    else {
      if (currStr.startsWith("+CMT")) {
        // Se a linha atual começa com um "+ CMT",
        // A linha seguinte é a mensagem
        isStringMessage = true;
      }
    }
    currStr = "";
  } 
  else if ('\n' != currSymb) {
    currStr += String(currSymb);
    char carray[currStr.length()+1];
    currStr.toCharArray(carray, sizeof(carray));
  }
}
void semaforo(){
  digitalWrite(ledverm, HIGH);
  digitalWrite(ledamar, LOW);
  digitalWrite(ledverd, LOW);
  delay(vm);
  digitalWrite(ledverm, LOW);
  digitalWrite(ledamar, HIGH);
  digitalWrite(ledverd, LOW);
  delay(am);
  digitalWrite(ledverm, LOW);
  digitalWrite(ledamar, LOW);
  digitalWrite(ledverd, HIGH);
  delay(vd);
}

Exibições: 430

Responder esta

Respostas a este tópico

Caio, Geralmente na linguagem C o tipo de variável int utilizado no seu código nas variáveis  vm, am e vd suportam valores de -32768 a 32767 ou seja considerando que vm1 = 45 e vm2 =0 a conta seria (10*45 + 0)*1000 = 450000, este valor está muito além da capacidade de um int. No padrão C ANSI , o int suporta 2 bytes (16 bits) então 2^16 = 65536 = 0 a 65535 para inteiro sem sinal (unsigned int) e -32768 a 32767 para inteiro com sinal (int). Isto também depende do sistema operacional, compilador ou arquitetura do processador.
Enfim, neste caso você poderá utilizar o tipo long ou long int que possui uma maior capacidade (4 bytes) de armazenamento.

Abraço JP.

Joao, muito obrigado pela resposta.

Imagino que o long int possa ajudar nesse caso.

Mas, quando a variavel vm1 neste caso vale 4, e vm2 vale 5 (verificados pelo serial monitor).

Quando se faz a conta "int vm = (10*vm1 + vm2)*1000"      vm é igual a 45000, e esta dentro da capacidade do tipo int.

Caio boa tarde,

O valor 45000 também está fora do int pois, o intervalo de um tipo int de 2 bytes é -32768 a 32767.
Como você está usando a variável para um delay e no meu entendimento não precisa de valores negativos, sugiro o unsigned int caso o valor deste delay fique entre 0 e 65535. Acima disto, e de acordo com sua necessidade, pode ser utilizado o tipo long int ou unsigned long int.

Sim sim!

Vou testar isso assim que possível, mas imagino que resolva o problema!

Cara, muito obrigado mesmo! Estava tão preocupado com coisas mais complexas no projeto que detalhes pequenos passam sem perceber!

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço