PPP and RTC sleep

Hi all

I have a cobra running SDK 4.3.6 and tried the latest PPP code from cellular radio to connect to a webpage and send some variables. The code is working ok.
I’m using the same cobra board to test RTC, everything works ok, my board goes to deepsleep and wakes up after 2 minutes.

When i joined the two pieces of code, the RTC doesn’t work anymore, it always wake up after 1 minute. I’m using the board without VS.

If i comment the part where i power on CR, RTC works ok, so it seems that CR conflicts with RTC…

Here is my code, i had some comments on it :

using Gadgeteer.Modules.GHIElectronics;
using GHI.Networking;
using GHI.Processor;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;
using System;
using System.Net;
using System.Text;
using System.Threading;
using G120 = GHI.Pins.G120;
using GT = Gadgeteer;

namespace Cerb_CR
{
    public partial class Program
    {
        private CellularRadio cr;
        private void RegisterExtenderSockets()
        {
            var socket = GT.Socket.SocketInterfaces.CreateNumberedSocket(8);
            socket.SupportedTypes = new char[] { 'I', 'K', 'U', 'X' };
            socket.CpuPins[3] = G120.P0_10;
            socket.CpuPins[4] = G120.P2_0;
            socket.CpuPins[5] = G120.P0_16;
            socket.CpuPins[6] = G120.P0_6;
            socket.CpuPins[7] = G120.P0_17;
            socket.CpuPins[8] = G120.P0_27;
            socket.CpuPins[9] = G120.P0_28;
            socket.SerialPortName = "COM2";
            GT.Socket.SocketInterfaces.RegisterSocket(socket);
        }

        void ProgramStarted()
        {
            Debug.Print("Program Started");
	    //**************************************************
	    // PART 1 - set datetime of the RTC
	    //**************************************************
            DateTime DT;
            try
            {
                DT = RealTimeClock.GetDateTime();
                Debug.Print("Current Real-time Clock " + DT.ToString());
            }
            catch
            {
                Debug.Print("The date was bad and caused a bad time");
                DT = new DateTime(2014, 1, 1, 1, 1, 1); 
                RealTimeClock.SetDateTime(DT); 
            }

            if (DT.Year < 2011)
            {
                Debug.Print("Time is not resonable");
            }

            Debug.Print("Current Real-time Clock " + RealTimeClock.GetDateTime().ToString());
            DT = new DateTime(2014, 9, 15, 7, 30, 0); 
            RealTimeClock.SetDateTime(DT);
            Debug.Print("New Real-time Clock " + RealTimeClock.GetDateTime().ToString());

	    //**************************************************
	    // PART 2 - hibernate for 2 seconds, just to test...
	    //**************************************************

            Debug.Print("Hibernating");
            Thread.Sleep(500);
            RealTimeClock.SetAlarm(RealTimeClock.GetDateTime().AddSeconds(120));
            Debug.Print("now is            : " + RealTimeClock.GetDateTime().Date + "-" + RealTimeClock.GetDateTime().Month + "-" + RealTimeClock.GetDateTime().Date + " - " + RealTimeClock.GetDateTime().Hour + ":" + RealTimeClock.GetDateTime().Minute + ":" + RealTimeClock.GetDateTime().Second);
            Debug.Print("Start Hibernate at: " + RealTimeClock.GetAlarm().Date + "-" + RealTimeClock.GetAlarm().Month + "-" + RealTimeClock.GetAlarm().Date + " - " + RealTimeClock.GetAlarm().Hour + ":" + RealTimeClock.GetAlarm().Minute + ":" + RealTimeClock.GetAlarm().Second);
            PowerState.WakeupEvents |= HardwareEvent.OEMReserved2;
            PowerState.Sleep(SleepLevel.Off, HardwareEvent.OEMReserved2);
            Debug.Print("Awaiking...");
            Thread.Sleep(500);

	    //**************************************************
	    // PART 3 - hibernate ok, now register cellular radio
	    //**************************************************

            this.RegisterExtenderSockets();
            cr = new CellularRadio(8);
            NetworkChange.NetworkAvailabilityChanged += (a, b) => Debug.Print("Network availability changed: " + b.IsAvailable.ToString());
            NetworkChange.NetworkAddressChanged += (a, b) => Debug.Print("Network address changed");
            Thread.Sleep(2000);
            this.cr.ModuleInitialized += this.cellularRadio_ModuleInitialized;
            Thread.Sleep(2000);
            this.cr.PowerOn(40);
            Mainboard.SetDebugLED(true);
        }

