Tecnicamente's Weblog

Just another WordPress.com weblog

Arduino, F-BUS del Nokia3310 ed invio di SMS

Premessa

E’ passato molto tempo da quando ho deciso di sperimentare la comunicazione tramite Arduino ed un Nokia 3310 e dopo qualche prova e molte ricerche su internet ci sono riuscito.

E’ doveroso dire che non sarei mai riuscito nell’impresa senza le importanti informazioni trovati nei seguenti siti:

http://www.embedtronics.com/nokia/fbus.html

http://www.insidegadgets.com/2013/01/12/how-to-use-nokia-f-bus-to-send-an-sms-message/

Consiglio vivamente le lettura e lo studio delle pagine in essi contenuti, se poi avete qualche problema o volete passare ad usare qualche cosa di rapido e immediato uso, allora spero che queste note possano esservi di aiuto.

Come collegare Arduino al Nokia 3310

In post precedenti ho descritto come Arduino alla porta seriale di un qualsiasi dispositivo, nel mio caso un cellulare Siemens M35, qui i post in questione:

Arduino, Max232 e comunicazione seriale – Parte 1

Arduino, Max232 e comunicazione seriale – Parte 2

Per un po’ di tempo mi sono accanito a far funzionare la comunicazione tra il mio Arduino ed il mio Nokia 3310 usando il MAX232, alla fine ho fatto una terribile scoperta… i livelli di tensione non erano compatibili!

Va bene, allora come possiamo interfacciare il Nokia all’Arduino?

In un modo molto semplice, rimuovendo la batteria  si accede ai contatti che ci interessano.

Pin-Out Nokia 3310

Pin-Out Nokia 3310

Ho saldato i pin 2, 3 e 4 a dei cavi e realizzato il seguente schema, dove tutto è direttamente collegato all’Arduino.

collegamento

Ok fatto ciò possiamo passare al software.

Comunicazione 7 e 8 bit

Un aspetto poco piacevole della comunicazione è che il nostro Arduino comunica i dati utilizzando una codifica ad 8 bit, il Nokia 3310 legge i dati usando una codifica a 7 bit.

Cosa vuol dire ciò?

La risposta è semplice, se inviamo da Arduino a Nokia la stringa “OK”, si ha che Arduino invierà due stringe da 8 bit:

O -> 01001111   [posizioni -> 7 6 5 4 3 2 1 0]

K -> 01001000 [posizioni -> 7 6 5 4 3 2 1 0]

Il nokia leggerà i messaggi a blocchi di 7 bit, quindi il primo carattere ricevuto sarà

1001111 – > O  [posizioni -> 6 5 4 3 2 1 0]

Il secondo carattere avrà come bit in posizione 0 il bit che nel primo carattere era in posizione 7, quindi la lettura effettuata dal Nokia è

0011110 – > nessun carattere ASCII associato

Ciò vuol dire che le stringhe di messaggi che voglio inviare tramite SMS devono essere codificate da 8 a 7 bit, a tal proposito ho scritto in piccolo programma in C che mi permette di ottenere le stringhe già codificate e di eseguire qualche debug.

#include <stdio.h> 
#include <string.h> 

int main(void){ 

    //String test; 128 
    char input[4]; 
    char msg[4]; 
    char decode[4]; 
    int len; 

    unsigned char c, w; 
    int i,n, shift, x; 
    len = strlen(input); 
    shift = 0; decode[0] = 0; 

    input[0] = 'h'; 
    input[1] = 'e'; 
    input[2] = 'l'; 
    input[3] = 'o'; 

    /* Decode into 7 bit characters */ 
    for (n=0; n<len; ++n) 
            { 
            c = input[n] & 0x7f; 
            c >>= shift; 
            w = input[n+1] & 0x7f; 
            w <<= (7-shift); 
            shift +=1; 
            c = c | w; 
            if (shift == 7) 
                    { 
                    shift = 0x00; 
                    n++; 
                    } 
            x = strlen(decode); 
            decode[x] = c; 
            decode[x+1] = 0; 
            } 

    // Display decoded output as Hex 
    for (i = 0; i < strlen(decode); i++) 
      { 
         printf("%c",decode[i]); 
      //sprintf(msg,"%.02X ",(unsigned char)decode[i]); 
      } 
    for(i=0;i<4;i++) {printf("%x",decode[i]);} 

}

Allo stesso modo il seguente codice mi permette di eseguire la decodifica da 7 bit a 8 bit per leggere le stringhe provenienti dal Nokia e di cui riporto solo la parte più significativa.

