I made an APP that read the ADC value from a PIC using USB HID custom, the first test was to use a button to read the value and pass the read value to a progress bar and a textbox, that worked fine:
private void btnRead_Click(object sender, EventArgs e)
{
txbCmd.Text = board.ADCVal().ToString();
progressBar1.Value = Convert.ToInt32(txbCmd.Text);
}
If I start to click the button as fast as I can I'll get multiple read values from the ADC, like a continous read.
Then I try to put a timer with an event every 1.5 seconds to read the ADC (that is more slow than me pressing the button multiple times continously):
private void timer1_Tick(object sender, EventArgs e)
{
txbCmd.Text = board.ADCVal().ToString();
progressBar1.Value = Convert.ToInt32(txbCmd.Text);
}
When I start the timer, the first read is done without problems but the next read give error 5 that is access denied, if I let the program run one read is made and the next giveme error then the next is made and then again the next giveme error... I don't know why it work from a click button event and not from an timer event that use the same code.
EDIT
The ADCVal method has a call to another private method inside the same class named WriteUSB to send the read ADC command to the PIC board and then read the command reception confirmation from the board using the private method ReadUSB and finally wait for the read the ADC value from the PIC board, the error come from the WriteUSB call:
public UInt16 ADCVal()
{
byte[] SndData = new byte[65];
byte[] RcvData = new byte[65];
SndData[0] = 0; //EP0 USB
SndData[1] = _ADC_Val; //Cmd
if (WriteUSB(ref SndData) == false)
{
MessageBox.Show("Write USB Error: " + Marshal.GetLastWin32Error().ToString());
return 0;
}
if (ReadUSB(ref RcvData, false) == true)
{
if ((RcvData[1] == SndData[1]) && (RcvData[2] == 255))
{
if (ReadUSB(ref RcvData, false) == true)
{
return BitConverter.ToUInt16(RcvData, 2);
}
else
{
MessageBox.Show("Read USB Error: " + Marshal.GetLastWin32Error().ToString());
return 0;
}
}
else
{
MessageBox.Show("Read USB Error: " + Marshal.GetLastWin32Error().ToString());
return 0;
}
}
return 0;
}
And the private method WriteUSB has the WriteFile call (the ReadUSB has the ReadFile call code):
public bool WriteUSB(ref byte[] OutBuffer)
{
int Bsize = OutBuffer.Length;
string error;
Int32 NumbersOfBytesWritten = 0;
IntPtr UnManagedBuffer = Marshal.AllocHGlobal(Bsize);
Marshal.Copy(OutBuffer, 0, UnManagedBuffer, Bsize);
if(WriteFile(USBDeviceInfo.WriteHandle, OutBuffer, Bsize, ref NumbersOfBytesWritten, IntPtr.Zero) == false)
{
error = Marshal.GetLastWin32Error().ToString();
return false;
}
if (Marshal.GetLastWin32Error().ToString() == "0")
{
Marshal.FreeHGlobal(UnManagedBuffer);
return true;
}
error = Marshal.GetLastWin32Error().ToString();
return false;
}