I am recently writing a wiimote program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
namespace WiiTester
{
public partial class Form1 : Form
{
Wiimote wm = new Wiimote();
public Form1()
{
InitializeComponent();
wm.WiimoteChanged += wm_WiimoteChanged;
wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;
wm.Connect();
wm.SetReportType(InputReport.IRAccel, true);
}
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
{
if (args.Inserted)
{
wm.SetReportType(InputReport.IRExtensionAccel, true);
}
else
{
wm.SetReportType(InputReport.IRAccel, true);
}
}
}
}
My wiimote keeps getting disconnected and this error keeps running on wm.Connect();
Timed out waiting for status report
Is there a solution?
I have a lot of experience with this library, and your problem is most likely being caused because you are calling SetRumble so often, this code:
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
Will call SetRumble constantly whether A is down or not, consider using this code instead:
bool rumbleOn = false;
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
bool newRumble = (ws.ButtonState.A == true);
if (rumbleOn != newRumble)
{
rumbleOn = newRumble;
wm.SetRumble(rumbleOn);
}
}
This way the set rumble method is only called when required and not constantly sending output reports to the WiiMote which causes the Bluetooth BUS to overload.
Related
I'm doing a program for serial communications. To centralize the process of access to serial, created a class.
I am having problem when an exception is lançanda within the class leaves the locked program.
example:
When trying aberir the serial port, can give error and the system is at that point to burst memory.
How should I handle errors?
Put try and catch?
Add another routine?
Error point:
portSerial.Open();
Program
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PortSerial.Lib;
namespace ProgramPortSerial
{
public partial class Form1 : Form {
public static LibPortaSerial portSerial = new LibPortSerial();
public Form1()
{
InitializeComponent();
portSerial.LineReceived += new LineReceivedEventHandler(sp1_LineReceived);
portSerial.Init(
ref cmbPortas,
ref cmbVelocidade,
ref cmbBitsDeDados,
ref cmbPariedade,
ref cmbBitsDeParada,
ref cmbControleDeFluxo);
}
void sp1_LineReceived(object sender, LineReceivedEventArgs Args)
{
// Tem que ser em uma nova thread para não travar
Invoke(new Action(() =>
{
memDadosRecebidos.Text += "\r\n" + Args.Resposta;
}));
}
private void btnAbrirPorta_Click(object sender, EventArgs e)
{
portSerial.Open();
}
}
}
Class PortSerial
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
namespace PortSerial.Lib
{
public class LibPortSerial : IDisposable
{
public SerialPort portSerial;
public LibPortSerial()
{
portSerial = new SerialPort();
}
public void Dispose()
{
if (portSerial != null)
portSerial.Dispose();
}
public void Open(
string port,
int veloc,
int bitsData,
string pariedade,
string bitsStop,
string control)
{
portSerial.PortName = port;
portSerial.BaudRate = veloc;
portSerial.DataBits = bitsData;
portSerial.Parity = SetPariedade(pariedade);
portSerial.StopBits = SetBitsStop(bitsStop);
portSerial.Handshake = Setcontrol(control);
portSerial.Open(); // ==> Erro this point
}
}
}
You should write it as:
public void Open(
string port,
int veloc,
int bitsData,
string pariedade,
string bitsStop,
string control)
{
portSerial.PortName = port;
portSerial.BaudRate = veloc;
portSerial.DataBits = bitsData;
portSerial.Parity = SetPariedade(pariedade);
portSerial.StopBits = SetBitsStop(bitsStop);
portSerial.Handshake = Setcontrol(control);
try
{
portSerial.Open(); // ==> Erro this point
}
catch(IOException exp)
{
return exp.Message;
}
}
I don't have enough rep to comment, so I am posting a question here. I read this question Get list of failing tests from Nunit. I am trying to implement the nunit addin, I used this code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using NUnit.Core.Extensibility;
namespace NunitAddin
{
[NUnitAddinAttribute(Type = ExtensionType.Core,
Name = "addin",
Description = "addin")]
public class NunitAddin : IAddin
{
public bool Install(IExtensionHost host)
{
IExtensionPoint listeners = host.GetExtensionPoint("EventListeners");
if (listeners == null)
return false;
listeners.Install(this);
return true;
}
public void TestStarted(NUnit.Core.TestName testName)
{
}
public void TestFinished(NUnit.Core.TestResult result)
{
}
public void RunStarted(NUnit.Core.TestName testName)
{
}
public void RunFinished(NUnit.Core.TestResult result)
{
}
public void UnhandledException(Exception exception)
{
}
public void TestOutput(NUnit.Core.TestOutput testOutput)
{
}
}
}
But when I call it using
var addin = new NunitAddin.NunitAddin();
var a = addin.Install(CoreExtensions.Host);
I get an error
NunitAddin.NunitAddin is not {0} extension point
on
listeners.Install(this);
Does anyone know how to solve this problem?
Never mind, issue solved. Just a stupid mistake, I had NunitAddin : IAddin instead of NunitAddin : IAddin; EventListener
I have some big trouble with serial requests.
Description from what i want:
establish a serial connection, send serial requests to 6 temperature
sensors one by one (this is done every 0,5 second in a loop)
the question and answer-destination is stored in a List array
every request is started in a separate thread so the gui does not bug
while the programme waits for the sensor-hardware to answer
My problem:
The connection and the request is working fine, but if I am browsing data at the local hard drive the answer from the sensor-unit gets destroyed (negative algebraic sign or value from other sensor or simply wrong value).
How does this happen or how can I solve this?
Where I guess the problem might be:
In the private void ReceiveThread() of class SerialCommunication
Here is my code:
Class CommunicationArray:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hardwarecommunication
{
public class CommunicationArray
{
public string request { get; set; }
public object myObject { get; set; }
public string objectType { get; set; }
}
}
Class SerialCommunication
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.IO.Ports;
using System.Windows.Forms;
namespace Hardwarecommunication
{
class SerialCommunication
{
Thread t2;
Thread t;
private SerialPort serialPort = new SerialPort("COM2", 115200, Parity.Even, 8, StopBits.One);
string serialAnswer = "";
private volatile bool _shouldStop;
private int counter;
List<CommunicationArray> ar = new List<CommunicationArray>();
object[] o = new object[3];
public void addListener(string request, object myObject, string objectType)
{
CommunicationArray sa = new CommunicationArray();
sa.request = request;
sa.myObject = myObject;
sa.objectType = objectType;
ar.Add(sa);
}
public void startListen()
{
t2 = new Thread(() => writeSerialPortThread());
t2.Start();
}
public void startSerialPort2()
{
try
{
serialPort.Open();
//MessageBox.Show("Connection opend!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
public void stopSerialPort2()
{
try
{
if (serialPort.IsOpen == true)
// Connection closed
serialPort.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void writeSerialPortThread()
{
string request = "";
for (int i = 0; i < ar.Count(); i++)
{
request = ar[i].request;
//request = ((object[])ar[0])[0].ToString();
//if (!t.IsAlive)
//{
try
{
t = new Thread(ReceiveThread);
_shouldStop = false;
//MessageBox.Show("start thread");
t.Start();
serialPort.Write(request);
Thread.Sleep(50);
_shouldStop = true;
t.Join();
}
catch
{
}
Label tmpLabelObject = (Label)ar[i].myObject;
serialAnswer = serialAnswer.Replace("=", "");
if (tmpLabelObject.InvokeRequired)
{
MethodInvoker UpdateLabel = delegate
{
tmpLabelObject.Text = serialAnswer;
};
try
{
tmpLabelObject.Invoke(UpdateLabel);
}
catch
{
}
}
}
}
private void ReceiveThread()
{
//MessageBox.Show("in thread");
while (!_shouldStop)
{
serialAnswer = "";
try
{
//MessageBox.Show("in thread");
serialAnswer = serialPort.ReadTo("\r");
if (serialAnswer != "")
{
}
return;
}
catch (TimeoutException) { }
}
}
}
}
Class Form1 //to establish the connection and to start the Sensor request
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;
namespace Hardwarecommunication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SerialCommunication serialCommunication1 = new SerialCommunication();
private void Form1_Load(object sender, EventArgs e)
{
//start up serial connection
serialCommunication1.startSerialPort2();
}
private void buttonStart_Click(object sender, EventArgs e)
{
timerRecord.Enabled = true;
if (this.buttonStart.Text == "Start")
this.buttonStart.Text = "Stop";
else
this.buttonStart.Text = "Start";
}
private void timerRecord_Tick(object sender, EventArgs e)
{
if (this.buttonStart.Text == "Stop")
{
this.serialCommunication1.startListen();
}
}
private void buttonFillRequestArray_Click(object sender, EventArgs e)
{
this.serialCommunication1.addListener("$0BR00\r" + "\r", this.labelResult0, "label0"); //request to the hardware
this.serialCommunication1.addListener("$0BR01\r" + "\r", this.labelResult1, "label1");
this.serialCommunication1.addListener("$01R00\r" + "\r", this.labelResult2, "label2");
this.serialCommunication1.addListener("$01R01\r" + "\r", this.labelResult3, "label3");
this.serialCommunication1.addListener("$01R02\r" + "\r", this.labelResult4, "label4");
}
}
}
I woud be happy about any try to fix the problem.
I coud also upload the solution as .zip but you can't test it at all because you do not have the sensor hardware.
Note: serialPort.Write(string) is a non-blocking store into the output buffer.
That means the following won't guarantee you've even finished writing your request before you stop listening for a response:
serialPort.Write(request);
Thread.Sleep(50);
_shouldStop = true;
You could add:
while( serialPort.BytesToWrite > 0 ) Thread.Sleep(1); // force blocking
but it's ill advised.
One thing I'm wondering. There is only a single serial port here. Why do you want many different threads to work with it when you could manage the entire serial port interaction with a single thread? (Or at worse, 1 thread for input 1 thread for output)
To me it makes a lot more sense to store up requests into a queue of some kind and then peel them off one at a time for processing in a single thread. Responses could be similarly queued up or fired as events back to the caller.
EDIT: If you don't mind one read/write cycle at a time you could try:
string response;
lock(serialPort) {
// serialPort.DiscardInBuffer(); // only if garbage in buffer.
serialPort.Write(request);
response = serialPort.ReadTo("\r"); // this call will block till \r is read.
// be sure \r ends response (only 1)
}
I'm creating a checkout system for a supermarket. It consists of a checkout, server and MIS program an operates WCF services between them. The problem I have is that the checkout program, which is a windows form, does a few neccessaries in it's application_load method and then just quits.
Here's the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CheckoutLibrary;
using Checkout.ServerLibraryService;
using Checkout.MarketService;
namespace Checkout
{
public partial class theForm : Form
{
private static int checkoutID = 3;
private Product[] allProducts;
public theForm()
{
InitializeComponent();
}
private void theForm_Load(object sender, EventArgs e)
{
// First cache all products
SupermarketServiceSoapClient marketService = new SupermarketServiceSoapClient();
allProducts = marketService.GetAllProducts();
// Load the service provided by the server
ServiceClient serverService = new ServiceClient();
// Load the event handlers for the bar code scanner
BarcodeScanner scanner = new BarcodeScanner();
scanner.ItemScanned += new BarcodeScanner.ItemScannedHandler(scanner_ItemScanned);
scanner.AllItemsScanned += new BarcodeScanner.AllItemsScannedHandler(scanner_AllItemsScanned);
scanner.Start(checkoutID);
}
void scanner_AllItemsScanned(EventArgs args)
{
throw new NotImplementedException();
}
void scanner_ItemScanned(ScanEventArgs args)
{
itemTextBox.Text = "Scanned " + GetItemName(args.Barcode);
}
private void scanItemButton_Click(object sender, EventArgs e)
{
scanner_ItemScanned(new ScanEventArgs(GetRandBarcode()));
}
// A barcode -> product name look up method
public string GetItemName(int barcode)
{
return allProducts[barcode].Description + " # " + allProducts[barcode].Price;
}
// Method to grab a random barcode for simulation
private int GetRandBarcode()
{
Random rand = new Random();
return rand.Next(0,500);
}
}
}
And program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Checkout
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new theForm());
}
}
}
Thanks for any insight.
In WinForms, if your form_load throws an exception, it quits without displaying anything. Annoying, but I'm guessing that's the problem.
You can try a try/catch, or you can hit CTRL+ALT+E and check the Thrown Column for Common Language Runtime Exceptions to see the error.
UPDATE:
Based on comments, here's a sample way to execute something on another thread.
ThreadStart ts = new ThreadStart(() => {
try {
scanner.Start(checkoutID);
} catch {
// Log error
}
});
Thread t = new Thread(ts);
t.Start();
I am trying to create a simple service in C# using VS2008 that creates a text file when the computer goes into sleep mode. My current code throws out the following error:
'SleepNotifierService.WqlEventQuery' does not contain a constructor that takes '1' arguments
Now I looked in the Object browser, and it looks like it does take in one argument. This is what the browser had to say:
public WqlEventQuery(string queryOrEventClassName)
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Management;
using System.IO;
namespace SleepNotifierService
{
public class WqlEventQuery : EventQuery { }
public partial class Service1 : ServiceBase
{
ManagementEventWatcher _watcher;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();
}
protected override void OnStop()
{
_watcher.Stop();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
//Log(ex.Message);
}
}
public void Sleep()
{
StreamWriter SW;
SW = File.CreateText("c:\\MyTextFile.txt");
SW.WriteLine("Sleep mode initiated");
SW.Close();
}
public void Resume()
{
}
}
}
Am I interpreting that object browser wrong? I'm new to creating services and C#/.NET in general so it might be something trivial.
Appreciate any help,
Tomek
You're using wrong WqlEventQuery. There's one defined in System.Management and it indeed has a one-argument constructor, but there's also your custom WqlEventQuery class.
If you want to use .NET BCL's class, you'll have to fully qualify it:
var query = new System.Management.WqlEventQuery("Win32_PowerManagementEvent");
or even prefix it with global keyword:
var query = new global::System.Management.WqlEventQuery("Win32_PowerManagementEvent");