I am trying to read weight from digital scale in c# app, found this question
this is exactly what I am trying to do
but for me below function never runs.
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(DoUpdate));
}
I have checked the scale in device manager, its location is set to Port_#0004.Hub_#0003 and appear to be working fine
I was not sure about port number of the scale so I did
var test = SerialPort.GetPortNames();
and only COM1 gets returned
Edit 1: When I do int a = port.ReadByte(); my application hangs and execution never moves forward from this statement.
I faced a problem like this and I solved it changing a COM configuration (Configuration > Comunication > Conections) to SICS in the device. I don't know your scale model but maybe my code can help. [Reading data from Mettler Toledo (IND560) scale device using C#]
Could you try polling instead of using the DataReceived event? Also, I believe the DataReceived event has a threshold before it fires, you might want to look into that too.
Are you able to get the serial number from the balance? This should be the first thing you do when connecting. It will let you verify the connection is established. If you are having trouble connecting through a C# interface try using HyperTerminal first. You can vary a lot of setting really quickly and dial in on the right ones to use. Although the balance should be able to use a wide variety of baud rates and stop bits and such. They are usually pretty adaptable. But do try HyperTerminal.
I'm looking for the pdf but there is a very long list of available commands (depending on your model). The pdf is like 130 pages long. Have you read this?
Please see this post, I used Mike library to connect.
using System;
using System.Linq;
using System.Text;
using HidLibrary;
namespace MagtekCardReader
{
class Program
{
private const int VendorId = 0x0801;
private const int ProductId = 0x0002;
private static HidDevice _device;
static void Main()
{
_device = HidDevices.Enumerate(VendorId, ProductId).FirstOrDefault();
if (_device != null)
{
_device.OpenDevice();
_device.Inserted += DeviceAttachedHandler;
_device.Removed += DeviceRemovedHandler;
_device.MonitorDeviceEvents = true;
_device.ReadReport(OnReport);
Console.WriteLine("Reader found, press any key to exit.");
Console.ReadKey();
_device.CloseDevice();
}
else
{
Console.WriteLine("Could not find reader.");
Console.ReadKey();
}
}
private static void OnReport(HidReport report)
{
if (!_device.IsConnected) { return; }
var cardData = new Data(report.Data);
Console.WriteLine(!cardData.Error ? Encoding.ASCII.GetString(cardData.CardData) : cardData.ErrorMessage);
_device.ReadReport(OnReport);
}
private static void DeviceAttachedHandler()
{
Console.WriteLine("Device attached.");
_device.ReadReport(OnReport);
}
private static void DeviceRemovedHandler()
{
Console.WriteLine("Device removed.");
}
}
}
Related
I have a stream of strings coming in via serial Port continuously at a fixed baud rate. And I need to separate a specific string every time it is received, split it into useful parts and print those parts in Winform interface. Any help and/or example is appreciated
I am receiving GPS data and have connected it to PC via UART to serial port. Setting up serial port with WinForms and receiving data is no problem. Placing filters to synthesize required messages and handling them is what I need help for.
////////////// This code is only for reference to the GUI ////////////
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Clear_Click(object sender, EventArgs e)
{
richTextBox1.Clear();
}
private void Start_Click(object sender, EventArgs e)
{
serialPort1.Open();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
richTextBox1.ScrollToCaret();
}
private void Read_Click(object sender, EventArgs e)
{
string data = serialPort1.ReadExisting(); //reads the whole
readbuffer
if (data.Length >= 10)
{
richTextBox1.Text = data;
}
}
private void Stop_Click(object sender, EventArgs e)
{
serialPort1.Close();
}
}
}
For Example: If you see the GPS data in the image
(link: https://www.google.com/imgres?imgurl=https%3A%2F%2Fidyl.io%2Fwp-content%2Fuploads%2F2017%2F05%2Fraw-gps-data-8.png&imgrefurl=https%3A%2F%2Fidyl.io%2Farduino%2Fhow-to%2Finterface-gps-module-arduino%2F&docid=zNdHsCmZc93QIM&tbnid=P0_E1tvN1Ur0HM%3A&vet=10ahUKEwjh9NudvqTgAhVL4eAKHYtyDHYQMwhbKA0wDQ..i&w=597&h=496&bih=938&biw=1920&q=gps%20data&ved=0ahUKEwjh9NudvqTgAhVL4eAKHYtyDHYQMwhbKA0wDQ&iact=mrc&uact=8#h=496&imgdii=P0_E1tvN1Ur0HM:&vet=10ahUKEwjh9NudvqTgAhVL4eAKHYtyDHYQMwhbKA0wDQ..i&w=597)
you will see that different messages are coming in cyclic order. I am interested in every message that starts with "$GPGGA". I want to read only this message every time it occurs, split it into useful parts, print them, and then go back to receive the next message that starts with "$GPGGA".
Note: When reception is not good, gps skips the positions in message that are reserved for actual readings so the string size gets smaller.
You could do this with a regular expression, or by splitting the received string using '$' - since each line starts with this character.
// Holds the partial/unprocessed data we've read from the serial port.
private string _serialRxString = string.Empty;
private void Start_Click(object sender, EventArgs e)
{
serialRxString = string.Empty;
serialPort1.Open();
}
private void Read_Click(object sender, EventArgs e)
{
// Add the new data to what we have.
_serialRxString += serialPort1.ReadExisting();
// Each line starts with a '$'.
string[] lines = _serialRxString.Split(
new char[] { '$' },
StringSplitOptions.None);
// Don't process the last one yet, it might not be complete.
for (int i = 0; i < lines.Length - 1; i++)
{
// Check if it's the line we're looking for.
if (lines[i].StartsWith("GPGGA"))
{
string[] values = lines[i].Split(new char[] { ',' });
// Do what you want with the values from the $GPGGA line.
}
}
// Keep the last line, since it might not be complete yet.
_serialRxString = lines.Last();
}
You also might want to subscribe to the serial port data received event. This way any data received on the serial port will automatically be processed, without having to click the read button. You can do this either through the designer or in your form constructor. Then the data received event would be the same as what's in the Read_Click function above.
To subscribe to the DataReceived event in the designer:
Or in the constructor:
public Form1()
{
InitializeComponent();
serialPort1.DataReceived += serialPort1_DataReceived;
}
The data received event then would be:
private void serialPort1_DataReceived(
object sender,
SerialDataReceivedEventArgs e)
{
// Add the new data to what we have.
_serialRxString += serialPort1.ReadExisting();
// Each line starts with a '$'.
string[] lines = _serialRxString.Split(
new char[] { '$' },
StringSplitOptions.None);
// Don't process the last one yet, it might not be complete.
for (int i = 0; i < lines.Length - 1; i++)
{
// Check if it's the line we're looking for.
if (lines[i].StartsWith("GPGGA"))
{
string[] values = lines[i].Split(new char[] { ',' });
// Do what you want with the values from the $GPGGA line.
}
}
// Keep the last line, since it might not be complete yet.
_serialRxString = lines.Last();
}
Then whenever anything is received on the serial port this function automatically gets called.
There are also some packages available for parsing NMEA messages that might be helpful. Such as this one: NmeaParser
I feel like this question comes up a lot. You've already done the hard part, that is sending/receiving data. Now you just need to parse it. Looks like from the example image, everything is comma delimited and each line ends with a Carriage Return Line Feed. See my answer to this, you should be able to build a string for each line then split it on commas and get the field you are looking for.
I'm new to the Arduino and serial communication, and I haven't coded in a while, but I'm trying to do what I think should be fairly simple, and have been having plenty of trouble. What I'd like to do is to create a simple GUI on Windows Forms and control a Arduino. I keep seeming to run into different problems every new session.
What I've been trying to do is to create a simple GUI that can toggle an LED on and off, and then to use NumericUpDown to toggle it blinking. Previously, I could get the numericUpDown to toggle values but nothing happens, now if I try and toggle, it tells me the port is closed. I've been trying different port communication methods. Since the Form is saying my port is closed, I cannot test to see if what I've written works. Please ignore the commented code as I'm still trying different things.
When I try to call the blink function, it hasn't blinked properly inside a if statement compared to if I kept it in the loop. I'm not sure how and where to send the value from the Winform to the Arduino.
Is Winform much different than using serial monitor commands?
EDIT1: I stepped away from my computer and now when I run the Windows Form, it shows no errors but The program has exited with code 0 (0x0). I've had the timer and haven't really messed with it yet but it wasn't telling me this error earlier and was running the form fine.
My Arduino Code:
// Define Function Prototypes that use User Types below here or use a .h file
int dorun;
int Blinks;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
getBlinks();
}
// the loop function runs over and over again forever
void loop()
{
if (Serial.available() > 0)
/*
{
byte Blinktimes = Serial.readBytes[];
}
*/
{
String serialInput = Serial.readString();
//Toggle LED
if (serialInput == "On")
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); //I have this just to see that the LED is staying on and off, and will need to change things.
for (int x = 1; x = Blinks; x++)
{
blink();
}
}
else
{
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (LOW is the voltage level)
}
Serial.flush(); //Clear Serial
}
/*
digitalWrite(LED_BUILTIN, HIGH);
if ((Serial.available()))
{
int dorun = Serial.read();
if (dorun = 1)
{
blink();
}
else
{
digitalWrite(LED_BUILTIN, LOW);
}
}
*/
/*turnon();
if (dorun == 1)
{
blink();
}
else
{
digitalWrite(LED_BUILTIN, LOW);
}
*/
}
void getBlinks()
{
byte message[3];
if (Serial.available())
{
Serial.readBytes(message, 3);
Blinks = message[3];
}
}
void blink()
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the
voltage level)
delay(250); // wait for a second
digitalWrite(LED_BUILTIN, LOW); //!digitalRead(LED_BUILTIN); // turn the LED off by making the voltage LOW
delay(1000);
}
void turnon()
{
if (Serial.available()> 0)
{
String run = Serial.readString();
if (run == "Run")
{
dorun == 1;
}
if (run == "Off")
{
dorun == 0;
}
}
}
My Windows Form Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace WindowsFormsApp9
{
public partial class Form1 : Form
{
SerialPort serial; // create serial port
/*
* public class Port
{
public string Name { get; set; }
public int Value { get; set; }
public Port(string n, int i)
{
Name = n;
Value = i;
}
}
*/
SerialPort port;
string[] availablePorts = SerialPort.GetPortNames();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("On");
port.Close();
}
private void button2_Click(object sender, EventArgs e)
{
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Off");
port.Close();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
UpdateBlink();
}
void UpdateBlink()
{
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
const byte messageType = 2;
byte Blinkcount = (byte)numericUpDown1.Value;
byte[] serialBlink = { messageType, Blinkcount };
serialPort1.Write(serialBlink, 0, serialBlink.Length);
port.Close();
}
private void timer1_Tick(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
}
I've been checking out these links:
Click here How I toggle the LED
Click here How to return an int since NumericUpDown returns a decimal
Click [here] (https://www.instructables.com/id/Arduino-Visual-Studio-Serial-Communication/) Arduino Visual Studio Serial communication timer things
Click [here] (https://www.instructables.com/id/Communication-From-a-WinForms-to-a-TinyDuino/) instructions about Winforms to TinyDuino, They should use similar commands as the Arduino right?
So I decided to do a slight overhaul. Instead of trying to deal with sending multiple different types of inputs(String and int) I have decided to just change everything into a byte array and then send it all at once.
Regarding 1. I was really just wondering if it'd be alright to create a function to return a value rather than just building the code in a void function. So I tried it and it worked, hence the change. From what I understood and saw that your protected override bool ProcessCmdKey, basically you wanted to see if the key was an arrow key. If it was return true. So what I did was basically if it's one of the selected colors, return a value corresponding to the color.
I was just hoping you could either help me understand the Serial and COM port connection or if you had a link for more explanation. Earlier when I was trying to send a string(On/Off) and then send a numeric(byte/int) to set a number of blink times, I couldn't figure out if the COM port is kind of like a singular channel. If I'm sending a string from the Windows Form, could I send out a int/byte in the same channel? Now that everything is of one keyword (byte) I can just create a byte array and figure out the communication between the Windows Form and Arduino. I'm a little confused about the underlying Serial aspect. When I saw your code I started to think a little differently.
In your code, if I'm understanding it properly, it seems that MyVCOM is how to communicate back and forth, just like port.Write. I believe it's singular as it's basically like the old telephone line, if I'm on a call, and you call try to call me, your call is blocked since my line is already being used.
So in your ConnReset, you want to make sure the COM's aren't open so you can set up communication. So your ConReset will clear the line if it's open already. What I'm confused about is the else part. If your port isn't open, open COM+PortNumber, so basically open the channel so you can communicate, but you declared port number to be 8, so shouldn't you just use:
MyVCOM.PortName = "COM8";
Where does the user select which COM? All of the communication is being done on COM8 isn't it? Or does is that part all part of a built in library? I believe all I need to do now is to send my byte array to my Arduino and then work on the Back End to take the data the Windows Form is sending.
public int Colorselection(string label3, int color) //Toggle a pin
{
if (label3 == "Red")
{
color = 6;
}
else if (label3 == "Green")
{
color = 5;
}
else if (label3 == "Blue")
{
color = 3;
}
return color;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
String label4 = LEDColor.SelectedItem.ToString(); //Generate A string of selected Color
int xled = Colorselection(label4, color); //Toggle the string into an int
LEDLabel.Text = xled.ToString(); //Generate a string from the int
}
private void Run_Click(object sender, EventArgs e) //Generate byte to send instead of sending strings and int/byte
{
byte RGBLED = Convert.ToByte(color);
byte BlinkNum = Convert.ToByte(number1.Value);
byte BlinkDur = Convert.ToByte(number2.Value);
byte[] array2 = new byte[] { RGBLED, BlinkNum, BlinkDur };
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
/*
port.Open();
port.Write(array2, 0, 2);
port.Close();
*/
}
Your WinForms application assumes that your Arduino is connected to COM3. Do you know if that's actually the case, or is that sample code that you just copy and pasted? (Check the Windows Device Manager under COM ports to see what ports are available, then unplug/plug your device to see which port it's being mapped to)
Besides that, have you tried debugging your Arduino code on target to see what, if anything, is actually being received?
From the MS documentation, it's not clear how the SerialPort.Write command works exactly in terms of synchronization, so it may not be a great idea to close the port immediately after sending your command. Unfortunately, since I'm not in possession of an Arduino I can't test your code. But I did create a WinForms GUI to accomplish essentially the same task (and more that you probably don't need) several years ago that I've since posted to github (https://github.com/mbhul/RoboCOM). Let me know if that helps, otherwise please tell us more about your development environment.
I am a noob looking for help. Here is my problem. I have an Arduino Uno with two servomotors; one attached to pin 10, the other to pin 11. I want the servos to move independently according to instructions sent through a serial port to the Arduino from Python on Windows. As such I need Arduino code and Python code. I have used both Python 2.7 and 3.6 with pySerial installed. So far I have only been able to move the servos when using C# to send the coordinates to the Arduino, or from the Arduino code itself. Here is the code. I do not take credit for the Arduino code or the C# code.
Arduino code (Credit to Michael Reeves)
#include<Servo.h>
Servo serX;
Servo serY;
String serialData;
void setup() {
serX.attach(10);
serY.attach(11);
Serial.begin(9600);
Serial.setTimeout(10);
}
void loop() {
}
void serialEvent() {
serialData = Serial.readString();
serX.write(parseDataX(serialData));
serY.write(parseDataY(serialData));
}
int parseDataX(String data){
data.remove(data.indexOf("Y"));
data.remove(data.indexOf("X"), 1);
return data.toInt();
}
int parseDataY(String data){
data.remove(0, data.indexOf("Y") + 1);
return data.toInt();
}
I know that the Arduino code works because I can write to the servos within it and the servos respond correctly. It is also working with C#.
C# code (Credit to Michael Reeves):
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
namespace LaserControl {
public partial class Form1 : Form {
public Stopwatch watch { get; set; }
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, System.EventArgs e) {
watch = Stopwatch.StartNew();
port.Open();
}
private void Form1_MouseMove(object sender, MouseEventArgs e) {
writeToPort(new Point(e.X, e.Y));
}
public void writeToPort(Point coordinates) {
if (watch.ElapsedMilliseconds > 15) {
watch = Stopwatch.StartNew();
port.Write(string.Format("X{0}Y{1}", (180 - coordinates.X / (Size.Width / 180)), (coordinates.Y / (Size.Height / 180))));
System.Diagnostics.Debug.WriteLine(string.Format("X{0}Y{1}", (coordinates.X / (Size.Width / 180)), (coordinates.Y / (Size.Height / 180))));
}
}
}
}
This code takes mouse input from a form and sends it to the servos. The data structure is a string that looks like this "X90Y100", where the letters correspond to servos and the numbers are the angle.
It is working and the servos move correctly.
Here is the Python code. It is simply a test of moving the servos.
import serial
port = serial.Serial("COM3", 9600)
port.write(b"X100Y70")
The servos do not move. What is the problem?
Any help would be greatly appreciated.
Thank you.
The answer is on this page: Arduino and Python
It is worth noting that the example above will not work on a Windows
machine; the Arduino serial device takes some time to load, and when a
serial connection is established it resets the Arduino.
Any write() commands issued before the device initialised will be
lost. A robust server side script will read from the serial port until
the Arduino declares itself ready, and then issue write commands.
Alternatively It is possible to work around this issue by simply
placing a 'time.sleep(2)' call between the serial connection and the
write call.
I've tested it and it works with the delay added:
import serial
import time
port = serial.Serial("COM3", 9600)
time.sleep(2)
port.write(b"X100Y70")
You should consider a more robust message format. At the least, it should have a terminator char (like "\n"). Serial.readString(); relies on a timeout to determine when a complete message has been received. This can cause errors. You can change your message format to have a terminator (or a fixed size):
void serialEvent() {
static String serialData;
while (Serial.available()) {
char c = (char)Serial.read();
if (c == '\n') {
// Complete message, call a function to handle it
serX.write(parseDataX(serialData));
serY.write(parseDataY(serialData));
// Reset for next message
serialData = "";
}
else {
// Otherwise keep building the message
serialData += c;
}
}
Life status of device connected via serial port.
Hello everyone.
How can I check if the device responds to the request? I'm googling this for couple days and tried lot of solutions also from SO, but nothing gave me results that I've expected. After lot of tries I'm in point described below. I think I'm very close but now I need little help, so thanks for every answer in advance.
The current situation
What am I doing right now is very simple. First of all I'm opening serial port serialPort.Open() at very beggining of app (data is receiving almost all the application running time).
As this is just an example in my form is only one label called labelStatus and labelStatus.Text = "Not connected"
Next I'm adding a timer and it's tick method, that contains execute of serialPort.Write(). Timer Interval is set to 100 if that matters.
private void timer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
}
}
Next step is create DataReceived event like below (very simplified version, in my app received data is parsing to floats and storing in array, but it's just to show the problem)
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
One last thing is create ErrorReceived method.
private void serialPort_ErrorReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Not connected"));
}
Untill now everything works brilliant. Sending data works. DataReceived event is executig each 100 miliseconds when data is send. My data is received properly with no problems. When I start application labelStatus text is "Not connected" (device cable is not plugged in). When I plugged in device labelStatus text changing to "Connected". But now when I plugged of cable ErrorReceived event is not executing and labelStatus text is still "Connected". So as I've asked before: How can I check is device still connected to computer? (Or maybe: how to execute ErrorReceived event, when data is not receiving?).
Note: Serial port ReadTimeout is set to 300 miliseconds.
What have I tried
I've tried lot of things but this one in my head seems to should work but doesn't.
I've modified DataReceived event and I've put serialPort.ReadLine() into try/catch block with TimeoutException where I've tried to manually execute ErrorReceived method like below
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
catch (TimeoutException)
{
serialPort_ErrorReceived(null, null);
}
}
I was hoping that will work like I want.
BTW. Sorry for my English. It's not perfect, but I do my best. Cheers!
Listen to the WM_DEVICECHANGE event that will be fired when a device is removed or inserted.
Here is an example of a implementation and some more information:
Detect serial port insertion/removal
http://www.codemiles.com/download/file.php?id=719 (USB Sample)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363480(v=vs.85).aspx
This is solution in my case
Regarding to Martjin's answer i need to further explain my situation. First of all I want to say that I'm not installing any hardware into my computer, so in my opinion WM_DEVICECHANGE event was not what i need (but of course thanks for information, I've learned something new). Application is reading data from scale. Scale after plug into com port is not sending any data and actually there's no communication between it and computer at all. The only way to read data is to send request to scale, so I have to rely on that.
First try
The plan:
Add two static int fields (flags) checkOld and checkNew,
increment checkNew in DataReceived, check in timer Tick method
is checkOld is equal to checkNew. If true that means checkNew
was not increment, and that means DataReceived was not executed.
`
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
checkNew++;
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
private void timer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
}
if (checkOld == checkNew)
{
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Not connected"));
}
}
`
The plan was good but when I've tested it result was not even good. What happened? Actually device status was blinking connected-not connected-connected-not connected etc. I've wrote some data to output and get answer. The timer was looping so fast that DataReceived event could not always increment checkNew value.
Final solution
Based on what I had at the moment I've decided to add some little changes. Instead of comparing two integers values try to collect couple last values ad check if all were the sem or not.
The plan:
Add three static fields: first six elements array of integers
statusArray, second integer index with value equals to 6 (last
element of array + 1), third integer checkNew,
increment checkNew in
DataReceived event,
in timer Tick event fill array to index,
decrement index value untill whole array is filled, and if index == 0 reset index value to
6,
and last check if last six values of checkNew, stored in
statusArray are the same. If true that means DataReceived did not
executed six times in a row, and now I can be sure that connection is
lost.
`
static int index = 6;
static int checkNew = 0;
static int[] statusArray = {0,0,0,0,0,0};
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
checkNew++;
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
private void timer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
}
if (index == 0)
index = 6;
index--;
int value = statusArray[index] = checkNew;
}
`
i try OpenNETCF for Open and close Wlan on win ce - and no Success !!
i try this:
[DllImport("coredll.dll", SetLastError = true)]
private static extern int SetDevicePower(string pvDevice, int dwDeviceFlags, DevicePowerState DeviceState);
private enum DevicePowerState : int
{
Unspecified = -1,
D0 = 0, // Full On: full power, full functionality
D1, // Low Power On: fully functional at low power/performance
D2, // Standby: partially powered with automatic wake
D3, // Sleep: partially powered with device initiated wake
D4, // Off: unpowered
}
private const int POWER_NAME = 0x00000001;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string driver = FindDriverKey();
SetDevicePower(driver, POWER_NAME, DevicePowerState.D0);
}
private void button2_Click(object sender, EventArgs e)
{
string driver = FindDriverKey();
SetDevicePower(driver, POWER_NAME, DevicePowerState.D4);
}
private static string FindDriverKey()
{
string ret = string.Empty;
string WiFiDriverClass = "{98C5250D-C29A-4985-AE5F-AFE5367E5006}";
foreach (string tmp in Registry.LocalMachine.OpenSubKey("\\System\\CurrentControlSet\\Control\\Power\\State", false).GetValueNames())
{
if (tmp.Contains(WiFiDriverClass))
{
ret = tmp;
break;
}
}
return ret;
}
}
and still no Success !!
how to open and close WIFI on win ce ? (no windows-mobile)
is it possible at all using C# code ?
thanks for any help
There is an API that may or may not be included in your CE build, in ossvcs.dll. You can use GetWirelessDevices() and ChangeRadioState() to turn radios on/off. You'll need to pinvoke ossvcs.dll
Pinvoke example here
Support for this greatly depends on the WiFi adapter, driver and the OS image your OEM provided. It seems you've tried the obvious stuff (SetDevicePower, CHangeRadioStatre, etc) so assuming you did this all correctly (I've not verified the driver class GUIKLD you used), then the poower for the radio could very well not be exposed, or may only be exposed via a proprietary API. Is the radio a plug-in type, or is it built into the hardware? What type of hardware is this? Have you checked with the OEM? Can you turn it off via the Control Panel (that would at least indicate if you do or don't have an API). It's quite possible that the radio is hard-wired for power or it's coming from something like a CPLD. Only the device OEM would really know.