//decodifica
     j=48;
     shift = 0;
        for(i=48;i<(152+MsgLen);i++){
             //c = buff_decode[i] & 0x7f;
             if(i==48){
                 c = buff_decode[i] & 0x7f;
                 decode[i-48] = c;
             }
             else{
                 w = buff_decode[i-48+1];
                 w >>= 7-shift;
                 c = buff_decode[i-48];
                 shift = shift+1;
                 c <<= shift;
                 c = w | c;
                 c = c & 0x7f;
                 decode[i-48] = c;
                 //c = w;
             }
         }

Andiamo al sodo, il CODICE

Qui il codice che ho usato per inviare il mio primo SMS tramite Arduino ed il Nokia 3310, buon divertimento, e mi raccomando se migliorate qualche cosa fatemi sapere😉


unsigned char FBusFrame[200];

// Numero del centro messaggi del gestore
// WIND     +393205858500 
// Vodafone +393492000200
// TIM      +393359609600
// TRE      +393916263333
// Dopo 0x91 si deve inserire il numero del centro messaggi in formato esadecimale a coppie di cifre invertire
// ES: WIND +39 -> 0x93 ; 32 -> 0x23 ; 05 -> 0x50 ; 58 -> 0x85 ; 58 -> 0x85 ; 0 -> 0x00 ; 0 -> 0x00
// Il nokia si attende un numero composto da 20 numeri, quindi quindi essendo in Italia il formato composto da 12 numeri
// occorre inserire 8 zeri finali, che si traduce in 4 0x00
unsigned char SMSC[] = {0x07, 0x91, 0x93, 0x23, 0x50, 0x58, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00};

// Numero che riceve l'SMS. dopo 0x81 inserire il numero del destinatario come già fatto per il centro messaggi
// non occore inserire gli 0x00 di chiudura, il formato è libero
// Es: 0123456789 
unsigned char RecipientNo[] = {0x0A, 0x81, 0x10, 0x32, 0x54, 0x76, 0x98};

void setup() { 
  // inizializzo la comunicazione su seriale a 115200 kbs come richiesto dal protocollo F-bus
  Serial.begin(115200);
  delay(100);
} 

void loop() { 
  // Inizializzazione dell'F-Bus inviando 128 volte il carattere 'U', corrispondente ad un segnale '0101010101...'
  for (int x = 0; x < 128; x++) {
    Serial.write("U");
  } 

  // Invio l'SMS
  SendSMS("EVVAI, il primo SMS");

  // Leggo la risposta dal Nokia, questa parte va estesa con l'individuazione e la decodifica di eventuali SMS di riposta ricevuti dal Nokia
  while (1) {
    while (Serial.available() > 0) { 
      int incomingByte = Serial.read(); 
      Serial.print(incomingByte, HEX); 
      Serial.print(" "); 
    }
  }
} 

unsigned char SendSMS(const char *Message) {
  // 
  unsigned char j = 0;
  memset(FBusFrame, 0, sizeof(FBusFrame));

  unsigned char MsgLen = strlen(Message), FrameSize = 0;
  unsigned char c, w, n, shift = 0, frameIndex = 0;
  unsigned char oddCheckSum, evenCheckSum = 0, SeqNo = 0x43;
  unsigned char MsgStartIndex = 48; // Indice di inizio dell'SMS

  // Codifica in 7 bit
  for (n = 0; n < MsgLen; n++) {
    c = Message[n] & 0x7f;
    c >>= shift;
    w = Message[n+1] & 0x7f;
    w <<= (7-shift);
    shift += 1;
    c = c | w;
    if (shift == 7) {
      shift = 0x00;
      n++;
    }
    FBusFrame[frameIndex + MsgStartIndex] = c;
    frameIndex++;
  }

  FBusFrame[frameIndex + MsgStartIndex] = 0x01;
  FrameSize = frameIndex + 44; // The size of the frame is frameIndex+48 (FrameIndex + 48 + 1 - 5)

  // Preparazione del frame prima del contenuto dell'SMS secondo il protocollo F-bus 
  FBusFrame[0] = 0x1E;
  FBusFrame[1] = 0x00;
  FBusFrame[2] = 0x0C;
  FBusFrame[3] = 0x02;
  FBusFrame[4] = 0x00;
  FBusFrame[5] = FrameSize;
  FBusFrame[6] = 0x00;
  FBusFrame[7] = 0x01;
  FBusFrame[8] = 0x00;
  FBusFrame[9] = 0x01;
  FBusFrame[10] = 0x02;
  FBusFrame[11] = 0x00;

  // Inserimento del numero del centro messaggi
  for (j = 0; j < sizeof(SMSC); j++) {
    FBusFrame[12 + j] = SMSC[j];
  }

  FBusFrame[24] = 0x15; //Message type
  FBusFrame[28] = MsgLen; //Lunghezza del messaggio (non compresso)

  // Inserimento del numero del ricevente
  for (j = 0; j < sizeof(RecipientNo); j++) {
    FBusFrame[j + 29] = RecipientNo[j];
  }

  FBusFrame[41] = 0xA7; // Validity period

  // Check if the Framesize is odd or even
  if (FrameSize & 0x01) {
    frameIndex = FrameSize + 5;
    FBusFrame[frameIndex] = SeqNo;
    frameIndex++;
    FBusFrame[frameIndex] = 0; // Insert to make the Frame even
    frameIndex++;
  }
  else {
    frameIndex = FrameSize + 5;
    FBusFrame[frameIndex] = SeqNo;
    frameIndex++;
  }

  // Calculate the checksum from the start of the frame to the end of the frame
  for (unsigned char i = 0; i < frameIndex+2; i += 2) {
    oddCheckSum ^= FBusFrame[i];
    evenCheckSum ^= FBusFrame[i+1];
  }
  FBusFrame[frameIndex] = oddCheckSum;
  FBusFrame[frameIndex+1] = evenCheckSum;

  // Invio dell'intero frame al Nokia 3310
  for (unsigned char j = 0; j < (frameIndex+2); j++) {
    // Debug to check in hex what we are sending
    //Serial.print(FBusFrame [j], HEX);
    //Serial.print(" ");

    Serial.write(FBusFrame [j]);
  }
}

