Transferring data over bluetooth-serial module with C # - c#

I need to transmit multiple 8-byte-packets over bluetooth-serial link. I am using JY MCU bluetooth-serial module. On the PC side, I have a C# application running that communicates with the COM port.
Considering 115200 baud, each 8 byte packet should take 8*8/115200 = 0.555 milliseconds.
The problem is that one in every 4 packets takes up to 39 milliseconds which completely destroys all the timing.
For measuring times, I am using stopwatch component of .net framework.
output from C # application:
Sample # 583 : 39.126841990471 ms
Sample # 584 : 0.7883273789593 ms
Sample # 585 : 0.93885067781563 ms
Sample # 586 : 0.884708368788226 ms
Sample # 587 : 8.65278575619526 ms
Sample # 588 : 1.05558303203074 ms
Sample # 589 : 0.870116824511337 ms
Sample # 590 : 0.888932236868378 ms
Sample # 591 : 39.0876752137277 ms
Sample # 592 : 1.02639994347697 ms
Sample # 593 : 0.820198383564084 ms
Sample # 594 : 0.960737994230964 ms
Sample # 595 : 15.2051571125331 ms
Note that each sample contains 8 bytes of data

Dogma #1: There is no such thing as a guaranteed timing in the bluetooth world.
Just consider a device dropping a frame (e.g. because your microwave oven just switched on) - the time to understand the frame as lost is substantial. Additionally the connect/disconnect as shown in your first sample is lengthy. If one of the devices uses e.g. a bluetooth mouse or is discoverable, all bets are off.
Long story short: Bluetooth messages have no consistent timing - if you want to keep timing information, include a timestamp in your payload.

Related

Reading CI Frequency In C# With NI USB-6363

Working LabVIEW Code
Attached above is LabVIEW code that I have successfully used in the past to read frequency data from a device. I also usually use the Start Task VI between my property node and while loop.
I am trying to code this in C#. So far I have successfully been able to code analog Output's and analog Input's on my device, USB-6363, (so I know I am able to write and read data from the device successfully with C#).
I have also used multimeters (Grainger link at bottom of post) to read frequency data (Orange Hz mode that the device is set to in the picture).
However, my C# code seems to be having issues reading the frequency data. My C# code is attached. When I try running this program I get the following error. This is the same error that I get when using the example program called 'MeasDigFreqBuffCont_ExtClk_ArmStart.2013'. The code I show is just creating the task, I do call the code later in my program in a different section and that is how I am getting the error.
------------------------------------------------- Begin Error Code -------------------------------------------------
{Error=-200077 Message="Requested value is not a supported value for
this property. The property value may be invalid because it conflicts
with another property.\n\nProperty:
NationalInstruments.DAQmx.CIChannel.FrequencyDivisor\nRequested Value:
1\nPossible Values: 4 to 4294967295\nChannel Name: Digital
Frequency\n\nTask Name: _unnamedTask<0>\n\nStatus Code: -200077"}
------------------------------------------------- End Error Code --------------------------------------------------
In the example program it asks for a sample clock source (A PFI channel from the device). However in the LabVIEW code it does not ask for this. Is this example maybe more in detail than what I am trying to do?
Task frequencyInput = new Task();
frequencyInput.CIChannels.CreateFrequencyChannel(
"Dev1/ctr0",
"Digital Frequency",
200,
15000,
CIFrequencyStartingEdge.Rising,
CIFrequencyMeasurementMethod.DynamicAveraging,
0.001,
1,
CIFrequencyUnits.Hertz
);
frequencyInput.CIChannels["Digital Frequency"].FrequencyTerminal = "/Dev1/PFI0";
CounterSingleChannelReader counterFreq = new CounterSingleChannelReader(frequencyInput.Stream);
double counterFreqData = counterFreq.ReadSingleSampleDouble();
txtPFI0.Text = Convert.ToString(counterFreqData);
FLUKE (R) Fluke-115 Compact - Basic Features Digital Multimeter, 14° to 122°F Temp. Range
Formatting the error message:
Requested value is not a supported value for this property. The property value may be invalid because it conflicts with another property.
Property: NationalInstruments.DAQmx.CIChannel.FrequencyDivisor
Requested Value: 1
Possible Values: 4 to 4294967295
Task Name: _unnamedTask<0>
Status Code: -200077
According to the documentation, you are asking the device to use an invalid divisor. Change your 1 to a 4:
frequencyInput.CIChannels.CreateFrequencyChannel(
"Dev1/ctr0",
"Digital Frequency",
200,
15000,
CIFrequencyStartingEdge.Rising,
CIFrequencyMeasurementMethod.DynamicAveraging,
0.001,
/* here */ 4,
CIFrequencyUnits.Hertz
);
NI installs C# examples for DAQmx, and it includes one for measuring frequency:
C:\Users\Public\Documents\National Instruments\NI-DAQ\Examples\DotNET4.0\Counter\Measure Digital Frequency\MeasDigFrequency_LowFreq1Ctr\CS

What Zebra QLn220 settings do I need to set (and to what value[s]) to get a setting to "stick"?

I am trying to programatically configure a Zebra QLn220 printer to set its "media.sense_mode" to either "bar" or "gap" (depending on what the user selects).
The reliability of these commands working, though, seems very low (sometimes it works, sometimes it doesn't).
To test the various possible commands, I used the Zebra Setup Utilities, with the PC plugged into the printer, of course.
I sent this command from the util:
! U1 setvar "media.sense_mode" "gap"
It worked; I know this, because testing it with:
! U1 getvar "media.sense_mode"
...showed me the expected/hoped for "gap" (it had been "bar" prior to sending the command above).
But trying to accomplish the same thing in code works for "bar" (almost always) but hardly ever for "gap"
Here's the code:
const string quote = "\"";
string advanceToBlackBar = string.Format("! U1 setvar {0}media.sense_mode{0} {0}bar{0}\r\n", quote);
string advanceToGap = string.Format("! U1 setvar {0}media.sense_mode{0} {0}gap{0}\r\n", quote);
. . .
if (radbtnBar.Checked)
{
PrintUtils.SendCommandToPrinter(advanceToBlackBar);
}
else if (radbtnGap.Checked)
{
PrintUtils.SendCommandToPrinter(advanceToGap);
}
So as you can see, the code is precisely the same except for "bar" vs. "gap"
Is it possible that the appended "\r\n" is causing a problem? It seems adding those were necessary or made the commands more reliable, but I'm open to anything at this point of frustration.
I always tested alternative commands for accomplishing the same thing, to see if they would be any more reliable, but neither of the other two alternatives worked, namely not this one:
! U1 setvar "ezpl.media_type" "web"
-nor this one:
{} {"media.sense_mode" "gap"}
...checking the val via getvar continued to show "bar" following the sending of those commands to the printer (after setting back to "bar" the value of "media.sense_mode" remains "bar" after sending these two commands).
Might it be that certain other printer settings need to be set for the printer to be more responsive to commands sent it? Not only is setting the commands programmatically unreliable, but even via the Zebra Setup Utility, it will sometimes "hourglass" for a LONG time before the command has been sent and returns - and other times it's quicker than Johnny Quick and Flash combined.
Looking through the voluminous output of this command:
! U1 getvar "allcv"
....the following are the most interesting/likely candidates. Which, if any, need to be changed, and to what values?
wlan.ip.dhcp.request_timeout : 2 , Choices: 2-30
wlan.ip.dhcp.session_interval : 10 , Choices: 0-60
. . .
wlan.ip.timeout.enable : on , Choices: on,off
wlan.ip.timeout.value : 300 , Choices: 1-3600
. . .
wlan.keep_alive.enable : on , Choices: on,off
wlan.keep_alive.timeout : 15 , Choices: 5-300
. . .
netmanage.avalanche.interval : 60000 , Choices: 0-4294967295
netmanage.avalanche.startup_update : off , Choices: on,off
netmanage.avalanche.interval_update : off , Choices: on,off
. . .
netmanage.avalanche.udp_timeout : 3000 , Choices: 0-4294967295
netmanage.avalanche.tcp_connection_timeout : 3000 , Choices: 0-4294967295
. . .
netmanage.avalanche.realtime_update_int : 300 , Choices: 0-4294967295
. . .
zpl.zpl_mode : zpl II , Choices: zpl II,zpl
. . .
internal_wired.ip.arp_interval : 0 , Choices: 0-30
. . .
internal_wired.ip.dhcp.requests_per_session : 2 , Choices: 1-10
internal_wired.ip.dhcp.request_timeout : 2 , Choices: 2-30
internal_wired.ip.dhcp.session_interval : 10 , Choices: 0-60
. . .
internal_wired.ip.timeout.enable : on , Choices: on,off
internal_wired.ip.timeout.value : 300 , Choices: 1-3600
. . .
internal_wired.ip.wins.permanent_source : off , Choices: on,off
. . .
interface.network.active.arp_interval : 0
. . .
interface.network.active.speed : 0
. . .
weblink.printer_reset_required : no
. . .
weblink.ip.conn1.retry_interval : 10 , Choices: 1-600
. . .
weblink.ip.conn1.maximum_simultaneous_connections : 10 , Choices: 1-100
. . .
weblink.ip.conn1.test.retry_interval : 900 , Choices: 1-1800
weblink.ip.conn1.num_connections : 0
. . .
capture.channel1.port : off , Choices: serial,usb,bt,parallel,off
capture.channel1.count : 0 , Choices: 0-4294967295
Anyone out there with a clue?
UPDATE
Here is the code that sends the commands:
public static bool SendCommandToPrinter(string cmd)
{
bool success; // init'd to false by default
try
{
using (SerialPort serialPort = new SerialPort())
{
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close(); // <= should be redundant within a using statement, but still getting "File 55" err...
}
success = true;
}
catch // may not need a try/catch block, as success defaults to false
{
success = false;
}
MessageBox.Show(success.ToString()); //TODO: Remove after testing
return success;
}
The SerialPort in question is from OpenNETCF.IO.Ports.SerialPort
NOTE: SerialPort.Write() returns void.
The command:
! U1 getvar "appl.name"
returns "V68.19.7Z" in the Zebra Setup Utility.
So does this mean my firmware is up-to-date (V68.19.7Z > v68.18.0Z), or does it mean since my "appl" is newer, I need to upgrade the firmware to V68.19.7Z? If I do need to update the firmware, how do I do that? Is it a matter of locating and downloading the latest firmware to my PC, then running its install app while the PC and Printer are connected via USB, or...???
UPDATE 2
From here, searching for QLn220, I see V68.18.0Z as the only firmware version available for download. So since I seem to have a newer version on my printer, I'm confused...why do they not offer what would seem to be the newer version (V68.19.7Z)?
UPDATE 3
If I click the "self-extracting archive" link at the page referenced above, I simply get a page with some generic but unactionable (so it seems) directions.
If I click the download link there, I get a page that says, "This webpage has a redirect loop"
UPDATE 4
It works after adding some debug strings; in the print code:
MessageBox.Show(success.ToString()); //TODO: Remove after testing
return success;
...and in the setting code:
if (radbtnBar.Checked)
{
MessageBox.Show(advanceToBlackBar);
PrintUtils.SendCommandToPrinter(advanceToBlackBar);
}
else if (radbtnGap.Checked)
{
MessageBox.Show(advanceToGap);
PrintUtils.SendCommandToPrinter(advanceToGap);
}
Could it be that this little "break in the action" is beneficial somehow?
UPDATE 5
Note: There is no "SerialPort.Flush" Maybe:
serialPort.Close();
...is accomplishing the same thing?
The SGD commands are well-formed. The intermittent behavior that you describe makes me think the problem originates in how consistently the printer actually receives the command, and not the syntax of the command itself. And generally speaking, no, you do not have to change other commands in order to make this command work. Since you can successfully send the command via Zebra Setup Utilities and get the desired behavior, then you should be able to do the same through your code.
Are you programmatically sending the commands over USB or over something else (Bluetooth, TCP, etc.)? You mentioned USB while using Zebra Setup Utilities, but what about in your code?
Can you provide the code underneath the hood of PrintUtils.SendCommandToPrinter()? I am not familiar with this API. Which API is it?
At the lowest levels of a connection you will often be calling 'write()' or 'writeData()' or something like that. Sometimes 'write' commands return the number of bytes written. If you can dig into your code a bit, perhaps there is a 'write' command that returns that value and you can verify yourself that the return value equals the length of the intended message (including new line characters).
Depending on the lower level API, there also may be a flush() command lying around that forcibly pushes all data in a stream to the other end. Again, this depends on what API you're using underneat the hood of 'PrintUtils'.
In the past I have seen inconsistent behavior with USB communication. You should make sure that your firmware is as up-to-date as possible. Your QLn220 is currently on v68.18.0Z: http://www.zebra.com/id/zebra/na/en/index/drivers_downloads/firmware/results.html?productType=6. You can check your current version by sending:
! U1 getvar "appl.name"
At the end of the day, you could always immediately query the printer for its gap/bar mode after setting it. This will cause as an additional delay in your program execution, but it is a good way of making sure that whatever you sent has actually taken effect.
for those with issues with labels printing too long, we had to set all our printer widths correctly via the zebra pc util.. send these commands to the printer.. PW means printer width, and JUS means Save the settings...
^XA
^PW832
^JUS
^XZ
Also this command helped with double labels printing
Sensor Calibration Command (source: Functional List of ZPL Commands) zpl_manual.pdf
~JC
It works after adding some debug strings; in the print code:
MessageBox.Show(success.ToString()); //TODO: Remove after testing
return success;
...and in the setting code:
if (radbtnBar.Checked)
{
MessageBox.Show(advanceToBlackBar);
PrintUtils.SendCommandToPrinter(advanceToBlackBar);
}
else if (radbtnGap.Checked)
{
MessageBox.Show(advanceToGap);
PrintUtils.SendCommandToPrinter(advanceToGap);
}
WHY it works, I don't know, so I'm still wary. But, for now at least, it is working with this tweak.

Get time of speech in a video file (in code)

I'm looking for a way (in java, c#..) to get the time when people speak in a video file (even in a movie).
I don't need to know the accurate words, just the time.
Output example:
00:03 - 01:03 (someone spoke for a minute),
03:00 - 06:12 (someone spoke again),
.
.
.
I have found Sphinx (written in java): http://cmusphinx.sourceforge.net/
but couldn't get it to recognize properly.
Any ideas?
Thanks.
EDIT:
This is what I've tried in sphinx (very basic):
StreamSpeechRecognizer recognizer = new StreamSpeechRecognizer(configuration);
recognizer.startRecognition(somefile);
SpeechResult result;
while ((result = recognizer.getResult()) != null) {
System.out.println(result);
}
recognizer.stopRecognition();
There were only 3 results (there should be allot more).
EDIT2:
well, I tried this on a song in my computer:
https://www.assembla.com/code/sonido/subversion/nodes/12/sphinx4/src/sphinx4/edu/cmu/sphinx/tools/endpoint/Segmenter.java
This is the output:
DataStartSignal: creation time: 1399716763914
SpeechStartSignal
DoubleData: 44100Hz, first sample #: 8820, collect time: 200
DoubleData: 44100Hz, first sample #: 9261, collect time: 210
.....
DoubleData: 44100Hz, first sample #: 1745037, collect time: 39570
SpeechEndSignal
SpeechStartSignal
DoubleData: 44100Hz, first sample #: 1894536, collect time: 42960
......
Two Problems:
1. My goal is to be able to do it on movies. It works on audio files (.wav)
2. I'm not sure it works well. As you can see, the output says the speech started after 200 milliseconds, where actually it started after 3 seconds at least (the song is 'Bee Gees - How Deep Is Your Love').
I have found Sphinx (written in java): http://cmusphinx.sourceforge.net/ but couldn't get it to recognize properly.
Like you said, you do not need to recognize. To get only voice activity detection in Java with times see the segmenter class edu.cmu.sphinx.tools.endpoint.Segmenter

snmp oid for scanner detail(HP LaserJet 3055)

How can i access scanner details (eg. HP LaserJet 3055 ) in windows service (.net framework 4.0).by using mib tree ?
Anyone please tell me the OID for getting detail such as scanner_ADF_PageCount,TotalPagesJammed,etc for scanner.
I compare each oid with "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2". But still it is not giving above detail.
1) scanner-accessory-adf-sheet-count - .1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.20.0
2) hrprinterdetectederrorstate - .1.3.6.1.2.1.25.3.5.1.2 . It returns an octet string and you need to interpret it as
Condition Bit # hrDeviceStatus
lowPaper 0 warning(3)
noPaper 1 down(5)
lowToner 2 warning(3)
noToner 3 down(5)
doorOpen 4 down(5)
jammed 5 down(5)
offline 6 down(5)
serviceRequested 7 warning(3)
I got this information from HP-LASERJET-COMMON-MIB and you can download it from here. Browse through it for more details.

.NET or COM HID iCLASS Smart Card Reader

I have coding I almost always use with my Omnikey RFID CardMan 5321 smart cards. Problem is we received new cards today which are marked "HID iCLASS GL" which do not appear to be working well with our coding.
Without going through the whole source, our problem is arising when we are calling the following line, which basically tells us the length of the data:
lResult = SCardTransmit(hCard, 0, bytCommand, lLen, 0, byReadBuffer, iReturnlength)
We are returning only a length of 2, which the data is marked as "x69 x86". Even if I tell it to read all 255 chr's the rest are just marked as null.
Now I know our reader can read these cards since the OMNIKEY Diagnostic tool is showing us the following:
Status: Smart Card Inserted
FW: 5.10
Port: USB
Lib: 1.0
Smart Card Nme: iCLASS 32KS 8x2+16
ART: Valid
Protocol: ISO 15693 (Part 2)
PICCtoPCD: 26,48 kbps
PCDtoPICC: 26,48 kbps
Frequ: 13.56 MHz
As I explained before, everything is working fine in my coding except no data is being returned for my card besides "x69 x86", which is surely not correct.
If anyone has any experience reading from a HID iCLASS card, I would greatly appreciate some feedback on how to. Even if we have to license software, that is ok.
Thanks in advance!
in case you are trying to access physical access data, I would thoroughly check the crypto protocol between reader and host first and also meke sure you are using a reader with teh latest firmware (5.20 for the OMNIKEY 5321).
I would also introduce code to check the card system withour secure communication channel between host and reader application.
Further references:
http://www.hidglobal.com/documents/ok_contactless_developer_guide_an_en.pdf
The reason cause you get a 2 Byte array is cause your command runs on an error so the chip returns only SW1 and SW2 Flag
in your case it's meaning is
x69 --> Command not allowed (further qualification in SW2, see table 17)
x86 --> Command not allowed (no current EF)
So you might proof that your application file on the chip is correctly selected
further information #
http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx#table17

Categories

Resources