Created
February 16, 2013 03:28
-
-
Save anonymous/4965401 to your computer and use it in GitHub Desktop.
Arduino Powered Cellphone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
*************************** 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); | |
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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