Gå til innhold

Arduino string/buffer help trenges


Anbefalte innlegg

Jeg trenger hjelp til å kunne lese og bruke data fra Serial1 porter på Arduino Mega 2560.

 

Jeg har en SIM900 koblet til Serial1 den mottar sms fra min telefon.

Det jeg ønsker er å kunne lagre telefonnr på en string "telefonnr" og vil at den skal søke etter ord i selve smsen.

F.eks "dittpassord" LEDON, når han finner denne vil jeg at den skal sette LED som er på pin 12 høy.

 

Noen som veit hvordan jeg skal gjøre dette?

Lenke til kommentar
Videoannonse
Annonse

Har brukt denne en del, men de har en annen måte å lese setninger for å utføre handlinger

  if(SIM900.available() >0)
  {   
    inchar=SIM900.read(); 
    if (inchar=='2')
    {
      delay(10);
      inchar=SIM900.read(); 
      if (inchar=='1')
      {
        delay(10);
        inchar=SIM900.read(); 
        if (inchar=='2')
        {
          delay(10);
          inchar=SIM900.read(); 
          if (inchar=='8')
          {
            delay(10);
            inchar=SIM900.read(); 
            if (inchar=='6')

osv.

 

Som du ser er det splittet opp jeg vil unngå det, vil helst 21286 og ikke

2

1

2

8

6

Lenke til kommentar

Var litt opptatt i går så fikk ikke sett noe mer på det. Du kan jo kjøre en løkke som legger på en string for hver gang.

No har ikke jeg gjort noe mot SoftwareSerial.h eller SIM900, men kanskje dette virker:

String text = "";
char bokstaver;

while(SIM900.available() > 0){
bokstaver = SIM900.read();
text.concat(bokstaver);
}

eller du kan lage ditt eget buffer som skal holde på meldningen, f.eks array med lengde 20 om du vet at meldningen ikke blir lenger en 20 tegn. Så kan du lage en for-løkke (som går 20 ganger) som legger dette inn i arrayen, når dette er gjort kan du konvertere fra char til string.

 

Det er mange måter, dette var bare noen eksempler, kanskje du kan benytte deg av dette eller kanskje ikke. Du får bare spørre om det er noe mer du lurer på.

Endret av cronbach alpha
Lenke til kommentar

Var litt opptatt i går så fikk ikke sett noe mer på det. Du kan jo kjøre en løkke som legger på en string for hver gang.

No har ikke jeg gjort noe mot SoftwareSerial.h eller SIM900, men kanskje dette virker:

String text = "";
char bokstaver;

while(SIM900.available() > 0){
bokstaver = SIM900.read();
text.concat(bokstaver);
}

eller du kan lage ditt eget buffer som skal holde på meldningen, f.eks array med lengde 20 om du vet at meldningen ikke blir lenger en 20 tegn. Så kan du lage en for-løkke (som går 20 ganger) som legger dette inn i arrayen, når dette er gjort kan du konvertere fra char til string.

 

Det er mange måter, dette var bare noen eksempler, kanskje du kan benytte deg av dette eller kanskje ikke. Du får bare spørre om det er noe mer du lurer på.

 

Tenkte å bruke en buffer til å lagre mottatt sms på.

Slik ser dataen ut når SIM900 mottar en sms, jeg brukte *** der mitt nr var

 

+CMT: "+47********","","14/0/0,19:19:23+0"
Password led
Slik jeg ser det har jeg ikke bruk for mer enn 100 bytes buffer den skal klare dette over her og vell så det.
Jeg er total nood når det kommer til string og buffer og forstår ikke noe av det enda, men prøver å lære.
Slik jeg ser det nå vil jeg følgende:
  1. Se etter +CMT og lagre all data etter +CMT til smsbuffer
  2. Finne "+47********" og lagre i en egen buffer, "sendernr"
  3. Bekrefte mottatt passordet med det som er lagret i en egen buffe.
  4. Finne ordet led og utføre handlingen viss passordet stemmer.
  5. Sende sms i retur til sender med å hente nummer fra buffer sendernr.
  6. Etter alt er gjort slett alle sms, tøm sendernr og smsbuffer.
Endret av Kimlorentz
Lenke til kommentar

Her er ett eksempel på hvordan man kan ekstrahere informasjon fra en streng.


#include <string.h>

//#define  MAX_SMS_SIZE  160  // Funker ikke

void setup() {
  
  Serial.begin(115200);
  Serial.print("Starting up...\n");
  delay(1000);
}

void loop() {

  int i, j;
  static const int MAX_SMS_SIZE = 160;
  
  char smsbuffer[] = "+CMT: \"+4722222222\",\"\",\"14/0/0,19:19:23+0\"\n\rPassword led";
  char sendernr[12];
  char meldingsbuf[MAX_SMS_SIZE];
  
  memset(sendernr, 0, sizeof(sendernr));  //Initialiser buffer med 0
  memset(meldingsbuf, 0, sizeof(meldingsbuf));  //Initialiser buffer med 0
  
  Serial.print("Før kopiering av chars...\n");
  Serial.print("smsbuffer = ");
  Serial.println(smsbuffer);
  Serial.print("sendernr = ");
  Serial.println(sendernr);  // Inneholder ingenting
  Serial.print("meldingsbuf = ");
  Serial.println(meldingsbuf);  // Inneholder ingenting
  
  // Ekstrakt telefonnr.
  for (i = 0; i<11; i++)  // Kopier 11 bytes fra smsbuffer (offset 7) over til sendernr-buffer og
    sendernr[i] = smsbuffer[7+i];  // la den 12te byte'n være 0 slik at strengen blir nullterminert

  // Ekstrakt melding
  for (i = 0, j = 0; i <= MAX_SMS_SIZE; i++) {
    if (smsbuffer[i] == 0x0a) {  //Meldingen begynner rett etter LINEFEED
      i++;  // Ikke kopier LF
      while (smsbuffer[i] != 0 && i <= MAX_SMS_SIZE)  {  // Iterer til vi er på slutten av strengen eller maks antall tegn i sms      
        meldingsbuf[j++] = smsbuffer[i++];  // Kopier meldingen til meldingsbuffer
      }      
      break;  // Ingen vits å kjøre igjennom hele smsbuffer når meldingen er funnet og kopiert
    }
    if (i == MAX_SMS_SIZE)
      Serial.println("Fant ingen melding\n");
  }    

  Serial.print("\nEtter kopiering av chars...\n");
  Serial.print("smsbuffer = ");
  Serial.println(smsbuffer);
  Serial.print("sendernr = ");
  Serial.println(sendernr);
  Serial.print("meldingsbuf = ");
  Serial.println(meldingsbuf);
  
  while (1) {};
}
Med forbehold om mulige bugs =)

 

Jeg antar at formatet er det samme hver gang du mottar en sms, derav

 


sendernr[i] = smsbuffer[7+i];
hvor 7 er den 8nde byte'n i strengen (vi starter å telle fra null i for løkka).

 

Merk at koden over ikke tar hensyn til andre lands tlf.nr. enn norges (og de land som tilfeldigvis har samme antall siffre i sitt nummere).

Hvis man f.eks tekster fra en mobil registrert på Hawaii, så vil landskoden være 1808 + x antall siffre og lengden på tlf.nr. vil sannsymligvis være forskjellig fra den norske.

En mulig løsning vil være å starte og kopiere fra byte 8 og iterere til man møter gåseøyne etter selve tlf.nr. i strengen.

 

For å ekstrahere selve meldingen må vi bruke en annen løsninig, da jeg kan se for meg at antall tegn for dato og tidssone kan variere.

F.eks:


+CMT: "+47********","","14/0/0,19:19:23+0"<CR><LF>Melding
kontra


+CMT: "+xx(xx)********","??","14/10/11,19:19:23+11"<CR><LF>Melding
derfor søker vi etter LINEFEED som er den siste char før selve meldingen.

 

Håper dette hjelper.

 

Sceptic

Endret av Sceptic
Lenke til kommentar

Ah dæven steike hehe, den der var over mitt hode. Får sette meg ned å lese.

 

For min nårværende løsning er ikke så stor.

 

Mottatt sms formelen skal være den samme, bare etter passord blir det endringer.

  • LED ON
  • LED OFF
  • LED2 ON
  • LED2 OFF
Endret av Kimlorentz
Lenke til kommentar

Tja, ser vel mer komplisert ut enn det det er pga. kommentarene som bryter inn mellom koden antar jeg.

Her er deler av koden uten kommentarer:


// Ekstrakt telefonnr.
for (i = 0; i<11; i++)
  sendernr[i] = smsbuffer[7+i];
Koden over er bare en enkel for løkke som kopierer data fra en buffer til en annen.

 


// Ekstrakt melding
  for (i = 0, j = 0; i <= MAX_SMS_SIZE; i++) {
    if (smsbuffer[i] == 0x0a) {
      i++;
      while (smsbuffer[i] != 0 && i <= MAX_SMS_SIZE)  {
        meldingsbuf[j++] = smsbuffer[i++];
      }
      break;
    }
    if (i == MAX_SMS_SIZE)
      Serial.println("Fant ingen melding\n");
  }
Koden over her er kanskje litt mer innvolvert da vi må finne starten av meldingen, men selve kopieringen er bare en variant av den forrige kodesnutten (while istedenfor for).

 

Prøvde du å kjøre koden?

 

Sceptic

Lenke til kommentar

Ja jeg prøvde koden, fungerte den slik den var. må bare få arduinoen til å lagre mottatt sms fra Serial2 til smsbuffer.

 

Slik er det jeg har satt opp til nå:

#define Sim900Serial Serial2
const int SIM = 7;          // on current Sim900 card the PWM pin 7 control                             //the PWRKEY to SIM900 chip
const int LED = 10;          // LED output, controlled by SMS
const int LED2 = 9;          // LED output, controlled by SMS
boolean LOWVOLT = true;     // Used to stop arduino to send many sms 
                            //during low voltage levels

Setup del:

    pinMode (LED, OUTPUT);
    pinMode (LED2, OUTPUT);
    pinMode (SIM, OUTPUT);
    digitalWrite(LED, LOW);
    digitalWrite(LED2, LOW);
// Starting up SIM900
  digitalWrite(SIM, HIGH);
  delay(3000);
  digitalWrite(SIM, LOW);
  delay(8000);

// SIM900 setup  
  Sim900Serial.begin(115200);               // the GPRS baud rate  
  delay(500);
  Sim900Serial.println("AT+IPR=19200");
  delay(500);
  Sim900Serial.begin(19200);               // the GPRS baud rate  
  delay(1000);  
  Sim900Serial.println("AT+CNMI=2,2,0,0,0\r");
  delay(1000);
  Sim900Serial.println("AT+CMGD=1,4"); // delete all SMS
  
}

Loop ser slik ut:

{
  sms();

  
////// Battery monitor code //////
int sensor1 = analogRead(A0);  
float power = sensor1 * (5 / 1023.0) * 2.487;

// When battery is lover then 7.00vdc
  if (power <= 7.00) {
    digitalWrite(LED, HIGH);
    if (LOWVOLT)
        SendTextMessage3();
        LOWVOLT = false;    
  }
  if (power >= 8.00) 
  {
    if(!LOWVOLT)
        LOWVOLT = true; 
  }
  
}

Det er sms(); som ikke er fullført. det er denne som leser sms, lagre telefon nr i egen buffer f.eks sendernr og utfører ordre fra sms

Endret av Kimlorentz
Lenke til kommentar
  • 3 uker senere...

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...