WPF writing/confirming write to serial port - events

I am writing a program which writes to a wireless device on the serial port. The firmware has a feature which will confirm the last message sent to the device was ok, so I'm trying to make use of that and update the settings readout on the GUI rather than ask the device for all of its settings every time I make a change. I think my code will explain it a little better:
// global variable
bool queryStatusOK;
//event handler response from serial port
this.QueryStatusReponseEvent += QueryStatusResponse;
private void QueryStatusResponse(byte[] packet)
{
if (packet[3] == 0) queryStatusOK = true;
else queryStatusOK = false;
}
public void setParameter(string device)
{
//send command to serial port to change a single device parameter
Thread.Sleep(100); //sleep thread so 2 commands are not sent at once
//send command to confirm previous command was received
Thread.Sleep(100); //sleep thread to give time for confirmation to receive
if (queryStatusOK)
{
//update GUI at this point
}
}
The program is not consistent. It works sometimes, but not always. Even if I extend the thread sleep to a full second to give the boolean time to update, it still sometimes will not hit it. Can anyone suggest a better way to do this?
Thanks!
Mike

Related

How do I implement a PARTIAL_WAKE_LOCK in Sketchware so that my timer sends SMS even when the screen is off

Hello dear community I am teaching myself app programming via Sketchware.
I'm writing a GPS tracker that does the following.
The user sets a time after which the location data is sent as an SMS. Ex: send location data every 60 minutes.
The battery state of charge is constantly monitored and at 30 percent it sends an SMS to the user to draw attention to it.
My problem now is that no SMS is sent when the screen is off. However, the app does not have to be visible. I read a lot of reports about power management and try to get a PARTIAL_WAKE_LOCK all the time. No matter how I try, it always ends in an error. I would be very happy to get help with my problem.
private void initializeLogic() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");
wl.acquire();
setBG = 0;
VideoView.setVisibility(View.GONE);
setTitle("GPS - Tracker BETA BUILD");
ArabWare = ArabWare.getDefault();
if (geoData.getString("setFirstRun", "").equals("")) {
_setVarDefault();
}
else {
if (geoData.getString("setFirstRun", "").equals("1")) {
_setSplash();
_getStats();
_batState();
_lfzV14();
_testInfo();
}
}
geoData.edit().putString("setFinish", "0").commit();
}
It is not possible for me to implement the PowerManager in the onCreate in Sketchware. Even if I edit the code manually, it always ends up in private void initializeLogic() I'm not getting a wake lock. This instruction PowerManager.WakeLock wl; always leads to an error.
wl cannot be resolved to a variable

How to read data from serial port using C#

I have to create as I thought pretty simple thing. I have physical button and serial port which is in my motherboard. I want to write a program which reads if button is pressed and that is it. The issue is I don't see any COM port in device manager (I use windows 10). Also I read I could receive some data from serial port if I connect 1 and 7 pin together.
Why I couldn't see COM Port and is it possible to make it work like is wrote above?
"Why I couldn't see COM Port"
Solution 1: Sometimes it's just hidden. You need to open Device Manager -> select View tab -> choose Show hidden devices. You might be able to see the Ports (COM & LPT) option.
Solution 2: Update your motherboard drivers.
Solution 3: Manually add your COM Ports. Check out this link.
"How to read data from serial port"
public static void Main()
{
SerialPort mySerialPort = new SerialPort("COM1");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
}
Everytime data comes in, the DataReceivedHandler will trigger and prints your data to the console.
You can check this link out for reference.

CFRunLoopSourceSignal doesn't work

I'm debugging Qt5.3.1 on Mac, because my program freezes sometimes (intermittent ). I discovered that it is because the QTimer can't work properly.
In Qt code, they use the following two lines to trigger function activateTimersSourceCallback
CFRunLoopSourceSignal(d->activateTimersSourceRef);
CFRunLoopWakeUp(mainRunLoop());
void QCocoaEventDispatcherPrivate::activateTimersSourceCallback(void *info)
{
static int counter = 0;
NSLog(#"finished activeteTimersSourceCallback %d", counter++);
}
but sometimes, these two lines doesn't work, activateTimersSourceCallback won't get called.
I googled, but I couldn't find any solution? is this a known OS bug?
the initialization details:
// keep our sources running when modal loops are running
CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode);
CFRunLoopSourceContext context;
bzero(&context, sizeof(CFRunLoopSourceContext));
context.info = d;
context.equal = runLoopSourceEqualCallback;
// source used to activate timers
context.perform = QCocoaEventDispatcherPrivate::activateTimersSourceCallback;
d->activateTimersSourceRef = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
Q_ASSERT(d->activateTimersSourceRef);
CFRunLoopAddSource(mainRunLoop(), d->activateTimersSourceRef, kCFRunLoopCommonModes);
Such behavior very likely can occur when UI event loop is overloaded with events or some business logic takes too long time. You should to check your business logic and move it to separate thread or run asynchronous.

GTK+ - How to listen to an event from within a method?

I'm writing an application that runs an algorithm, but allows you to 'step through' the algorithm by pressing a button - displaying what's happening at each step.
How do I listen for events while within a method?
eg, look at the code I've got.
static int proceed;
button1Event(GtkWidget *widget)
{
proceed = 0;
int i = 0;
for (i=0; i<15; i++) //this is our example 'algorithm'
{
while (proceed ==0) continue;
printf("the nunmber is %d\n", i);
proceed = 0;
}
}
button2Event(GtkWidget *widget)
{
proceed = 1;
}
This doesn't work because it's required to exit out of the button1 method before it can listen for button2 (or any other events).
I'm thinking something like in that while loop.
while(proceed == 0)
{
listen_for_button_click();
}
What method is that?
The "real" answer here (the one any experienced GTK+ programmer will give you) isn't one you will like perhaps: don't do this, your code is structured the wrong way.
The options include:
recommended: restructure the app to be event-driven instead; probably you need to keep track of your state (either a state machine or just a boolean flag) and ignore whichever button is not currently applicable.
you can run a recursive main loop, as in the other answer with gtk_main_iteration(); however this is quite dangerous because any UI event can happen in that loop, such as windows closing or other totally unrelated stuff. Not workable in most real apps of any size.
move the blocking logic to another thread and communicate via a GAsyncQueue or something along those lines (caution, this is hard-ish to get right and likely to be overkill).
I think you are going wrong here:
while(proceed == 0)
{
listen_for_button_click();
}
You don't want while loops like this; you just want the GTK+ main loop doing your blocking. When you get the button click, in the callback for it, then write whatever the code after this while loop would have been.
You could check for pending events & handle the events in while loop in the clicked callback. Something on these lines:
button1Event(GtkWidget *widget)
{
proceed = 0;
int i = 0;
for (i=0; i<15; i++) //this is our example 'algorithm'
{
while (proceed ==0)
{
/* Check for all pending events */
while(gtk_events_pending())
{
gtk_main_iteration(); /* Handle the events */
}
continue;
}
printf("the nunmber is %d\n", i);
proceed = 0;
}
}
This way when the events related click on the second button is added to the event queue to be handled, the check will see the events as pending and handle them & then proceed. This way your global value changes can be reflected & stepping should be possible.
Hope this helps!
If you want to do it like this, the only way that comes to my mind is to create a separate thread for your algorithm and use some synchronization methods to notify that thread from within button click handlers.
GTK+ (glib, to be more specific) has its own API for threads and synchronization. As far as I know Condition variables are a standard way to implement wait-notify logic.

Android Development: Writing a for loop inside onClick with Intent

I am trying to get an application to run 5 times after the user presses the designated button, but it only runs once and prints out my debugging statement (Log.v) five times.
What is the correct format to do this?
This is what I tried:
Button btnStart = (Button) findViewById(R.id.StartService);
btnStart.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
for (int i = 0; i < 5; i++)
{
Intent intent = new Intent(currentClass.this, different.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
finish();
Log.v(TAG, "testing");
}
}
});
EDIT:
I tried to make the service do my task five times, but after the first time, I get a java.io.IOException: invalid preview surface. when mMediaRecorder.prepare() is called, and startRecording() is called again.
Your service has not yet had the chance to finish when your for() loop runs five times. You need to implement communication between your UI and the service - let the service send you a message when it's done so that you can call it again (read on service-activity communication here).
Alternatively, modify the service to do whatever it does five times. If your data is dynamic each time you want to run the service, you may have to go with the first approach.

Resources