Posts

Interfacing Arduino to a Cellular Phone

Motorola RAZR talks to Arduino

Motorola RAZR talks to Arduino


One of the main motivations for adding asynchronous CDC support code to rev.2.0 of USB Host Library was to be able to use cell phones in Arduino projects – establish simple data exchange via SMS, take pictures or connect to the Internet. Second hand phones are inexpensive yet quite capable. Also, m2m (machine to machine) SIM cards start at $4-$6/mo, some even allow for free incoming SMS. All that makes a cell phone an attractive communication option for hobby projects. In this post, I will be talking about basics of cell phone control using data port and AT commands. I will also present simple terminal emulator sketch – to use the code you will need an Arduino board, USB Host Shield, as well as USB Host Shield 2.0 library.

Modern (<10 year old) phones have standard gsm chip interface implemented and accessible via so-called "data port". the oldest implement ttl level asynchronous serial by means of "custom" usb data cable, which is just proprietary connector on one end, other usb-to-serial converter (almost always prolific pl2303) between them. newer cell built-in. motorola usually terminate port mini-usb connector, others, like samsung sony ericsson, use cable. in these almost cdc acm type. many functions phone can be accessed at commands, similar to commands used control hayes modems. are defined 3GPP TS 07.07 (look for the latest version, which is 7.8.0). Cell phone manufacturers also define their own AT commands. In documentation AT commands are usually presented in uppercase, however, most phones accept lowercase just as well. A command shall be followed by CR,LF (usually Enter key). If a command is accepted, OK is returned, along with response. If command is not recognized, ERROR is returned. Some commands will be accepted in certain phone states and rejected in others.

There are several variants of invoking each command:

  1. Execute This variant is used for commands which require no parameters. The format is ATcommand. For example, the following command returns power source and battery charge level:

    AT+CBC

    +CBC: 2,66

    OK

    The response means that a phone is powered from external power supply (2) and battery level is 66 percent.

  2. Test This variant is used to query parameters and their values for the command. The format is ATcommand=?.

    AT+CIND=?
    +CIND: ("Voice Mail",(0,1)),("service",(0,1)),("call",(0,1)),("Roam",(0-2)),("signal",(0-5)),("callsetup",(0-3)),("smsfull",(0,1))

    OK

    This command outputs all indicators available on the phone screen, and their possible values.

  3. Get This variant is used to query current settings for the command. The format is ATcommand?.

    AT+CIND?
    +CIND: 0,1,0,0,4,0,0

    OK

    Comparing to output of previous “Test” variant of the same command we can see that “Service” indicator on the phone screen is on and “signal” indicator is at level 4.

  4. Set This variant is used to change settings for the command. The format is ATcommand=param,param....

    AT+CKPD="1"
    OK

    This command simulates a keypress on phone keypad. The key pressed is number “1”.

  5. Unsolicited response is output of some event other than command result. The format is +COMMAND:result. It is the same as command response sans command itself. Take a look at the following example:

    A +CMER command enables or disables sending of unsolicited result codes in the case of key pressings, display changes, and indicator state changes. The parameters for this command are as follows:

    AT+CMER=?
    +CMER: (0,3),(0,1,2),(0),(0,1,2),(0)
    OK

    First parameter sets output mode, next three parameters turn output on or off for keypad, display and indicator. Last parameter controls buffering. On Motorola RAZR, the default state of this command is as follows:

    AT+CMER?
    +CMER: 0,0,0,0,0
    OK

    which means all responses off. Now, if we turn reporting on and set keypad to on:

    AT+CMER=3,1,0,0,0
    OK

    and start pressing buttons on the phone, we will see the following:

    +CKEV: "E",1
    +CKEV: "E",0
    +CKEV: "1",1
    +CKEV: "1",0
    +CKEV: "2",1
    +CKEV: "2",0
    +CKEV: "3",1
    +CKEV: "3",0
    +CKEV: "E",1
    +CKEV: "E",0

    Here, “E” means “Red” button (the one used to turn phone on/off, terminate a call, abort an action and many other things), “1”, “2”, and “3” are numerical buttons, and number after the comma means “press” if 1 and “release” if 0. It is now evident that I first pressed “Red” button to turn screen on, then pressed “123” and then pressed “Red” button again to erase the digits.

The following sketch is a simple terminal program. Only main loop is shown, Full text is available in examples directory on gitHub. Compile it, load, attach your phone to the USB host shield and open the terminal window. If a phone is detected successfully, sketch outputs configuration descriptor and waits for keyboard input.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void loop()
{
    Usb.Task();
 
    if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
    {
       uint8_t rcode;
 
       /* reading the keyboard */
       if(Serial.available()) {
         uint8_t data= Serial.read();
         /* sending to the phone */
         rcode = Acm.SndData(1, &data);
         if (rcode)
            ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
       }//if(Serial.available()...
 
       delay(50);
 
        /* reading the phone */
        /* buffer size must be equal to max.packet size */
        uint8_t buf[32];
        uint16_t rcvd = 32;
        rcode = Acm.RcvData(&rcvd, buf);
         if (rcode && rcode != hrNAK)
            ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
 
            if( rcvd ) { //more than zero bytes received
              for(uint16_t i=0; i < rcvd; i++ ) {
                Serial.print(buf[i]); //printing on the screen
              }
            }
        delay(10);
    }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
}

Lines 10-16 contain sending part of the terminal. Keyboard buffer is checked and if not empty, a character is read and sent to the phone ( line 13, Acm.SndData()). The rest of the loop() is reading the phone and it is a little more complicated.

When USB host sends IN transfer request to the phone, it doesn’t know how much data will be received. It could be one byte or it could be a big packet. That’s why the buffer allocated in line 22 must be equal to the maximum possible chunk of data, i.e. endpoint’s Max.packet size. Most phones have Max.packet size of 32 bytes, one notable exception being Samsung (64 bytes). If you see strange symbols and occasional Arduino resets while outputting large chunks of data, check Max.packet sizes of bulk endpoints and increase buffer size accordingly.

The request is sent in line 24. One important property of Acm.RcvData() function is that it returns actual number of bytes received from endpoint. The loop in lines 28-32 uses rcvd as a loop counter; this way, only part of the buffer filled during the transfer will be printed.

