C# GUI to Arduino: Serial Data Not Working - c#

I'm trying to send an integer through the usb connection to my arduino. When using the sketch monitor I can verify that the code works; However, when using the C# .NET GUI, I'm unable to get anything working.
I do know that the data is sending via the LEDs lighting up on the arduino.
I'm typing an RPM into a text box, converting it to 4 bytes (integer) and writing it. Here is the GUI code:
RPMMove = Convert.ToInt32(tbRPM.Text);
byte[] bRPM = BitConverter.GetBytes(RPMMove);
port.Write(bRPM, 0, 4);
On the arduino:
void setup()
{
Serial.begin(9600);
Serial.setTimeout(100);
}
void loop()
{
while (Serial.available() > 0)
{
i = Serial.parseInt();
stepper.setRPM(i); //move motor of other library
//Serial.println(i); //I get the correct integer via the arduino monitor here.
}
}

parseInt and the fact that it works when you type the number into the console both indicate that the device wants the string sent as text. So do not use BitConverter, instead:
byte[] bRPM = Encoding.Ascii.GetBytes($"{RPMMove}\r\n");
You may need to adjust the line ending, naturally using the same one configured in your terminal emulator ("console") should work.

Related

Assign Image To ZKTeco Device

I am trying to assign image to ZKTeco device with the model SFace900. Purpose is to recognize user on face detection. I've a SDK that works fine to download attendance from device using a C# app, in the same time I can see two default methods is given to assign image or user face as follows:
axCZKEM1.SetUserFace()
axCZKEM1.SetUserFaceStr()
I am not sure but I think it requires base64 string to transfer image to the device. So I tried something like this:
private void SetUserFaceStr(string val)
{
zkemkeeper.CZKEMClass axCZKEM1 = new zkemkeeper.CZKEMClass();
axCZKEM1.Connect_Net(IP, Port);
int idwErrorCode = 0;
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(val);
if (axCZKEM1.SetUserFaceStr(axCZKEM1.MachineNumber, userId, 50, val, byteString.Length))
{
MessageBox.Show("SetUserFaceStr!", "Success");
}
else
{
axCZKEM1.GetLastError(ref idwErrorCode);
MessageBox.Show("Operation failed,ErrorCode=" + idwErrorCode.ToString(), "Error");
}
}
The val variable is actually a base64 string that I am trying to pass. The reason I tried the above, is for this link - Assign Image or Set face. Though I failed, it throws error code 2. Is there anyone who faced the same situation or came up with a solution? This is one of my R & D project, so expecting some suggestions if this can be done.
Model: SFace900 doesnt record the face image for matching, rather it records the face template which is encrypted data of the face features. So, you can not add the face for attendance/punch recording.
You can try this with SpeedFace(AI) series models. If you want to try the cloud based api, then you can try cams utron multiface model with its own api

using an Audio Endpoint other than 'DefaultAudioEndpoint' in C#

This program is an audio visualizer for an rgb keyboard that listens to windows' default audio device. My audio setup is a bit more involved, and I use way more than just the default audio device. For instance, when I play music from Winamp it goes through the device Auxillary 1 (Synchronous Audio Router) instead of Desktop Input (Synchronous Audio Router) which I have set as Default. I'd like to be able change the device that the program listens to for the visualization.
I found in the source where the audio device is declared; Lines 32-36 in CSCoreAudioInput.cs:
public void Initialize()
{
MMDevice captureDevice = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console);
WaveFormat deviceFormat = captureDevice.DeviceFormat;
_audioEndpointVolume = AudioEndpointVolume.FromDevice(captureDevice);
}
The way that I understand it from the documentation, the section MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console) is where Windows gives the application my default IMMEndpoint "Desktop Input."
How would I go about changing DefaultAudioEndpoint?
Further Reading shows a few ways to get an IMMDevice, with DefaultAudioEnpoint being one of them. It seems to me that I'd have to enumerate the devices, and then separate out Auxillary 1 (Synchronous Audio Router) using PKEY_Device_FriendlyName. That's a bit much for me, as I have little to no C# experience. Is there an easier way to go about choosing a different endpoint? Am I on the right track? or am I missing the mark completely?
Also, what is the difference between MMDevice and IMMDevice? The source only seems to use MMDevice while all the Microsoft documentation references IMMDevice.
Thanks.
I DID IT!
I've found why the program uses MMDevice rather than IMMDevice. The developer has chosen to use the CSCore Library rather than Windows' own Core Audio API.
From continued reading of the CSCore MMDeviceEnumerator Documentation, it looks like I'll have to make a separate program that outputs all endpoints and their respective Endpoint ID Strings. Then I can substitute the DefaultAudioEndpoint method with the GetDevice(String id) method, where String id is the ID of whichever Endpoint I chose from the separate program.
To find the the Endpoint I wanted, I wrote this short program to find all the info I wanted:
static void Main(string[] args)
{
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
Console.WriteLine($"\nNumber of active Devices: {collection.GetCount()}");
int i = 0;
foreach (MMDevice device in collection){
Console.WriteLine($"\n{i} Friendly name: {device.FriendlyName}");
Console.WriteLine($"Endpoint ID: {device.DeviceID}");
i++;
}
Console.ReadKey();
}
This showed me that the Endpoint I wanted was item number 3 (2 in an array) on my list, and instead of using GetDevice(String id) I used ItemAt(int deviceIndex).
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
MMDevice captureDevice = collection.ItemAt(2);
However in this case, the program was not using captureDevice to bring in the audio data. These were the magic lines:
_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
_capture.Initialize();
I found that WasapiLoopbackCapture uses Windows' default device unless changed, and the code was using DefaultAudioEndpoint to get the properties of the default device. So I added
_capture.Device = captureDevice;
//before
_capture.Initialize();
And now the program properly pulls the audio data off of my non-default audio endpoint.
I had been asked to solve a similar type of problem this week. Although there are a few librarys to do this I was specifically asked to do this for "non ish" programmers so I developed this in PowerShell.
Powershell default audio device changer - Github
Maybe you can alter it to your needs.

