Bluetooth to serial device using Xamarin/Android - c#

I'm attempting to write an application that can read and write to a device that accepts ordinary serial communication through a serial com port. I'm using a bluetooth to serial device. The bluetooth to serial device is a bolutek BK-MD-BC04-B_DEMO. It's basically a bluetooth device with a serial port on it.
I am able to connect to the device using my Android phone, and I can send data to it. With my computer connected to the serial port on the bluetooth device using PuTTY on COM5 with USB to serial, I can see the data I'm sending using my Android phone. I cannot seem to be able to get the serial commands to work properly when I connect the bluetooth adapter to my serial device, however. I am also unable to read anything back from the bluetooth adapter.
I have verified that all of the serial settings seem to be correct. The baud rate, data bits, stop bits, and parity are all set correctly on the bluetooth device.
I tried to contact bolutek via email, but they are very slow to respond. Here are some things I found on the device I'm trying to use:
http://www.electrodragon.com/w/index.php?title=BC04
http://docs.teguna.ro/BC04-electrondragon-2013-01-17.pdf
http://diwo.bq.com/wp-content/uploads/2014/11/BLK-MD-BC04-B_AT-COMMANDS.pdf
Here is my code:
using System;
using System.Linq;
using System.IO;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Bluetooth;
//...
public class MainActivity : Activity
{
private BluetoothSocket socket;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Button button = FindViewById<Button>(Resource.Id.MyButton);
EditText text = FindViewById<EditText>(Resource.Id.editText);
button.Click += delegate
{
BluetoothAdapter adapter = BluetoothAdapter.DefaultAdapter;
Action finish = new Action(async delegate
{
if (socket == null)
{
BluetoothDevice device = (from bd in adapter.BondedDevices where bd.Name == "BOLUTEK" select bd).FirstOrDefault();
if (device == null)
{
AndroidMethods.message("Error", "BOLUTEK device not found. Please make sure you are paired with the BOLUTEK device.",
"OK", this);
return;
}
socket = device.CreateRfcommSocketToServiceRecord(Java.Util.UUID.FromString("00001101-0000-1000-8000-00805f9b34fb"));
}
if (!socket.IsConnected)
await socket.ConnectAsync();
string outString = text.Text + "\r";
string wakeString = "\t\r";
byte[] output = charsToBytes(outString.ToCharArray());
byte[] wakeUp = charsToBytes(wakeString.ToCharArray());
await socket.OutputStream.WriteAsync(wakeUp, 0, wakeUp.Length);
await socket.OutputStream.WriteAsync(wakeUp, 0, wakeUp.Length);
await socket.OutputStream.WriteAsync(wakeUp, 0, wakeUp.Length);
await socket.OutputStream.WriteAsync(output, 0, output.Length);
byte[] output2 = stringToBytes(outString);
byte[] wakeUp2 = stringToBytes(wakeString);
await socket.OutputStream.WriteAsync(wakeUp2, 0, wakeUp.Length);
await socket.OutputStream.WriteAsync(wakeUp2, 0, wakeUp.Length);
await socket.OutputStream.WriteAsync(wakeUp2, 0, wakeUp.Length);
await socket.OutputStream.WriteAsync(output2, 0, output.Length);
});
if (socket != null)
finish();
else if (adapter == null)
{
AndroidMethods.message("Error", "No bluetooth adapter found.", "OK", this);
return;
}
else if (!adapter.IsEnabled)
{
DialogBuilder.createConfirmDialog(this, "Error", "Bluetooth adapter is not enabled. Would you like to enable it now?",
"No", "Yes", delegate
{
adapter.Enable();
finish();
});
}
else
finish();
};
}
public static byte[] stringToBytes(string value)
{
byte[] bytes = new byte[value.Length * sizeof(char)];
System.Buffer.BlockCopy(value.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
public static string bytesToString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
public static byte[] charsToBytes(char[] chars)
{
int length = chars.Length;
byte[] returnVal = new byte[length];
for (int x = 0; x < length; x++)
returnVal[x] = (byte)chars[x];
return returnVal;
}
}
You'll notice I'm using two different methods of converting the string to a byte array. One of them just creates a char array and converts it to a byte array while the other converts a string array to a byte array and each byte is separated by a 0. Either method SEEMS to work when I am watching the incoming bluetooth to serial communication on my computer.
To communicate with the serial device, I would normally use PuTTY and hit tab then enter on my keyboard. This puts the serial device in command mode. You can do this multiple times. Thus the "\t\r". After you send a "\t\r", you should be able to enter a command followed by a "\r". So in PuTTY, I would enter on my keyboard something like "(tab)(enter)commandstring(enter)". The command I'm sending should change some settings on the serial device, yet when I connect to it through PuTTY, the settings are unchanged.
Is there anything I may be overlooking that could be causing this issue? I have spent a lot of time trying to figure this out and have yet to come up with a solution.

Related

reading data from trupulse 360 C#

Trupulse 360B - a device that can measure the distance to any object.
It reads the data and sends it in this form:
$PLTIT,HV,HDvalue,units,AZvalue,units,INCvalue, units,SDvalue,units,*csum
I need to get this data on my PC using BLUETOOTH
Application should be written in c #
MANUAL - http://wiki.awf.forst.uni-goettingen.de/wiki/images/7/71/TruPulse_360-B_Users_Manual_2nd_Edition_English.pdf
Thanks!
data is not always there, from 10 times goes 2-3 times normally, in other cases blank lines appear.What am I doing wrong?
private static void Connect(IAsyncResult result)
{
if (result.IsCompleted)
{
// client is connected now :)
Console.WriteLine(BC.Connected);
stream = BC.GetStream();
if (stream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
// Incoming message may be larger than the buffer size.
NmeaParser.StreamDevice truepulse = new NmeaParser.StreamDevice(stream);
truepulse.OpenAsync();
do
{
numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat(Encoding.ASCII.GetString(myReadBuffer));
}
while (stream.DataAvailable);
// Print out the received message to the console.
Console.WriteLine("You received the following message : " + myCompleteMessage);
}
else
{
Console.WriteLine("Sorry. You cannot read from this NetworkStream.");
}
Console.ReadLine();
}
}

Sending data to a TCP Server

I'm trying to realize a program that sends data to a TCP-server and then receives the same message by COM-port. I have the following code but it sends the data but doesn't receive any data.
When I monitor the serial port I can't see that the data is received.
How do I fix this? Do I have to switch to a multi threading system or is there a other way to sync this? Because I can see that the COM-port is opened but not read out.
And when I test this with Putty I can get it to work.
public class Variables
{
private static int v_VarI = 0;
public static int VarI
{
get { return v_VarI; }
set { v_VarI = value; }
}
private static int v_VarJ = 0;
public static int VarJ
{
get { return v_VarJ; }
set { v_VarJ = value; }
}
}
class Program
{
public class TcpTimeClient
{
private const int portNum = 6666;
private const string hostName = "192.168.1.51";
private const string data = "test";
public static int Main(String[] args)
{
new SerialPortProgram();
while (Variables.VarI < 10)
{
Byte[] bytesSent = Encoding.ASCII.GetBytes(data);
try
{
TcpClient client = new TcpClient(hostName, portNum);
NetworkStream ns = client.GetStream();
byte[] bytes = new byte[1024];
ns.Write(bytesSent, 0, bytesSent.Length);
int bytesRead = ns.Read(bytes, 0, bytes.Length);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Variables.VarI++;
while (Variables.VarJ < Variables.VarI)
{
}
}
Console.ReadLine();
return 0;
}
}
public class SerialPortProgram
{
public SerialPort receiveport = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
public SerialPortProgram()
{
receiveport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
receiveport.Open();
}
public void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// Show all the incoming data in the port's buffer
string rec_data = receiveport.ReadExisting();
Console.WriteLine(rec_data);
Variables.VarJ++;
}
}
}
Update
I've found that the program I wrote and putty and an other program named Serial Port Monitor differ in the IOCTL_SERIAL_SET_WAIT_MASK.
Serial Port Monitor: 0x00 00 01 19
Putty: Unkown
Own program: 0x00 00 01 FB
Does anyone know how to change this mask? Because it's not in the System.IO.Ports.SerialPort class.
you can use this :
public void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int length = receiveport.BytesToRead;
byte[] buf = new byte[length];
SerialPort2.Read(buf, 0, length);
}
buf array is your answer but in decimal mode . and you can changed it to want.
The wait mask is not your problem. Your wait mask enables the serial port for RXCHAR RXFLAG CTS DSR RLSD BRK ERR RING and has everything except ERR turned on.
This is correct for the way .Net wraps serial ports, and anyway it is not exposed in the .NET serial port class. Don't waste time pursuing that difference; your problem lies elsewhere.
Your serial port code ran perfectly on my system and printed all the data received from an external serial source, so I suspect your problem is with the TCP server whose code you did not post, or with your serial ports. Perhaps your configuration requires that you transmit something before the port begins sending? Try something like:
receiveport.Open();
receiveport.WriteLine("?");
Then if you still have problems, try connecting to another serial device to see if you can prove your receive code is working for you as it is for me. If you still can't figure it out, post more information about what's happening on the serial source end.

