Reputation: 77
so i have an adrduino that sends me data constantly, I made it Json data. so arduino sends me [0,0,0,0] constantly and the 0 changes depending on the condition in the arduino. My Issue is, in my c# im reading this arduino data and i'm using it, however my methods keeps on firing because the conditions are met. i want it to just fire once if the value is changed and that's all. for example if i get from arduino [0,2,0,0] i want it to update and if stays 2 i don't want my method to fire unless it's back to 0 again.
This is my c# code where i read the data
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
var str = serial.ReadLine();
outputStr = str;
//intvalue = int.Parse(str);
try{
var json = JSON.Parse(str);
FirstSet = int.Parse(json[0].Value); // can be either 0 or 1
SecondSet = int.Parse(json[1].Value);// can be either 0 or 2
ThirdSet = int.Parse(json[2].Value);// can be either 0 or 3
ForthSet = int.Parse(json[3].Value);// can be either 0 or 4
}catch(Exception ex){
VLog.Info("EXCEPTION!: " + ex.Message);
}
// Set 1
if (FirstSet == 1)
On1();
else if (FirstSet == 0)
Off1();
// Set 2
if (SecondSet == 2)
On2();
else if (SecondSet == 0)
Off2();
// Set 3
if (ThirdSet == 3)
On3();
else if (ThirdSet == 0)
Off3();
// Set 4
if (ForthSet == 4)
On4();
else if (ForthSet == 0)
Off4();
changed = true;
}
Upvotes: 0
Views: 222
Reputation: 460
some basic validation?
above the class:
private string lastParsed;
inside the class start with:
if (lastParsed != null && lastParsed == str)
{
return;
}
else
{
lastParsed = str;
}
EDIT: looks like you deleted your original code, but if you want to check only one of the int values for each sensor perhaps you could try another approach
above method:
private bool[] sensorState = new bool[4];
I don't remember exactly how you called the On & Off methods but in each IF and ELSE IF you could add
if (first == 0 && sensorState[0]) // it means you should switch OFF and it's currently ON
else if (first == 1 && !sensorState[0]) // it means you should switch ON and it's currently OFF
EDIT: after each if/else block you update the sensorState
if (first != 0)
sensorState[0] = true;
else
sensorState[0] = false;
and so on..
Upvotes: 1
Reputation: 2143
You probably want to look into Event Handlers. Specifically when properties change. You're already using event handlers for when data is received as a SerialDataReceivedEvent, now you're adding another layer on top of it to handle if the value changes.
The basic concept is you build a class that is responsible for reading your Arduino inputs. Use Task.Run()
to monitor on another thread so it doesn't lock your main process. That class will have an event handler in it that you will call from within your monitor class.
When your app instantiates this monitoring object, it will then register an action to that event handler.
This answer lays out a modern version of a class with a PropertyChangedEventHandler
. That class should be the monitor that is checking the sensor. Then if the property changes, it will fire the event handler that your main program has registered with.
If I use the example from that answer, here's what your program might look like:
class Program
{
public ISensorMonitor Sensor1 { get; }
public ISensorMonitor Sensor2 { get; }
public ISensorMonitor Sensor3 { get; }
public ISensorMonitor Sensor4 { get; }
static void Main(string[] args)
{
// In this example Sensor1Monitor would implement ISensorMonitor
Sensor1 = new Sensor1Monitor();
Sensor1.PropertyChanged += DoSomethingWithSensor1;
Sensor1.StartMonitoring();
// ... implement the other 3 sensors.
}
void DoSomethingWithSensor1(object sender, PropertyChangedEventArgs e)
{
// This ensures that only the SensorValue property will handled.
if (e.PropertyName != nameof(ISensorMonitor.SensorValue))
return;
// ... Do something with Sensor1.SensorValue
}
// ... implement the other 3 sensors.
}
This will ensure DoSomething()
only is called when the value of the monitor's sensor property reading changes.
Upvotes: 1
Reputation: 13448
Consider changing your model first... there is no need to store numbers for an On/Off state, just make your properties bool
. Then, if you want to signal changes to the state, just pack it into the property setter instead of trying to be smart in some other area:
class MyContainerIsNotPartOfTheQuestion
{
private bool m_FirstSet;
public bool FirstSet
{
get { return m_FirstSet; }
set
{
if (value != m_FirstSet)
{
m_FirstSet = value;
// handle On/Off where it belongs
if (value) On1();
else Off1();
}
}
}
// same for SecondSet etc.
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// ... your starting code
FirstSet = int.Parse(json[0].Value) != 0;
// set others
// Done, no handling of On/Off here
}
}
Upvotes: 0