        void cellularRadio_ModuleInitialized(CellularRadio sender)
        {
            Mainboard.SetDebugLED(false);
            Thread.Sleep(15000);
            this.cr.UseThisNetworkInterface("my_ISP_Address", "", "", PPPSerialModem.AuthenticationType.Pap);
            while (this.cr.NetworkInterface.IPAddress == "0.0.0.0")
            {
                Debug.Print("Waiting on DHCP");
                Thread.Sleep(250);
            }
            Thread.Sleep(2000);
            if (this.cr.NetworkInterface.IPAddress != "0.0.0.0")
            {

	    //**************************************************
	    // PART 4 - infinite loop: send TCP request, hibernate, wake up, ...
	    //**************************************************
                while (1 == 1)
                {
                    Mainboard.SetDebugLED(true);
                    using (var req = HttpWebRequest.Create("http://mysite/read.php?txt=CAP&id=123456&value=99") as HttpWebRequest)
                    {
                        req.KeepAlive = false;
                        req.ContentLength = 0;
                        using (var res = req.GetResponse() as HttpWebResponse)
                        {
                            using (var stream = res.GetResponseStream())
                            {
                                int read = 0, total = 0;
                                var buffer = new byte[1024];
                                do
                                {
                                    read = stream.Read(buffer, 0, buffer.Length);
                                    total += read;

                                    Thread.Sleep(20);
                                } while (read != 0);

                                Debug.Print("TCP answer: " + new string(Encoding.UTF8.GetChars(buffer)));

                                if (new string(Encoding.UTF8.GetChars(buffer)) == "ok")
                                {
                                    Mainboard.SetDebugLED(false);
                                }
                            }
                        }
                    }

                    Debug.Print("Hibernating");
                    Thread.Sleep(500);
                    RealTimeClock.SetAlarm(RealTimeClock.GetDateTime().AddSeconds(120));
                    Debug.Print("now is            : " + RealTimeClock.GetDateTime().Date + "-" + RealTimeClock.GetDateTime().Month + "-" + RealTimeClock.GetDateTime().Date + " - " + RealTimeClock.GetDateTime().Hour + ":" + RealTimeClock.GetDateTime().Minute + ":" + RealTimeClock.GetDateTime().Second);
                    Debug.Print("Start Hibernate at: " + RealTimeClock.GetAlarm().Date + "-" + RealTimeClock.GetAlarm().Month + "-" + RealTimeClock.GetAlarm().Date + " - " + RealTimeClock.GetAlarm().Hour + ":" + RealTimeClock.GetAlarm().Minute + ":" + RealTimeClock.GetAlarm().Second);
                    PowerState.WakeupEvents |= HardwareEvent.OEMReserved2;
                    PowerState.Sleep(SleepLevel.Off, HardwareEvent.OEMReserved2);
                    Debug.Print("Awaiking...");
                    Thread.Sleep(500);

                }

            }

        }
    }
}

@ geologic - Does the RTC itself keep valid time? Is it always 60 seconds exactly that it wakes up after?

Yes, it keeps valid time, and yes, it always wakes after 60 seconds, no matter what alarm i set

@ geologic - We will take a look and see what we can find.

Just to let you know, I am also VERY much looking at this thread :whistle:

If I remember correctly, you had a problem “always wake up after 1 min”. Can you share to us, how did you fix it, please, or that was because your code also included PPP?

RTC works ok if i do not use PPP. As soon i had the PPP code, RTC always wakes up after 1 minute. See the code on my first post.

@ geologic -

Hello,

I don’t know I should be happy or unhappy now.

Happy because I can not reproduce again with your problem. It means the firmware is still OK, at least as I see now.

Unhappy because we know that you don’t want to hear that we were not able to reproduce. :smiley:

Anyway, if what you posted here is exactly what you tried, I think your code is not right because, call hibernate at OFF mode, after wake up, the board will be same as Reset state, you can not go to next step. Your application will run: Boot up -> hibernate -> reset -> hibernate -> reset…, I think.

Second is, if you are using gadgeteer code, the function “ProgramStarted()” should be returned as soon as possible. Calling hibernate in here not a good way. Not sure if this is reason for your problem, but, anyway, move to another thread is better.

Below is our code, we tested with 2 different Fez Cobras and 2 different COM ports (1,2). We also tried 90, 120, 180 seconds

Please help us to give it a try. There may have problem that we still don’t know yet, but don’t worry, just tell us what you see and we will try again.


using System;
using System.Collections;
using System.Threading;
using System.IO.Ports;
using System.Net;
using System.Text;

using Microsoft.SPOT;

using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

using GHI.Networking;
using GHI.Processor;
using G120 = GHI.Pins.G120;
using Gadgeteer.Modules.GHIElectronics;

namespace G120_RTC_PPP
{
    public partial class Program
    {
        private CellularRadio cr;
       
        void ProgramStarted()
        {
            Debug.Print("Program Started");
            new Thread(DoPPP).Start();
        }
        
        private static InputPort _ldr1 = new InputPort((Cpu.Pin)(22), false, Port.ResistorMode.PullUp); // LDR1
        bool ledsts = false;
        SerialPort port;
        private void DoPPP()
        {
            
            while (_ldr1.Read() == true)
            {
                Thread.Sleep(50);
                Mainboard.SetDebugLED(ledsts);
                ledsts = !ledsts;
                Debug.Print("DoPPP : Board is in initialize state.");

            }
            // Set up RTC
            DateTime DT;
            try
            {
                DT = RealTimeClock.GetDateTime();
                Debug.Print("Current Real-time Clock " + DT.ToString());
            }
            catch
            {
                Debug.Print("The date was bad and caused a bad time");
                DT = new DateTime(2014, 1, 1, 1, 1, 1);
                RealTimeClock.SetDateTime(DT);
            }

            if (DT.Year < 2011)
            {
                Debug.Print("Time is not resonable");
            }

            Debug.Print("Current Real-time Clock " + RealTimeClock.GetDateTime().ToString());
            DT = new DateTime(2014, 9, 15, 7, 30, 0);
            RealTimeClock.SetDateTime(DT);
            Debug.Print("New Real-time Clock " + RealTimeClock.GetDateTime().ToString());


            NetworkChange.NetworkAvailabilityChanged += (a, b) => Debug.Print("SPOT NAVAC " + b.IsAvailable.ToString());
            NetworkChange.NetworkAddressChanged += (a, b) => Debug.Print("SPOT NADRC");

          

             // Test RTC first time
            Thread.Sleep(500);
            RealTimeClock.SetAlarm(RealTimeClock.GetDateTime().AddSeconds(120));
            Debug.Print("now is            : " + RealTimeClock.GetDateTime().Date + "-" + RealTimeClock.GetDateTime().Month + "-" + RealTimeClock.GetDateTime().Date + " - " + RealTimeClock.GetDateTime().Hour + ":" + RealTimeClock.GetDateTime().Minute + ":" + RealTimeClock.GetDateTime().Second);
            Debug.Print("Will Wakeup at: " + RealTimeClock.GetAlarm().Date + "-" + RealTimeClock.GetAlarm().Month + "-" + RealTimeClock.GetAlarm().Date + " - " + RealTimeClock.GetAlarm().Hour + ":" + RealTimeClock.GetAlarm().Minute + ":" + RealTimeClock.GetAlarm().Second);
            Debug.Print("Entering Hibernate mode - before accessing network");
            PowerState.WakeupEvents |= HardwareEvent.OEMReserved2;
            PowerState.Sleep(SleepLevel.DeepSleep, HardwareEvent.OEMReserved2);
            Debug.Print("Now is            : " + RealTimeClock.GetDateTime().Date + "-" + RealTimeClock.GetDateTime().Month + "-" + RealTimeClock.GetDateTime().Date + " - " + RealTimeClock.GetDateTime().Hour + ":" + RealTimeClock.GetDateTime().Minute + ":" + RealTimeClock.GetDateTime().Second);
            
            Thread.Sleep(500);
            Debug.Print("Next step is opening network!");


           // Do PPP 
            port = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);
            port.Open();

            port.DiscardInBuffer();
            port.DiscardOutBuffer();

            //SendAT("AT+CGDCONT=2,\"IP\",\"your apn\"");
            SendAT("AT+CGDCONT=2,\"IP\",\"your apn\"");
            SendAT("ATDT*99***2#");

            using (var netif = new PPPSerialModem(port))
            {
                netif.Open();
                netif.Connect(PPPSerialModem.AuthenticationType.Pap, "", "");
                

                var responseBuffer = new byte[8192];
                int i = 0;
                while (i == 0)
                {
                    i++;

                    using (var req = HttpWebRequest.Create("http://www.bing.com/robots.txt") as HttpWebRequest)
                    {
                        req.KeepAlive = false;
                        req.ContentLength = 0;

                        using (var res = req.GetResponse() as HttpWebResponse)
                        {
                            using (var stream = res.GetResponseStream())
                            {
                                int read = 0, total = 0;

                                do
                                {
                                    read = stream.Read(responseBuffer, 0, responseBuffer.Length);
                                    total += read;

                                    Thread.Sleep(20);
                                } while (read != 0);

                                //Debug.Print(new string(Encoding.UTF8.GetChars(responseBuffer)));
                            }
                        }
                    }
                }
            }

            while (_ldr1.Read() == true)
            {
                Thread.Sleep(500);
                Mainboard.SetDebugLED(ledsts);
                ledsts = !ledsts;
                Debug.Print("Press ldr to enter hibernate 2nd time.");

            }
           // Test RTC second time
            RealTimeClock.SetAlarm(RealTimeClock.GetDateTime().AddSeconds(180));
            Debug.Print("Now is            : " + RealTimeClock.GetDateTime().Date + "-" + RealTimeClock.GetDateTime().Month + "-" + RealTimeClock.GetDateTime().Date + " - " + RealTimeClock.GetDateTime().Hour + ":" + RealTimeClock.GetDateTime().Minute + ":" + RealTimeClock.GetDateTime().Second);
            Debug.Print("Will wake up at: " + RealTimeClock.GetAlarm().Date + "-" + RealTimeClock.GetAlarm().Month + "-" + RealTimeClock.GetAlarm().Date + " - " + RealTimeClock.GetAlarm().Hour + ":" + RealTimeClock.GetAlarm().Minute + ":" + RealTimeClock.GetAlarm().Second);
            Debug.Print("Entering Hibernate mode - after accessing network");
            PowerState.WakeupEvents |= HardwareEvent.OEMReserved2;            
            PowerState.Sleep(SleepLevel.DeepSleep, HardwareEvent.OEMReserved2);            
            
            while (_ldr1.Read() == true)
            {
                Thread.Sleep(500);
                Mainboard.SetDebugLED(ledsts);
                ledsts = !ledsts;
                Debug.Print("Test is done.");
                Debug.Print("Now is            : " + RealTimeClock.GetDateTime().Date + "-" + RealTimeClock.GetDateTime().Month + "-" + RealTimeClock.GetDateTime().Date + " - " + RealTimeClock.GetDateTime().Hour + ":" + RealTimeClock.GetDateTime().Minute + ":" + RealTimeClock.GetDateTime().Second);

            }

        }

        private void SendAT(string command)
        {
            command += "\r";

            var sendBuffer = Encoding.UTF8.GetBytes(command);
            var readBuffer = new byte[256];
            var read = 0;

            port.Write(sendBuffer, 0, sendBuffer.Length);

            while (true)
            {
                read += port.Read(readBuffer, read, readBuffer.Length - read);

                var response = new string(Encoding.UTF8.GetChars(readBuffer, 0, read));

                if (response.IndexOf("OK") != -1 || response.IndexOf("CONNECT") != -1)
                    break;
            }
        }

    }
}

Hi Dat,

Your code works ok on my board, but again you are not using a cellular radio board… As soon i add the code to add cellular radio, RTC always wakes up after 1 minute…

I have moved all the code to a new Thread (so ProgramStarted() returns immediately) and the loop was to test the deepsleep (with OFF i removed it), but still doesn’t matter, RTC does not work as it should…

Can you test it again with a CR attached?

Thanks

@ geologic -

I was using cellular radio board. I just did not use its driver. The problem can be in CR driver. While we are looking on it, you can modify this driver.

How did you connect cellular radio to cobra? I want to try the same way you did…

The code I posted is used for socket 5 on FEZ Cobra II (COM1).
But I also tried on COM2 ( socket 8 ) with FEZ Cobra II Ext.

They work well.

I don’t know how to exprees my feelings about this… :frowning:

1 - your code worked great, i didn’t realise we coud connect CR to socket 5 and use it like a COM port. I just remove the “button press” stuff so when the board is powered on it connects to the network and sends the WebRequest . (DHL is on the way to Dat’s home with a box of beers…)

2 - I changed your code from “deepsleep” to “off”, hoping that my CR would send a request every 2 minutes (reboot, send request, sleep, wakeup, reboot…)… Wrong! it sends the first request, goes to sleep, wakes up, reboot, but it hangs on this line:


(At this time i call DHL back...)

3 - i get back to deepsleep and add a infinite loop to try the same thing (send message, sleep, wakeup, send message....)

```cs
While (1==1) {
     using (var netif = new PPPSerialModem(port))
     (...)
     PowerState.Sleep(SleepLevel.DeepSleep, HardwareEvent.OEMReserved2);
}

Same problem as above, it sends the first request ok, the second hangs…

4 - looking to original Dat code i realise that it waits for the http request to complete and then goes to the sleep stuff (i removed the button part), so i moved the sleep code inside the while loop and commented the “i++” line. This way i have the same infinite loop with a deepsleep. When running the code what appened??? it sends several request ok BUT every 1 minute… ??? (This time i wrapped a letter bomb and call the DHL guy again…)

So bottom line:

  • I can do a deepsleep/off but can only send a request
  • to send several requests, deepsleep/off wakes up after 1 minute…

I’m so fustrated!

@ geologic -

[quote]- I can do a deepsleep/off but can only send a request

  • to send several requests, deepsleep/off wakes up after 1 minute…[/quote]

Unfortunately I still can not reproduce.

For deepsleep, I can send more than 1 request, alarm still work correctly
For off mode, I can send more than 1 request, alarm still work correctly. But after the board wake up (actually reset), send AT command will raise an exception. I am thinking about 2 issues:

  • UART work incorrectly after wake up from off mode
  • Or the CR module needs to be reset.

We will look into this later but really don’t know how to reproduce your problem “wakes up after 1 minute”.

I see a DHL guy is carrying a box of beer coming my house but suddenly he turn back and go away. So now I know why. :smiley:

HURRAY!!!

Finaly i got this thing to work!!!
I was looking for a way to reset/poweroff the CR module and found this page:
http://wiki.epalsite.com/index.php?title=SIM900_Quad-Band_GPRS_shield_with_Micro_SD_card_slot
Managing PWRKEY pin will do the trick, so i created a GPIO mapped to pin3, get back to sleep.off and before sleeping the board i turn CR off:

// GPIO Mapped to PWRKEY
GT.Socket Socket;
Gadgeteer.SocketInterfaces.DigitalIO digital;
Socket = GT.Socket.GetSocket(5, true, null, null);
digital = GT.SocketInterfaces.DigitalIOFactory.Create(Socket, GT.Socket.Pin.Three, false, GT.SocketInterfaces.GlitchFilterMode.Off, GT.SocketInterfaces.ResistorMode.PullUp, null);

// to power off: LOW > 1sec, HIGH > 1,7sec
digital.Write(false);
Thread.Sleep(1500);
digital.Write(true);
Thread.Sleep(2000);

//call sleep.off
PowerState.Sleep(SleepLevel.Off, HardwareEvent.OEMReserved2);

Thank you all for your help.

@ geologic - really good. Persistency matters.

Maybe you could summarize your findings a little more explicitly. I think you have been stumbling over quite a few interesting learnings. :think:

@ geologic - The CellularRadio driver has two methods, PowerOn and PowerOff, that toggle pin 3 like you did. You can always see if they work as well.

Yes, sure.

1 - latest CR driver doesn’t work together with deepsleep/off. The code showed at Cellular Radio Module page makes the RTC wake up every 1 minute, no matter what time i set to;

2 - CR module without the driver (using PPP) worked ok for me, but when sending several requests, the code hangs after the first sleep, throwing an exception

3 - To get thinks to work, before calling sleep.off i powered off the CR module using the PWRKEY pin. Basically i mapped pin 3 as a digitalInput and set it to LOW/HIGH as i mentioned on the previous post.

Now i have my cobra sending some data to my webservice.

;D

I tried that too, but didn’t work. The CR doesn´t power off with PowerOff() method, i still can see the leds on. Setting PWRKEY to LOW/HIGH, i see the leds going off.

Ops… if i am drinking beer, what did i sent to Dat???