Now let’s start our terminal. Once a terminal session is open, commands can be entered from the keyboard. To check if connection is live, type at and press Enter. If phone is alive, you should see it replying with OK. The next command to try is AT+CLAC. This command outputs all supported commands. Other commands can be tried “by hand”; also, it is possible to get key codes with AT+CMER, as was described earlier.

As cool as it may look, entering commands from the keyboard is not very useful for automation. It is desirable to have functions to call numbers, send and receive SMSes and browse the Internet. Luckily for us, such software has already being developed. There are several GSM shields on the market, and GSM/GPRS modules these shields are based on are almost identical to GSM phones. For example, I was able to follow most part of this tutorial using Motorola RAZR phone. Some commands are different but most work. Many commands described on this page also work. Finally, there is very well written GSM Playground Arduino Library, which can easily be modified to use USB methods to send/receive data to the phone. I’m planning on looking into it after finalizing new USB Host library.

Finally, I want to talk a little about compatibility. I checked this sketch with Motorola RAZR, Motorola V220 and Samsung A-777. Motorola phones work out of the box, Samsung requires changing buffer size. I also tried Sony Ericsson TM-506 and TM-717 – the configuration descriptor in these phones is very complex and the Init() method won’t initialize them correctly. This will be fixed in the future. I’m also curious about other phones – please let me know if your phone worked with this sketch.

Oleg.