UWP: BluetoothDevice.FromBluetoothAddressAsync throws 0x80070002 exception on non-discoverable & unpaired BT device

I'm trying to pair from a Universal Windows C# app to a Bluetooth - Serial converter, without user interaction.
Development is in Visual Studio 2015 under Windows 10 Pro, but app is intended to run in any Windows 10 based device with a Bluetooth adapter.
For security reasons, BT-serial converter isn't discoverable and is protected by a pin, so I'm not able to perform any enumeration procedure to detect and pair it.
My application only knows BT address (MAC) and PIN's device (Also it knows friendly Bluetooth name, but I never used it).
Previously I'd been able to perform this task under Windows Mobile 6 Pocket PC, using Windows Mobile SDK and C++, but unfortunately code isn't portable to Universal Windows Platform.
Playing with MS samples for Universal Windows(https://github.com/Microsoft/Windows-universal-samples) I achieved to write a code that achieves to pair device, creating from strings some objects that in source sample are derived from enumeration process.
But it only works if device is visible. This is the code:
using System;
using Windows.UI.Xaml.Controls;
using Windows.Networking;
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace UWPBTTest
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DoPairing();
}
async public void DoPairing()
{
UInt64 targetMAC = 32217180653; //target MAC in decimal, this number corresponds to my device (00:07:80:4b:29:ed)
BluetoothDevice btDev = await BluetoothDevice.FromBluetoothAddressAsync(targetMAC); //We create target BT device object, here app throws 0x80070002 exception
DeviceInformation infDev = btDev.DeviceInformation; //We need this aux object to perform pairing
DevicePairingKinds ceremoniesSelected = DevicePairingKinds.ConfirmOnly | DevicePairingKinds.ProvidePin; //Only confirm pairing, we'll provide PIN from app
DevicePairingProtectionLevel protectionLevel = Windows.Devices.Enumeration.DevicePairingProtectionLevel.Encryption; //Encrypted connection
DeviceInformationCustomPairing customPairing = infDev.Pairing.Custom; //Our app takes control of pairing, not OS
customPairing.PairingRequested += PairingRequestedHandler; //Our pairing request handler
DevicePairingResult result = await customPairing.PairAsync(ceremoniesSelected, protectionLevel); //launc pairing
customPairing.PairingRequested -= PairingRequestedHandler;
if ((result.Status == DevicePairingResultStatus.Paired) || (result.Status == DevicePairingResultStatus.AlreadyPaired))
{
//success, now we are able to open a socket
}
else
{
//pairing failed
}
}
//Adapted from https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/DeviceEnumerationAndPairing , scenario 9
private async void PairingRequestedHandler(
DeviceInformationCustomPairing sender,
DevicePairingRequestedEventArgs args)
{
switch (args.PairingKind)
{
case DevicePairingKinds.ConfirmOnly:
// Windows itself will pop the confirmation dialog as part of "consent" if this is running on Desktop or Mobile
// If this is an App for 'Windows IoT Core' where there is no Windows Consent UX, you may want to provide your own confirmation.
args.Accept();
break;
case DevicePairingKinds.ProvidePin:
// As function must be asyn, we simulate a delay of 1 second on GetPinAsync
var collectPinDeferral = args.GetDeferral();
string pin = "1234"; //BT converter pin, currently is "1234" for testing purposes
args.Accept(pin);
collectPinDeferral.Complete();
break;
}
}
}
}
This prototype app uses a blank form, as all data are hardcoded.
Also in Package.appxmanifest -> Capabilities, I checked all fields to discard any permission lack.
Currently this code only can perform pairing operation if BT-serial converter is visible.
If BT device isn't visible, BluetoothDevice.FromBluetoothAddressAsync throws an exception (Resource not found: 0x80070002), instead of creating the BluetoothDevice object.
Is as if Windows "needed" to know something of BT device in order to perform operation, I suspect that when I call FromBluetoothAddressAsync, OS internally lists all devices in system (this includes detected BT devices in range) looking for and item with given address.
I've been looking for other methods to perform mac-based pairing against hidden bt devices, but without success (maybe some type of "pre-pairing"? I didn't find anything)
Thanks.

