0

Rotary cellphone with FONA 3G issue
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Rotary cellphone with FONA 3G issue

by ajkatz83 on Fri Aug 28, 2020 6:14 pm

Hello:

I am not sure where else to go here. I was on the skysedge.us where this project is located, but is using a FONA 3G to make and receive calls, and so far for me it has been confusing.

At the moment I do have service with AT&T, yes I am able to receive calls on the FONA, but when it comes to making an answering, that doesn't work at all! I am starting to believe that the FONA 3G I have has a defect to it, seeing I cannot see software wise what the problem is

Code: Select all | TOGGLE FULL SIZE
/***************************************************
Rotary cellphone original firmware written by Justine Haupt.
MIT license, all text above must be included in any redistribution.

1/12/2020: v1.0
1/13/2020: v1.1
1/18/2020: v1.1.1

  Cellphone program for ATMega2560-based board controlling the Adafruit FONA v1. Adafruit libraries are not used for the FONA
  but this does use the Adafruit 2.13" Tri-Color E-Ink display with the associated libraries. The license from Lady Ada for
  that part of the program is as follows:

    ***************************************************
    Adafruit invests time and resources providing this open source code,
    please support Adafruit and open-source hardware by purchasing
    products from Adafruit!
    Written by Limor Fried/Ladyada for Adafruit Industries.
    MIT license, all text above must be included in any redistribution
   ****************************************************

NOTES:
Regarding references to "ModeSwitch_631". The mode switch is a SP3T switch which changes the operating mode of the phone. The primary mode, as listed in this code,
is "631", which is my area code. In this mode, 631 is prepended automatically to any 7-digit numbers dialed. All instances of this must be changed to your preferred
area code. The other two modes are "NP" and "Alt". NP stands for "no prepend", to enter full 10-digit numbers, and "Alt" is the alternate mode. To minimize the total
number of switches, the function of the bottom four buttons on the phone changes depending on the position of the mode switch.

Arduino IDE needs board support for 2560V. For this, add "MegaCore" board configuration from here: https://github.com/MCUdude/MegaCore
Also add the Adafruit EOD and the GxEPD2 libraries, which can be added from within the Arduino IDE by going to tools > Manage Libraries...

Use an AVR-ISP-MK2 to flash firmware. This is much easier than dealing with the USB port for programming. Just plug the programmer into the ICSP
header and use "Ctrl+Shift+U" within the Arduino IDE to compile and upload. No need to pick a dev assignment for the USB port.

The board settings under Tools in the Arduino IDE should be as follows (after installing the above MegaCore thingy):
Board: ATmega2560
Clock: External 8MHz
BOD: BOD 2.7v
Compiler LTO: LTO enabled
Pinout: Arduino MEGA pinout
Bootloader: Yes (UART0)
****************************************************/


#include <avr/io.h>
#include <SoftwareSerial.h>
#include "Adafruit_EPD.h"
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSerifItalic9pt7b.h>
#include <Fonts/FreeSerif9pt7b.h>
#include <Fonts/FreeSansOblique9pt7b.h>

//For Adafruit e-ink display:
#define ENABLE_GxEPD2_GFX 0
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= 800 / (EPD::WIDTH / 8) ? EPD::HEIGHT : 800 / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_213_flex, MAX_HEIGHT(GxEPD2_213_flex)> display(GxEPD2_213_flex(25, 26, 28, 29)); //Pin order is ECS, D/C, RESET, BUSY. For Adafruit 2.13" Flexible Monochrome EPD (AKA GDEW0213I5F)

//Define variables:
const byte nChars = 32;
byte n = 1;   //For counting up numbers from the rotary dial for entering a digit in the phone number
byte k = 0;   //For specifying the digit in a phone number
unsigned long TimeSinceLastPulse = 0;   //used to see if enough of a delay has happened since the last pulse from the rotary dial to consider the sequence complete.
char ReceivedChars[32]; // an array to store strings received over RS232 from FONA
byte PNumber[30]; // an array to store phone numbers as they're dialed with the rotary dial
bool NewData = false;  // a flag to indicate whether a string has been received over RS232
bool StillOn = false;  // a flag to indicate that th
bool StartTimeSinceLastPulse = false;  //This gets sets to "true" the first time the rotary dial is used.
bool CallOn = false;   //Set to "true" when a call is in progress, to determine the function of the "call_startedn" pin.
bool newrotaryinput = false;
float fholder1;
int iholder;
int clvl;   //call level storage integer
int rlvl;    //ring level storage integer
float BattLevel;
float SigLevel;
int lhlf;
int rhlf;
int pagenum;      //holder for page number
int mode;   //1 = 631, 2 = NP, 3 = Alt. Marks the mode the phone's currently in. Needed for certain things.

//Define general output pins
const byte StatusLED = 13;
const byte HookLED = 49;
const byte BGLED1 = 7;      //bargraph LED 0 (D15)
const byte BGLED2 = 6;      //bargraph LED 1 (D14)
const byte BGLED3 = 16;      //bargraph LED 2 (D13)
const byte BGLED4 = 17;      //bargraph LED 3 (D12)
const byte BGLED5 = 14;      //bargraph LED 4 (D11)
const byte BGLED6 = 15;      //bargraph LED 5 (D10)
const byte BGLED7 = 42;      //bargraph LED 6 (D9)
const byte BGLED8 = 43;      //bargraph LED 7 (D8)
const byte BGLED9 = 47;      //bargraph LED 8 (D7)
const byte BGLED10 = 48;      //bargraph LED 9 (D6)
const byte FONAWake = A0;
const byte eink_ENA = 31;

