# Arduin-o-Phone

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/025/593/medium800thumb/adafruit_products_PhoneaDemoGIF.jpg?1448318173)

Apple, Schmapple! Make your _own_ phone with an Arduino & Adafruit FONA shield. This project will show you how you can use the FONA shield and a TFT shield stacked on top to make a touch-screen phone that you can program yourself.

![](https://cdn-learn.adafruit.com/assets/assets/000/025/583/medium800/adafruit_products_Phone_tutorial_iso_assembled_ORIG.jpg?1432145735)

Using Adafruit's great libraries, you can make your own touch-screen dialer in 200 lines of code. Extend it yourself, or keep it simple. Design your own interface or code up a custom app, right from the Arduino IDE

OK sure, you can't check your facebook on the Arduin-o-Phone, but maybe that's not such a bad idea?

![](https://cdn-learn.adafruit.com/assets/assets/000/025/584/medium800/adafruit_products_Phone_tutorial_top_ORIG.jpg?1432145756)

# Arduin-o-Phone

## Parts and Prep

![](https://cdn-learn.adafruit.com/assets/assets/000/025/594/medium800/adafruit_products_Phone_tutorial_top_ORIG.jpg?1432157445)

This project doesn't need a ton of parts, and there's some flexibility based on whether you want to use a headset or speaker&mic.

Start off with the basics:

- [Adafruit FONA 800 shield](https://www.adafruit.com/product/2468)
- [Adafruit TFT Shield w/Resistive touch](https://www.adafruit.com/product/1651)
- [Stacking headers](https://www.adafruit.com/product/85)
- [GSM SIM card - we suggest a TING SIM](http://www.adafruit.com/product/2505), they're a great mobile provider
- [1200mAh LiPoly Battery](https://www.adafruit.com/products/258), or&nbsp;[you could use a 500mAh](https://www.adafruit.com/product/1578) but 1200 is recommended.
- [GSM Antenna, this uFL sticker-type is quite nice](http://www.adafruit.com/product/1991)
- Arduino UNO ([we later changed our prototype to a Metro so that there was space in the 'shield sandwich' for the lipoly battery](https://www.adafruit.com/product/2466))

Then you can either go with speaker + mic for 'hold it up and talk' style

- [Wired electret microphone](https://www.adafruit.com/product/1064)
- [Small metal speaker](https://www.adafruit.com/product/1890)

or

- [A plug-in headset](http://www.adafruit.com/product/1966)

You'll also need a microUSB cable, soldering iron and solder, and possibly some wire or other basic electronic components!

# Learn all about it!

Before you put together the Arduin-o-Phone you'll want to read up a bunch and be familiar with the:

- [Arduino and Arduino IDE](../../../../category/learn-arduino)
- [2.8" TFT Shield](../../../../adafruit-2-8-tft-touch-shield-v2)&nbsp;- make sure you get this working nicely first
- [FONA 800 Shield](../../../../adafruit-fona-800-shield/overview)&nbsp;- **solder this one up with the stacking headers so you can stack the TFT shield on top!** Then go through the example and make sure you have it working first

![](https://cdn-learn.adafruit.com/assets/assets/000/025/581/medium800/adafruit_products_2468_iso_demo_ORIG.jpg?1432144624)

# Wire & Test FONA shield

OK now you're ready to put it together. Most of the soldering happens on the FONA shield. Don't forget to solder it with stacking headers!

- Attach the Mini Metal Speaker to the **SPKR** pins by soldering the + wire to the + pad, and same with the - wire
- Attach the Wired Electret Microphone to the **MIC** pins by soldering the red wire to + and black wire to -
- Solder the Vibrating Motor Disc to the **Buzzer** pins by soldering the red wire to the + pad, and the black wire to -
- Plug the Lipoly battery into the JST connector, and switch the slide switch to **CHRG**
- Insert the SIM card
- Carefully plug the GSM antenna into the uFL connector, it should snap on nicely
- Plug the shield onto the Arduino and connect the Arduino to your computer

&nbsp;OK now go through the FONA test to make sure your FONA can get onto the cellular network, make phone calls, etc:

[Go through the Arduino FONA shield test](https://learn.adafruit.com/adafruit-fona-800-shield/arduino-test)
# Test TFT Shield
![](https://cdn-learn.adafruit.com/assets/assets/000/025/582/medium800/adafruit_products_1651-00.jpg?1432144807)

Once that works, plug the 2.8" TFT shield on top and run the touch-paint tutorial to make sure you've got the display and touch capability working

[Go through 2.8" TFT Shield tutorial](https://learn.adafruit.com/adafruit-2-dot-8-color-tft-touchscreen-breakout-v2)
All working? OK,&nbsp;_now_ you can go to the next step

# Arduin-o-Phone

## Arduin-o-Phone Sketch

![](https://cdn-learn.adafruit.com/assets/assets/000/025/595/medium800/adafruit_products_Phone_tutorial_top_hand_demo_ORIG.jpg?1432157466)

Now you're ready to upload the Arduin-o-phone sketch. [Visit the github repository](https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/master/Arduino_Phone)for the full code history and details, or simply download by clicking this link:

[Download Arduin-o-Phone sketch](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/master/Arduino_Phone/Arduino_Phone/Arduino_Phone.ino)
https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Arduino_Phone/Arduino_Phone/Arduino_Phone.ino

# A tour of the code

The sketch will likely get updated with more capability but here's a tour of the code for the initial commit

## Setup code

In the **setup()** code we start by initializing the screen first, before the FONA, so that we can display the status updates

```auto
void setup() {
  Serial.begin(9600);
  Serial.println("Arduin-o-Phone!"); 
  
  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");
```

We then create 15 buttons using the Adafruit\_GFX\_Button helper. These make nice rounded rectangle buttons with the text centered. The buttons don't have any sort of touch 'knowledge' but its handy to have a shortcut to drawing a button!

We use the BUTTON\_X, \_Y, \_SPACING #defines we made to define the size of the buttons and the spacing.

```auto
  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X), 
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE); 
      buttons[col + row*3].drawButton();
    }
  }
```

This just draws the 'outline' of the number text field

```auto
    // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
```

Now that the screen is drawn, we can check on the FONA, resetting it and turning on the external audio port. We print the _status_ of the FONA module code to a little bar of text under the number textfield, using the **status()** helper function

```auto
  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  
  status(F("Checking for FONA..."));
  // Check FONA is there
  fonaSS.begin(4800); // if you're using software serial

  // See if the FONA is responding
  if (! fona.begin(fonaSS)) {
    status(F("Couldn't find FONA :("));
    while (1);
  }
  status(F("FONA is OK!"));
  
  // Check we connect to the network
  while (fona.getNetworkStatus() != 1) {
    status(F("Looking for service..."));
    delay(100);
  }
  status(F("Connected to network!"));
 
  // set to external mic & headphone
  fona.setAudio(FONA_EXTAUDIO);
```

With that, the Arduin-o-Phone is set up

## The main Loop()

Now we can perform a user-interface loop, where we check for button presses and respond

We start by checking for touch presses on the screen, and scaling the presses so they align with the 240x320 size of the display

```auto
void loop(void) {
  TS_Point p;
  
  if (ts.bufferSize()) {
    p = ts.getPoint(); 
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }
  
  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", "); 
    Serial.print(p.y); Serial.print(", "); 
    Serial.print(p.z); Serial.println(") ");
  }
```

next, we can use that press location to ask the buttons if that point is inside the bounds of the outline, if so we tell the button it is being pressed

```auto
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }
```

The Adafruit\_GFX\_Button object keeps track of whether it was _just_ pressed or _just_ released which is handy so we can only perform an action when it is first pressed or released. For example, if it was just pressed, redraw it so its 'inverted' colors, easy to tell it was pressed

```auto
  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }
    
    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!
```

Now we can perform actions based on the presses. If its button #3-15, its one of the number or \* # buttons, we can add that to the text field array

```auto
// if a numberpad button, append the relevant # to the textfield
        if (b >= 3) {
          if (textfield_i < TEXT_LEN) {
            textfield[textfield_i] = buttonlabels[b][0];
            textfield_i++;
	        textfield[textfield_i] = 0; // zero terminate
          }
        }
```

In case we make a typo, the **CLR** button will let you delete a character

```auto
        // clr button! delete char
        if (b == 1) {
          
          textfield[textfield_i] = 0;
          if (textfield > 0) {
            textfield_i--;
            textfield[textfield_i] = ' ';
          }
        }

```

Now that those buttons are taken care of, we should redraw the text field, because it may have more or fewer characters

```auto
        // update the current text field
        Serial.println(textfield);
        tft.setCursor(TEXT_X + 2, TEXT_Y+10);
        tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
        tft.setTextSize(TEXT_TSIZE);
        tft.print(textfield);
```

Button #2 is **END** and you can always just tell the FONA to hang up

```auto
        // its always OK to just hang up
        if (b == 2) {
          status(F("Hanging up"));
          fona.hangUp();
        }
```

Button #0 is **SEND** so you can tell the FONA to call whatever is in that text field

```auto
        // we dont really check that the text field makes sense
        // just try to call
        if (b == 0) {
          status(F("Calling"));
          Serial.print("Calling "); Serial.print(textfield);
          
          fona.callPhone(textfield);
        }
```

Finally, we have a delay here to keep the UI button pressing handling from being too 'fast'

```auto
      delay(100); // UI debouncing
    }
  }
}
```


## Related Guides

- [Adafruit 2.8" TFT Touch Shield v2 - Capacitive or Resistive](https://learn.adafruit.com/adafruit-2-8-tft-touch-shield-v2.md)
- [Crickit Powered Mini Chair Swing Ride!](https://learn.adafruit.com/mini-chair-swing-ride.md)
- [Twin Peaks Light Reactive Picture Frame](https://learn.adafruit.com/twin-peaks-light-reactive-pyportal-picture-frame.md)
- [MIT Green Building NeoPixel Tetris](https://learn.adafruit.com/tetris-building.md)
- [Textable Sensor with FONA and CircuitPython](https://learn.adafruit.com/textable-sensor-with-fona-and-circuitpython.md)
- [The Scream: Interactive Screaming Painting](https://learn.adafruit.com/the-scream-munch-screaming-interactive-scream-painting.md)
- [How to Choose a Microcontroller](https://learn.adafruit.com/how-to-choose-a-microcontroller.md)
- [BLE Buzzy Box](https://learn.adafruit.com/ble-buzzy-box.md)
- [SpaceX Helmet](https://learn.adafruit.com/spacex-helmet.md)
- [CircuitPython BLE Heart Rate Zone Trainer Display](https://learn.adafruit.com/circuitpython-ble-heart-rate-monitor-gizmo.md)
- [Adafruit OV7670 Camera Library For SAMD51 Processors](https://learn.adafruit.com/adafruit-ov7670-camera-library-samd51.md)
- [Low-Tech Buzzing Operation Game](https://learn.adafruit.com/low-tech-operation-game.md)
- [Garmin Lidar Lite Range Finder](https://learn.adafruit.com/garmin-lidar-lite-range-finder.md)
- [Robotic AI Bear using ChatGPT](https://learn.adafruit.com/robotic-ai-bear-using-chatgpt.md)
- [BLE Vibration Bracelet](https://learn.adafruit.com/ble-vibration-bracelet.md)
- [Thanksgiving Robotic Turkey Hand with Circuit Playground Express and Crickit](https://learn.adafruit.com/talking-turkey-hand.md)
