Skip to content

Instantly share code, notes, and snippets.

Created February 16, 2013 03:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save anonymous/4965401 to your computer and use it in GitHub Desktop.
Save anonymous/4965401 to your computer and use it in GitHub Desktop.
Arduino Powered Cellphone
/*
*************************** Brick Cellphone with Sim900 **********************************************
Motorola, Ultra Sleek 9660
Code for replacement motherboard for Motorola, Ultra Sleek 9660,
using ATmega328p and Adafruit 128x32 OLED Screen
Created 19 October 2012
by Andrew D. Farquharson
Some code based off High-Low Tech Cellphone: http://hlt.media.mit.edu/?p=2182
And from the Open Electronics Sim900 library http://www.open-electronics.org/arduino-gsm-shield/
*******************************************************************************************************
*/
#include <Keypad.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_RESET 5
Adafruit_SSD1306 display(OLED_RESET);
const byte rows = 5;
const byte cols = 4;
char keys[rows][cols] = {
{'1','2','3','4'},
{'5','6','7','8'},
{'9','0','*','#'},
{'C','S','R','E'},
{'T','F','L','X'}
};
byte rowPins[rows] = {8, 9, 10, 11, 12};
byte colPins[cols] = {A0, A1, A2 , A3};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );
SoftwareSerial cell(2, 3);
unsigned long cleardisplay = 0;
unsigned long checktext = 0;
unsigned long keytime = 0;
char key;
char text;
char D1;
char D2;
char D3;
char D4;
char D5;
String textMessage;
String number;
String inData;
String DataOut;
String CSQout;
String time;
const int phonepower = 4;
const int Scallpin = 7;
const int textpin = 6;
const int keydelay = 500;
int x = 0, y = 0;
int textmode = 0;
int phonebook = 1;
int readTXT = 1;
int Position;
int endPosition;
int NamePosition;
int displaycall = 0;
int callstop = 0;
int callpin;
int Battery;
int keycount = 0;
int newtext = 0;
int CellConnect = 0;
int boottime = 0;
int dots = 0;
int incall = 0;
int missed = 0;
int CSQint = 0;
//int pin = A7;
//volatile int state = LOW;
void setup(void) {// *********************************************
pinMode(phonepower, OUTPUT);
pinMode(Scallpin, INPUT);
pinMode(textpin, INPUT);
//pinMode(pin, OUTPUT);
// Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("Starting");
display.display();
digitalWrite(phonepower, HIGH); // power on cell chip
delay(1200);
digitalWrite(phonepower, LOW);
display.clearDisplay();
display.setCursor(0,0);
display.print("Connecting");
display.display();
delay(200);
cell.begin(9600); // start cellphone
delay(50);
cell.print("ATZ\r");
delay(150);
// start of cell boot delay * * *
while(CellConnect < 1){ // check and wait for cell network connection
cell.flush();
delay(150);
cell.print("\rAT+CREG?\r");
delay(250);
if (cell.available() > 0) {
inData="";
int h=cell.available();
for (int i=0;i<h;i++){
inData += (char)cell.read();
}
}
delay(500);
Position = inData.indexOf(',') + 1;
endPosition = Position + 1;
inData = inData.substring(Position, endPosition);
delay(100);
if(inData == "1" || inData == "5"){
CellConnect ++;
inData = "";
cell.flush();
}
else {
if(dots > 10){
display.clearDisplay();
display.setCursor(0,0);
display.print("Connecting");
display.display();
delay(200);
dots = 0;
}
display.print(".");
display.display();
dots ++;
inData = "";
delay(1000);
}
}
// end of cell start delay * * *
CSQ(); //get signal quality
gettime(); //get time
display.clearDisplay();
display.setCursor(0,0);
display.print("Connected");
display.display();
delay(1000);
display.clearDisplay();
display.display();
topbar(); // load main display
// cell.print("\rAT+CCLK=\"12/10/22,10:11:00+12\"\r"); //set time
}
void loop()//*****************************************************************************
{
// if (cell.available())
// Serial.write(cell.read());
//if (Serial.available())
// cell.write(Serial.read());
callpin = digitalRead(Scallpin); // check for phone call
if(callpin == 1 && callstop == 0){
cell.flush();
delay(200);
if (cell.available() > 0) {
inData="";
int h=cell.available();
for (int i=0;i<h;i++){
inData += (char)cell.read();
}
}
delay(500);
Position = inData.indexOf(',') + 10;
endPosition = inData.indexOf(',') + 25;
DataOut = inData.substring(Position, endPosition);
callstop = 1;
display.clearDisplay();
topbar();
vdisplay("Call From: \r\n");
vdisplay(DataOut);
delay(50);
inData = "";
}
if(callpin == 0 && callstop == 1 && incall == 0 && missed == 0){ //check for missed call
display.clearDisplay();
topbar();
vdisplay("Missed Call!!!! \r\n");
missed = 1;
}
checktext = digitalRead(textpin); // check for text
if(checktext == 1 && newtext == 0){
vdisplay("New Text \r\n");
newtext = 1;
}
if (((millis () - cleardisplay) > 15000) && callstop == 0) { // reset / clear screen every 15 seconds unelss phone ringing
CSQ();
gettime();
cleardisplay = 1;// clear screen
display.clearDisplay();
topbar();
x = 0;
y = 9;
number = ""; // clear all values no longer needed
textMessage = "";
phonebook = 1;
readTXT = 1;
cleardisplay = millis(); //reset counter
if(newtext == 1){
vdisplay("New Text \r\n");
}
if(missed == 1){
vdisplay("Missed Call!!!! \r\n");
}
}
while (textmode == 1){ //texting mode
textMessageMode();
}
while (textmode == 2){ // read text mode
ReadText();
}
key = keypad.getKey();
if (key == 'E') { // hang up
// buttonpress();
display.clearDisplay();
topbar();
display.setCursor(x,y);
display.display();
vdisplay("hanging up.");
vdisplay("\r\n");
cell.print("ATH\r");
callstop = 0;
incall = 0;
missed = 0;
}
else if (key == 'S') { // dial / answer call
// buttonpress();
if (number.length() > 0) {
x = 0;
y = 8;
display.clearDisplay();
topbar();
display.setCursor(x,y);
display.display();
vdisplay("dialing: ");
vdisplay(number);
vdisplay("\r\n");
cell.print("ATD");
cell.print(number);
cell.print(";\r");
number = "";
}
else {
x = 0;
y = 8;
display.clearDisplay();
topbar();
display.setCursor(x,y);
display.display();
vdisplay("answering.");
vdisplay("\r\n");
cell.print("ATA\r");
incall = 1;
}
}
else if (key == 'T'){
cell.flush(); //********** Phone Book Code ********************
// buttonpress();
delay(10);
cell.print("\rAT+CPBR=");
cell.print(phonebook);
cell.print("\r");
delay(250);
phonebook += 1;
if(phonebook >= 29){
phonebook = 1;
}
if (cell.available() > 0) {
inData="";
int h=cell.available();
for (int i=0;i<h;i++){
inData += (char)cell.read();
}
}
number = "";
Position = inData.indexOf('"') + 1;
endPosition = Position + 10;
number = inData.substring(Position, endPosition);
NamePosition = Position + 17;
DataOut = inData.substring(NamePosition);
DataOut = DataOut.substring(0, DataOut.length() - 9);
x = 0;
y = 9;
display.clearDisplay();
topbar();
display.setCursor(x,y);
display.display();
vdisplay(DataOut);
vdisplay("\r\n");
vdisplay(number);
vdisplay("\r\n");
DataOut = "";
inData=""; //********** Phone Book Code end ********************
}
else if (key == 'R'){
vdisplay("Redialing..."); //****Redial code****
cell.print("ATDL\r"); //***********redial code******
}
else if (key == 'L'){ // start texting/tweeting
textmode = 1;
y = 8;
x = 0;
display.clearDisplay();
topbar();
// buttonpress();
}
else if (key == 'C') { // clear / delete
if (number.length() > 0) {
number = number.substring(0, number.length() - 1);
vdisplay('\b');
// buttonpress();
}
}
else if (key) { // enter number
vdisplay(key);
number += key;
//buttonpress();
}
inData="";
}
//********************************************************************************************************
void vdisplay(char *s) // display settings
{
do {
vdisplay(*s);
} while (*++s);
}
void vdisplay(String s)
{
for (int i = 0; i < s.length(); i++) vdisplay(s[i]);
}
void vdisplay(char c)
{
if (c == '\n') y += 8;
else if (c == '\r') x = 0;
else if (c == '\b') {
if (x > 0) {
x -= 6;
display.clearDisplay();
topbar();
display.setCursor(0,y);
if(textmode >= 1){
display.print(textMessage);
}
else
{
display.print(number);
}
display.display();
}
} else {
display.setCursor(x,y);
display.print(c);
display.display();
cleardisplay = millis();
x += 6;
if (x > 128) {
x = 0;
y += 8;
}
}
if (y > 32 || y < 8) {
x = 0;
y = 8;
display.clearDisplay();
topbar();
display.setCursor(x,y);
display.display();
}
}
void topbar(){ // refresh screen/ update top bar, with signal quality, time, battery %
// battery();
if(textmode == 1){ // topbar for texting
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(0,0);
display.print(" Texting ");
display.setTextColor(WHITE);
display.setCursor(x,y);
display.display();
}
else if(textmode == 2){ //topbar for tweeting
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(0,0);
display.print(" Read Text Messages ");
display.setTextColor(WHITE);
display.setCursor(x,y);
display.display();
}
else // main topbar (with clock, battery and CSQ)
{
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(0,0);
display.print(" ");
display.setCursor(1,0);
display.print(CSQint); // csqout
display.print("%");
display.setCursor(95,0);
display.print(time);
// display.setCursor(100,0);
// display.print(Battery);
// display.print("%");
display.setTextColor(WHITE);
y = 8;
display.display();
}
}
void CSQ(){ //get signal quality
cell.flush();
delay(10);
cell.print("\rAT+CSQ\r");
delay(250);
if (cell.available() > 0) {
inData="";
int h=cell.available();
for (int i=0;i<h;i++){
inData += (char)cell.read();
}
}
delay(500);
Position = inData.indexOf(':') + 1;
endPosition = inData.indexOf(',');
CSQout = inData.substring(Position, endPosition);
cell.flush();
CSQint = CSQout.toInt();
CSQint = map(CSQint, 0, 31, 0, 100); // map signal quality to 0-100% value
}
void battery(){ // get battery level (to be updated)
Battery = 100; // battery %
}
void gettime(){ // get time
cell.flush();
delay(10);
cell.print("\rAT+CCLK?\r");
delay(250);
if (cell.available() > 0) {
inData="";
int h=cell.available();
for (int i=0;i<h;i++){
inData += (char)cell.read();
}
}
delay(500);
Position = inData.indexOf(',') + 1;
endPosition = Position + 5;
time = inData.substring(Position, endPosition);
inData = "";
cell.flush();
}
void textMessageMode(){ //input text (multi-press number pad)
key = keypad.getKey();
if (key == '2'){
D1 = 'a';
D2 = 'b';
D3 = 'c';
D4 = '2';
D5 = '!';
textMessageCode();
}
if (key == '3'){
D1 = 'd';
D2 = 'e';
D3 = 'f';
D4 = '3';
D5 = '?';
textMessageCode();
}
if (key == '4'){
D1 = 'g';
D2 = 'h';
D3 = 'i';
D4 = '4';
D5 = ')';
textMessageCode();
}
if (key == '5'){
D1 = 'j';
D2 = 'k';
D3 = 'l';
D4 = '5';
D5 = '(';
textMessageCode();
}
if (key == '6'){
D1 = 'm';
D2 = 'n';
D3 = 'o';
D4 = '6';
D5 = ':';
textMessageCode();
}
if (key == '7'){
D1 = 'p';
D2 = 'q';
D3 = 'r';
D4 = 's';
D5 = '7';
textMessageCode();
}
if (key == '8'){
D1 = 't';
D2 = 'u';
D3 = 'v';
D4 = '8';
D5 = '8';
textMessageCode();
}
if (key == '9'){
D1 = 'w';
D2 = 'x';
D3 = 'y';
D4 = 'z';
D5 = '9';
textMessageCode();
}
if (key == '0'){
D1 = ' ';
D2 = '@';
D3 = '#';
D4 = '!';
D5 = '0';
textMessageCode();
}
if (key == 'C') {
// buttonpress();
if (textMessage.length() > 0) {
textMessage = textMessage.substring(0, textMessage.length() - 1);
vdisplay('\b');
}
}
if(key == 'S'){
// buttonpress();
display.clearDisplay();
topbar();
x = 0;
y = 8;
vdisplay("\r\nSending Text to:\r\n");
vdisplay(number);
cell.print("\rAT+CMGS=\"");
cell.print(number);
cell.print("\"\r");
delay(1000);
cell.print(textMessage);
cell.print("\x1A\r"); //send <ctrl-Z> at end of message
}
if(key == 'L'){
// buttonpress();
textmode = 2; // cycle to reading mode
number = ""; // clear all values no longer needed
newtext = 0;
textMessage = "";
x = 0;
y = 8;
topbar();
gettext();
}
}
void ReadText(){ //read text loop
key = keypad.getKey();
if (key == '2'){
// buttonpress();
readTXT -= 1; //go up
gettext();
}
if (key == '5'){
// buttonpress();
vdisplay("del all");
cell.print("\rAT+CMGD=1,4\r");
}
if (key == '8'){
// buttonpress();
readTXT += 1; // go down
gettext();
}
if(key == 'L'){
// buttonpress();
readTXT = 1;
textmode = 0; // go back to main screen
number = ""; // clear all values no longer needed
textMessage = "";
topbar();
}
}
void gettext(){
cell.flush(); //********** read text code ********************
delay(10);
cell.print("\rAT+CMGR=");
cell.print(readTXT);
cell.print("\r");
delay(800);
if (cell.available() > 0) {
inData="";
int h=cell.available();
for (int i=0;i<h;i++){
inData += (char)cell.read();
}
}
Position = inData.indexOf('/') + 21;
inData = inData.substring(Position, inData.length()-5);
display.clearDisplay();
topbar();
x = 0;
y = 10;
vdisplay(inData);
DataOut = "";
inData = "";
cell.flush();
//********** text read code end ********************
}
void textMessageCode(){ //input text (multi-press number pad)
// buttonpress();
if ((millis() - keytime) > keydelay){
keycount = 0;
}
keytime = 0;
keycount +=1;
if ((millis() - keytime) > keydelay && keycount == 1){
text = D1;
vdisplay(text);
textMessage += text;
}
else if ((millis() - keytime) > keydelay && keycount == 2){
if (textMessage.length() > 0) {
textMessage = textMessage.substring(0, textMessage.length() - 1);
vdisplay('\b');
}
text = D2;
vdisplay(text);
textMessage += text;
}
else if ((millis() - keytime) > keydelay && keycount == 3){
if (textMessage.length() > 0) {
textMessage = textMessage.substring(0, textMessage.length() - 1);
vdisplay('\b');
}
text = D3;
vdisplay(text);
textMessage += text;
}
else if ((millis() - keytime) > keydelay && keycount == 4){
if (textMessage.length() > 0) {
textMessage = textMessage.substring(0, textMessage.length() - 1);
vdisplay('\b');
}
text = D4;
vdisplay(text);
textMessage += text;
}
else if ((millis() - keytime) > keydelay && keycount == 5){
if (textMessage.length() > 0) {
textMessage = textMessage.substring(0, textMessage.length() - 1);
vdisplay('\b');
}
text = D5;
vdisplay(text);
textMessage += text;
}
else if ((millis() - keytime) > keydelay && keycount == 6){
keycount = 1;
}
keytime = millis();
}
//void buttonpress(){
//state = !state;
//digitalWrite(pin, state);
//}
unsigned long RItime;
int RIstop = 0;
int sms = 0;
int call = 3; // random number higher than two to stop "call" on boot?
int callpin = 6;
int smspin = 5;
int button = 0;
int inbutton = 7;
int state = 0;
int oldstate = 0;
int sound = 0;
void setup()
{
delay(5000);
pinMode(callpin, OUTPUT);
pinMode(smspin, OUTPUT);
pinMode(inbutton, INPUT);
digitalWrite(callpin, LOW);
digitalWrite(smspin, LOW);
delay(5000);
attachInterrupt(0, RI, CHANGE);
}
void loop()
{
if(sms == 1){
//play text tone
digitalWrite(smspin, HIGH);
smsS();
delay(2000);
digitalWrite(smspin, LOW);
sms = 0;
}
if(RIstop == 1 && millis() - RItime > 1200 && call == 1){
call = 2;
RIstop = 0;
}
if(call == 2){
//play ring tone
digitalWrite(callpin, HIGH);
ring();
}
if(call > 2){
call = 0;
digitalWrite(callpin, LOW);
}
}
void RI()
{
if(millis() - RItime < 1200 && RIstop == 1){
RIstop = 0;
sms = 1;
}
else{
RIstop = 1;
RItime = millis();
call ++;
}
}
void ring(){
while(sound <= 25){
tone(9, 1600, 20);
delay(20);
tone(9, 1000, 20);
delay(20);
sound ++;
}
delay(1000);
sound = 0;
}
void smsS(){
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 400);
delay(500);
tone(9, 1700, 400);
delay(600);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
delay(2000);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 400);
delay(500);
tone(9, 1700, 400);
delay(600);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
tone(9, 1700, 100);
delay(200);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment