PocketPC SerialPort and turning off/on the device

Hi,

Here a simple C# example that reads data from a GPS Device
Assume two Buttons on the form and one Textbox.
Further a SerialPort with the DataReceived Event handled in the form.



publicclassForm1 :Form {
publicdelegatevoidSetText(string strPar);
publicSetText myDelegate;

public
Form1() {

InitializeComponent();

}

privatevoid Form1_Load(object sender,EventArgs e) {
myDelegate =
newSetText(SetTheText);
serialPort1.BaudRate = 4800;
serialPort1.Handshake = System.IO.Ports.
Handshake.None;
}

privatevoid serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) {
string strErg=serialPort1.ReadExisting();
this.Invoke(this.myDelegate,newobject[] { strErg });
}

privatevoid SetTheText(string strText) {
textBox1.Text=strText;
}

privatevoid btnOpen_Click(object sender,EventArgs e) {
serialPort1.Open();
}

privatevoid btnZu_Click(object sender,EventArgs e) {
serialPort1.Close();
}


When i turn the power of the device off and back on -- there comes no data from the SerialPort.
After Close(); and Open(); it works again.

Is this by design (so I have to handle power up events) or a problem?

Cheers

Manfred

[4692 byte] By [ManniAT] at [2008-1-27]
# 1
Hi Manfred,

Regarding the issue, do you mean that the DataReceived event of the SerialPort class works properly until you power off the device and then switch it back on, when the event does not fire until you close and re-open the port?

Cheers,
Anthony

AnthonyWong at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 2
Hi Anthony,

I mean that after power off/on only rare data (or nothing) is sent from the serial port.
Or in other words - I don't think the event isn't fired correctly.
Because (sometimes) the event is fired and since I read all the received data it should then bring a lot of text in my textbox. But it does not.
To see all whats coming just replace the textBox1.Text=... with textBox1.Text+=

So I think this has the reason in not receiving (or almost not) anymore from the comport.
I use an IPAQ 3070 clean setup (hardreset) with just this onyl one app installed on it.

The solution would be easy if MS had provided a "PowerEvent" for the PPC.
So we can do two three things -
a.) hope that this will be fixed
b.) write a simple driver (drivers get Power notifications) an let it inform my app
c.) write some kind of watchdog

Solution c.) is possilbe in this case since a GPS device sends at least n bytes per second - and if those bytes are not receive - i just have to close / reopen the SerialPort.

The only problem with it is if a user remove the device from the (lets say) car cradle I will also not receive any data - and reopen would not help.
I couldn't find any "Craddled status" (or "OnAuxPower status") in the .NET CF - so it's hard to detect whats going on.
And last not least if I use (for an example) a BarcodeReader which doesn't send data continuously this thing wont work too.

So we had a lot of hope for the new .NET CF 2.0 but since extreme essential things
--power notfications
--status informations
--reliable SerialPort class :-)
are still missing we have to go on using our "Private driver" which notifies us about power status changes.

Cheers

Manfred

ManniAT at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 3
Hi Manfred,

Thank you for your information. We will definitely consider your suggestions. Did you try the RequestPowerNotifications() API in Windows CE to obtain power notifications? Also, is it possible for you to prevent power suspension on the device by P/Invoking into SystemIdleTimerReset()?

Cheers,
Anthony

AnthonyWong at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 4
Hi Anthony,

RequestPowerNotification I think is not available in PPC 2003.
So we keep on having our Driver with the notification message.

The SystemIdleTimerReset would help - but nor for a user pressing the button :-)
By the way - we made settings, that the is no "AutoOff" if Powerconnected.
And as long as the device recides in the cradle there is power. When it is removed, there is no need to stay running - since GPS Data comes also from the cradle.

To be precise - our problem is not that the device can be powered off - that is OK an usefull (save battery life).
Our problem is that the SerialPort class fails to work correct after a power on/off.

Or in other words: Assume: you feel pain when you take a breath.
Do you think it is a solution when I tell to stop breathing? Big SmileBig Smile

I thank you that you tried to help me with this - aspecially the tip with RequestPowerNotification is great since (if available) could help us to prevent the thing with the "PowerNotificatioDriver".

So I would be interested to hear what MS-Guys say about that SerialPort class problems.
By the way I can solve (work around) this one. But for that http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=9843 a driver wont help, since it fails to open the port.

Thankx

Manfred

ManniAT at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 5
Hi Manfred,

RequestPowerNotifications is available on Windows CE since 4.0, and so is available on PPC 2003 as well. NETCF V2 will not be provide managed API for power notifications, but you can create managed wrapper to obtain the power notifications and close/re-open any instances of serial port.

You can refer to my post below for codes of the managed PowerNotifications class:

http://blogs.msdn.com/anthonywong/archive/2005/06/07/426392.aspx

Cheers,
Anthony

AnthonyWong at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 6
Hi Anthony,

thanks for your response - and the code in your BLOG.
I think it is a good base to start from - my thinking that it is not available in PPC 2003 was because in the help there is no word about it.
But I will give it a try - two things I will change -- Close the Q and stop the powernotifications.

One question about your code - is there a practical reason why you dont wait infinite? Or is it just because the "simple shutdown" of the thread?
What I mean is - is there a known problem on waiting for Qs?

By the way - does this also work on Smartphones?

Thanks

Manfred

ManniAT at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 7

Hi Manfred,

I didn't wait infinitely in my code because there was a bug in NETCF V2 that caused the CLR to wait for a thread even if it is a background thread.

I have tried the code on PPC 2003 but not on Smartphone. I suppose the code should work on SP as well.

Cheers,
Anthony

AnthonyWong at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 8
Hi Anthony,

I ported the code to a windows app and I'm playing with it.
But your wrote about "the console add-in" in your blog.
Where can I get it?

Thanks

Manfred

ManniAT at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 9
Hi Manfred,

You can find an implementation of console on Pocket PC at http://www.symbolictools.de/public/pocketconsole/index.htm.

Cheers,
Anthony

AnthonyWong at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 10

Hi Anthony

I've included your code in my project http://blogs.msdn.com/anthonywong/archive/2005/06/07/426392.aspx and found that it works great on a Dell X50 running PPC 2003. I modified the code to use message boxes instead of Console and that seemed to work fine.

One thing I noticed is that since I'm using NETCF V1.1, I get a message when I try to complie regarding the t.Abort(); statement in

public void Stop()
{
done = true;
t.Abort();
}

Error Message: 'System.Threading.Thread' does not contain a definition for 'abort'

So, I just commented out 't.abort()' to get it to compile and it seems to work. My understand is that my code does not stop the power notification thread using the abort command and I'm hoping that it stops the 'DoWork' function by setting the variable done to true which terminates the infinite while loop.

Will the OS clean up this thread when the application is terminated or will threads start to accumulate in the device? If the OS will not clean up the thread, what steps should be taken to terminate the thread?

Thanks

TokenWorks at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 11
Hello All

I

also used your code Anthony. I created a class library with event

handling that I now use in my app. If its OK with Anthony I could post

my changes here?

I don't terminate the thread either. Could this be a problem?

Cheers
Thomas

easygysi at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 12

Thomas

I also added event handling to Anthony's code but it is not working as expected.

I added the following to Anthony's code

public delegate void PowerStatusChangeEventHandler (object sender, System.EventArgs e, string strPowerMessage);

public event PowerStatusChangeEventHandler PowerStatusChanged;

and for the case of 'power on'

case 65536:
msg = "Power On";
System.EventArgs p = new System.EventArgs();
PowerStatusChanged (
this, p, msg);
break;

Then in the code which loads the initial form, I added this.

PowerNotifications pn = new PowerNotifications();
pn.Start();
pn.PowerStatusChanged += new PowerNotifications.PowerStatusChangeEventHandler(this.PowerNotifications_PowerStatusChanged);

And I added this to handle the events in the main application

private void PowerNotifications_PowerStatusChanged (object sender, System.EventArgs e, string strPowerMessage)
{
if (strPowerMessage == "Power On")
code that opens the com port here
}

I'm having a couple problems.
1.) After the application runs and exits, I can't get it to run again without doing a soft reset. I'm guessing its because the thread started by power notification is still running. Not sure

2.) The other problem is the event seems to fire off correctly and my code which should re-open the com port is getting executed but I get a message the the com port is not available or still in use. I'm using the CFSerialIO.dll to manage the com port from Richard Grier

Any help would be greatly appreciated.

TokenWorks at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 13
Hi TokenWorks

I implemented my event handling almost the same (only diffrence is that

I created an inherited class of eventargs to pass the args instead

of using a string).

I only use the power state to close the serialport wenn the PPC is turned of. Opening happens

only when the user tells my app to reopen the port to send or recieve

data. If I needed the port to be open all the time I would also first close

the port before the PPC is turned off, then reopen on the PowerOn

event, maybe this is causing your problem.

My app has no problem with exiting and reopening, even though I don't stop the thread myself.

I rewrote my app to use the .NET CF 2.0 serialport implementation, we

also used Richard Grier's com port implementation before. We rewrote

because it wasn't working on WM5.0 but it still doesn't work on WM5

because of Dells configuration of WM5.0 on the Axim :-(.

Cheers

Thomas

easygysi at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 14

Hi Thomas

We discovered the solution to one of our problems yesterday, which was to put a delay before we opened the serial port after a power up event. We have a UART plugged into the CompactFlash slot and discovered the OS briefly turns on the CF slot after a power on event. We believe the OS accesses the CF card to figure out what is plugged into the CF slot and then turns off the power to the CF slot. Our problem was due to a conflict between drivers accessing the port at the same time. With the delay, we no longer get an exception stating ‘port not available or already in use’

So now our code re-opens the COM port after a power cycle but we still have an issue with being unable to re-launch the application without a soft reset after a power cycle event. If we don't have a power cycle event, then the app terminates fine but once we have a power cycle, a soft reset is required to restart the application.

When we try to install a new version of the code, we get a message stating the program is still in use or in ROM so we surmise part of the program is still running.

What is strange is this problem only starting happening once we added this power notification event. Previously, the application terminated properly and new installations or re-launching wasn’t an issue. We believe it has something to do with the COM port not being closed correctly now that this power notification code has been added to the project.

Thanks for the info on Richard Grier's code. Do you have a post or link that discusses the conflict with Dell's configuration of WM5.0 on the AXIM. We are aware of a bus timing issue with Dell X51 with WM5.0 which violates the CompactFlash specification – See http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=291568&SiteID=1 but if your using the built in COM port of the AXIM, this shouldn’t apply.

Regards

TokenWorks at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 15

Hi Thomas

We figured out the second issue which was related to how we opened the com port after the power off/on cycle. We had the Power On event call our normal open com port code which resulted in a duplicate com port being opened. While the com port worked, it appears the previous com port was still active which is why the code would not relaunch properly. So to solve this, We created a new method which first called the serialport.dispose() method and then reopened the port. Now after a Power On event, we wait 2-3 seconds, and then call this new method.

FYI - we get two events when the unit powers off and on. The first is a Power Suspend Event and then a Power On event. Both occur after the device turns on. We tried putting the serialport.dispose() method on the power suspend event but ran into our previous problem which was not having a delay to allow the OS to access the CF card before calling the disponse method. We also tried calling the serialport.dispose() method with a Power Off event but as mentioned above, we don't seem to get that event when the unit either automatically suspends power or when the power button is hit.

So there are two solutions (at this point) and they are basically the same.
1.) Use the power suspend event to trigger a delay and then execute the serialport.dispose() method, then use the Power On event to open the port as normal
2.) forget the power suspend event and use the power on event to trigger a delay (about 2- 3 seconds), then execute serialport.dispose, then open the port.

Not sure why we don't see the Power Off event. It would have been nice to call the serialport.dispose while the powering off and then use the normal com port opening method after powering back up. Anyways, now that this works, back to developing the rest of our application!

TokenWorks at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 16
Hi TokenWorks

We also use a UART plugged into the CF slot. The only post discussing the timing issue that I know about is the one you linked to.
The built in COM port of the Axim uses standard TTL signals and does not support hardware handshaking. By using this cable: http://www.gomadic.com/dell-axim-x50-rs232-serial-db9-gps-data-cable.html the TTL signals are converted to standard RS232C signal strength but the port still lacks hardware handshaking, so it is of no use to us.

Regards
Thomas

easygysi at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 17
If this has only happened since adding the powernotifications, have you checked that you are closing the handle created by CreateMsgQueue.

Graham

gmk at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 18

Hi

The problem was not with power notifications. It was related to how we opened the com port after the power off/on cycle. We had the Power On event call our normal open com port code which resulted in a second instance of the com port. While this new com port worked, our code did not close both instances of the com port when the application stopped, thus the app. would not relaunch properly. So to solve this, We created a new method which first called the serialport.dispose() method and then reopened the port. Now after a Power On event, we wait 2-3 seconds, and then call this new method.

TokenWorks at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 19
Hi all,

I am coming back to as I am having some issues at the moment.

I am running it on a MC50 PocketPC with Windows Mobile 4.* version 2.

When running the application on the device (that has the console app installed) I always get a flag value of '0', even when taking the device out of the cradle or placing it back into the cradle. Is a known issue with this device?

Thanks

Tryst

Tryst at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 20

Hi all

I try to use the RequestPowerNotifications to catch power up event, but I can't get any event whereas each API call return success code.

I try this sample : http://www.alexfeinman.com/download.asp?doc=PowerAwareApp.zip and then try to code my one, but without more success.

I use WM5 on an iPAQ hx2490 and my sample are build in Vb.net 2005. Did I need to install some more element to be able to use PowerManagement?

Did someone can help me to find what is wrong in the sample?

Thanks for your help

Regards

snorky2001 at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...
# 21

I found the solution in order this sample works but I still have a strange problem.

I use the API RequestPowerNotifications to be warn about power notifications.
It works well with this call and give me Transition notifications:

RequestPowerNotifications(m_hQueue, PowerEventType.PBT_TRANSITION)
but if I use this:

RequestPowerNotifications(m_hQueue, PowerEventType.PBT_TRANSITION Or PowerEventType.PBT_POWERSTATUSCHANGE)
I get no notification at all


I use this prototype
<DllImport("coredll")> _
Private Shared Function RequestPowerNotifications(ByVal _
hMsgQ As IntPtr, _
ByVal Flags As PowerEventType) _
As IntPtr
End Function

Is the mistake in the prototype or in a bad convention I use?

Regards

snorky2001 at 2007-8-21 > top of Msdn Tech,Smart Device Development,.NET Compact Framework...