1. You can now buy finished microcontroller project from us, Check out the Store for the complete list of projects.
  2. Need a custom project, Send us some details about your project. So that we can quote the price for it.

Sending SMS through Nokia 3310/5110

Sending SMS through Nokia 3310/5110

  1. Binu
    FBUS & MBUS basics


    Introduction
    The communication methods called FBUS and MBUS are used in Nokia mobile phones for data transmission, service, and adjustments. NokiaWorld has researched and tested these communications methods to get information for developing better cables for mobile phones and PCs.
    The MBUS method, that uses only a single pin, is a half-duplex method used also in older Nokia phones. With MBUS it is possible to interface with almost all Nokia mobile phones for service and adjustment purposes. The FBUS is a newer solution and offers high-speed full-duplex communications link between the phone and the computer. The service and adjustment operations, which are traditionally made over MBUS, are available also via FBUS, but usually much faster.


    FBUS communication

    Here you'll find a description of the protocol used in Nokia phones. Please note that Nokia doesn't provide any official information about the protocol it uses. The source of this information is mainly Gnokii and the hex command heaps that I made by sniffing the communication between the P.C. and Nokia phones. Nokia phones use two kinds of protocols, the Mbus protocol and the Fbus protocol. There is a lot of difference between the two, the basic difference being that one cannot transmit and receive data simultaneously with mbus, but the same is possible using fbus. Also there is a difference in the speeds. While Mbus operates at 9600 bps, Fbus operates at 115200 bps. So, if you want some fast data transfer between the pc and your phone, better use Fbus. Both mbus and fbus documentation can also be found at Gnokii, which is the original source of this document.
    Protocol Exchange Layout
    1. The Microcontroller sends some type of request or command packet
    2. Phone sends acknowledgement
    3. Phone sends response to the request packet
    4. Microcontroller sends acknowledgement

    Protocol Speed
    Speed :: 115,200 bps
    Bits :: 8
    Parity :: None
    Stop Bits :: 1

    Format of packets from Microcontroller (General packet format)
    { FrameID, DestDEV, SrcDEV, MsgType, 0x00, FrameLength, {block}, FramesToGo, SeqNo, PaddingByte?, ChkSum1, ChkSum2 }

    Where FrameID = 0X1c --- IR/Fbus
    = 0x1e --- Serial/Fbus

    DestDEV, SrcDEV = 0X00 --- Mobile Phone
    = 0x0c --- Microcontroller

    MsgTpye = Indicates the type of message .. can be 0x00 or 0x40 .. I haven't been able to decode it :(

    Framelength = {block} + 2 (+ 1 if PaddingByte exists)

    {Block} = The actual command body

    FramesToGo = If this packet is part of a group (eg. long sms), indicates how many more messages, including this one there are . 0x01 means the last frame

    SeqNo = [0xXY] where X: 4: first block 0: continuing block Y: sequence number ... haven't had much success with this either. The sequence number for a standard frame seems to be between 40 and 47. So, one can use 40 at the beginning to initialize.

    PaddingByte? = 0x00 if FrameLength would be an odd number

    ChkSum1 = XOR on frame's odd numbers --- Note
    ChkSum2 = XOR on frame's even numbers --- Note

    Note :: A 16 bit XOR all the preceding bits can also be taken.

    Format of acknowledgement from the phone
    Now that's where the problem is .. There is no information available about this in the Gnokii documentation. I have been able to get some information though.. But there are a lot of loop holes in it ..

    {1e, 0c, 00, 7f, 00, len, MsgType, SeqNo, Chksum }

    where len = length in bytes (always 02)

    MsgType = Corresponds to the the original message type.

    SeqNo = Haven't been able to decode this .. One of the docs says .. Last 3 bits indicate sequence no. of packet being acknowledged, most significant nibble is normally 0, 8 for sequence error.

    Chksum = 16 bit Xor of all preceding 16 bit words.

    Format of packet from the phone
    {1e, 0c, 00, MsgType, 00, FrameLength, {block}, FramesToGo, SeqNo, PaddingByte, Chksum}

    This is based on the original message sent by the Microcontroller to the phone.

    Format of acknowledgement from the phone
    {1e, 00, 0c, 7f, 00, len, Msgtype, SeqNr, Chksum}

    where len = length in bytes (always 02)

    MsgType = Corresponds to the original message type

    SeqNr = Same as above

    Chksum = 16 bit Xor off all preceding 16 bit words

    MBUS communication

    The MBUS data is transferred with a one pin to both directions. This requires that the outputs must be three-state or open-collector type. Simple measurements with a multimeter show that it is possibly pulled up with a 5 kilo-ohm resistor. This means that the MBUS is an open-collector type pin on the phone.

    In the measurement circuit the FBUS Rx input is connected together with the MBUS. This is not a problem from the electronics, because the FBUS Rx is a high-impedance input (in theory, it could be a problem for the protocols, but it is not that either). The data speed is assumed to be standard 9600 baud.


    Designing Data Cable

    This chapter contains building instructions for NokiaWorld's 8-component FBUS-only adapter based on the idea described in chapter 1. The industry standard MAX232 has been used as the RS 232 buffers. The MAX232 chip is a very common 16-pin that is manufactured by many IC manufactures with different codes.

    This adapter may be used with all Nokia phones with both FBUS and MBUS. The voltage level of the phone is not a problem, so this circuit is useful also with older phones than the Nokia 5110/6110 series. For simplicity, this page uses the pin outs of the Nokia 5100/6100 series GSM phones. You must find out the correct pin numbers of the phone by yourself, if you are going to use another phone model.

    Circuit to connect a Nokia 6110 to PC serial port

    [​IMG]

    The adapter circuit consists of a standard MAX232 design. The interesting part is the power supply, where the positive voltage rectified from the DTR signal is directly used as the V+ of the MAX232. Therefore the other of the internal charge pumps is disabled and the number of capacitors is reduced. [Maxim1997]

    The main goal in this power supply design is to ensure better voltage level on the VCC pin. The V+ is now taken directly from the rectifier and the V- is generated with the internal charge pump of the chip using capacitor C2. The current in VCC pin is then reduced and the voltage there is enough to be in specifications, at least 4,5 volts.



    The pull-up resistor from the basic configuration of an FBUS adapter shown in chapter 1 has been removed, and instead of it the internal 5 kilo-ohm pull-up of the MBUS pin has been used. (The internal pull-up pulls to +3 V, which is not available in the adapter circuit at all!) Although the FBUS data now enters also to the MBUS input, it creates no problems.

    The T2IN input the MAX232 has an internal pull-up of 400 kilo-ohms, so the high impedance state of FBUS Tx is ok.


    Circuit to connect a Nokia 6110 to Microcontroller serial port using the Datacable

    [​IMG]
    Circuit to connect a Nokia 6110 to Microcontroller serial port without the Datacable
    [​IMG]
    To modify the standard layout for direct phone to controller connection, leave out the MAX232, the four 1 µ F capacitors and 100nF capacitor and install three resistors instead, as shown in Fig. The transmit (TXD), receive (RXD) and ground (GND) pins from the on-board D9 connector are then wired to the FBUS_RX, FBUS_TX and L_GND pins of the phone using shielded data cable. The length of this cable should be 550-600mm and the cable shield must be connected to ground.
    C Program for Sending SMS through Microcontroller (AT89C55)
    Code (Text):
    1. #include        <reg55.h>
    2. #include        <string.h>
    3.  
    4. xdata unsigned char TX_Buf[200];
    5. xdata unsigned char Temp[200];
    6. xdata unsigned char SMS_Message[] = "Your Mother My Mother Your Father My Father Your Brother My Brother and Your Wife is EveryBody's ....Hey hope you are enjoying our success!project done!";                                        //Texxt Message
    7. xdata unsigned char SMSC_Number[]        = "919841044446"; //Message center number
    8. xdata unsigned char TX_Phone_Number[]        = "9142957045";        //Receiver number
    9.  
    10. bdata unsigned int                  Flag = 0;
    11. sbit TX_Enable                = Flag ^ 0;
    12. sbit RX_Enable                = Flag ^ 1;
    13. sbit SMS_Handling                = Flag ^ 2;                //0x02
    14. sbit Version                        = Flag ^ 3;        //0xd2
    15. sbit Acknowledge                = Flag ^ 4;        //0x7f
    16. sbit Key_Break                = Flag ^ 5;
    17. sbit Key_Enable                = Flag ^ 6;
    18. sbit Bst                                = Flag ^ 7;
    19. sbit Blt                                = Flag ^ 8;
    20. sbit Data_Enable                = Flag ^ 9;
    21.  
    22. sbit KB_DATA                          = P3^4;
    23.  
    24. unsigned char TX_Len                                = 0;
    25. unsigned char RX_Len                                = 0;
    26. unsigned char TX_Max_Len                        = 0;
    27. unsigned char RX_Max_Len                        = 0;
    28. unsigned char TX_Message_Pack_Len        = 0;
    29. unsigned char TX_Message_Unpack_Len        = 0;
    30. unsigned char RX_Message_Pack_Len        = 0;
    31. unsigned char RX_Message_Unpack_Len        = 0;
    32. unsigned char Sequence_Number                = 0;
    33.  
    34. extern LCD(unsigned char *,unsigned char) reentrant;
    35. extern LCD_Back_Light(bit);
    36.  
    37. void Delay(unsigned int Temp_Delay) reentrant
    38. {
    39.       unsigned char Ver;
    40.       for(;Temp_Delay>0;Temp_Delay--);
    41.       {
    42.               for(Ver=0;Ver<100;Ver++);
    43.       }
    44. }
    45.  
    46. void UARTinit(void)
    47. {
    48.       SCON                = 0x50;
    49.       RCAP2H        = 0xff;
    50.       RCAP2L        = 0xfd;
    51.       T2CON        = 0x34;
    52.       T2MOD        = 0;
    53.       ES                = 1;
    54. }            
    55. void Start_TX(void)
    56. {
    57.       TX_Enable = 1;
    58.       TX_Len = 1;
    59.       SBUF = TX_Buf[0];
    60. }
    61.  
    62. void Phone_Init(void)
    63. {
    64.       unsigned char Ver=0;
    65.       for(Ver = 0;Ver<=127;Ver++)
    66.       {
    67.               TX_Buf[Ver] = 0x55;
    68.       }
    69.       TX_Max_Len = 128;
    70.       Start_TX();
    71.       while(TX_Enable);
    72.       Delay(10000);
    73. }
    74. void LCDinit(void)
    75. {
    76.       LCD("À",0x03);
    77.       LCD("À",0x20);
    78.       LCD("À",0x28);
    79.       LCD("À",0x0c);
    80.       LCD("À",0x01);
    81.       LCD("À",0x80);
    82. }
    83.  
    84. void Wait_Msg()
    85. {
    86.       LCD("À",0x01);
    87.       LCD("À",0x80);
    88.       LCD(" Please Wait... ",0);
    89. }
    90.  
    91. unsigned char SMSC_Pack(unsigned char xdata *Temp1,unsigned char xdata *Temp2)
    92. {
    93.       unsigned char High,Low,Ver1=0,Ver2;
    94.       if(Temp2[Ver1]=='+')
    95.       {
    96.               Temp1[1] = 0x91;
    97.               Ver1++;
    98.       }
    99.       else
    100.               Temp1[1] = 0x91;
    101.       Ver2=2;
    102.       for(;Temp2[Ver1]!=0;)
    103.       {
    104.               Low = Temp2[Ver1]-'0';
    105.               if(Temp2[Ver1+1]!=0)
    106.               {
    107.         High=Temp2[Ver1+1]-'0';
    108.         Ver1=Ver1+2;
    109.       }
    110.       else
    111.       {
    112.         High=15;
    113.         Ver1=Ver1+1;
    114.       }
    115.       Temp1[Ver2]=High*16+Low;              
    116.       Ver2++;
    117.     }
    118.   Temp1[0]=Ver2-1;
    119.   return(Ver2);
    120. }
    121. unsigned char Phone_Number_Pack(unsigned char xdata *Temp1,unsigned char xdata *Temp2)
    122. {
    123.       unsigned char High,Low,Ver1=0,Ver2;
    124.       if(Temp2[Ver1]=='+')
    125.       {
    126.               Temp1[1] = 0x81;
    127.               Ver1++;
    128.       }
    129.       else
    130.       Temp1[1] = 0x81;
    131.       Ver2=2;
    132.       for(;Temp2[Ver1]!=0;)
    133.       {
    134.               Low = Temp2[Ver1] - '0';
    135.               if(Temp2[Ver1+1]!=0)
    136.               {
    137.                       High=Temp2[Ver1+1] - '0';
    138.                 Ver1=Ver1+2;
    139.           }
    140.             else
    141.           {
    142.                 High=15;
    143.                 Ver1=Ver1+1;
    144.             }
    145.     Temp1[Ver2]=High*16+Low;              
    146.     Ver2++;
    147.     }
    148.         Temp1[0]=10;
    149.         return(Ver2);
    150. }
    151.  
    152. unsigned char Message_Pack(unsigned char xdata *Message)
    153. {
    154.       volatile unsigned char i=0,j=0,k=0,l1=0,l2=0;
    155.       j=strlen(Message);
    156.       k=j;
    157.       i=0;
    158.       while(Message[i])
    159.       {
    160.               Temp[j--] = Message[i++];
    161.       }
    162.       j=k;
    163.       for(k=0;k<j;k++)
    164.       {
    165.               for(i=j;i>1;i--)
    166.               {
    167.                       Bst=(Temp[i-1]        &        0x01);
    168.                       if(Bst)
    169.                       Temp[i]=Temp[i]        |        0x80;
    170.               }
    171.       l1++;
    172.       if(l1>8)
    173.       {
    174.             l1=0;
    175.               l2++;
    176.       }
    177.       j--;
    178.           for(i=j;i>0;i--)
    179.               {
    180.                       Temp[i]=Temp[i]>>1;
    181.               }  
    182.               if(j>k)
    183.               k--;
    184.       }
    185.       j=strlen(Message);
    186.       if((j%2)==0)
    187.       l2--;
    188.       if(l1!=0)
    189.       l2++;
    190.       l1=j-l2;
    191.       Temp[l2]='\0';
    192.       i=48;
    193.       while(Temp[j])
    194.       {
    195.                 TX_Buf[i++] = Temp[j--];
    196.       }
    197.       return(l1);
    198. }
    199.  
    200. unsigned char Packet_Sequence_Number()
    201. {
    202.       Sequence_Number++;
    203.       Sequence_Number=Sequence_Number &        0x07;
    204.       return(Sequence_Number        |        0x40);
    205. }
    206.  
    207. void Checksum()
    208. {
    209.       unsigned char Odd,Even,Temp;
    210.       Odd        = TX_Buf[0];
    211.       Even        = TX_Buf[1];
    212.       for(Temp = 2;Temp<=TX_Max_Len-3;Temp=Temp+2)
    213.       {
    214.               Odd        = Odd ^ TX_Buf[Temp];
    215.               Even        = Even ^ TX_Buf[Temp+1];
    216.       }
    217.       TX_Buf[TX_Max_Len-2] = Odd;
    218.       TX_Buf[TX_Max_Len-1] = Even;
    219. }
    220.  
    221.  
    222. void Send_SMS(unsigned char *SMSC_Number,unsigned char *TX_Phone_Number ,unsigned char xdata *Message)
    223. {
    224.       xdata unsigned char Bcd[15];
    225.       unsigned char Temp,Length;
    226.       Phone_Init();
    227.       Delay(10000);
    228.       TX_Buf[0] = 0x1e;
    229.       TX_Buf[1] = 0x00;
    230.       TX_Buf[2] = 0x0c;
    231.       TX_Buf[3] = 0x02;
    232.       TX_Buf[4] = 0x00;
    233.       TX_Buf[5] = 0x59;
    234.       TX_Buf[6] = 0x00;
    235.       TX_Buf[7] = 0x01;
    236.       TX_Buf[8] = 0x00;
    237.       TX_Buf[9] = 0x01;
    238.       TX_Buf[10] = 0x02;
    239.       TX_Buf[11] = 0x00;
    240.       Length = SMSC_Pack(Bcd,SMSC_Number);
    241.       for(Temp = 0;Temp<12;Temp++)
    242.       {
    243.               if(Temp<Length)
    244.                           TX_Buf[Temp+12] = Bcd[Temp];
    245.               else
    246.                           TX_Buf[Temp+12] = 0;
    247.       }
    248.       TX_Buf[24] = 0x15;
    249.       TX_Buf[25] = 0x00;
    250.       TX_Buf[26] = 0x00;
    251.       TX_Buf[27] = 0x00;
    252.       TX_Buf[28] = strlen(Message);
    253.       TX_Message_Unpack_Len=TX_Buf[28];
    254.       Length = Phone_Number_Pack(Bcd,TX_Phone_Number);
    255.       for(Temp = 0;Temp<12;Temp++)
    256.       {
    257.               if(Temp<Length)
    258.                         TX_Buf[Temp+29] = Bcd[Temp];
    259.               else
    260.                           TX_Buf[Temp+29] = 0;
    261.       }
    262.       TX_Buf[41] = 0xa7;
    263.       TX_Buf[42] = 0x00;
    264.       TX_Buf[43] = 0x00;
    265.       TX_Buf[44] = 0x00;
    266.       TX_Buf[45] = 0x00;
    267.       TX_Buf[46] = 0x00;
    268.       TX_Buf[47] = 0x00;
    269.       Length = Message_Pack(Message);
    270.       TX_Message_Pack_Len=Length;
    271.       TX_Buf[48+Length] = 0x01;
    272.       TX_Buf[48+Length+1] = Packet_Sequence_Number();
    273.       TX_Max_Len = 48+Length+1+1+2;
    274.       Temp = 0;
    275.       if(((Length+48+1)%2)==0)
    276.       {
    277.               TX_Max_Len++;
    278.               TX_Buf[Length+48+2] = 0;
    279.                 Temp=1;
    280.       }
    281.       if(Temp==1)
    282.                 TX_Buf[5] = TX_Max_Len-6-3;
    283.       else
    284.                 TX_Buf[5] = TX_Max_Len-6-2;
    285.         Checksum();
    286.         Start_TX();
    287.         while(TX_Enable);
    288.  
    289. }
    290.  
    291. void Serila_IRQ(void) interrupt 4
    292. {
    293.       if(RI==1)
    294.       RI = 0;
    295.       if(TI==1)
    296.       {
    297.               TI = 0;
    298.               if(TX_Len != TX_Max_Len && TX_Enable==1)
    299.                 {
    300.                           SBUF = TX_Buf[TX_Len++];
    301.                   }
    302.                   else
    303.                   TX_Enable = 0;
    304.       }
    305. }
    306.  
    307. void main(void)
    308. {
    309.         unsigned char t;
    310.         Delay(65530);
    311.       LCDinit();
    312.       LCD_Back_Light(0);
    313.       UARTinit();
    314.       EA = 1;
    315.       Wait_Msg();
    316.       for(t = 0;t<=5;t++)
    317.         {
    318.                 Send_SMS(SMSC_Number,TX_Phone_Number,SMS_Message);
    319.           }
    320.         while(1);
    theninthlight likes this.