/* *** T-mobilE Software *** Created by Dr. Tõnis, February 2016 * Commands for the FONA are written by Limor Fried/Ladyada * for Adafruit Industries. * FONA commands are designed specifically to work with the Adafruit FONA ----> http://www.adafruit.com/products/1946 ----> http://www.adafruit.com/products/1963 ----> http://www.adafruit.com/products/2468 ----> http://www.adafruit.com/products/2542 * For more inforamtion about FONA commands one could use * FONAtest sketch. There everything is done through serial. * * The sketch code could be improved. There are several * workarounds that should be improved. Nevertheless, it works, * but the user has to know how to operate the device. */ // ------------------------------------------------------------- // Defining constants int BootTimeLength = 1; // how many seconds the boot screen is shown int KeyValue; // keypad Pad number int ScreenMode = 1; // Mode that is displayed at the start int MessageTime = 1000; // time to show messages on the screen int RingPin = 10; // d10 as the input to registre incoming call int Callout = 0; // Call out notification // Keyboard parameters const int KeyBoardPin = A0; // anlog pin where the keypad is connected String Keys = "0123456789ABCD*#"; // different keys/symbols boolean key_lockout = false; // helps to define one button click at the time // Calling parameters String PhoneNumber ; String PhoneNumberShow; // Measuring voltage at Pin (for the battery level indication): const int sensorPin = A1; // Battery chareg level indicator voltages (will be defined experimentally) const float MaxVolt = 4.5; // Arduino Operating voltage const float BaseVolt = 3.3; // Battery nominal voltage const float EmptyVolt = 3.0; // Voltage when Battery is empty // ------------------------------------------------------------- // NOKIA 5110 LCD library #include #include #include // pin 4 - Serial clock out (SCLK) // pin 5 - Serial data out (DIN) // pin 6 - Data/Command select (D/C) // pin 8 - LCD chip select (CS) // pin 7 - LCD reset (RST) // Adafruit_PCD8544(CLK, DIN, DC, CS(CE), RST); Adafruit_PCD8544 LCD = Adafruit_PCD8544(4, 5, 6, 8, 7); // I2C/TWI library #include // Adafruit Fona library and needed components #include #include "Adafruit_FONA.h" SoftwareSerial fonaSS = SoftwareSerial(3, 2); SoftwareSerial *fonaSerial = &fonaSS; Adafruit_FONA fona = Adafruit_FONA(9); // ------------------------------------------------------------- // ------ SETUP ------ void setup(){ // Send data to the serial port, for debugging only Serial.begin(115200); Serial.println("T-mobilE serial interface"); // LCD NOKIA LCD.begin(); // initialiation done // Set LCD screen contrast for better viewing. Trial and error method! LCD.setContrast(60); // 50-60 works the best (depending on the screen) // Boot start-up sequence LCD.setTextColor(BLACK); BootUpSequence(); // Check if FONA is working (from Adafruit) SIM800LstartCheck(); // define the Ring (call in) inforamtion Pin pinMode(RingPin, INPUT); } // ------------------------------------------------------------- // --- Loop --- void loop(){ // define the text color (black or white possible) LCD.setTextColor(BLACK); // Check if there is a call in if (ScreenMode != 11) { // do prevent delays if (digitalRead(RingPin) == LOW) { // check if it's a call or SMS delay(250); if (digitalRead(RingPin) == LOW) ScreenMode = 11; // else SMSin(); }} // which screen will be shown if (ScreenMode == 1) Phone_Screen(); if (ScreenMode == 11) CallIn_screen(); if (Callout == 1) messages("Calling"); LCD.display(); delay(10); } // ------------------------------------------------------------- // ------ FUNCTIONS ------ // show FONA Status messages void status(const __FlashStringHelper *msg) { LCD.clearDisplay(); // clears the screen and buffer LCD.println(msg); LCD.display();} // show messages void messages(char *msg) { LCD.fillRect(0, 23, 84, 11, BLACK); LCD.setTextColor(WHITE); LCD.setCursor(15, 25); LCD.println(msg); // display a message LCD.display(); delay(MessageTime);} // show the message so long and block everything else // write text void TextToScreen(int x, int y, String msg) { LCD.setCursor(x, y); LCD.println(msg);} // display a message // draw basics for the screen void StandardScreen() { LCD.clearDisplay(); VoltageReference(); KeyValue = getKeypad(); // upper line LCD.drawLine(0, 7, 84, 7, BLACK); // bottom left box LCD.drawRect(0, 36, 24, 12, BLACK); // bottom right box LCD.drawRect(60, 36, 24, 12, BLACK); // bottom middle box 1 LCD.drawRect(24, 36, 36, 10, BLACK); // bottom middle box 2 LCD.fillRect(24, 46, 36, 4, BLACK);} // Phone Screen and its menus void Phone_Screen() { StandardScreen(); // write upper left corner TextToScreen(1, 0, "Tel"); // setCursor(x,y) and "text" // bottom left box TextToScreen(3, 39, "Esc"); // setCursor(x,y) and "text" // bottom right box TextToScreen(67, 39, "OK"); // setCursor(x,y) and "text" // bottom middle box 1 TextToScreen(31, 37, "back"); // setCursor(x,y) and "text" // Type the Phone Number PhoneNumber = TypePhoneNumber(); // write the Phone Number TextToScreen(1, 10, "Nr:"); // setCursor(x,y) and "text" TextToScreen(20, 10, PhoneNumber); // setCursor(x,y) and "text" // Make the call MakeTheCall(); // Hang up if (KeyValue == 10) { fona.hangUp(); Callout = 0; } } // Call in Screen void CallIn_screen() { StandardScreen(); // write upper left corner TextToScreen(1, 0, "Call IN"); // setCursor(x,y) and "text" // bottom left box TextToScreen(3, 39, "NO"); // setCursor(x,y) and "text" // bottom right box TextToScreen(67, 39, "OK"); // setCursor(x,y) and "text" // Write a message messages("RingRing!"); // answer the call if (KeyValue == 11) fona.pickUp(); // Hang up if (KeyValue == 10) { fona.hangUp(); ScreenMode = 1; } } // Get the pressed keyboard button value int getKeypad(){ int KeyValue = -1; boolean reset_lockout = false; int KeyRead = analogRead(KeyBoardPin); // read the analog value int Analog[16] = { // defined from the measurements 511, 526, 550, 570, // 0 1 2 3 600, 623, 655, 682, // 4 5 6 7 717, 750, 797, 831, // 8 9 A B 923, 979, 1000, 1023};// C D * # // Keys = "0123456789ABCD*#"; if(KeyRead <= 375) key_lockout=false; // if analog value too small ignore (no key pressing) else if(!key_lockout){ if (KeyRead > Analog[0]-7 && KeyRead < Analog[0]+7) KeyValue = 0; if (KeyRead > Analog[1]-7 && KeyRead < Analog[1]+7) KeyValue = 1; if (KeyRead > Analog[2]-7 && KeyRead < Analog[2]+7) KeyValue = 2; if (KeyRead > Analog[3]-7 && KeyRead < Analog[3]+7) KeyValue = 3; if (KeyRead > Analog[4]-7 && KeyRead < Analog[4]+7) KeyValue = 4; if (KeyRead > Analog[5]-7 && KeyRead < Analog[5]+7) KeyValue = 5; if (KeyRead > Analog[6]-7 && KeyRead < Analog[6]+7) KeyValue = 6; if (KeyRead > Analog[7]-7 && KeyRead < Analog[7]+7) KeyValue = 7; if (KeyRead > Analog[8]-7 && KeyRead < Analog[8]+7) KeyValue = 8; if (KeyRead > Analog[9]-7 && KeyRead < Analog[9]+7) KeyValue = 9; if (KeyRead > Analog[10]-7 && KeyRead < Analog[10]+7) KeyValue = 10; if (KeyRead > Analog[11]-7 && KeyRead < Analog[11]+7) KeyValue = 11; if (KeyRead > Analog[12]-7 && KeyRead < Analog[12]+7) KeyValue = 12; if (KeyRead > Analog[13]-7 && KeyRead < Analog[13]+7) KeyValue = 13; if (KeyRead > Analog[14]-7 && KeyRead < Analog[14]+7) KeyValue = 14; if (KeyRead > Analog[15]-7 && KeyRead < Analog[15]+7) KeyValue = 15; delay(10); key_lockout = true; } return KeyValue; } // TypePhoneNumber String TypePhoneNumber() { if (KeyValue >= 0 && KeyValue <= 9) PhoneNumber = PhoneNumber + Keys[KeyValue]; //save what the user types if (KeyValue == 12 && PhoneNumber.length() > 0) PhoneNumber.remove(PhoneNumber.length()-1); if (KeyValue == 10 && PhoneNumber.length() > 0) PhoneNumber.remove(0); return PhoneNumber;} // MakeTheCall void MakeTheCall() { if (KeyValue == 11 && PhoneNumber.length() == 0) { // here comes comment when the number is too short, 0 numbers long messages("no number");} if (KeyValue == 11 && PhoneNumber.length() > 0) { // make the call // convert the number into char char number[30]; PhoneNumber.toCharArray(number,30); // write it to the serial Serial.print(F("Calling ")); Serial.println(number); // call the PhoneNumber if (!fona.callPhone(number)) Serial.println(F("Failed")); else Serial.println(F("Sent!")); messages("Calling"); Callout = 1;}} // Boot-up screen void BootUpSequence() { for (int BootTime = BootTimeLength; BootTime > 0; BootTime--) { LCD.clearDisplay(); LCD.setTextSize(2); LCD.setCursor(0, 15); LCD.println("TmobilE"); LCD.setTextSize(1); LCD.setCursor(0, 38); LCD.println("Dr. Tonis"); // show how many seconds will the boot screen shown LCD.drawRect(71, 35, 13, 13, BLACK); LCD.setCursor(75, 38); LCD.println(BootTime); LCD.display(); delay(1000);} } // Check at start up the SIM800 connections void SIM800LstartCheck() { status(F("Checking for FONA...")); // Check FONA is there fonaSS.begin(4800); // 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!"));} // Battery votlage measurements void VoltageReference() { // Read the battery charge percentage from SIM800L // (adds extra lines to the serial and not very convenient) // uncomment the next line // uint16_t VoltPercentage; if (fona.getBattPercent(&VoltPercentage)) // comment the between the // *** // // *** // // Read the value on AnalogIn pin "sensorPin" and store it int SensorVal = analogRead(sensorPin); // Send the 10-bit sensor value out the serial port // Serial.print("sensor Value: "); // Serial.print(SensorVal); // Convert the ADC reading to voltage // We asume "MaxVolt" is the maximum operating voltage float Voltage = (SensorVal / 1024.0) * MaxVolt; // Convert the ADC reading to Percentage. We assume, that // "EmptyVolt" means empty battery voltage (arbitary value) float VoltPercentage = ((SensorVal / 1024.0) * MaxVolt - EmptyVolt) / (BaseVolt - EmptyVolt) * 100; // *** // if (VoltPercentage > 100) VoltPercentage = 100; if (VoltPercentage < 0) VoltPercentage = 0; // Write battery charge as a percentage LCD.setCursor(58, 0); LCD.println((int) VoltPercentage); TextToScreen(77, 0, "%");} // setCursor(x,y) and "text"}