C# Windows Application using WebSocket for streaming image

I have a camera (now using Arducam OV2640) connected to ESP8266. I am trying to build something that sends websocket data between a C# application and ESP8266. The main purpose of this project is to build a robot, that can view the camera on the robot and control it using a C# application via Websocket.
However, the progress of my project is that it is able to send the command to the robot to make it move, but upon receiving the data from ESP8266, I am not able to piece the data into a proper video streaming to view on the windows C# application. I have used C# bitmap library but not able work properly. Any help is much appreciated. Below is what I have done so far:
//to send the data to ESP8266 Wifi board
public async void webSocketOperation(String operation)
{
ArraySegment<byte> bytesToSend = new ArraySegment<byte>(
Encoding.UTF8.GetBytes(operation));
await UserInterface.ws.SendAsync(
bytesToSend, WebSocketMessageType.Text,
true, CancellationToken.None);
}
//to receive the data sent from ESP8266 board
public async Task receiveData()
{
while(true)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[819200]);
WebSocketReceiveResult result = await ws.ReceiveAsync(buffer, CancellationToken.None);
pbVideoFeed.Image = BytesToBitmap(buffer);
if (ws.State != WebSocketState.Open)
{
break;
}
}
}
//to convert from bytes to image
private Bitmap BytesToBitmap(ArraySegment<byte> buffer)
{
MemoryStream stream = null;
byte[] image_data = new byte[409600];
Bitmap resize_img = new Bitmap(pbVideoFeed.Width, pbVideoFeed.Height);
Graphics graphic = Graphics.FromImage(resize_img);
image_data = buffer.ToArray();
try
{
stream = new MemoryStream(image_data);
Bitmap result = new Bitmap(stream);
graphic.InterpolationMode = InterpolationMode.High;
graphic.DrawImage(result, new Rectangle(0, 0, pbVideoFeed.Width, pbVideoFeed.Height));
graphic.Dispose();
return new Bitmap((Image)resize_img);
//return new Bitmap((Image)new Bitmap(stream));
}
catch (ArgumentException ex)
{
throw ex;
}
finally
{
stream.Close();
}
}

Reading Response from IDTech Card Reader/Writer C# Com Port

I'm working on a C# project in visual studio 2015. For this project I have to read/write data to a hi-co Magnetic ID card. The model of writer I'm using is the IDTECH IDWA-336133B reader/writer.
The company gives you a set of commands to send to the unit through an emulated rs232 port (physical USB port). So far I have sent commands to turn the LEDs on and off on the unit with System.IO.Ports, but I have yet to figure out how I am supposed to receive data from the swipe, or write data on the swipe.
I'm attaching the frmMain.cs file I have, and the manual for the unit. You can see the commands on that manual that I'm using (Sending the hex code as bytes).
So what I was wondering: is there a way someone can show me the correct syntax / way to write a command to read the data from the card swipe back in?
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.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace SerialPortCommunication
{
public partial class Form1 : Form
{
static SerialPort _serialPort;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
_serialPort = new SerialPort();
byte[] command = new byte[] { 0x1B, 0x81 };
_serialPort.PortName = "COM4";
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_serialPort.Write(command, 0, command.Length);
_serialPort.Close();
_serialPort.Dispose();
}
private void btnLedon_Click(object sender, EventArgs e)
{
_serialPort = new SerialPort();
byte[] command = new byte[] { 0x1B, 0x84};
_serialPort.PortName = "COM4";
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_serialPort.Write(command, 0, command.Length);
_serialPort.Close();
_serialPort.Dispose();
}
private void btnRead_Click(object sender, EventArgs e)
{
_serialPort = new SerialPort();
byte[] command = new byte[] { 0x1B, 0x52 };
byte[] hico = new byte[] {0x1B, 0x78 };
_serialPort.PortName = "COM4";
_serialPort.ReadTimeout = 10000;
_serialPort.WriteTimeout = 500;
byte[] answer = new byte[] { };
_serialPort.Open();
// setting it to hico cards just incase
_serialPort.Write(hico, 0, hico.Length);
//sends command to read data
_serialPort.Write(command, 0, command.Length);
// I don't know if this is even remotely right
String response =_serialPort.ReadExisting();
lblReadData.Text = response;
_serialPort.Close();
_serialPort.Dispose();
}
}
}
I know this is sloppy code, but I'm just trying to get it working so I can migrate it to the real program and do it correctly.
Here is part of the manual that has all the hex codes and responses etc.:
Command & Response Introduction
The EzWriter supports the following commands. The responses are
provided.
Command: Reset Buffer Command code: <ESC> a Hex code: 1B
61 Response: none Description: This command reset the EzWriter
buffer to initial state. Encoding settings are not affected by this
command.
Command: Read Command code: <ESC> r Hex code: 1B 72
Response: [data block] <ESC> [status byte] Description: This
command requests the EzWriter to read a card swiped and respond with
the data read.
Command: Write Command code: <ESC> w [data block] Hex
code: 1B 77 [data block] Response: <ESC> [status byte]
Description: This command requests the EzWriter to write the data
block into the card swiped.
Command: Communication test Command code: <ESC> e Hex
code: 1B 65 Response: <ESC> y [1B] [79] Description:
This command is used to verify that the communication link between
computer and the EzWriter is up and good.
The serial port class fires the DataReceived event when data is sent to it. Keep in mind that this event fires on its own thread, separate from the main thread running the UI of your form. In order to receive data you need to implement this event. I did a quick example but have not tested it.
class Program
{
private static SerialPort _SerialPort;
private const int baudRate = 9600;
private const string PortName = "Com4";
static void Main(string[] args)
{
_SerialPort = new SerialPort(PortName, baudRate);
_SerialPort.DataReceived += _readSerialPort_DataReceived;
_SerialPort.Open();
var command = new byte[] { 0x1B, 0x81 };
Console.WriteLine("Sending {0} to device", command);
sendData(command);
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
_SerialPort.Close();
}
static void sendData(byte[] command)
{
_SerialPort.Write(command,0,command.Length);
}
static void _readSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var sp = (SerialPort) sender;
// Edited following line. See comment
var data = sp.ReadLine();
Console.WriteLine("Data Received: {0}", data);
//you may be able to do something like this as well but I am not sure if this is a blocking call
var messageLength = 10;
var buffer = new byte[messageLength];
sp.Read(buffer, 0, buffer.Length);
//if you are going to update the UI you need to invoke a delegate method on the main thread
}
}
There are a few options on how to read the data as well if you want to read it into a byte array or only take a snip-it of the data returned.
More info on Serial port class: Here
Info on updating UI elements from another thread: Here
MSDN example of Serial port DataReceived event: Here

TCP IP Client in WPF for Ubuntu 14 Server

I am trying to create TCP IP Client in WPF GUI / C#.NET for a Ubunu Server.
Problem: I am able to connect to the server machine , the connection work correctly, send the message correctly and the ubuntu console show as well , Client Connected and sent this command like Start Video Feed on the server but When it comes to Read the Response nothing happens - It does not read the byte array that should be returned by the Ubuntu Server. Actually on message - 102 it should start the video feed on the server and return back the video feed byte array which should be read further and display the video. No code written yet to display the video feed as I am unable to read the feed from the server however, the client sends the commands(messages) to the server correctly as mentioned can view it on a console of the Ubuntu server machine. Please suggest thanks !!
Below is the code please have a look and suggest me what I am doing wrong :
namespace POC_TCP_Listener
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private int WhichEventFired = 0;
private void Button_Click_1(object sender, RoutedEventArgs e)
{
try
{
// string message = "{Site: 1}";
WhichEventFired = 1; //Start Video Feed
Thread ClientThread = new Thread(new ThreadStart(ConnectToServerAndRetrieveBytes));
ClientThread.Start();
}
catch (Exception ex)
{
string st = ex.Message;
}
}
private void ConnectToServerAndRetrieveBytes()
{
TcpClient TCP = new TcpClient();
TCP.Connect("IPAddress", 5001);
byte[] packet;
var size = 9;
var header = 102;
var siteId = 1;
var state = 1;
if (WhichEventFired == 1)
{
header = 102; // Start Video Feed
}
else if (WhichEventFired == 2)
{
header = 114; // Stop Video Feed
}
else
{
header = 115; // query Temperature
}
// <8> <115> <1>
packet = BitConverter.GetBytes(size).Reverse().Concat(BitConverter.GetBytes(header).Reverse()).Concat(BitConverter.GetBytes(siteId).Reverse()).Concat(BitConverter.GetBytes(state).Reverse()).ToArray();
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = packet;
// Get a client stream for reading and writing.
NetworkStream stream = TCP.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
byte[] buffer = new byte[64 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
// In the below line - it stops and nothing happens after it - Please Suggest
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
// return ms.ToArray();
}
stream.Close();
TCP.Close();
}
}
}
strong text
Please suggest why it stops working or let me know if I am doing anything wrong.
I think the problem is that if there are no more packages left, it escapes the while-loop. If you want to check it endlessly you should try using a for. But i am not sure.
Yeah that should be it. If there are no Packages in the moment the while-loop is starting, it terminates itself because there is nothing to read. So you could check if the Ubuntu Server returns you something.

Categories