Example program for UART power saving configuration of cellular modem. This program can be used with UBLOX_C030_R412M board. It has nothing to do with 3GPP power saving mode.

Dependencies:   ublox-at-cellular-interface ublox-cellular-base ublox-cellular-base-n2xx ublox-at-cellular-interface-n2xx

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 u-blox
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed.h"
00017 #include "UbloxATCellularInterface.h"
00018 #include "UbloxATCellularInterfaceN2xx.h"
00019 
00020 // You must select the correct interface library for your board, by
00021 // uncommenting the correct line below. Supported combinations are
00022 // indicated with a "Y" in the table below.
00023 //
00024 //                            C030_U201   C030_N211      C027
00025 // UbloxATCellularInterface       Y            -           Y
00026 // UbloxATCellularInterfaceN2xx   -            Y           -
00027 // Note: the N211 module supports only UDP, not TCP
00028 
00029 // UbloxATCellularInterface and UbloxATCellularInterfaceN2xx
00030 // uses an IP stack on the cellular module and hence uses less RAM (significant on C027).
00031 // This also allows other AT command operations (e.g. sending an SMS) to happen
00032 // during a data transfer (for which you should replace the
00033 // UbloxATCellularInterface library with the UbloxATCellularInterfaceExt
00034 // library).  However, it is slower than using the LWIP/PPP on the mbed
00035 // MCU interface since more string parsing is required.
00036 #define INTERFACE_CLASS  UbloxATCellularInterface
00037 //#define INTERFACE_CLASS  UbloxATCellularInterfaceN2xx
00038 
00039 // The credentials of the SIM in the board.  If PIN checking is enabled
00040 // for your SIM card you must set this to the required PIN.
00041 #define PIN "0000"
00042 
00043 // Network credentials.  You should set this according to your
00044 // network/SIM card.  For C030 non-N2xx boards, leave the parameters as NULL
00045 // otherwise, if you do not know the APN for your network, you may
00046 // either try the fairly common "internet" for the APN (and leave the
00047 // username and password NULL), or you may leave all three as NULL and then
00048 // a lookup will be attempted for a small number of known networks
00049 // (see APN_db.h in mbed-os/features/netsocket/cellular/utils).
00050 #define APN         NULL
00051 #define USERNAME    NULL
00052 #define PASSWORD    NULL
00053 #define TCP_SERVER "os.mbed.com"
00054 
00055 //comment out the following line to disable modem current measurement
00056 #define CURRENT_MEASUREMENT
00057 
00058 // LEDs
00059 DigitalOut ledRed(LED1, 1);
00060 DigitalOut ledGreen(LED2, 1);
00061 DigitalOut ledBlue(LED3, 1);
00062 
00063 // The user button
00064 volatile bool buttonPressed = false;
00065 #ifdef CURRENT_MEASUREMENT
00066 AnalogIn ain_icellular(MDMCURRENTSENSE);
00067 Thread icell_thread;
00068 #endif
00069 
00070 static void good() {
00071     ledGreen = 0;
00072     ledBlue = 1;
00073     ledRed = 1;
00074 }
00075 
00076 static void bad() {
00077     ledRed = 0;
00078     ledGreen = 1;
00079     ledBlue = 1;
00080 }
00081 
00082 static void event() {
00083     ledBlue = 0;
00084     ledRed = 1;
00085     ledGreen = 1;
00086 }
00087 
00088 static void pulseEvent() {
00089     event();
00090     wait_ms(500);
00091     good();
00092 }
00093 
00094 static void ledOff() {
00095     ledBlue = 1;
00096     ledRed = 1;
00097     ledGreen = 1;
00098 }
00099 
00100 static void printNtpTime(char * buf, int len)
00101 {
00102     time_t timestamp = 0;
00103     struct tm *localTime;
00104     char timeString[25];
00105     time_t TIME1970 = 2208988800U;
00106 
00107     if (len >= 43) {
00108         timestamp |= ((int) *(buf + 40)) << 24;
00109         timestamp |= ((int) *(buf + 41)) << 16;
00110         timestamp |= ((int) *(buf + 42)) << 8;
00111         timestamp |= ((int) *(buf + 43));
00112         timestamp -= TIME1970;
00113         localTime = localtime(&timestamp);
00114         if (localTime) {
00115             if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) {
00116                 printf("NTP timestamp is %s.\n", timeString);
00117             }
00118         }
00119     }
00120 }
00121 
00122 static void cbButton()
00123 {
00124     buttonPressed = true;
00125 }
00126 
00127 #ifdef CURRENT_MEASUREMENT
00128 float calculate_icellular_samples() {
00129     float ain=0.0f;
00130     float icellular_val;
00131     float c_number_of_analog_samples = 50;
00132 
00133     ain = 0;
00134     icellular_val = 0;
00135     for(int i = 0; i < c_number_of_analog_samples; i++) {
00136         ain = (ain + ain_icellular.read());
00137         wait_ms(20);
00138     }
00139     ain = ain/c_number_of_analog_samples;
00140     icellular_val = (ain*1.8*1000)/7.0f;
00141 
00142 
00143     printf("Voltage in mV: %f\n", icellular_val * 7.0f);
00144     printf("Current draw in mA: %f\n\n", icellular_val);
00145 
00146     return icellular_val;
00147 }
00148 
00149 void icell_thread_handler() {
00150 
00151     while(1) {
00152         calculate_icellular_samples();
00153     }
00154 }
00155 #endif
00156 
00157 /* This example program for the u-blox C030 and C027 boards instantiates
00158  * the UbloxATCellularInterface and uses it to make a simple sockets
00159  * connection to a server, using 2.pool.ntp.org for UDP and developer.mbed.org for TCP.
00160  * For a more comprehensive example, where higher layer protocols
00161  * make use of the same sockets interface, see example-ublox-mbed-client.
00162  * Progress may be monitored with a serial terminal running at 9600 baud.
00163  * The LED on the C030 board will turn green when this program is
00164  * operating correctly, pulse blue when a sockets operation is completed
00165  * and turn red if there is a failure.
00166  */
00167 
00168 int main()
00169 {
00170 #ifdef CURRENT_MEASUREMENT
00171     //current monitoring using Icellular
00172     icell_thread.start(icell_thread_handler);
00173 #endif
00174     INTERFACE_CLASS *interface = new INTERFACE_CLASS();
00175     // If you need to debug the cellular interface, comment out the
00176     // instantiation above and uncomment the one below.
00177     // For the N2xx interface, change xxx to MBED_CONF_UBLOX_CELL_BAUD_RATE,
00178     // while for the non-N2xx interface change it to MBED_CONF_UBLOX_CELL_N2XX_BAUD_RATE.
00179 //    INTERFACE_CLASS *interface = new INTERFACE_CLASS(MDMTXD, MDMRXD,
00180 //                                                     xxx,
00181 //                                                     true);
00182 #ifndef TARGET_UBLOX_C030_N211
00183     TCPSocket sockTcp;
00184 #endif
00185     UDPSocket sockUdp;
00186     SocketAddress udpServer;
00187     SocketAddress udpSenderAddress;
00188     SocketAddress tcpServer;
00189     char buf[1024];
00190     int x;
00191 #ifdef TARGET_UBLOX_C027
00192     // No user button on C027
00193     InterruptIn userButton(NC);
00194 #else
00195     InterruptIn userButton(SW0);
00196 #endif
00197 
00198     // Attach a function to the user button
00199     userButton.rise(&cbButton);
00200 
00201     interface->set_credentials(APN, USERNAME, PASSWORD);
00202     interface->init(PIN);
00203 
00204     printf("Checking if already registered!\n");
00205 
00206     if ( (interface->is_registered_csd() || interface->is_registered_psd() || interface->is_registered_eps()) ) {
00207         printf("De-registering...\n\n");
00208         interface->nwk_deregistration();
00209     }
00210 
00211     if (interface->set_modem_rat(UbloxATCellularInterface::GPRS_EGPRS)) {
00212         printf("GPRS_EGPRS RAT configured\n");
00213     }
00214     else {
00215         printf("GPRS_EGPRS RAT not configured\n");
00216     }
00217 
00218     if (interface->reboot_modem()) {
00219         printf("Reboot successful");
00220     }
00221 
00222     good();
00223     printf("Starting up, please wait up to 180 seconds for network registration to complete...\n");
00224     for (x = 0; interface->connect(PIN) != 0; x++) {
00225         if (x > 0) {
00226             bad();
00227             printf("Retrying (have you checked that an antenna is plugged in and your APN is correct?)...\n");
00228         }
00229     }
00230     pulseEvent();
00231 
00232 #ifdef TARGET_UBLOX_C030_R41XM
00233     int status;
00234     if (interface->get_idle_mode(&status)) {
00235         printf("\n\nIdle mode is %s\n", status ? "Enabled" : "Disabled");
00236     }
00237     if (!status) {
00238         printf("Enabling idle mode...\n");
00239         if (interface->set_idle_mode(true) == false)
00240         {
00241             printf("Unable to set idle mode, is PSM enabled?\n");
00242         }
00243         if (interface->get_idle_mode(&status)) {
00244             printf("Idle mode is %s\n", status ? "Enabled" : "Disabled");
00245         }
00246     }
00247 #ifdef TARGET_UBLOX_C030_R412M
00248     if (interface->set_power_saving_mode(30, 30) == false)
00249     {
00250         printf("Unable to set PSM, is idle mode enabled?\n\n");
00251     }
00252 #endif
00253 #endif
00254 
00255     printf("Getting the IP address of \"" TCP_SERVER "\" and \"2.pool.ntp.org\"...\n");
00256     if ((interface->gethostbyname("2.pool.ntp.org", &udpServer) == 0) &&
00257         (interface->gethostbyname(TCP_SERVER, &tcpServer) == 0)) {
00258         pulseEvent();
00259 
00260         udpServer.set_port(123);
00261         tcpServer.set_port(80);
00262         printf("\"2.pool.ntp.org\" address: %s on port %d.\n", udpServer.get_ip_address(), udpServer.get_port());
00263         printf("\"os.mbed.com\" address: %s on port %d.\n", tcpServer.get_ip_address(), tcpServer.get_port());
00264 
00265         printf("Performing socket operations in a loop (until the user button is pressed on C030 or forever on C027)...\n");
00266         while (!buttonPressed) {
00267             // UDP Sockets
00268             printf("=== UDP ===\n");
00269             printf("Opening a UDP socket...\n");
00270             if (sockUdp.open(interface) == 0) {
00271                 pulseEvent();
00272                 printf("UDP socket open.\n");
00273                 sockUdp.set_timeout(10000);
00274                 printf("Sending time request to \"2.pool.ntp.org\" over UDP socket...\n");
00275                 memset (buf, 0, sizeof(buf));
00276                 *buf = '\x1b';
00277                 if (sockUdp.sendto(udpServer, (void *) buf, 48) == 48) {
00278                     pulseEvent();
00279                     printf("Socket send completed, waiting for UDP response...\n");
00280                     x = sockUdp.recvfrom(&udpSenderAddress, buf, sizeof (buf));
00281                     if (x > 0) {
00282                         pulseEvent();
00283                         printf("Received %d byte response from server %s on UDP socket:\n"
00284                                "-------------------------------------------------------\n",
00285                                x, udpSenderAddress.get_ip_address());
00286                         printNtpTime(buf, x);
00287                         printf("-------------------------------------------------------\n");
00288                     }
00289                 }
00290                 printf("Closing socket...\n");
00291                 sockUdp.close();
00292                 pulseEvent();
00293                 printf("Socket closed.\n");
00294             }
00295 
00296 #ifndef TARGET_UBLOX_C030_N211
00297             // TCP Sockets
00298             printf("=== TCP ===\n");
00299             printf("Opening a TCP socket...\n");
00300             if (sockTcp.open(interface) == 0) {
00301                 pulseEvent();
00302                 printf("TCP socket open.\n");
00303                 sockTcp.set_timeout(10000);
00304                 printf("Connecting socket to %s on port %d...\n", tcpServer.get_ip_address(), tcpServer.get_port());
00305                 if (sockTcp.connect(tcpServer) == 0) {
00306                     pulseEvent();
00307                     printf("Connected, sending HTTP GET request to %s over socket...\n", TCP_SERVER);
00308                     strcpy (buf, "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\r\n\r\n");
00309                     // Note: since this is a short string we can send it in one go as it will
00310                     // fit within the default buffer sizes.  Normally you should call sock.send()
00311                     // in a loop until your entire buffer has been sent.
00312                     if (sockTcp.send((void *) buf, strlen(buf)) == (int) strlen(buf)) {
00313                         pulseEvent();
00314                         printf("Socket send completed, waiting for response...\n");
00315                         x = sockTcp.recv(buf, sizeof (buf));
00316                         if (x > 0) {
00317                             pulseEvent();
00318                             printf("Received %d byte response from server on TCP socket:\n"
00319                                    "----------------------------------------------------\n%.*s"
00320                                    "----------------------------------------------------\n",
00321                                     x, x, buf);
00322                         }
00323                     }
00324                 }
00325                 printf("Closing socket...\n");
00326                 sockTcp.close();
00327                 pulseEvent();
00328                 printf("Socket closed.\n");
00329             }
00330 #endif
00331             printf("Sleeping for 20 seconds \n");
00332             wait_ms(20000); //modem will enter sleep after 6 seconds. This can be observed from Icellular value.
00333             printf("Waking up\n");
00334 #ifndef TARGET_UBLOX_C027
00335             printf("[Checking if user button has been pressed]\n");
00336 #endif
00337         }
00338 
00339         pulseEvent();
00340         printf("User button was pressed, stopping...\n");
00341         interface->disconnect();
00342         ledOff();
00343         printf("Stopped.\n");
00344     } else {
00345         bad();
00346         printf("Unable to get IP address of \"developer.mbed.org\" or \"2.pool.ntp.org\".\n");
00347     }
00348 }
00349 
00350 // End Of File