7 risposte a “Arduino, F-BUS del Nokia3310 ed invio di SMS

  1. Simone 23 luglio 2013 alle 7:17 am

    non ho capito una cosa, come faccio a convertire un numero di cellulare 3xxxxxxxxx ?

    • Simone 23 luglio 2013 alle 7:35 am

      credo di aver capito, si mette la stringa 0x0A, 0x81 e poi il proprio numero a 2 a 2 ( per esempio 3405 diventa 0x43, 0x50.

      • tecnicamente 14 agosto 2013 alle 4:43 pm

        Scusa il ritaro. Si hai capito bene, i numeri si invertono due a due

  2. Fabio Tossani 25 settembre 2014 alle 5:49 pm

    Complimenti ottima guida! Vorrei porti una domanda..
    Riesco ad inviare correttamente gli sms con il mio nokia 3330 e ora vorrei leggere quelli in arrivo. Stranamente quando invio un sms al mio nokia non mi compare nessun byte in arrivo nemmeno col ciclo
    while (1) {
    while (Serial.available() > 0) {
    int incomingByte = Serial.read();
    Serial.print(incomingByte, HEX);
    Serial.print(” “);
    }
    }
    Mi sapresti dire come hai fatto a implementare la ricezione degli SMS?
    Grazie!

  3. tecnicamente 28 settembre 2014 alle 9:51 am

    Ciao,
    stavo lavorando alla ricezione, poi a causa di riduzioni dei tempi a disposizioni per l’hobby ho lasciato perdere.
    Ho preparato il codice per la decodifica, quindi passare dai 7bit sul bus agli 8bit del PC per leggere gli SMS, ma forse non l’ho mai messo sul blog, devo cercare.

    Devo rimettere su il Nokia e fare una prova con il codice che mi hai inviato.
    Alla ricezione di un SMS il nokia deve inviare sul BUS un con un byte settato con l’info che il cellulare comunica su fbus, da qui si deve procedere alla decodifica con l’acquisizione dei contenuti
    ================================================
    Byte: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
    Data: 1E 00 0C D1 00 07 00 01 00 03 00 01 60 00 72 D5

    1E: Frame ID – this packet is being sent using F-bus
    00: DestDev – this packet is being sent to the phone
    0C: SrcDev – this packet is coming from F-bus
    D1: MsgType – the type of message we are going to send/receive
    ==================================================

    Devo provare e cercare i codici che già avevo preparato.
    Nell’attesa se hai la possibilità di fare uno sniffer anche con dei LED, mettili sulla linee RX e TX così dai lampeggi capisci se c’e’ una comunicazione elettrica o meno.

    Provo nei prossimi giorni.

    • Fabio Tossani 29 settembre 2014 alle 1:07 pm

      Grazie, sono finalmente riuscito a ricevere la risposta del telefono in seguito alla ricezione degli SMS. E’ bastato inviare al nokia una richiesta HW&SW come indicato nel secondo link che hai citato. Ora proverò a decodificare i bit in ingresso!

      • tecnicamente 8 dicembre 2014 alle 10:52 am

        Grande, perchè nn posti il codice usato cos anche altri vedranno come hai fatto.
        Grazie.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: