|
OK ... in your code snippet (before my last response) I haven't seen (or realized) that your loop works with the Analogue Inputs - not the different values from each Input (in that case my posted Solution has matched).
So you have another loop (outside the AI-Loop) which takes the samples ...?
I will create another code-suggestion for you which works with an array you need. But now (and that is what you really wanted to have) you would get a method which builds an Average at the end of the meassurering - not moving. The difference is : Moving means during and not at the End ...
One moment please ...
|
|
|
|
|
double[,] AnalogSensorValue = new double[7,6];
for (int cycle = 1; cycle <= 5; cycle++)
{
for (int sensor = 0; sensor <= 6; sensor++)
{
AnalogSensorValue[sensor, cycle] = 1234;
}
}
for (int sensor = 0; sensor <= 6; sensor++)
{
AnalogSensorValue[sensor, 0] = 0;
for (int cycle = 1; cycle <= 5; cycle++)
{
AnalogSensorValue[sensor, 0] += AnalogSensorValue[sensor, cycle];
}
AnalogSensorValue[sensor, 0] /= 5;
}
programming in C# is not my favourite ...
|
|
|
|
|
Thanks a lot.Have some questions. Trying to understand your code.
You are running 5 cycles to save 5 sensor values?
What is the measuring value you are referring to?
Are you talking about:
Analogsensorvalues=sObj[id].GetDigitalValue();
Because this is where and how I actually enter or get the randomly generated sensor values from the Sensor.cs class.
for (int cycle = 1; cycle <= 5; cycle++)
{
for (int sensor = 0; sensor <= 6; sensor++)
{
AnalogSensorValue[sensor, cycle] = AnalogSensorValues;
txtNumberWritings.Text += sensor.ToString();
}
}
I tired something here, but not really sure if I understood how I am suppose to store my values.
I am just getting 0,1,2,3,4,5,6 in the text box
If the code works as intended I should be getting values I have for each sensor?
|
|
|
|
|
Yes ... I'm talking about that assignment
Analogsensorvalues=sObj[id].GetDigitalValue();
This couldn't be tested by me. But you have to realize that in my "method" the variable 'id' isn't used. I guess you you replace it by my loop-variable 'sensor'.
Inside the loop which you refer you assign 'sensor.toString' to the Textbox. That isn't correct - here you have to assign 'AnalogSensorValues.toString' as you have done before.
If you make all changes to my code-snippet as necessary the code should work as you want ...
If not please provide your actual code - apologize that my code-suggestion wasn't better ... but because C# isn't my 1st choice for coding I had to test my code before providing - so some of your assignments couldn't be made by me because I didn't have your complete project ...
Waiting for your Feedback ...
|
|
|
|
|
Hi Ralf, I think I have solved the problem now.
I created a class for MovingAverageFilter.
The only little problem I have left is implementing an automatic sampling by ticking off check box. Struggling with that at the moment.
Also I guess I do not have proper Random numbers as I always start off from the same Seed No., would be great to Randomize that properly, so that it creates completely new numbers next time I run the app.
See my code:
Main Form1.cs
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.IO;
using System.Xml.Linq;
using System.Windows.Forms;
using System.Globalization;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
namespace DAQ_Simulator
{
public partial class Form1 : Form
{
int counter;
int count_lines;
System.Timers.Timer t;
int LoggingTime=56;
int LogTimeLeft;
float SamplingTime = 5.9f;
private int clickcounterSampling;
private DateTime datetime;
private DateTime datetime2;
private DateTime NextLoggingTime;
int maxAI = 7;
int maxDI = 3;
int maxSid = 9;
String SensorText;
String sTxt1;
String fTxt;
Sensor[] SensorObject = new Sensor[10];
MA_Filter[] FilterObject = new MA_Filter[10];
public Form1()
{
InitializeComponent();
for (counter = 0; counter < maxSid; counter++)
{
SensorObject[counter] = new Sensor(counter);
FilterObject[counter] = new MA_Filter(counter);
}
}
private void displaySensorData(object sender, EventArgs e)
{
}
private void groupSampl_Enter(object sender, EventArgs e)
{
}
private void textSampling_TextChanged(object sender, EventArgs e)
{
}
private void btnSampling_Click(object sender, EventArgs e)
{
txtNextSamplingTime.Text = "5.9sec";
clickcounterSampling++;
if (clickcounterSampling == 1)
{
txtSensorValues.Text = "TimeStamp AI.1, AI.2, AI.3, AI.4, AI.5, AI.6, AI.7, DI.1, DI.2, DI.3" + "\r\n";
txtFilterValues.Text = "AI.1, AI.2, AI.3, AI.4, AI.5, AI.6, AI.7" ;
}
if (clickcounterSampling >= 5)
{ txtFilterValues.Text += "\r\n"; }
if (SamplingTime <= 0)
{
SamplingTime = SamplingTime + 5.9f;
}
if (SamplingTime <= 5.9f && SamplingTime >= 0)
{
btnSampling.Enabled = false;
}
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000;
timer1.Start();
datetime2 = DateTime.Now.AddSeconds(5).AddMilliseconds(900);
String time2 = datetime2.ToString("HH:mm:ss.FFF", CultureInfo.InvariantCulture);
textSampling.Text = time2;
count_lines = txtFilterValues.Lines.Length;
count_lines =count_lines- 1;
txtNumberWritings.Text = count_lines.ToString();
Sampling();
}
private void groupLogg_Enter(object sender, EventArgs e)
{
}
private void labelLoggingText_Click(object sender, EventArgs e)
{
}
private void btnLogging_Click(object sender, EventArgs e)
{
if (LoggingTime == 0)
{
LoggingTime = LoggingTime + 56;
}
if (LoggingTime <= 56 && LoggingTime >= 0)
{
btnLogging.Enabled = false;
}
timer2 = new System.Windows.Forms.Timer();
timer2.Tick += new EventHandler(timer2_Tick);
timer2.Interval = 1000;
timer2.Start();
txtLogging.Text = LoggingTime.ToString();
NextLoggingTime = DateTime.Now.AddSeconds(4);
String time3 = NextLoggingTime.ToString("HH:mm:ss.FFF", CultureInfo.InvariantCulture);
txtLogging.Text =time3;
Logging();
}
private void timer1_Tick(object sender, EventArgs e)
{
SamplingTime--;
txtNextSamplingTime.Text = SamplingTime.ToString("F2")+"sec";
if (SamplingTime <= 0)
{
timer1.Stop();
btnSampling.Enabled = true;
txtNextSamplingTime.Clear();
}
}
private void Sampling()
{
datetime = DateTime.Now;
txtSensorValues.Text += datetime.ToString("HH:mm:ss.FFF", CultureInfo.InvariantCulture) + " ";
double[] AnalogSensorValues = new double[maxAI];
for (int id = 0; id < maxAI; id++)
{
AnalogSensorValues[id] = SensorObject[id].GetAnalogValue();
double filter=+FilterObject[id].CalculateMovingAverage(AnalogSensorValues[id]);
SensorText = AnalogSensorValues[id].ToString("F3");
fTxt = filter.ToString("F3");
txtSensorValues.Text += SensorText + " ";
if (clickcounterSampling >= 5)
{
txtFilterValues.Text += " " + fTxt + " ";
}
}
for (int id = maxSid - maxDI; id < maxSid; id++)
{
int DigitalSensorValues = SensorObject[id].GetDigitalValue();
sTxt1 = DigitalSensorValues.ToString();
txtSensorValues.Text += " " + sTxt1 + " ";
}
txtSensorValues.Text += "\r\n";
}
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("This is a DAQ Simulator that recieves 7analog and 3 digital signals and displayes the values in a textbox." +
"Raw measuremnt data is filtered with a Moving Average filter where average of the 5 last measuremnts are displayed","Input Information",System.Windows.Forms.MessageBoxButtons.OK);
}
private void Logging()
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
using (Stream s = File.Open(saveFileDialog1.FileName,FileMode.CreateNew))
using (StreamWriter sw = new StreamWriter(s))
{
sw.WriteLine(txtSensorValues.Text+txtSensorValues);
textFilePath.Text = string.Format("{0}", openFileDialog1.FileName);
}
textFilePath.Text = saveFileDialog1.FileName.ToString();
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
{
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
}
private void timer2_Tick(object sender, EventArgs e)
{
LoggingTime--;
txtNextLogg.Text = LoggingTime.ToString()+"sec";
if (LoggingTime <= 0)
{
timer2.Stop();
btnLogging.Enabled = true;
txtNextLogg.Clear();
txtNextLogg.Text = "56 sec";
}
}
private void chckAutSampl_CheckedChanged(object sender, EventArgs e)
{
if (chckAutSampl.Enabled==true)
{
SamplingTime--;
txtNextSamplingTime.Text = SamplingTime.ToString("F2") + "sec";
if (SamplingTime <= 0)
{
timer3.Stop();
txtNextSamplingTime.Clear();
}
timer3 = new System.Windows.Forms.Timer();
timer3.Tick += new EventHandler(timer1_Tick);
timer3.Interval = 1000;
timer3.Start();
}
}
private void timer3_Tick(object sender, EventArgs e)
{
SamplingTime--;
txtNextSamplingTime.Text = SamplingTime.ToString("F2") + "sec";
if (SamplingTime <= 0)
{
timer3.Stop();
chckAutSampl.Enabled = false;
txtNextSamplingTime.Clear();
}
}
}
}
Sensor class,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DAQ_Simulator
{
public class Sensor
{
double AnalogVal;
int DigVal;
int sId;
Random rSensVal;
public Sensor(int id)
{
sId = id;
rSensVal = new Random(id);
AnalogVal = 0.0F;
}
public double GetAnalogValue(double minAnalogVolt=0.00F,double maxAnalogVolt=1.00F)
{
if(minAnalogVolt <= AnalogVal && AnalogVal<= maxAnalogVolt)
AnalogVal = rSensVal.NextDouble();
return AnalogVal;
}
public int GetDigitalValue(int digMin = 0, int digMax = 1)
{
DigVal = rSensVal.Next(0,2);
return DigVal;
}
public int GetSensId()
{
return sId;
}
}
}
Moving Average Filter Class,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DAQ_Simulator
{
public class MA_Filter
{
public double[] samples = new double[5];
public int index;
public int count;
public MA_Filter(int id)
{
count = 0;
index = 0;
}
public double CalculateMovingAverage(double newVal)
{
if (count != samples.Length) count++;
samples[index++] = newVal;
if (index == samples.Length) index = 0;
double sum = 0.0;
for (int i = 0; i < count; i++)
{
sum += samples[i];
}
return sum / (double)(count);
}
}
}
|
|
|
|
|
Well ... very good if it works now.
What I like to know now : for what is that good ? OK ... you have a kind of Simulation ... but what is the final goal ? Do you want to communicate with a PLC which will give you Values of a Meassurement ? In that case you should realize that a PLC (or something similar) will give you each Millisecond a new Value ... and those Values (of course) need to be smoothed - but continiuesly. Or is the goal something complete different ?
|
|
|
|
|
I just did an assignment for a specific course I am doing at the Uni.This was just meant as a simulation so there really is no further goal behind this. Sensors were suppose to simulate signals from field instruments I guess.
Thanks for the help Ralf Maier.
|
|
|
|
|
Into the deep...
double[] values = new double[] { 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0 };
double avg = ( values.Length > 0 ) ? values.Reverse().Take( 5 ).Average() : 0;
Console.WriteLine( $"Avg: {avg}" );
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
I need a simple Service which will do the next:
1. Use an SDK to convert some files;
2. Call Windows processes;
3. Work synchronous (only one active thread);
4. Call from a WCF service in another Server;
I want to select this service (Web API2, WCF, WebSocket, etc.) which will be easy to support and will use fewer resources. What will you choose?
Thank you!
|
|
|
|
|
Pick the one with the "best" examples. Test it.
If it performs satisfactorily (which it usually does), you're done.
Nothing to do with "fewest" or "easiest"; it's not that "big".
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
i am looking for some suggestion. suppose i will install a winform apps in a pc which will stop after when reach expiry date. so what i need to do....when i will install the apps then i will store installation date and expiry date in db. so every try when software will start then check the system date <= expiry date if yes then process else show a message trial period over.
but the problem is if user is cleaver enough then he every day change his system date to software installation date. so my checking for expiry date will never reach and he will use my software.
suppose user may not have internet connection. so give me suggestion how can i design trial version independent of system date. looking for good discussion. thanks
|
|
|
|
|
You are looking for license management. There are numerous articles that can help you with this; a quick google will find you many examples.
This space for rent
|
|
|
|
|
Morning sir,
i will search google but from your side please share some good resource and links to have good knowledge for license management.
i am not sure my intention is clear or not. i will install a winform apps in client pc. client pc may have no internet connection. so how could i expiry the apps depend on expiry date because client may change his pc system date every day before running my winform apps. so please share some logic to develop apps which will not depend on client pc system's date and time.
thanks & have good weekend.
|
|
|
|
|
Mou_kol wrote: looking for good discussion. thanks You're not the first one to ask; so I'd assume you looked for it by Googeling.
To repeat the answer; there are larger companies that spend a lot of money on copy-protections and they have given up on winning that war. I need not muck with the systems' time, just to install your software in a VM, and disallow writing.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
You can't.
Unless there is a connection to an external, trusted, reliable time source - and without an internet connection there isn't - the only time and /or date source you have is the system clock. And that is so easily spoofed or played with that you are wasting your time trying work round that.
What I would suggest is: trust your users. Think about how much of your time you will invest on coding unbreakable security, how much your time is worth, and how many users you will manage to convert to paying customers as a result. Do not forget to figure in all the customers you annoy by having an overly-rigid security system that penalizes legitimate users and the number of sales you will lose as a result of that. Then look at the cost of your software. If it's cheap, you are probably wasting your time. If it's seriously expensive, then you are probably wasting your time - as that attracts hacked versions; Adobe Photoshop has had man-years spent on security in the past, only for a cracked version to be released the same day as the official product!
Remember that it's easy to lose a good reputation, and very hard to get it back - and penalizing a single legitimate user by mistake can really harm your standing.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
"Turning back" the system clock doesn't work too well if the app itself depends on a "current" clock in order to function properly.
One has to be pretty desperate to live with "bad" output dates in a "crack".
If "device clocks" aren't synched, you can create wonderful messes.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
suppose in a pc dotnet and java runtime both install but when we run dotnet application then how CLR understand that he need to take control of the apps?
when and who associate dotnet application and CLR? i guess OS windows. if it is true then how windows os does it?
i search google but found no relevant link. so my request is please some one discuss the same here in details or redirect me to right article.
|
|
|
|
|
|
thanks a lot Sir for sharing such valuable links.
i have one small question that when we click on dotnet exe or vb6 exe file then how controls goes to windows OS?
for dotnet exe file there is CLR Header, which tells windows that it should use the CLR Loader to read the CLR Header's metadata. but what happen for vb6 exe file when we click on that to run?
please share some knowledge. thanks
|
|
|
|
|
VB6 is an old language which has nothing to do with .NET (i.e., a VB6 executable has a PE Header but no CLR header). What happens when you click an executable compiled from VB6 is that the assembler code produced by the compilation process is simply executed.
Inside the executable: a VB programmer's guide to the portable executable format[^]
I would not spend too much time on VB6, though, as it is quite outdated nowadays.
"I'm neither for nor against, on the contrary." John Middle
|
|
|
|
|
thanks for your another reply sir.
hence my knowledge is low so i am curious to know the inner story of various tool and technology like how they run. java application has any PE header ?
thanks for your time sir. good day
|
|
|
|
|
ALL .EXE's have the PE header that tells the Windows Loader how to load the executable. It doesn't matter what runtimes the .EXE runs under.
|
|
|
|
|
Morning, thanks a lot for reply.
i am not java guy but i heard java do not come with exe file....so what happen in case of java apps when it run on windows OS?
i heard java has .jar file which is self executable....so jar has PE header?
C and C++ generate exe file when compile....so C and C++ generated exe file has PE header?
please share the knowledge. thanks
|
|
|
|
|
JAR files are not executable. They are just a bunch of data that Java interprets as code, referred to as "bytecode". Java is a virtual machine environment with its own instruction set. This bytecode isn't run natively by your CPU like .EXE executables.
You apparently don't know how file associations work. Ever double-click a .TXT file or a Word file? You're actually launching the executable associated with that file extension.
For .txt files, the command line launched is
%SystemRoot%\system32\notepad.exe %1
where the %1 is replaced by the full path to the .txt file you double-clicked.
For .jar files, it's no different. The command line launched is something like this:
"C:\Program Files (x86)\Java\jre1.8.0_102\bin\javaw.exe" -jar "%1" %*
Again, the %1 is replaced by the full path to the .jar file.
|
|
|
|
|
Hi,
I have a view which has two list boxes, one on left contains all the selection, two buttons to "add or remove" selection and one more listbox on right which contains selected values.
I am able to get the list of selected values, but what I would like is the list of unselected values on posting. The object in the model is null for the list of unselected values.
How can pass the list of unselected values?
Thank you!
|
|
|
|