225 comments to Interfacing Arduino to a Cellular Phone

  • Just started today looking at remote control over Wi Fi and display remotely of video from a Nokia Phone. I have found readymade software that will send the video over wi fi. Issue now is control path between host computer indoors and the phone and its robot mover outside.

    Thanks for the info great help in seeing what might be possible with different tyoes of hardware.

  • Folks,
    I’m trying to use the acm_terminal sketch to talk to blackberry tour via an arduino with a usb shield. I don’t seem to be able to get the thing to take AT commands.. I think htere’s something wrong with the USB open.. I put in some code to print out the USB state and see I’m getting a USB_ERROR.

    Here’s the add I made to acm_terminal

    int g=0;


    void loop()
    {

    Usb.Task();

    if (Usb.getUsbTaskState() != g) {
    Serial.println(Usb.getUsbTaskState(),HEX);
    g = Usb.getUsbTaskState();
    }

    Here’s the results I get.. :

    Start
    20
    30
    40
    50
    80
    ACM Init
    Addr:1
    NC:1
    A0

    note from usb.h I see

    A0 maps to USB_STATE_ERROR

    Any thoughts ? Thanks !
    -jc

  • john cohn

    Oleg,
    Thanks for the response ! Where do I find ACM::Init() and how would I call it from that sketch ? I see it in cdcacm.cpp but I don’t see any code that calls it.
    -jc

    • It’s called automatically from USB::Task() when it’s time to initialize a device. The purpose of Init() is to recognize a device and plug some data structures into USB system if device is detected successfully. Init() should return zero if successful.

  • john cohn

    I modified Usb.Task() to to return the usb_state..
    looks like it’s HEX A0
    -jc

    • This is correct. Look at Usb.cpp line 480, that’s the place where Task() state machine switches to error state (0xa0). Something happens during Init(), which is called from Configuring() at line 476. You may want to find out how your device’s configuration descriptor looks like.

  • Dimitar

    No Oleg, it works not:(
    I tryed it with Nokia 5500 – it stops in OnInit with SetControlLineState error.

  • Tijmen

    Trying to connect it to a huawei K3765 3G modem but only this who’s up in terminal:

    Start
    ACM Init
    Addr:1
    NC:1

    Any suggestions?

    • tytower

      How you going with this ?

        • Ty Tower

          How is it progressing to connect a 3G Modem to the USB host shield and how is it done is my question

          • Ty Tower

            Hello anybody there?
            Oleg has anybody connected your board to a USB plug in 3G modem ? If so can you give me any references please

          • Which one? Do you have a link to it? I have one bought at Dealextreme, haven’t had time to try it yet but it should be accessible using pl2303 code.

        • Ty Tower

          OK we can keep to and froing as long as you like but I am asking if you have got anywhere with this and if so how ? . If you havn’t then can you be more specific as to what I should do to get it connected?. Your knowledge of these matters is obviously extensive and I have ended up with one of your boards via a deceased estate and I would like to get it running.
          HID programs and others appear to be running properly on your board but nothing connects to the 3G Modem

          • According to this -> http://blog.pew.cc/blog/Huawei+E160+and+Linux/ your device starts in mass storage mode and has to be switched to serial in order to be used as a modem. My drivers were developed for serial devices and won’t work with it.

          • Ty Tower

            Yes OK Thanks .
            modeswitch is the program to run first then to switch to the modem. In fact it has 3 areas(modes) USB mini storage ,another storage internal which shows as a CD and the Modem. So I guess then I must get it to Modem somehow before running your programs . Well that does not seem that hard to do . I’ll work on it.I wonder if your program reads the other two modes.Don’t answer that . I will look and try for myself. Cheers

        • Ty Tower

          I notice it may start in USB storage mode but it connects itself to the network-the blue light flashes rythmically. Whilst in that mode (which is only achievable by supplying additional voltage to the arduino by battery)…the program usb hub gives out the following
          Start

          01

          Device descriptor:

          Descriptor Length: 12

          Descriptor type: 01

          USB version: 0200

          Device class: 00

          Device Subclass: 00

          Device Protocol: 00

          Max.packet size: 40

          Vendor ID: 12D1

          Product ID: 1003

          Revision ID: 0000

          Mfg.string index: 02

          Prod.string index: 01

          Serial number index: 00

          Number of conf.: 01

          Configuration descriptor:

          Total length: 0020

          Num.intf: 01

          Conf.value: 01

          Conf.string: 03

          Attr.: E0

          Max.pwr: FA

          Interface descriptor:

          Intf.number: 00

          Alt.: 00

          Endpoints: 02

          Intf. Class: 08

          Intf. Subclass: 06

          Intf. Protocol: 50

          Intf.string: 00

          Endpoint descriptor:

          Endpoint address: 81

          Attr.: 02

          Max.pkt size: 0040

          Polling interval: 00

          Endpoint descriptor:

          Endpoint address: 01

          Attr.: 02

          Max.pkt size: 0040

          Polling interval: 00

          Addr:1(0.0.1)

          At this point I don’t know exactly what this all means. Maybe you do.

  • john cohn

    Oleg,
    still no luck.. now trying a Samsung SGH-a07 track phone.. I print out the return code from the call to Configuring in usb.cpp (line 476).. I also print the value of rcode in Configuring (about line 576).. It looks like it’s returning a HEX value of D
    or decimal 13. Is that a clue ?

    -jc

    • D means no reply; it usually happens when you send something unexpected to the endpoint like OUT transaction to IN endpoint. The Init() may try to configure it incorrectly. If you can, find old Motorola, like V180, V220, or RAZR – they are guaranteed to initialize correctly. Also, try to connect your phone to a Windows PC and see how it appears in Device Manager.

  • john cohn

    Hmm.. I don’t think i will be bale to find one of those phones.. .. but I’ll look.
    When I try plugging the Samsung track phone into my windos pc it tries to install, but it comes in as an ‘unknown USB device’. I suspect that I need ot find soem drivers for it.. Is that a clue ?
    -jc

    • it could be proprietary device – in this case it won’t work with my code which assumes standard ACM class USB to serial converter. Do you have configuration descriptor of your phone?

  • john cohn

    Oleg.. how would I fetch that ? I’d be happy to send it
    -jc

    • you can use hub_demo sketch, with or without a hub. It will print configuration descriptors of all devices connected to a host.

  • Jeremy

    Simple Question: When the cell phone is connected to the USB Host Shield is it always charging / Will the phone stay charged while connected to the shield?

    • Usually, yes; the charging speed would depend on the amount of current provided to VBUS. Obviously, if current is not sufficient for the phone circuit functioning plus extra for charging, the battery will keep draining.

  • john cohn

    Oleg,
    I just got a V220 and it also does not work.. neither the hub_demo or acm_terminal stretches seem to ‘see’ the phone when I plug it into the usbshield.. I see the message ‘Start’ in the Com terminal and then nothing. I suspect it’s a baud rate issue as I can successfully talk to the phone from hyperterminal from my laptop and it answers AT commands. What should the phones’ baud rate be set at ? Any other ideas why my shield cant talk to this (or any other ) phone so far ? Thanks !
    -jc

    • John,

      Whatever baud rate you have in hyperterm should work. Have you tried to type AT after seeing ‘Start’? I own V220 and it was like the first phone that i tried, it worked with no issues. Now, I don’t understand why hub_demo won’t show anything – have you been able to communicate to _anything_ using USB Host Shield?

      Oleg.

  • john cohn

    Oleg..
    No.. I can’t say I’ve ever successfully talked to anything with this usb shield. Do you think I may have a bad board ? BTW. I’m using a 328-based duemilenueve . I’m also powering it through usb.. (ie no separate power).. could any of that be a problem ? Let me plug in some other USB things and see if I can see them

  • john cohn

    I’m trying other stuff like cameras and not seeing anything in the hub demo.. what do you think that means ?
    -jc

  • john cohn

    it’s from Sparkfun .. no visible serial num.. Here’s the output I get from the device when hooked to my pc and the v220 (same result when I try with my blackberry 9630, a moto droid 2 and a canon powershot camera) . I notice there’s the word ‘failed’ in the GPIO test.. but it says the overall test passed. is this a normal readout ?

    I eventually stop it since the output doesn’t change

    Circuits At Home 2011
    USB Host Shield Quality Control Routine
    Reading REVISION register… Die revision 03
    SPI long test. Transfers 1MB of data. Each dot is 64K……………. SPI long test passed
    GPIO test. Connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, and so on
    Test failed. Value written: 00 Value read: FF
    Press any key to continue…
    GPIO test passed.
    PLL test. 100 chip resets will be performed
    Resetting oscillator
    Reset number 0 Time to stabilize – 689 cycles
    Reset number 1 Time to stabilize – 691 cycles
    Reset number 2 Time to stabilize – 689 cycles
    Reset number 3 Time to stabilize – 691 cycles
    Reset number 4 Time to stabilize – 689 cycles
    Reset number 5 Time to stabilize – 689 cycles
    Reset number 6 Time to stabilize – 691 cycles
    Reset number 7 Time to stabilize – 689 cycles
    Reset number 8 Time to stabilize – 691 cycles
    Reset number 9 Time to stabilize – 689 cycles
    Reset number 10 Time to stabilize – 690 cycles
    Reset number 11 Time to stabilize – 689 cycles
    Reset number 12 Time to stabilize – 691 cycles
    Reset number 13 Time to stabilize – 689 cycles
    Reset number 14 Time to stabilize – 690 cycles
    Reset number 15 Time to stabilize – 689 cycles
    Reset number 16 Time to stabilize – 691 cycles
    Reset number 17 Time to stabilize – 689 cycles
    Reset number 18 Time to stabilize – 691 cycles
    Reset number 19 Time to stabilize – 689 cycles
    Reset number 20 Time to stabilize – 691 cycles
    Reset number 21 Time to stabilize – 689 cycles
    Reset number 22 Time to stabilize – 691 cycles
    Reset number 23 Time to stabilize – 689 cycles
    Reset number 24 Time to stabilize – 691 cycles
    Reset number 25 Time to stabilize – 689 cycles
    Reset number 26 Time to stabilize – 691 cycles
    Reset number 27 Time to stabilize – 689 cycles
    Reset number 28 Time to stabilize – 691 cycles
    Reset number 29 Time to stabilize – 689 cycles
    Reset number 30 Time to stabilize – 689 cycles
    Reset number 31 Time to stabilize – 689 cycles
    Reset number 32 Time to stabilize – 689 cycles
    Reset number 33 Time to stabilize – 689 cycles
    Reset number 34 Time to stabilize – 689 cycles
    Reset number 35 Time to stabilize – 689 cycles
    Reset number 36 Time to stabilize – 689 cycles
    Reset number 37 Time to stabilize – 689 cycles
    Reset number 38 Time to stabilize – 689 cycles
    Reset number 39 Time to stabilize – 689 cycles
    Reset number 40 Time to stabilize – 689 cycles
    Reset number 41 Time to stabilize – 689 cycles
    Reset number 42 Time to stabilize – 689 cycles
    Reset number 43 Time to stabilize – 689 cycles
    Reset number 44 Time to stabilize – 689 cycles
    Reset number 45 Time to stabilize – 689 cycles
    Reset number 46 Time to stabilize – 689 cycles
    Reset number 47 Time to stabilize – 689 cycles
    Reset number 48 Time to stabilize – 689 cycles
    Reset number 49 Time to stabilize – 691 cycles
    Reset number 50 Time to stabilize – 689 cycles
    Reset number 51 Time to stabilize – 691 cycles
    Reset number 52 Time to stabilize – 689 cycles
    Reset number 53 Time to stabilize – 690 cycles
    Reset number 54 Time to stabilize – 689 cycles
    Reset number 55 Time to stabilize – 690 cycles
    Reset number 56 Time to stabilize – 689 cycles
    Reset number 57 Time to stabilize – 690 cycles
    Reset number 58 Time to stabilize – 689 cycles
    Reset number 59 Time to stabilize – 690 cycles
    Reset number 60 Time to stabilize – 689 cycles
    Reset number 61 Time to stabilize – 691 cycles
    Reset number 62 Time to stabilize – 689 cycles
    Reset number 63 Time to stabilize – 691 cycles
    Reset number 64 Time to stabilize – 689 cycles
    Reset number 65 Time to stabilize – 691 cycles
    Reset number 66 Time to stabilize – 689 cycles
    Reset number 67 Time to stabilize – 690 cycles
    Reset number 68 Time to stabilize – 689 cycles
    Reset number 69 Time to stabilize – 691 cycles
    Reset number 70 Time to stabilize – 689 cycles
    Reset number 71 Time to stabilize – 691 cycles
    Reset number 72 Time to stabilize – 689 cycles
    Reset number 73 Time to stabilize – 691 cycles
    Reset number 74 Time to stabilize – 689 cycles
    Reset number 75 Time to stabilize – 691 cycles
    Reset number 76 Time to stabilize – 689 cycles
    Reset number 77 Time to stabilize – 689 cycles
    Reset number 78 Time to stabilize – 689 cycles
    Reset number 79 Time to stabilize – 689 cycles
    Reset number 80 Time to stabilize – 689 cycles
    Reset number 81 Time to stabilize – 689 cycles
    Reset number 82 Time to stabilize – 689 cycles
    Reset number 83 Time to stabilize – 689 cycles
    Reset number 84 Time to stabilize – 689 cycles
    Reset number 85 Time to stabilize – 689 cycles
    Reset number 86 Time to stabilize – 689 cycles
    Reset number 87 Time to stabilize – 689 cycles
    Reset number 88 Time to stabilize – 689 cycles
    Reset number 89 Time to stabilize – 689 cycles
    Reset number 90 Time to stabilize – 689 cycles
    Reset number 91 Time to stabilize – 689 cycles
    Reset number 92 Time to stabilize – 689 cycles
    Reset number 93 Time to stabilize – 689 cycles
    Reset number 94 Time to stabilize – 689 cycles
    Reset number 95 Time to stabilize – 689 cycles
    Reset number 96 Time to stabilize – 691 cycles
    Reset number 97 Time to stabilize – 689 cycles
    Reset number 98 Time to stabilize – 690 cycles
    Reset number 99 Time to stabilize – 689 cycles
    Reset number 100 Time to stabilize – 691 cycles
    Checking USB device communication.

    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …
    Waiting for device …

  • john cohn

    ahhhh.. I though this was your device.. how can I get one of yours ?

  • Steve

    Will this work with a Mifi 2200 as easily as a Razr via USB?

  • Steve

    http://cache.vzw.com/multimedia/mim/mifi_2200/mifi2200.pdf
    It is popular. I am testing AT commands with VZaccess Manager now…

  • Steve

    Can I query it to find out with an AT command?

    • You can find out by looking at what drivers are used in Windows for this device. You’d need ACM, that’s the same driver which is used by Arduino UNO/2560.

  • Steve

    In the device manager I see:
    modem.sys
    nwusbmdm_000.sys
    nwusbser_000.sys

    Does this mean it’s impossible?
    It works from the PC with AT commands.

  • Anders Borg

    Regarding problems with detecting ACM: Can’t it be because phones act as several endpoints: ACM, Mass Storage etc, and the code might “lock on to” the wrong endpoint?

    Just guessing.

    I started experimenting with your example code today, so I’ll check what endpoints it finds.

    Thanks for the library, by the way.

    Anders

  • This is what I get back frÃ¥n an HTC Wildfire by using hub_demo (two interface descriptors with two endpoints each):

    Device descriptor:
    Descriptor Length: 12
    Descriptor type: 01
    USB version: 0200
    Device class: 00
    Device Subclass: 00
    Device Protocol: 00
    Max.packet size: 40
    Vendor ID: 0BB4
    Product ID: 0C8B
    Revision ID: 0226
    Mfg.string index: 01
    Prod.string index: 02
    Serial number index: 03
    Number of conf.: 01

    Configuration descriptor:
    Total length: 0037
    Num.intf: 02
    Conf.value: 01
    Conf.string: 00
    Attr.: C0
    Max.pwr: FA

    Interface descriptor:
    Intf.number: 00
    Alt.: 00
    Endpoints: 02
    Intf. Class: 08
    Intf. Subclass: 06
    Intf. Protocol: 50
    Intf.string: 00

    Endpoint descriptor:
    Endpoint address: 83
    Attr.: 02
    Max.pkt size: 0040
    Polling interval: 00

    Endpoint descriptor:
    Endpoint address: 02
    Attr.: 02
    Max.pkt size: 0040
    Polling interval: 00

    Interface descriptor:
    Intf.number: 01
    Alt.: 00
    Endpoints: 02
    Intf. Class: FF
    Intf. Subclass: 42
    Intf. Protocol: 01
    Intf.string: 07

    Endpoint descriptor:
    Endpoint address: 84
    Attr.: 02
    Max.pkt size: 0040
    Polling interval: 00

    Endpoint descriptor:
    Endpoint address: 03
    Attr.: 02
    Max.pkt size: 0040
    Polling interval: 00

    • The code looks for ACM interface descriptor (the one which has certain class, subclass, protocol combination). You have mass storage on the first interface and vendor-defined class on the second. If you are certain that the second interface is ACM, you can modify the criteria for conf.descriptor parser in Init() – look at cdcacm.cpp line 136.

  • Steve

    You said RAZR…
    Is the RAZR v3m somehow too different?
    In Windows it uses these drivers by default:
    Dmgr Susteen USB Cable
    modem.sys
    sustucam.sys

  • Steve

    hub_demo:
    nothing

    PC terminal:
    no ports show

    But Device Manager / Susteen properties / Diagnostics works!
    Do I need to install a different driver? How?
    Help?

  • Steve

    Thanks for saving me the time I would waste on Sparkfun Host.

  • Steve

    Most of the AT commands respond with ERROR. Do I need a signal to test these? Do I need to upgrade the firmware?

  • Steve

    Figured it out for Verizon RAZR V3m. First AT+MODE=2. Thanks for listening!
    This is not required for your phone?

  • Do you have a list of supported commands already? ‘at+clac’ ?

  • Steve

    at+cfun is not in the at+clac listing. I’ve noticed the phone stays on even when no related sketch is running. Because there is power to the phone in addition to the battery? What if I cut the V+ wire in the USB cable to the phone?

    • If you cut V+ host won’t be able to detect the device. You may try to switch V+ to 3.3V, there is a pair of jumpers on shield’s PCB marked VBUS PWR, open 5V and close 3.3V. If nothing helps, you can pull the battery off the phone and wire a switch to VBUS, for example, a P-type MOSFET.

  • Steve

    I don’t understand how it could help using 3.3v. If it recognizes the connection it will not sleep.

    Yours may be the only solution. Even with the battery in the phone, when you remove the USB power it sleeps, also closing the connection. Will use cheap relay that’s handy.

  • Chris

    Hey Oleg,

    thanks very much for providing your library. I got it running on a Seeeduino Mega ADK using a Huawei E160 UMTS stick. There was only to change the parsing arguments in cdcacm.cpp, remapping the SS pin and pulling the Reset pin of the Max3421 HIGH.
    Now I have access to this modem on AT-level and will try to set up a data connection next.
    While reviewing your code I saw you did a very good job.
    But maybe you can have a look why all Nokia mobile phones (e.g. E51) responding a STALL in setting the linecoding. I read several posts here about this problem.

    Thanky you.

    • It ‘s likely that config descriptor parser picks the wrong interface in Nokias. I have a couple of Sony Ericssons with like 10 different interfaces in the config doing the same. You probably need to change the parser.

    • Peter

      Hello Chris,
      I’m also trying to connect a Huawei UMTS but can’t manage to send AT commands to it (I’m in the very beginning of knowing Arduino and USB Shield).
      Can you specify the values you used in ConfigDescParser (regarding class, subclass and protocol)? Changing the Huawei initialization mode: AT^U2DIAG=0 (device-only modem), it only exposes interface class FF (vendor specific), and the PC recognizes the UMTS modem and able to send AT commands through hyper terminal.
      As specified in Usb.h the SS pin is configured for P10 (Arduino Uno) or P53 (Arduino Mega ADK), you mention that SS pin was remapped… can you tell what was done?
      Thanks in advance.

      @Oleg: fantastic work! Thanks…

  • john cohn

    Oleg..
    OK.. now I shelved my sparkfun usb_host, bought your usb_host. and I’m having a different sort of problem.. When I run the hubdemo I get

    Start
    OSC did not start.

    when I try board_qc I get

    Circuits At Home 2011
    USB Host Shield Quality Control Routine
    Reading REVISION register… Die revision invalid. Value returned: 00
    Unrecoverable error – test halted!!
    0x55 pattern is transmitted via SPI
    Press RESET to restart test

    I’m using your usb_host version 2 code

    any clues ? Thanks !
    -jc

  • john cohn

    Oleg… yes i do.. but I missoldered the 2×3 one and had to remove it to resolder it on the other side (d-oh !) .. I wonder if I damaged it. do you have any simple connectivity info I can check to see if i have an open there .. eg.. where does the ICSP connections go on your board ? (or should I just buy another board)..
    sorry for my stupid mistake !
    -jc

  • john cohn

    Oleg..
    Looks like that did it.. the RST line of the ICSP was not connected. A little yellow wire and I’m back in biz. Can you confirm this QC report looks OK ? The device at the oter end is my Blackberry. I can’t get it to respond to AT commands from the AT_TERMINAL sketch.. but I suspect that’s blackberry weirdness.. I’ll try with my simple moto phone later..

    Does this QC trace look OK ? Note there is a memory write error

    Circuits At Home 2011
    USB Host Shield Quality Control Routine
    Reading REVISION register… Die revision 03
    SPI long test. Transfers 1MB of data. Each dot is 64K……………. SPI long test passed
    GPIO test. Connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, and so on
    Test failed. Value written: 00 Value read: FF
    Press any key to continue…
    GPIO test passed.
    PLL test. 100 chip resets will be performed
    Resetting oscillator
    Reset number 0 Time to stabilize – 690 cycles
    Reset number 1 Time to stabilize – 689 cycles
    Reset number 2 Time to stabilize – 690 cycles
    Reset number 3 Time to stabilize – 689 cycles
    Reset number 4 Time to stabilize – 689 cycles
    Reset number 5 Time to stabilize – 690 cycles
    Reset number 6 Time to stabilize – 688 cycles
    Reset number 7 Time to stabilize – 690 cycles
    Reset number 8 Time to stabilize – 689 cycles
    Reset number 9 Time to stabilize – 690 cycles
    Reset number 10 Time to stabilize – 689 cycles
    Reset number 11 Time to stabilize – 690 cycles
    Reset number 12 Time to stabilize – 689 cycles
    Reset number 13 Time to stabilize – 690 cycles
    Reset number 14 Time to stabilize – 689 cycles
    Reset number 15 Time to stabilize – 690 cycles
    Reset number 16 Time to stabilize – 689 cycles
    Reset number 17 Time to stabilize – 690 cycles
    Reset number 18 Time to stabilize – 689 cycles
    Reset number 19 Time to stabilize – 690 cycles
    Reset number 20 Time to stabilize – 689 cycles
    Reset number 21 Time to stabilize – 690 cycles
    Reset number 22 Time to stabilize – 689 cycles
    Reset number 23 Time to stabilize – 690 cycles
    Reset number 24 Time to stabilize – 689 cycles
    Reset number 25 Time to stabilize – 690 cycles
    Reset number 26 Time to stabilize – 689 cycles
    Reset number 27 Time to stabilize – 690 cycles
    Reset number 28 Time to stabilize – 689 cycles
    Reset number 29 Time to stabilize – 690 cycles
    Reset number 30 Time to stabilize – 689 cycles
    Reset number 31 Time to stabilize – 690 cycles
    Reset number 32 Time to stabilize – 689 cycles
    Reset number 33 Time to stabilize – 690 cycles
    Reset number 34 Time to stabilize – 689 cycles
    Reset number 35 Time to stabilize – 690 cycles
    Reset number 36 Time to stabilize – 689 cycles
    Reset number 37 Time to stabilize – 690 cycles
    Reset number 38 Time to stabilize – 689 cycles
    Reset number 39 Time to stabilize – 689 cycles
    Reset number 40 Time to stabilize – 689 cycles
    Reset number 41 Time to stabilize – 689 cycles
    Reset number 42 Time to stabilize – 689 cycles
    Reset number 43 Time to stabilize – 689 cycles
    Reset number 44 Time to stabilize – 689 cycles
    Reset number 45 Time to stabilize – 689 cycles
    Reset number 46 Time to stabilize – 689 cycles
    Reset number 47 Time to stabilize – 689 cycles
    Reset number 48 Time to stabilize – 689 cycles
    Reset number 49 Time to stabilize – 689 cycles
    Reset number 50 Time to stabilize – 689 cycles
    Reset number 51 Time to stabilize – 689 cycles
    Reset number 52 Time to stabilize – 689 cycles
    Reset number 53 Time to stabilize – 689 cycles
    Reset number 54 Time to stabilize – 689 cycles
    Reset number 55 Time to stabilize – 689 cycles
    Reset number 56 Time to stabilize – 689 cycles
    Reset number 57 Time to stabilize – 689 cycles
    Reset number 58 Time to stabilize – 690 cycles
    Reset number 59 Time to stabilize – 689 cycles
    Reset number 60 Time to stabilize – 690 cycles
    Reset number 61 Time to stabilize – 689 cycles
    Reset number 62 Time to stabilize – 690 cycles
    Reset number 63 Time to stabilize – 689 cycles
    Reset number 64 Time to stabilize – 690 cycles
    Reset number 65 Time to stabilize – 689 cycles
    Reset number 66 Time to stabilize – 690 cycles
    Reset number 67 Time to stabilize – 689 cycles
    Reset number 68 Time to stabilize – 690 cycles
    Reset number 69 Time to stabilize – 689 cycles
    Reset number 70 Time to stabilize – 690 cycles
    Reset number 71 Time to stabilize – 689 cycles
    Reset number 72 Time to stabilize – 690 cycles
    Reset number 73 Time to stabilize – 689 cycles
    Reset number 74 Time to stabilize – 690 cycles
    Reset number 75 Time to stabilize – 689 cycles
    Reset number 76 Time to stabilize – 690 cycles
    Reset number 77 Time to stabilize – 689 cycles
    Reset number 78 Time to stabilize – 690 cycles
    Reset number 79 Time to stabilize – 689 cycles
    Reset number 80 Time to stabilize – 690 cycles
    Reset number 81 Time to stabilize – 689 cycles
    Reset number 82 Time to stabilize – 690 cycles
    Reset number 83 Time to stabilize – 689 cycles
    Reset number 84 Time to stabilize – 690 cycles
    Reset number 85 Time to stabilize – 689 cycles
    Reset number 86 Time to stabilize – 690 cycles
    Reset number 87 Time to stabilize – 689 cycles
    Reset number 88 Time to stabilize – 690 cycles
    Reset number 89 Time to stabilize – 689 cycles
    Reset number 90 Time to stabilize – 689 cycles
    Reset number 91 Time to stabilize – 689 cycles
    Reset number 92 Time to stabilize – 689 cycles
    Reset number 93 Time to stabilize – 689 cycles
    Reset number 94 Time to stabilize – 689 cycles
    Reset number 95 Time to stabilize – 689 cycles
    Reset number 96 Time to stabilize – 689 cycles
    Reset number 97 Time to stabilize – 689 cycles
    Reset number 98 Time to stabilize – 689 cycles
    Reset number 99 Time to stabilize – 689 cycles
    Reset number 100 Time to stabilize – 689 cycles
    Checking USB device communication.

    Device connected. Resetting
    Reset complete. Waiting for the first SOF…
    Getting device descriptor
    Descriptor Length: 12
    Descriptor type: 01
    USB version: 0200
    Device class: 00
    Device Subclass: 00
    Device Protocol: 00
    Max.packet size: 40
    Vendor ID: 0FCA
    Product ID: 8004
    Revision ID: 0211
    Mfg.string index: 01
    Prod.string index: 0F
    Serial number index: 0D
    Number of conf.: 01

    All tests passed. Press RESET to restart test

    • Congratulations, you’ve fixed it! Don’t pay attention to GPIO test failing – in order for it to pass you need to connect GPIN to GPOUT as shown in the output. The rest of the tests passed so your shield is ready to be used.

  • john cohn

    All working well.. getting sms’s on my razr now.. thanks Oleg

  • john cohn

    OK.. now I can do everythign I want using AT commands from the ACM_TERM app. I’m now interested to see if anyone has written a quick arduino sketch to read SMS msgs from the phone and do something with them.. eg. print them on the serial terminal , blink a light, etc .. Just wanted to check before I wrote my own. Know of anything like that ?
    -jc

  • john cohn

    Hmm.. things working well on my Moto V220 .. reading and writing SMS now.. but cannot delete them. the command ‘at+cmgl’ fetches all SMS but.. ‘at+cgmd’ throws an error.. Is there some other way to delete read msgs ?
    -jc

  • Christo

    Hi hope someone can be of guidance.

    I just got my usb host shield, I am wondering if someone has ever tried to use a bluetooth dongle connected to it and communicate with a mobile phone (through bluetooth of course)?

    I would like to use mobile processing. Or is it easier to use a bluetooth module (instead of usb host shield) to achieve communication with my phone? Would be great if someone knows of a blog or source code to get me started. thanks

  • john cohn

    Oleg…
    Sorry.. I mistyped.. I’m using at+cmgd=1 and get ERROR. I get the same thing when I use AT+cmgd=? If I turn on the diagnostics and look at return code (4) .. it means ‘not supported’. Some other commands like ‘at+cmgl’ work .. but others like ‘at+cmgr’ do not. Ever seen that ?
    -jc

    • Here’s what I have on Motorola V220:

      at+cmgl
      ...

      ...
      +CMGL: 1708, "STO SENT", "17205607054"
      I can come but abit late.
      OK
      at+cmgd=1708
      OK

      next at+cmgl won’t show this message. You need to pass index of a message to cmgd. If you pass non-existing index, cmgd returns error (as well as at+cmgd?, at+cmgd=?)

      cmgr (read) should be similar, you need message index. On some phones, there are several message storages, you’ll have to switch to correct storage first.

  • Bernie

    Am trying to use Arduino Uno to connect to a phone so that it can send an sms. The project in totality is a robot that can detect a fire then notify the person in charge via a preset i.d. Am using a tone decoder to sense the fire alarm. Any help??

  • Brent

    I have the USB shield connected to a Motorola RAZR and have been successful in using several of the AT commands in the serial terminal. I wrote some code for the Arduino for commands to be executed via the Serial.println when I push a button. The commands come up in the terminal window but they don’t reach the phone. I am still pretty new to writing code and I could not figure out how to actually send the commands to the phone through the USB Shield. I think I might be missing something with a CR and LF.
    Ultimately I want to send a text or photo based off a motion trigger.

  • Brent

    I can’t seem to get the Acm,SndData() function in the right spot to get the code to compile. I only see it in the code you wrote here. Do I need to do something with the “rcode”?

    /* reading the keyboard */
    if(Serial.available()) {
    uint8_t data= Serial.read();
    /* sending to the phone */
    rcode = Acm.SndData(1, &data);
    if (rcode)
    ErrorMessage(PSTR(“SndData”), rcode);
    }//if(Serial.available()…

    I would like to send Acm.SndData(“AT+CKPD”1””); when I press the momentary switch so it tells the phone to that I am pressing #1. Once I can get this figured out I am sure that I can write the code to press all the right buttons to have the camera take a photo and send it to me.

    • You need to do something like that:

      const char* ckpd_one_cmd = "AT+CKPD=1,0,0";
      rcode = Acm.SndData( strlen( ckpd_one_cmd ), (uint8_t *)ckpd_one_cmd );

  • Brent

    Have tried several different ways to get this code to compile, I keep getting these errors

    Cell_phone_control_2:24: error: expected constructor, destructor, or type conversion before ‘=’ token
    Cell_phone_control_2:32: error: ‘ACMAsyncOper’ has not been declared
    Cell_phone_control_2:60: error: ‘ACMAsyncOper’ does not name a type
    Cell_phone_control_2:61: error: ‘AsyncOper’ was not declared in this scope
    Cell_phone_control_2.cpp: In function ‘void loop()’:
    Cell_phone_control_2:122: error: expected primary-expression before ‘)’ token
    Cell_phone_control_2:122: error: expected `;’ before ‘)’ token
    looking for a constructor


    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #include

    #include
    #include
    #include
    #include

    #include "pgmstrings.h"

    #define BUTTON 7// here is the button that I put in
    int val =0;
    int old_val = 0;
    int state = 0;

    const char* ckpd_one_cmd = "AT+CKPD=1,0,0";
    rcode = Acm.SndData( strlen( ckpd_one_cmd ), (uint8_t *)ckpd_one_cmd );

    class ACMAsyncOper : public CDCAsyncOper
    {
    public:
    virtual uint8_t OnInit(ACM *pacm);
    };

    uint8_t ACMAsyncOper::OnInit(ACM *pacm)
    {
    uint8_t rcode;
    // Set DTR = 1 RTS=1
    rcode = pacm->SetControlLineState(3);

    if (rcode)
    {
    ErrorMessage(PSTR("SetControlLineState"), rcode);
    return rcode;
    }

    LINE_CODING lc;
    lc.dwDTERate = 115200;
    lc.bCharFormat = 0;
    lc.bParityType = 0;
    lc.bDataBits = 8;

    rcode = pacm->SetLineCoding(&lc);

    if (rcode)
    ErrorMessage(PSTR("SetLineCoding"), rcode);

    return rcode;
    }

    USB Usb;
    //USBHub Hub(&Usb);
    ACMAsyncOper AsyncOper;
    ACM Acm(&Usb, &AsyncOper);

    void setup()
    {
    Serial.begin( 115200 );
    Serial.println("Start");

    if (Usb.Init() == -1)
    Serial.println("OSCOKIRQ failed to assert");

    delay( 200 );
    pinMode(BUTTON, INPUT);
    }

    void loop()
    {
    Usb.Task();

    if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
    {
    uint8_t rcode;

    /* reading the keyboard */
    if(Serial.available()) {
    uint8_t data= Serial.read();
    /* sending to the phone */
    rcode = Acm.SndData(1, &data);
    if (rcode)
    ErrorMessage(PSTR("SndData"), rcode);
    }//if(Serial.available()...

    delay(50);

    /* reading the phone */
    /* buffer size must be greater or equal to max.packet size */
    /* it it set to 64 (largest possible max.packet size) here, can be tuned down
    for particular endpoint */
    uint8_t buf[64];
    uint16_t rcvd = 64;
    rcode = Acm.RcvData(&rcvd, buf);
    if (rcode && rcode != hrNAK)
    ErrorMessage(PSTR("Ret"), rcode);

    if( rcvd ) { //more than zero bytes received
    for(uint16_t i=0; i < rcvd; i++ ) {
    Serial.print(buf[i]); //printing on the screen
    }
    }
    delay(10);
    }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..

    { val = digitalRead(BUTTON);
    if ((val == HIGH) && (old_val == LOW))
    {
    state = 1;
    }
    else
    {
    state = 0;
    }
    if (state == 1) { ); // Here is where I press the button
    }
    }
    }

  • April Steel

    Always the replies are vague . Never a direct answer .Read all the rest of his blogs . He wishes to feel important by making everyone chase him for answers. It is pointless to set up such a site and then avoid direct answers .
    What does he gain by this ?
    Notoriety?

  • Mark

    oleg, i am working on a project where I can control a cell phone solely from the arduino using AT commands. I was wondering if you could give me a simple sample code of how to send an AT command to the phone. From the sample sketches i looked through it seems like Acm.SndData is a command to send data to the phone. Is this correct? If i wanted to send an AT command, what would the arduino sketch look like?

  • Mark

    i am just unsure of the syntax of the acm.senddata fxn and what it returns

  • Mark

    also, if im reading all of this correctly, in order for the usb shield to communicate with the cell phone it first needs to recognize the phone? You can’t just simply write a sketch that has the acm.senddata command and expect the phone to respond, correct?

    • ACM::Init() detects the device, not necessarily the phone. For example, it will also recognize 16U2-based USB-to-serial converter used in newer Arduinos. Init() is called from Usb, you don’t need to worry about it, just declare an instance of ACM class in your sketch, like I do. I also suggest studying the source code of ACM class -> https://github.com/felis/USB_Host_Shield_2.0/blob/master/cdcacm.cpp, you will find answer to your previous question there as well.

    • Scotty

      Mark, have you been able to get this to work? In Oleg’s reply to you he states “Just replace strings that I send with strings you need to send.” I’ve tried replacing ‘data’ in the line rcode = Acm.SndData(1, &data); with various characters, strings, decimal numbers to no avail. I am getting error messages that ultiamtely reflect to uint8_t ACM::SndData(uint16_t nbytes, uint8_t *dataptr)in the ACM class. Have you had any success? – Scotty

      • Scotty

        Mark, Oleg, this is the code that worked for me. :

        #include
        #include
        #include “pgmstrings.h”

        // Satisfy IDE, which only needs to see the include statment in the ino.
        #ifdef dobogusinclude
        #include
        #endif

        class ACMAsyncOper :
        public CDCAsyncOper
        {
        public:
        virtual uint8_t OnInit(ACM *pacm);
        };

        uint8_t ACMAsyncOper::OnInit(ACM *pacm)
        {
        uint8_t rcode;
        // Set DTR = 1 RTS=1
        rcode = pacm->SetControlLineState(3);

        if (rcode)
        {
        ErrorMessage(PSTR(“SetControlLineState”), rcode);
        return rcode;
        }

        LINE_CODING lc;
        lc.dwDTERate = 115200;
        lc.bCharFormat = 0;
        lc.bParityType = 0;
        lc.bDataBits = 8;

        rcode = pacm->SetLineCoding(&lc);

        if (rcode)
        ErrorMessage(PSTR(“SetLineCoding”), rcode);

        return rcode;
        }

        USB Usb;
        //USBHub Hub(&Usb);
        ACMAsyncOper AsyncOper;
        ACM Acm(&Usb, &AsyncOper);

        boolean done = false; //flag to ensure message only sent once
        uint8_t rcode;
        char mode[] = “AT+CMGF=1\r”;//used to put phone into text mode
        int modelen = strlen(mode);
        char phone[] = “AT+CMGS=\”+16105551212\”\r”; //phone number to text to
        int phonelen = strlen(phone);
        char message[] = “From Razr!”; //message to be sent
        int messagelen = strlen(message);
        byte ctrlz = 26; //send message

        void setup()
        {
        Serial.begin( 115200 );
        while (!Serial); // Wait for serial port to connect – used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
        Serial.println(“Start”);

        if (Usb.Init() == -1)
        Serial.println(“OSCOKIRQ failed to assert”);
        delay( 200 );
        }

        void loop()
        {
        Usb.Task();

        if( Acm.isReady()) {
        //uint8_t rcode;

        /* sending to the phone */
        if (done==false){//if true, prevents multiple messages from being sent

        Mode_Setup();//used to put phone into text mode
        delay(100);
        Read_Function();
        delay(100);
        Enter_Number(); //used to enter phone number to be texted to
        delay(100);
        Read_Function();
        delay(100);
        Message(); // used to enter message to be sent
        delay(100);
        Read_Function();
        delay(100);
        Send_Ctrlz(); //used to signal ‘send message’
        delay(100);
        Read_Function();
        delay(100);
        }

        if (rcode)
        ErrorMessage(PSTR(“SndData”), rcode);

        done = true;
        }
        delay(50);

        }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..

        int Mode_Setup(){
        for (int i = 0; i < modelen; i++){
        uint8_t data = mode[i];
        rcode = Acm.SndData(1, &data);
        }
        //Serial.println(" Mode Setup Complete");
        }

        int Enter_Number(){
        for (int i = 0; i < phonelen; i++){
        uint8_t data = phone[i];
        rcode = Acm.SndData(1, &data);
        delay(50);
        }
        //Serial.println(" Enter Number Complete");
        }

        int Message(){
        for (int i = 0; i < messagelen; i++){
        uint8_t data = message[i];
        rcode = Acm.SndData(1, &data);
        }
        //Serial.println(" Send Message Complete");
        }

        int Send_Ctrlz(){
        uint8_t data = ctrlz;
        rcode = Acm.SndData(1, &data);
        //Serial.println(" Send Ctrlz Complete");
        }

        int Read_Function(){
        /* reading the phone */
        /* buffer size must be greater or equal to max.packet size */
        /* it it set to 64 (largest possible max.packet size) here, can be tuned down
        for particular endpoint */
        //Serial.println ("In Read Function");
        uint8_t buf[64];
        uint16_t rcvd = 64;
        rcode = Acm.RcvData(&rcvd, buf);
        if (rcode && rcode != hrNAK)
        ErrorMessage(PSTR(“Ret”), rcode);

        if( rcvd ) { //more than zero bytes received
        for(uint16_t i=0; i < rcvd; i++ ) {
        Serial.print((char)buf[i]); //printing on the screen
        }
        }
        delay(10);
        }

  • mark

    Thanks for the help

  • Joe

    to send AT commands to a cell phone, could you not just use the SPI interface and library provided on the arduino website?

  • taz

    good day ..
    can i ask a question ..as what I’ve seen ..theirs two usb cable ,black and white,I wonder where’s the black cable goes..then does mean.
    looking forward for your response..

    taz

  • taz

    good day to all..
    .. this article is very interesting ..can I ask for a question..
    as what i’ve seen there are two usb cable wire.white and black..
    I wonder were the black cable goes.??..and what is its function

    looking forward for your respond..
    thank u