C# & Pcap.Net - Forwarding received packets

First I'm using Visual Studio 2012 with C# and the Pcap.Net Library.
I try to to forward packets which I captured before.
What I try to do:
Spoof ARP-Table of my phone.
Redirect the traffic which normally goes to the gateway to my computer.
Log the packets.
Forward them to the gateway.
What I did:
Spoofing ARP-Table -> works fine.
Redirect traffic to my PC -> works fine (logically).
Log the packets to a dumpfile (.pcap) as shown in the tutorial on this site -> works fine (I can open it and read it with wireshark and it looks good).
Forward the packets to the gateway. -> does not work.
I would like to forward them fluently. So what I did was use the "sendBuffer()" function as shown in the tutorial. So I just read in the .pcap file where all the packet information is saved and try to resend it with this "sendBuffer()" function. And of course I use the same adapter to do it.
When I capture the traffic with wireshark I can see that my packets don't even get sent.
(I'm also not sure if it works at the same time while I capture the data to the file. Because the code which should forward them need to read the packets from the file. Isn't there another way?)
My code to forward the packets from the .pcap file (the IDE doesn't give me any error):
It's approximately my code, I don't have it available cause I'm not at home. But should be right.
IList<LivePacketDevice> devices = LivePacketDevice.AllLocalMachine;
PacketDevice selectedOutputDevice = devices[0];
long capLength = new FileInfo(#"E:\CSharp\Pcap\dumpFile.pcap").Length;
bool isSync = true;
OfflinePacketDevice selectedInputDevice = new OfflinePacketDevice(#"E:\CSharp\Pcap\dumpFile.pcap");
using (PacketCommunicator inputCommunicator = selectedInputDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
using (PacketCommunicator outputCommunicator = selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
if (inputCommunicator.DataLink != outputCommunicator.DataLink)
{
tB_Log.Text = tB_Log.Text + Environement.NewLine + "ERROR: Different Datalinks!";
}
using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength))
{
Packet packet;
while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
{
sendBuffer.Enqueue(packet);
}
outputCommunicator.Transmit(sendBuffer, isSync);
}
}
}
Thank you very much for helping!

Using Sockets to transfer Data with MonoDroid

I'm trying to send some information to a server with Android using Monodroid.
The code is as follows:
public void sendSomething()
{
sock = new TcpClient();
sock.Connect(Dns.GetHostAddresses("a.domain.com"), 7777);
String d;
d = "somedata";
StreamWriter w = new StreamWriter(sock.GetStream());
// StreamReader r = new StreamReader(sock.GetStream());
w.WriteLine(d);
w.Flush();
sock.Close();
}
It works fine if I run the exact same routine in a winforms application, but when linked to a button click in monodroid (running on the android virtual device - I'm using the evaluation version) the server will see the connection but no data is received.
Does anybody have any idea why this could be?
(edited to ammend code)
It could be a server issue. E.g. let's assume that:
a) your winform app running on Windows / MS.NET (and not on Mono / Linux or OSX);
b) your server is Windows-based too and does a ReadLine to read sockets
Then the NewLine between the write (Unix \n) and the read (Windows \r\n\) could explain why the server does not report what's being read.
Can you show us how you're reading the data on the server ? (edit your question)

Categories

Resources