C# Signal Processing Plotting Rapid Data - c#

I have a circuit that sends me two different data from sensors. Data is coming as packets. First data is '$' to separate one packet to another. After '$' it sends 16 bytes microphone data and 1 byte pulse sensor data. I have an array to store incoming data and after plotting the data in each 20 ms, i start to write new bytes from zero index of array. I need to plot these data to different graphs using ZedGraph. However i could not separate those data correctly. Sometimes one or more data of audio are shown in other graph. Here is my code:
for (int i = 0; i < 4; i++)
{
if (data[i * 18] == Convert.ToByte('$'))
{
for (int x = ((i * 18) + 1); x < ((i * 18) + 17); x++)
{
listAuido.Add(time, data[x]);
}
for (int a = ((i * 18) + 17); a < ((i * 18) + 18); a++)
{
listPulse.Add(time, data[a]);
}
}
}
How can i solve this issue?
Circuit settings: BaudRate: 38400, Frequency: 200hz, CommunicationType: RS232.
Port Settings:ReadTimeOut=5 WrtieTimeOut=5;
While reading data i am using codes below. Read_Data1 refers data[] the code above. I have a counter and after plotting the data its value equals zero and i prevent my buffer index out of range exception
byte[] Read_Data1 = new byte[1000];
private void myPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (!myPort.IsOpen)
return;
if (myPort.BytesToRead > 0)
{
byte[] buffer = new byte[myPort.BytesToRead];
myPort.Read(buffer, 0, buffer.Length);
DataConversion.bytetobyte(Read_Data1, buffer, buffer.Length, count);
count += buffer.Length;
DataRecord.SaveBytesToFile(buffer, save.FileName);
}
}
public static void bytetobyte(byte[] Storage, byte[] databyte, int datacount, int count)
{
int abc;
for (abc = 0; abc < datacount; abc++)
{
Storage[abc + count] = databyte[abc];
}
}

Without seeing the data stream its hard to understand exactly what's going on but when you multiply by 18 the offset will be different as i increases. in order for that to work you need to be sure that exactly 4 packets are actually in the buffer at this time or things might get weird. Having worked a far bit with rs232 connected measurement hardware I often find that their software is not all that consistent, so I'd be careful about assuming the data is there :)
Look into how and when you're reading data into the data buffer, are you sure it contains fresh data everytime you call your code?
The loop looks correct but its a little difficult to read, I'd rewrite it as
for (int i = 0; i < 4; i++)
{
if (data[i * 18] == Convert.ToByte('$'))
{
for (int x = 0; x < 16; x++)
{
listAuido.Add(time, data[(i * 18) +1 + x]);
}
for (int a = 0; a < 1; a++) // this doesn't really need to be a loop
{
listPulse.Add(time, data[ ((i * 18) + 17)+ a]);
}
}
I looked at the code you added but its not immediately clear how the first bit of code is called by the second. I still think that there is something with the buffer handling that is causing your issue, but you could possibly eliminate that but using the buffer built into the serial port and just one byte at the time:
while(true){ //you could do this on a separate thread or on a timer
if(port.ReadByte() == Convert.ToByte('$')){
for (int x = 0; x < 16; x++)
listAuido.Add(time, port.ReadByte());
listPulse.Add(time, port.ReadByte());
}
}

Related

How to append/insert bytes? [duplicate]

I want to add some string in the middle of image metadata block. Under some specific marker. I have to do it on bytes level since .NET has no support for custom metadata fields.
The block is built like 1C 02 XX YY YY ZZ ZZ ZZ ... where XX is the ID of the field I need to append and YY YY is the size of it, ZZ = data.
I imagine it should be more or less possible to read all the image data up to this marker (1C 02 XX) then increase the size bytes (YY YY), add data at the end of ZZ and then add the rest of the original file? Is this correct?
How should I go on with it? It needs to work as fast as possible with 4-5 MB JPEG files.
In general there is no way to speed up this operation. You have to read at least portion that needs to be moved and write it again in updated file. Creating new file and copying content to it may be faster if you can parallelize read and write operations.
Note: In you particular case it may not be possible to just insert content in the middle of the file as most of file formats are not designed with such modifcations in mind. Often there are offsets to portions of the file that will be invalid when you shift part of the file. Specifying what file format you trying to work with may help other people to provide better approaches.
Solved the problem with this code:
List<byte> dataNew = new List<byte>();
byte[] data = File.ReadAllBytes(jpegFilePath);
int j = 0;
for (int i = 1; i < data.Length; i++)
{
if (data[i - 1] == (byte)0x1C) // 1C IPTC
{
if (data[i] == (byte)0x02) // 02 IPTC
{
if (data[i + 1] == (byte)fileByte) // IPTC field_number, i.e. 0x78 = IPTC_120
{
j = i;
break;
}
}
}
}
for (int i = 0; i < j + 2; i++) // add data from file before this field
dataNew.Add(data[i]);
int countOld = (data[j + 2] & 255) << 8 | (data[j + 3] & 255); // curr field length
int countNew = valueToAdd.Length; // new string length
int newfullSize = countOld + countNew; // sum
byte[] newSize = BitConverter.GetBytes((Int16)newfullSize); // Int16 on 2 bytes (to use 2 bytes as size)
Array.Reverse(newSize); // changes order 10 00 to 00 10
for (int i = 0; i < newSize.Length; i++) // add changed size
dataNew.Add(newSize[i]);
for (int i = j + 4; i < j + 4 + countOld; i++) // add old field value
dataNew.Add(data[i]);
byte[] newString = ASCIIEncoding.ASCII.GetBytes(valueToAdd);
for (int i = 0; i < newString.Length; i++) // append with new field value
dataNew.Add(newString[i]);
for (int i = j + 4 + newfullSize; i < data.Length; i++) // add rest of the file
dataNew.Add(data[i]);
byte[] finalArray = dataNew.ToArray();
File.WriteAllBytes(Path.Combine(Path.GetDirectoryName(jpegFilePath), "newfile.jpg"), finalArray);
Here is an easy and quite fast solution. It moves all bytes after given offset to their new position according to given extraBytes, so you can insert your data.
public void ExpandFile(FileStream stream, long offset, int extraBytes)
{
// http://stackoverflow.com/questions/3033771/file-io-with-streams-best-memory-buffer-size
const int SIZE = 4096;
var buffer = new byte[SIZE];
var length = stream.Length;
// Expand file
stream.SetLength(length + extraBytes);
var pos = length;
int to_read;
while (pos > offset)
{
to_read = pos - SIZE >= offset ? SIZE : (int)(pos - offset);
pos -= to_read;
stream.Position = pos;
stream.Read(buffer, 0, to_read);
stream.Position = pos + extraBytes;
stream.Write(buffer, 0, to_read);
}
Need to be checked, though...

How can I specify a subset of a 1-D array as the send or receive buffer in MPI.NET for C#?

I am learning C# parallel programming using MPI.NET. In the example given below, I define a 1-D array (x) in each process and then I do some simple calculation on the corresponding part assigned to that process (i.e only the assigned part of x) to obtain its corresponding part in (y). My primary interest is to gather all these assigned parts (part of y calculated on each process) into the y-array on the root process to be able to finally calculate the sum. I mean, I want to copy each assigned part from all processes on the corresponding part on y-array located on root process.However, I could not do it; the only thing I could do was to gather 1-D arrays into a 2-D array or to gather all of them on a new defined 1-D array with the size of "comm.size*y.length". As I searched, using "MPI_Gather ($sendbuf , sendcnt, sendtype, &recbuf, recvcount, root, comm)" keyword in C++ we are able to do this task, HOWEVER, as it seams to me that "MPI.Gather" in C# is different and it does not have the flexibility of MPI_Gather in C++. I need to gather all the calculated parts of y in each process into the corresponding location in the y-array on root process. In other words, how can I specify a subset of an array as the send or receive buffer in MPI.NET for C#. I would appreciate it if you help me in this matter.
using (new MPI.Environment(ref args))
{
double sumSerial = 0;
double sumParallel = 0;
int arraySize = 100000;
double[] x = new double[arraySize];
double[] y = new double[arraySize];
Intracommunicator comm = Communicator.world;
int numProc = comm.Size;
int numItr = arraySize / numProc;
for (int i = 0; i < x.Length; i++)
{
x[i] = i;
sumSerial += i;
}
int firstInx = comm.Rank * numItr;
int lastInx = firstInx + numItr;
for (int i = firstInx; i < lastInx; i++)
{
y[i] = 5.0 * x[i];
}
//double[][] zz=comm.Gather<double[]>(y,0);
double[] z = comm.GatherFlattened(y, 0);
comm.Barrier();
if (comm.Rank==0)
{
//for (int i = 0; i < numProc; i++)
//{
// for (int j = 0; j < zz[0].Length; j++)
// {
// sumParallel += zz[i][j];
// }
//}
for (int i = 0; i < z.Length; i++)
{
sumParallel += z[i];
}
Console.WriteLine("sum_Parallel: {0}; sum_Serial= {1};
Ratio: {2}; z_length: {3}", sumParallel, sumSerial,
sumParallel / sumSerial, z.Length);
}
}

If a transmitter wants to send 4k of data and the serial port receives 32 byte of data at a time how to save these bytes in the same memory stream?

I have a problem with displaying an image it's bytes comes to my pc serial port as chunks of data, 32 bytes at a time, how to keep all the incoming bytes in the same memory stream, then how can I display this image in a picture box
Here is a piece of code
if (((int)header[0] == 0x76) && (header[1] == 0x00) && (header[2] == 0x32) && (header[3] == 0x00) && (header[4] == 0x00)) /// the header is true ,read the image bytes
{
for (int i = 0; i < 32; i++)
Jpg[i] = (byte)CamPort.ReadByte();
fs.Write(Jpg, 0, Jpg.Length);
for (int i = 1; i < Jpg.Length; i++)
{
if ((Jpg[i - 1] == 0xFF) && (Jpg[i - 0] == 0xD9))// reaching the last two bytes(FF D9) of Jpg //
{
EndFlag = true;
MessageBox.Show("done");
//OneSnap.Image = Image.FromStream(fs);
fs.Close();
}
}
}
else
{
MessageBox.Show("DONE");
}
I would just use a nested loop and add 32 bytes at a time to a larger array.
int offset = 0;
for(int i = 0; i < total; i++){
for(int j = 0; j < 32; j++){
offset = i * 32;
jpg[offset + j] = (byte)CamPort.ReadByte();
}
}
Something like that should get all your data into one array, then you can do manipulation with/on that data. From there it should be a relatively straight-forward matter to display the data in whichever fashion you'd like.

how to calculate the transfer rate speed kb/s SOCKETS c#

How to calculate the transfer rate speed in kilobyte per second, i used stopwatch but it doesnt work , because it gives me an error about div on zero ( count / 0)
public void sendFile(string filePath)
{
Stopwatch stopWatch = new Stopwatch();
FileInfo file = new FileInfo(filePath);
try
{
int fileSize = (int)file.Length;
Program.mainForm.MaxProgressBarHandler(fileSize);
byte[] fileDetial;
string detail = file.Name + "," + fileSize.ToString();
fileDetial = Encoding.ASCII.GetBytes(detail);
client.Send(fileDetial);
byte[] fileData = new byte[fileSize];
int count;
int sum = 0;
file.OpenRead().Read(fileData, 0, fileSize);
while (sum < fileSize)
{
stopWatch.Restart();
if (fileSize - sum < packetSize)
{
count = client.Send(fileData, sum, fileSize - sum, SocketFlags.None);
Program.mainForm.UpdateProgressBarHandler(count);
}
else
{
count = client.Send(fileData, sum, packetSize, SocketFlags.None);
Program.mainForm.UpdateProgressBarHandler(count);
}
stopWatch.Stop();
sum += count;
Program.mainForm.AppendLabel(((fileSize * 8) / stopWatch.ElapsedMilliseconds).ToString());
Console.WriteLine(sum + "of" + fileSize + "sent");
}
}
finally
{
Console.WriteLine("sent");
CloseClient();
}
}
Please help me =)
For first part of your question take a look a this Joel On Software Forum Thread. It is not specifically .Net related but is directly dealing with transferring a file using TCP.
As for second part, since I do not have your full code, so I am not able to see why your stopWatch.ElapsedMilliseconds is equal to zero. My guess is that there was no data to transfer. You could try doing something like this to avoid the divide by zero error.
if (stopWatch.ElapsedMilliseconds != 0)
Program.mainForm.AppendLabel(((fileSize * 8) / stopWatch.ElapsedMilliseconds).ToString());
Though I would probably have a 1 second timer and make sum a Class scoped variable and update your label every second i.e:
public partial class Form1 : Form
{
int sum = 0;
int seconds = 0;
...
private void timer1_Tick(object sender, EventArgs e)
{
seconds += 1;
Program.mainForm.AppendLabel(((sum * 8) / seconds).ToString());
}
and reset them when you finish your transfer.
....
finally
{
timer1.Stop();
sum = 0;
seconds = 0
Console.WriteLine("sent");
CloseClient();
}

Naudio - putting audio stream into values [-1,1]

Hi all I need to put my audio stream into values of [-1,1].
Can someone tell me a good approach. I was reading byte array and float array from stream but I don't know what to do next.
Here is my code:
float[] bytes=new float[stream.Length];
float biggest= 0;
for (int i = 0; i < stream.Length; i++)
{
bytes[i] = (byte)stream.ReadByte();
if (bytes[i] > biggest)
{
biggest=bytes[i];
}
}
and I don't know how to put values into stream. Because byte is only positive values. And I need to have from [-1,1]
for (int i = 0; i < bytes.Count(); i++)
{
bytes[i] = (byte)(bytes[i] * (1 / biggest));
}
In your second code snippet, you're scaling the values, but using integers to do it. Have you tried just using the float values directly:
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] /= biggest; // scale bytes to 0..1
bytes[i] *= 2; // scale bytes to 0..2
bytes[i]--; // scale bytes to -1..1
}
Btw bytes is a more-than-slightly-confusing variable name for an array of floats.

Categories

Resources