//Define input pin
const byte HookButton = 33;   //Make call, hangup call, or answer incoming call (momentary switch shorts to gnd)
const byte ClearButton = 36;     //Clear number currently in dialout buffer from rotary dial (momentary switch gnd)
const byte SignalButton = 34;     //Hold to check signal strengh
const byte BatteryButton = 37;    //Hold to check battery level
const byte SaButton = 35;    //Hold to check battery level
const byte FnButton = 32;    //Hold to check battery level
const byte ModeSwitch_631 = 20;    //SP3T switch positioned to append a certain area code to all calls
const byte ModeSwitch_NP = 19;      //SP3T switch posiioned to "No Prepend" mode, in which a full 10-digit phone number is needed.
const byte ModeSwitch_alt = 18;    //SP3T switch positioned to switch to taking the alternate function of each button.
const byte RotaryPulseIn = 39;          //The pin that reads the state of the rotary dial.

SoftwareSerial FONAserial(53, 9); //Rx, Tx

void setup(){
// Set output pin functions
   pinMode(StatusLED, OUTPUT);
   pinMode(HookLED, OUTPUT);
   pinMode(BGLED1, OUTPUT);
   pinMode(BGLED2, OUTPUT);
   pinMode(BGLED3, OUTPUT);
   pinMode(BGLED4, OUTPUT);
   pinMode(BGLED5, OUTPUT);
   pinMode(BGLED6, OUTPUT);
   pinMode(BGLED7, OUTPUT);
   pinMode(BGLED8, OUTPUT);
   pinMode(BGLED9, OUTPUT);
   pinMode(BGLED10, OUTPUT);
   pinMode(FONAWake, OUTPUT);
   pinMode(eink_ENA, OUTPUT);

   // Define input pin functions
   pinMode(RotaryPulseIn, INPUT_PULLUP);
   pinMode(HookButton, INPUT_PULLUP);
   pinMode(ClearButton, INPUT_PULLUP);
    pinMode(SignalButton, INPUT_PULLUP);
   pinMode(BatteryButton, INPUT_PULLUP);
   pinMode(SaButton, INPUT_PULLUP);
   pinMode(FnButton, INPUT_PULLUP);
   pinMode(ModeSwitch_631, INPUT_PULLUP);
   pinMode(ModeSwitch_NP, INPUT_PULLUP);
   pinMode(ModeSwitch_alt, INPUT_PULLUP);

   digitalWrite(eink_ENA, HIGH);      //Pull the enable pin up on the e-ink display

   Serial.begin(9600);
   FONAserial.begin(4800);

   //Turn on the FONA
  digitalWrite(FONAWake, LOW);              //Holding LOW for ~5s wakes FONA
  delay(6000);
  FONAserial.println(F("AT"));              // Helps baud rate auto selection
  delay(50);                                // see: https://en.wikipedia.org/wiki/Hayes_command_set#Autobaud
  FONAserial.println(F("AT+IPREX=4800"));   // Set FONA baud rate (non-volatile), takes a while this command.
  delay(200);
   FONAserial.println("AT+CVHU=0");   //Sets voice "hang up" control so that "ATH" disconnects voice calls.
   delay(50);
   FONAserial.println("AT+CSDVC=3");   //Set audio output channel. 3 is the speaker.
   delay(50);
   FONAserial.println("AT+VMUTE=0");   //Set speaker mute to OFF
   delay(50);
   FONAserial.println("AT+CRXGAIN=10000");   // Set Rx Gain, which affects the speaker volume during calls. This is a good value for use of the speaker as a handset.
   delay(50);
   FONAserial.println("AT+CLVL=3");   //Set volume (0-8)
   delay(50);
   FONAserial.println("AT+CRSL=8");   //Ringer volume (0-8)

   n = 0;    //Starting phone number digit value is 0
   k = 0;    //Starting phone number digit position is 1

   display.init(115200);
   display.setRotation(0);
   display.setTextColor(GxEPD_BLACK);

   digitalWrite(StatusLED, HIGH);
   delay(500);
   digitalWrite(StatusLED, LOW);
   ClearBuffer();
}

void loop(){
   
   if (CallOn == true){
      digitalWrite(HookLED, HIGH);
   }
   else if (CallOn == false){
      digitalWrite(HookLED, LOW);
   }

   if (digitalRead(ModeSwitch_631) == LOW){
      mode = 1;
   }
    else if (digitalRead(ModeSwitch_NP) == LOW){
      mode = 2;
   }
   else if (digitalRead(ModeSwitch_alt) == LOW){
      mode = 3;
   }

   //*********************ROTARY DIAL INPUT & FUNCTION BUTTON*******************************************************************************
   if (digitalRead(ModeSwitch_631) == LOW || digitalRead(ModeSwitch_NP) == LOW){
      if (digitalRead(FnButton) == LOW){
         StarPoundRotaryIn();   //This function doesn't loop on it's own, but rather depends on the main "void loop" to do its work.
      }
      else{
         RotaryIn();   //This function doesn't loop on it's own, but rather depends on the main "void loop" to do its work.
      }
   }
   else{
      RotaryIn();   //This function doesn't loop on it's own, but rather depends on the main "void loop" to do its work.
   }

   //*********************CLEAR (C) BUTTON**************************************************************************
   if (digitalRead(ClearButton) == LOW){
      delay(200);
      //IF THE CLEAR BUTTON IS STILL DEPRESSED, CLEAR THE BUFFER
      if (digitalRead(ClearButton) == LOW){
         ClearBuffer();   //Clear whatever number has been entered so far
         digitalWrite(StatusLED, HIGH);
         delay(100);
         digitalWrite(StatusLED, LOW);
         delay(500);
      }
   }

   //*********************HOOK (H) BUTTON***************************************************************************
   if (digitalRead(HookButton) == LOW){   //Check CALL button
      //PLACE A CALL IF THE ROTARY HAS BEEN USED & AT LEAST 7 DIGITS WERE DIALED
      if (newrotaryinput = true && PNumber[6] != 99){
         if (digitalRead(ModeSwitch_631) == LOW){   //Check mode switch
            MakeCall216();   //Make a call using the number stored in the buffer as input from the rotary dial, prepended with 631
         }
         else {   //If in either No-Prepend or Alt mode
            MakeCall();   //Make a call using the number stored in the buffer as input from the rotary dial
         }
      }
      //ANSWER INCOMING CALL IF CALLON = FALSE
      else if (CallOn == false){
         FONAserial.println("ATA");
         //CallOn = true;   //!!!FIX!!!. The problem with turning the CallOn flag ON is that there's no check to see if a call was actually picked up.
      }
      delay(400);      
      //IF STILL HOLDING THE HOOK BUTTON BY ITSELF, HANGUP CALL REGARDLESS OF CALLON STATE
      if (digitalRead(HookButton) == LOW){
         FONAserial.println("ATH");
         delay(100);
         FONAserial.println("AT+CHUP");
         if (CallOn == true){      //If CallOn = true, make it false. This is just for the hook LED.
            CallOn = false;
         }
      }
   }

   //*********************S BUTTON**********************************************************************************
   if (digitalRead(SignalButton) == LOW){   //If the signal strength button is being depressed, go to the function that displays the signal strength with the LEDs
      //IF IN 631 MODE CHECK SIGNAL STRENGTH
      if (digitalRead(ModeSwitch_631) == LOW){
         mode = 1;
         SignalStrength();
      }
      //IF IN NP MODE CALL SPEED DIAL 1
      else if (digitalRead(ModeSwitch_NP) == LOW){
         mode = 2;
         ClearBufferSilent();
         pagenum = 5;
         PNumber[0] = 4;
         RetrieveContact();
         MakeCall();
      }
      //IF IN ALT MODE, SET CALL VOLUME
      else if (digitalRead(ModeSwitch_alt) == LOW){
         mode = 3;
         ClearBufferSilent();
         while (digitalRead(SignalButton) == LOW){
            RotaryIn();
         }
         if (PNumber[0] != 99){
            clvl=PNumber[0];
            FONAserial.print("AT+CLVL=");
            FONAserial.println(clvl);
            BarGraphSlow(PNumber[0]);
            delay(100);
            BarGraphSlow(PNumber[0]);
            delay(100);
            BarGraphSlow(PNumber[0]);
            ClearBufferSilent();
         }
      }
   }
   //*********************B BUTTON**********************************************************************************
   if (digitalRead(BatteryButton) == LOW){   
      //IF IN 631 MODE, CHECK BATTERY LEVEL
      if (digitalRead(ModeSwitch_631) == LOW){
         mode = 1;
         BatteryLevel();
      }
      //IF IN NP MODE, CALL SPEED DIAL 2
      else if (digitalRead(ModeSwitch_NP) == LOW){
         mode = 2;
         ClearBufferSilent();
         pagenum = 3;
         PNumber[0] = 4;
         RetrieveContact();
         MakeCall();
      }
      //IF IN ALT MODE, SET RING VOLUME
      else if (digitalRead(ModeSwitch_alt) == LOW){
         mode = 3;
         ClearBufferSilent();
         while (digitalRead(BatteryButton) == LOW){
            RotaryIn();
         }
         if (PNumber[0] != 99){
            rlvl = PNumber[0];
            FONAserial.print("AT+CRSL=");
            FONAserial.println(rlvl);
            BarGraphSlow(PNumber[0]);
            delay(100);
            BarGraphSlow(PNumber[0]);
            delay(100);
            BarGraphSlow(PNumber[0]);
            ClearBufferSilent();
         }
      }
   }

   //*********************Sa BUTTON**********************************************************************************
   if (digitalRead(SaButton) == LOW){   //I couldn't think of a name for this button. Sa doesn't have particular meaning.
      //IF IN 631 MODE, DO SOMETHING TBD
      if (digitalRead(ModeSwitch_631) == LOW){
         mode = 1;
         //placeholder
      }
      //IF IN NP MODE, CALL VOICEMAIL
      else if (digitalRead(ModeSwitch_NP) == LOW){
         mode = 2;
         ClearBufferSilent();
         pagenum = 8;
         PNumber[0] = 4;
         RetrieveContact();
         MakeCall();
      }
      //IF IN ALT MODE, CALL CONTACT FROM CURRENT PAGE
      else if (digitalRead(ModeSwitch_alt) == LOW){
         mode = 3;
         ClearBufferSilent();
         newrotaryinput = false;
         while (digitalRead(SaButton) == LOW){
            RotaryIn();
         }
         if (PNumber[0] != 99){
            RetrieveContact();
            MakeCall();         
            newrotaryinput = false;
            ClearBufferSilent();
         }
      }
   }

   //*********************ALT MODE (IN GENERAL)**********************************************************************************
   //In addition to the ALT MODE stuff specific to each button this section is needed for general stuff.
   //PREVENT CONTACTS PAGE FROM UPDATING IF THE ROTARY DIAL WAS USED BEFORE SWITCHING TO ALT MODE
   if (digitalRead(ModeSwitch_alt) == LOW){
      if ((mode == 1) || (mode == 2)){
         ClearBufferSilent();         
         newrotaryinput = false;   //Prevents display from updating upon entering ALT mode if a number was dialed previously but not used for another function.
      }
      mode = 3;
      //DISPLAY CONTACTS PAGES
      if (newrotaryinput == true){
         DisplayContacts();
         newrotaryinput = false;
         ClearBufferSilent();         
      }
   }
}


This is the main sketch here. There are two other parts for contacts and functions, but I don't believe that has anything to do with this problem. Also from the schematic I am using the connections to the 2560V are all LEDs, USB Bridge and then the FONA as a little daughter board as it were, and all those connections are pretty straight forward. Also no DTMF tones come out of the speaker neither, though the speaker works when receiving calls. I just don't know what's wrong with this FONA board, I don't believe it is this hard to make or answer call, not according to the code I am using here.

Code: Select all | TOGGLE FULL SIZE
void RotaryIn(){   //Listen for pulses from the rotary dial. NO LOOP here. This runs once per iteration of "void loop", so the timing of other things in the main loop will affect this.
   if (digitalRead(RotaryPulseIn) == HIGH){    //If the pin connected to the rotary dial goes high...
      StartTimeSinceLastPulse = true;
      if (StillOn == false){     //...and if we're not still in the same (continuous) pulse from the previous iteration of void loop()...
         BarGraphFast(n+1);
         n++;    //...Increment the counter...
         if (n == 10){
            n = 0;
         }
         delay(10);
      }
      StillOn = true;   // ...and turn on the flag that says a pulse just happened.
   }

   if (StillOn == true){     //If a pulse just happened...
      if ((digitalRead(RotaryPulseIn) == LOW)){   //See if the pin connected to the rotary dial goes low...
         StillOn = false;    //...if it did, we turn off the "StillOn" flag.
         digitalWrite(StatusLED, HIGH);
         delay(20);
         digitalWrite(StatusLED, LOW);
         delay(40);
         TimeSinceLastPulse = 0;     //Reset the time since last pulse (not really time... rather a counter for "void loop").
      }
   }

   if (StartTimeSinceLastPulse == true){
      TimeSinceLastPulse++;
   }

   if (TimeSinceLastPulse == 1000){    //If a long enough time has lapsed since the last pulse from the rotary dial, assume the dial has stopped rotating...
      PNumber[k] = n;    //...and write the current value of n to the current position (k) in the phone number (PNumber)
      k++;      //increment to the next position of the phone number
      FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
      FONAserial.println(n);
      delay(20);
      FONAserial.print("AT+VTS=");   //Send DTMF tone over network (for menu entries, etc).
      FONAserial.println(n);
      newrotaryinput = true;
      n = 0;  //reset n
   }
}

void StarPoundRotaryIn(){   //Listen for pulses from the rotary dial. NO LOOP here. This runs once per iteration of "void loop", so the timing of other things in the main loop will affect this.
   if (digitalRead(RotaryPulseIn) == HIGH){    //If the pin connected to the rotary dial goes high...
      StartTimeSinceLastPulse = true;
      if (StillOn == false){     //...and if we're not still in the same (continuous) pulse from the previous iteration of void loop()...
         BarGraphFast(n+1);
         n++;    //...Increment the counter...
         if (n == 10){
            n = 0;
         }
         delay(10);
      }
      StillOn = true;   // ...and turn on the flag that says a pulse just happened.
   }

   if (StillOn == true){     //If a pulse just happened...
      if ((digitalRead(RotaryPulseIn) == LOW)){   //See if the pin connected to the rotary dial goes low...
         StillOn = false;    //...if it did, we turn off the "StillOn" flag.
         digitalWrite(StatusLED, HIGH);
         delay(20);
         digitalWrite(StatusLED, LOW);
         delay(40);
         TimeSinceLastPulse = 0;     //Reset the time since last pulse (not really time... rather a counter for "void loop").
      }
   }

   if (StartTimeSinceLastPulse == true){
      TimeSinceLastPulse++;
   }

   if (TimeSinceLastPulse == 1000){    //If a long enough time has lapsed since the last pulse from the rotary dial, assume the dial has stopped rotating...
      PNumber[k] = n;    //...and write the current value of n to the current position (k) in the phone number (PNumber)
      k++;      //increment to the next position of the phone number
      if (n == 2){      //Consider this a "*"
         FONAserial.println("AT+CPTONE=*");   //Play DTMF tone over speaker            
         delay(20);
         FONAserial.println("AT+VTS=*");   //Send DTMF tone over network (for menu entries, etc).
      }
      else if (n == 1){   //Consider this a "#"
         FONAserial.println("AT+CPTONE=#");   //Play DTMF tone over speaker            
         delay(20);
         FONAserial.println("AT+VTS=#");   //Send DTMF tone over network (for menu entries, etc).
      }
      n = 0;  //reset n
   }
}



void FONAserialReceive(){    //Listens over RS232, puts any string that's received into "ReceivedChars", and looks for some EndMarker character to change the NewData flag to True.
   static byte n = 0;
   char EndMarker = 'O';   //This is the "K" from "OK", which the SIM5230 always returns after accepting a command.
   char rc;
   int cnt;
    while (FONAserial.available() && NewData == false){      //For some reason the conditional MUST be "FONAserial.available()" and not "FONAserial.available() > 0".
      rc = FONAserial.read();
      if (rc != EndMarker){
         ReceivedChars[n] = rc;
         n++;
         if (n >= nChars){
            n = nChars - 1;
         }
      }
      else{
         ReceivedChars[n] = '\0'; // terminate the string
         n = 0;
         NewData = true;
      }
   }
}

void ClearBuffer(){  //Clear the currently entered phone number
   PNumber[0] = 99;  //Reset the phone number
   PNumber[1] = 99;
   PNumber[2] = 99;
   PNumber[3] = 99;
   PNumber[4] = 99;
   PNumber[5] = 99;
   PNumber[6] = 99;
   PNumber[7] = 99;
   PNumber[8] = 99;
   PNumber[9] = 99;
   PNumber[10] = 99;
   PNumber[11] = 99;
   PNumber[12] = 99;
   PNumber[13] = 99;
   PNumber[14] = 99;
   PNumber[15] = 99;
   k = 0;    //Reset the position of the phone number
   newrotaryinput = false;
   BarGraphWipeUp();
}

void ClearBufferSilent(){  //Clear the currently entered phone number
   PNumber[0] = 99;  //Reset the phone number
   PNumber[1] = 99;
   PNumber[2] = 99;
   PNumber[3] = 99;
   PNumber[4] = 99;
   PNumber[5] = 99;
   PNumber[6] = 99;
   PNumber[7] = 99;
   PNumber[8] = 99;
   PNumber[9] = 99;
   PNumber[10] = 99;
   PNumber[11] = 99;
   PNumber[12] = 99;
   PNumber[13] = 99;
   PNumber[14] = 99;
   PNumber[15] = 99;
   newrotaryinput = false;
   k = 0;    //Reset the position of the phone number
}

void BarGraphSlow(int level){
   Serial.println(level);
   if (level >= 1){
      digitalWrite(BGLED1, HIGH);
   }
   if (level >= 2){
      digitalWrite(BGLED2, HIGH);
   }
   if (level >= 3){
      digitalWrite(BGLED3, HIGH);
   }
   if (level >= 4){
      digitalWrite(BGLED4, HIGH);
   }
   if (level >= 5){
      digitalWrite(BGLED5, HIGH);
   }
   if (level >= 6){
      digitalWrite(BGLED6, HIGH);
   }
   if (level >= 7){
      digitalWrite(BGLED7, HIGH);
   }
   if (level >= 8){
      digitalWrite(BGLED8, HIGH);
   }
   if (level >= 9){
      digitalWrite(BGLED9, HIGH);
   }
   if (level >= 10){
      digitalWrite(BGLED10, HIGH);
   }
   delay(200);
   digitalWrite(BGLED1, LOW);
   digitalWrite(BGLED2, LOW);
   digitalWrite(BGLED3, LOW);
   digitalWrite(BGLED4, LOW);
   digitalWrite(BGLED5, LOW);
   digitalWrite(BGLED6, LOW);
   digitalWrite(BGLED7, LOW);
   digitalWrite(BGLED8, LOW);
   digitalWrite(BGLED9, LOW);
   digitalWrite(BGLED10, LOW);
   delay(100);
}

void BarGraphFast(int level){
   Serial.println(level);
   if (level >= 1){
      digitalWrite(BGLED1, HIGH);
   }
   if (level >= 2){
      digitalWrite(BGLED2, HIGH);
   }
   if (level >= 3){
      digitalWrite(BGLED3, HIGH);
   }
   if (level >= 4){
      digitalWrite(BGLED4, HIGH);
   }
   if (level >= 5){
      digitalWrite(BGLED5, HIGH);
   }
   if (level >= 6){
      digitalWrite(BGLED6, HIGH);
   }
   if (level >= 7){
      digitalWrite(BGLED7, HIGH);
   }
   if (level >= 8){
      digitalWrite(BGLED8, HIGH);
   }
   if (level >= 9){
      digitalWrite(BGLED9, HIGH);
   }
   if (level >= 10){
      digitalWrite(BGLED10, HIGH);
   }
   delay(20);
   digitalWrite(BGLED1, LOW);
   digitalWrite(BGLED2, LOW);
   digitalWrite(BGLED3, LOW);
   digitalWrite(BGLED4, LOW);
   digitalWrite(BGLED5, LOW);
   digitalWrite(BGLED6, LOW);
   digitalWrite(BGLED7, LOW);
   digitalWrite(BGLED8, LOW);
   digitalWrite(BGLED9, LOW);
   digitalWrite(BGLED10, LOW);
}

void BarGraphMed(int level){
   Serial.println(level);
   if (level >= 1){
      digitalWrite(BGLED1, HIGH);
   }
   if (level >= 2){
      digitalWrite(BGLED2, HIGH);
   }
   if (level >= 3){
      digitalWrite(BGLED3, HIGH);
   }
   if (level >= 4){
      digitalWrite(BGLED4, HIGH);
   }
   if (level >= 5){
      digitalWrite(BGLED5, HIGH);
   }
   if (level >= 6){
      digitalWrite(BGLED6, HIGH);
   }
   if (level >= 7){
      digitalWrite(BGLED7, HIGH);
   }
   if (level >= 8){
      digitalWrite(BGLED8, HIGH);
   }
   if (level >= 9){
      digitalWrite(BGLED9, HIGH);
   }
   if (level >= 10){
      digitalWrite(BGLED10, HIGH);
   }
   delay(80);
   digitalWrite(BGLED1, LOW);
   digitalWrite(BGLED2, LOW);
   digitalWrite(BGLED3, LOW);
   digitalWrite(BGLED4, LOW);
   digitalWrite(BGLED5, LOW);
   digitalWrite(BGLED6, LOW);
   digitalWrite(BGLED7, LOW);
   digitalWrite(BGLED8, LOW);
   digitalWrite(BGLED9, LOW);
   digitalWrite(BGLED10, LOW);
   delay(50);
}

void BarGraphWipeUp(){
      int holdtime = 20;
       digitalWrite(StatusLED, HIGH);   
      digitalWrite(BGLED10, HIGH);
      delay(holdtime);
      digitalWrite(BGLED10, LOW);
      digitalWrite(BGLED9, HIGH);
      delay(holdtime);
      digitalWrite(BGLED9, LOW);
      digitalWrite(BGLED8, HIGH);
      delay(holdtime);
      digitalWrite(BGLED8, LOW);
      digitalWrite(StatusLED, LOW);   
      digitalWrite(BGLED7, HIGH);
      delay(holdtime);
      digitalWrite(BGLED7, LOW);
      digitalWrite(BGLED6, HIGH);
      delay(holdtime);
      digitalWrite(BGLED6, LOW);
      digitalWrite(BGLED5, HIGH);
      delay(holdtime);
      digitalWrite(BGLED5, LOW);
      digitalWrite(BGLED4, HIGH);
      delay(holdtime);
      digitalWrite(BGLED4, LOW);
      digitalWrite(BGLED3, HIGH);
      delay(holdtime);
      digitalWrite(BGLED3, LOW);
      digitalWrite(BGLED2, HIGH);
      delay(holdtime);
      digitalWrite(BGLED2, LOW);
      digitalWrite(BGLED1, HIGH);
      delay(holdtime);
      digitalWrite(BGLED1, LOW);
}

void BarGraphWipeDown(){
      int holdtime = 20;
      digitalWrite(BGLED1, HIGH);
      delay(holdtime);
      digitalWrite(BGLED1, LOW);
      digitalWrite(BGLED2, HIGH);
      delay(holdtime);
      digitalWrite(BGLED2, LOW);
      digitalWrite(BGLED3, HIGH);
      delay(holdtime);
      digitalWrite(BGLED3, LOW);
      digitalWrite(BGLED4, HIGH);
      delay(holdtime);
      digitalWrite(BGLED4, LOW);
      digitalWrite(BGLED5, HIGH);
      delay(holdtime);
      digitalWrite(BGLED5, LOW);
      digitalWrite(BGLED6, HIGH);
      delay(holdtime);
      digitalWrite(BGLED6, LOW);
      digitalWrite(BGLED7, HIGH);
      delay(holdtime);
      digitalWrite(BGLED7, LOW);
      digitalWrite(BGLED8, HIGH);
      delay(holdtime);
      digitalWrite(BGLED8, LOW);
      digitalWrite(BGLED9, HIGH);
      delay(holdtime);
      digitalWrite(BGLED9, LOW);
      digitalWrite(BGLED10, HIGH);
      delay(holdtime);
      digitalWrite(BGLED10, LOW);
}

void BatteryLevel(){
   while (digitalRead(BatteryButton) == LOW){   //Loop for as long as the battery level button is depressed.
      FONAserial.println("AT+CBC");
      FONAserialReceive();
      delay(10);
      if (NewData == true){
         digitalWrite(StatusLED, HIGH);
         lhlf = (int)ReceivedChars[20] - 48;
         BarGraphSlow(lhlf);
         Serial.print(ReceivedChars);
         Serial.print(ReceivedChars[20]);
         Serial.println(ReceivedChars[21]);
         NewData = false;
         digitalWrite(StatusLED, LOW);
      }
   }
}

void SignalStrength(){
   while (digitalRead(SignalButton) == LOW){   //Loop for as long as the signal strength button is depressed.
      FONAserial.println("AT+CSQ");      //FONA returns signal strength from 0-31
      Serial.println("AT+CSQ");
      FONAserialReceive();
      delay(100);
      if (NewData == true){
         digitalWrite(StatusLED, HIGH); 
         lhlf = (int)ReceivedChars[18] - 48;
         //rhlf = (int)ReceivedChars[19] - 48;
         //fholder1 = (10*lhlf)+rhlf;
         SigLevel = lhlf;      //10*(fholder1/31);      //Signal strength is 0-31: 0 is < -113dBm and 31 is > -51dBm
         Serial.println(ReceivedChars);
         Serial.println(SigLevel);
         BarGraphSlow(SigLevel);
         //Serial.println(ReceivedChars[18]);
         //Serial.println(ReceivedChars[19]);
         NewData = false;
         digitalWrite(StatusLED, LOW);
      }
   }
}

void MakeCall216(){
   ToneReport();
   FONAserial.print("ATD216");
   Serial.print("ATD216");
   FONAserial.print(PNumber[0]);
   Serial.print(PNumber[0]);
   FONAserial.print(PNumber[1]);
   Serial.print(PNumber[1]);
   FONAserial.print(PNumber[2]);
   Serial.print(PNumber[2]);
   FONAserial.print(PNumber[3]);
   Serial.print(PNumber[3]);
   FONAserial.print(PNumber[4]);
   Serial.print(PNumber[4]);
   FONAserial.print(PNumber[5]);
   Serial.print(PNumber[5]);
   FONAserial.print(PNumber[6]);
   Serial.print(PNumber[6]);
   FONAserial.println(";");
   Serial.print(";");
   delay(10);
   FONAserialReceive();
   digitalWrite(StatusLED, HIGH);
   delay(500);
   digitalWrite(StatusLED, LOW);
   NewData = false;
   CallOn = true;
   ClearBufferSilent();
}

void MakeCall(){
   ToneReport();
   CallOn = true;
   FONAserial.print("ATD");
   Serial.print("ATD");
   FONAserial.print(PNumber[0]);
   Serial.print(PNumber[0]);
   FONAserial.print(PNumber[1]);
   Serial.print(PNumber[1]);
   FONAserial.print(PNumber[2]);
   Serial.print(PNumber[2]);
   FONAserial.print(PNumber[3]);
   Serial.print(PNumber[3]);
   FONAserial.print(PNumber[4]);
   Serial.print(PNumber[4]);
   FONAserial.print(PNumber[5]);
   Serial.print(PNumber[5]);
   FONAserial.print(PNumber[6]);
   Serial.print(PNumber[6]);
   FONAserial.print(PNumber[7]);
   Serial.print(PNumber[7]);
   FONAserial.print(PNumber[8]);
   Serial.print(PNumber[8]);
   FONAserial.print(PNumber[9]);
   Serial.print(PNumber[9]);
   FONAserial.println(";");
   Serial.println(";");
   delay(100);
   FONAserialReceive();
   digitalWrite(StatusLED, HIGH);
   delay(500);
   digitalWrite(StatusLED, LOW);
   NewData = false;
   CallOn = true;
   ClearBufferSilent();
}

void ToneReport(){
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[0]);
         BarGraphMed(PNumber[0]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[1]);
         BarGraphMed(PNumber[1]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[2]);
         BarGraphMed(PNumber[2]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[3]);
         BarGraphMed(PNumber[3]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[4]);
         BarGraphMed(PNumber[4]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[5]);
         BarGraphMed(PNumber[5]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[6]);
         BarGraphMed(PNumber[6]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[7]);
         BarGraphMed(PNumber[7]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[8]);
         BarGraphMed(PNumber[8]);
         FONAserial.print("AT+CPTONE=");   //Play DTMF tone over speaker
         FONAserial.println(PNumber[9]);
         BarGraphMed(PNumber[9]);   
}


I am just so confused why the FONA is not answering or making calls. Any help would be appreciate if this is like a common problem with this board. I've been trying for a month now and it's just a no-go.

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Re: Rotary cellphone with FONA 3G issue

by rskup on Sun Aug 30, 2020 8:08 am

I am also working on a rotary cellphone project using the FONA 3G (and a Feather to control it).

Every time I wonder whether my FONA 3G board is still working right I disconnect the board from my project and use X-CTU software and SIMCOM's AT commands from their big manual to test the board.

This way there's none of my code or breadboard wiring "in the way" that could be the source of a problem.

To me (and I'm not claiming to be an expert, this is my first FONA project) it's the most basic way to test the board and verify I can still make and receive calls with it and that I didn't damage it somehow during my breadboarding.

rskup
 
Posts: 63
Joined: Sat Aug 01, 2020 9:04 pm

Re: Rotary cellphone with FONA 3G issue

by ajkatz83 on Sun Aug 30, 2020 2:24 pm

Just recently I found out that there were x64 drivers for this SIMCOM chip and just this weekend out the AT COMM port working.

I was using Tera-Term to query the FONA, and every last command worked. I would think "OK" is the appropriate response from AT commands, though things change and then it's something else I need to look for other then "OK." I'm pretty disillusioned with this project.

All the commands that were in the code I ran through and, ever last one checked out fine. So still have no clue why there is no making or answering of calls. I am just close to the giving up stage of the project.

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Re: Rotary cellphone with FONA 3G issue

by rskup on Sun Aug 30, 2020 5:36 pm

Not sure if I'm helping or not, but I'm confused by your post--you mention that you tried all the commands in the code using Tera-Term, and that all the commands checked out fine, which to me implies the board must be ok since the code contains the AT commands to make and receive calls.

So let me ask this, did you at any point use Tera-Term and send "AT+CREG?" to the FONA board?

And did you get back "+CREG: 0,1"?

rskup
 
Posts: 63
Joined: Sat Aug 01, 2020 9:04 pm

Re: Rotary cellphone with FONA 3G issue

by ajkatz83 on Sun Aug 30, 2020 8:54 pm

That one I did not try.

I looked up further for AT commands for GSM and I am about to try some additional testing I didn't do at all.

It is strange that with straight AT, that tells me the modem is active an accepting commands, however, it still doesn't make or answer the calls at all, so let me try what you're saying here, because I think there is still something wrong. Right now, I got this:


PNN DONE

SMS DONE

+VOICEMAIL: INIT_STATE, 0, 0

PB DONE

+STIN: 25

and then this:

ATE, 0 ,0
ERROR

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Re: Rotary cellphone with FONA 3G issue

by ajkatz83 on Sun Aug 30, 2020 9:04 pm

So I just did AT+CMSG="phone no." and both messages I sent to myself came through......so this is proof SMS works.....

I tried AT+CREG and all I got back was OK....

UPDATE: Yes I got +CREG, 0 , 1

So if I am reading this correctly 0=not registered, MT is not currently searching a new operator to register to, 1=GSM Compact

Uh-oh this is an AT&T problem :-o Oh geez I wish I did this and knew this sooner.

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Re: Rotary cellphone with FONA 3G issue

by rskup on Sun Aug 30, 2020 10:52 pm

Hey "0,1" is a good sign!! Note the 1 is <stat> for "registered".

Now try calling a number using the ATD command.

For example, if you were calling 222-333-4444, use this:

ATD12223334444;

Note the "1" before the area code and the ";" at the end.

If the number you're trying to call doesn't ring, try adjusting the antenna, get it as vertical as possible, and dial again.

I seem to be in an area where my connection to the tower is marginal, every time AT+CREG? returns "0,1" yet I can't make a call, I simply re-adjust the antenna, make sure nothing metal is near it, dial again, and it works.

If it still doesn't work you just might need a better antenna. I recently ordered one that supposedly has an 8db gain, but haven't connected it yet, I just keep resorting to moving the antenna around currently.

Hope that helps, I have to head out of town tomorrow so if you have other questions I can't answer until Tuesday.

Good luck, I really enjoy tinkering with this board, and am looking forward to getting a 4G board after I finish my phone project.

rskup
 
Posts: 63
Joined: Sat Aug 01, 2020 9:04 pm

Re: Rotary cellphone with FONA 3G issue

by ajkatz83 on Sun Aug 30, 2020 11:21 pm

Ok, yes you are right, I used ATD as you had said and the call went through :-o

According to this site I guess I had the wrong information:
https://m2msupport.net/m2msupport/atcre ... istration/

But then I must have some how interpreted it wrong:
https://m2msupport.net/m2msupport/network-registration/

What about AT+COPS? With that I get 0, 0, AT&T ,2.....I still think with that "2" there I am deregistered still.

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Re: Rotary cellphone with FONA 3G issue

by ajkatz83 on Mon Aug 31, 2020 12:30 am

Never mind, the terminal program was my best friend here.

I had to changed the AT+IPREX to 4800bps, which is what her software runs on, and everything came to life here.

Everything was working perfect!

Thanks for your help here and the terminal encouragement!

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Re: Rotary cellphone with FONA 3G issue

by rskup on Mon Aug 31, 2020 9:24 pm

Glad to hear it's working, that's great!

Below is a link to the SIM5320 manual, the manual goes into more detail about the responses from the chip:

https://simcom.ee/documents/SIM5320/SIM ... _V2.05.pdf

Also added a pic of my setup, currently working on brackets to hold all the parts in the phone, will post another pic when it's all finished.

Hope you have a good week!
Attachments
phone_rotocell_86.jpg
phone_rotocell_86.jpg (99.74 KiB) Viewed 148 times

rskup
 
Posts: 63
Joined: Sat Aug 01, 2020 9:04 pm

Re: Rotary cellphone with FONA 3G issue

by ajkatz83 on Tue Sep 01, 2020 6:56 am

Thanks again for the help, getting into the terminal program really saved my sanity there!

This was what I was working on here. It is the design by Justine Haupet, and this has been one of the more challenging things I have worked on.

IMG_20200813_211524.jpg
IMG_20200813_211524.jpg (150.75 KiB) Viewed 147 times


IMG_20200813_211515.jpg
IMG_20200813_211515.jpg (82.3 KiB) Viewed 147 times


Definitely like the look there, I believe I was talking with my dad about a rotary phone just like that not long ago, looks like you got it on the run there. Brackets should be easy to position inside there.

Hope you have a good week too.

ajkatz83
 
Posts: 25
Joined: Fri Sep 05, 2014 2:13 pm

Please be positive and constructive with your questions and comments.