I start learning Netduino short time ago. At now, I want to use it with MS5803 30BAR sensor. This Components communicate with I2C Protocol. I learned this protocol a little bit but not enough.
I wrote introducing of code. When I came main code, I did not do anything. My code is below.
Can anybody help about this matter? I will be so pleased :)
public class Program
{
public static void Main()
{
// Configuration of MS5803 30BA
I2CDevice i2c = new I2CDevice(new I2CDevice.Configuration(0x76>>1, 400));
byte[] read = new byte[1];
I2CDevice.I2CTransaction[] i2cTx = new I2CDevice.I2CTransaction[1];
i2cTx[0] = I2CDevice.CreateReadTransaction(read);
// ???
}
}
It looks like you're missing the I2C.Execute call. Without knowing anything about the device you're communicating with this will at least start the transmission.
Try to add this line after you create the read transaction.
i2c.Execute(i2cTX[0],500);
byte[] returnByte = new byte[3];
var readX = new I2CDevice.I2CTransaction[] {I2CDevice.CreateReadTransaction(returnByte) };
int executed = 0;
I2CDevice i2c = new I2CDevice(new I2CDevice.Configuration(0x76, 400));
executed = i2c.Execute(readX, 400);
if (executed == 0)
{
//Debug.Print("Read FAIL!");
}
else
{
//Debug.Print("Read SUCCESS!");
}
//throw new Exception("I2C transaction failed");
//you will need to do some bit shifting with the readX array to get your values.
}
Here an excellent document on netMF i2c: https://www.ghielectronics.com/docs/12/i2c
The device data sheet:
http://www.amsys-sensor.eu/sheets/amsys.en.ms5803_30ba.pdf
Related
I have a USB HID device that I would like to communicate with. I am successfully doing so on Windows using the HidSharp library (link: https://github.com/treehopper-electronics/HIDSharp). My Windows application is developed using the .NET Framework 4.5, C#, and Visual Studio.
I now want to communicate with this same USB HID device from an Android tablet instead of from the Windows desktop. I am encountering some problems doing so. When I have the device plugged in to my tablet, it reports a single interface with a single "read" endpoint. Here is what is reported to me:
Interface #0
Class: Human Interaction Device (0x3)
Endpoint: #0
Address : 0x81 (10000001)
Number : 1
Direction : Inbound (0x80)
Type : Intrrupt (0x3)
Poll Interval : 1
Max Packet Size: 64
Attributes : 000000011
As you can see, it only reports a single endpoint, which is an inbound endpoint. I need to be able to output simple commands to this device, which I was able to do so successfully on Windows using HidSharp.
HidSharp abstracted everything into a single "stream" object that you could read from and write to. Using the Android APIs, there isn't a single "stream" object, but rather there seem to be 3 different ways of reading/writing: bulk transfer, control transfer, and USB Request. I've tried sending out data using all 3, but with seemingly no success.
Any suggestions on what to do? Is there a reason why I could send out data to this device on Windows, but seemingly cannot do so from Android? Is there a way to use a single endpoint as both a read and a write endpoint? Is there something that I am just obviously missing and not understanding?
I am using Xamarin as my development environment (C#, Visual Studio 2017). Since code is always helpful, here is how I am connecting to the device:
int VendorID = 0x04d8;
int ProductID = 0x2742;
UsbManager USB_Manager = null;
UsbDevice USB_Device = null;
UsbDeviceConnection DeviceConnection = null;
UsbInterface DeviceInterface = null;
UsbEndpoint OutputEndpoint = null;
UsbEndpoint InputEndpoint = null;
//Grab the Android USB manager and get a list of connected devices
var USB_Manager = MyMainActivity.ApplicationContext.GetSystemService(Android.Content.Context.UsbService) as Android.Hardware.Usb.UsbManager;
var attached_devices = USB_Manager.DeviceList;
//Find the device in the list of connected devices
foreach (var d in attached_devices.Keys)
{
if (attached_devices[d].VendorId == VendorID && attached_devices[d].ProductId == ProductID)
{
USB_Device = attached_devices[d];
break;
}
}
//Assuming we found the correct device, let's set everything up
if (USB_Device != null)
{
for (int j = 0; j < USB_Device.InterfaceCount; j++)
{
DeviceInterface = USB_Device.GetInterface(j);
for (int i = 0; i < DeviceInterface.EndpointCount; i++)
{
var temp_ep = DeviceInterface.GetEndpoint(i);
if (temp_ep.Type == Android.Hardware.Usb.UsbAddressing.XferInterrupt)
{
if (temp_ep.Direction == Android.Hardware.Usb.UsbAddressing.In)
{
InputEndpoint = temp_ep;
}
if (temp_ep.Direction == Android.Hardware.Usb.UsbAddressing.Out)
{
OutputEndpoint = temp_ep;
}
}
}
}
//Request permission to communicate with this USB device
UsbReceiver receiver = new UsbReceiver();
PendingIntent pending_intent = PendingIntent.GetBroadcast(Game.Activity, 0, new Android.Content.Intent(UsbReceiver.ACTION_USB_PERMISSION), 0);
IntentFilter intent_filter = new IntentFilter(UsbReceiver.ACTION_USB_PERMISSION);
Game.Activity.RegisterReceiver(receiver, intent_filter);
USB_Manager.RequestPermission(USB_Device, pending_intent);
bool has_permission = USB_Manager.HasPermission(USB_Device);
var device_connection = USB_Manager.OpenDevice(USB_Device);
device_connection.ClaimInterface(DeviceInterface, true);
DeviceConnection = device_connection;
}
Next, here is how I attempt to read from the device:
//3 methods of attempting to read from the device
//Method 1:
byte[] inpt = new byte[64];
var request = new UsbRequest();
request.Initialize(DeviceConnection, InputEndpoint);
var byte_buffer = ByteBuffer.Allocate(64);
request.Queue(byte_buffer, 64);
DeviceConnection.RequestWait();
byte_buffer.Rewind();
for(int i = 0; i < 64; i++)
{
inpt[i] = (byte) byte_buffer.Get();
}
//Method 2:
byte[] inpt = new byte[64];
DeviceConnection.BulkTransfer(InputEndpoint, inpt, inpt.Length, 1000);
//Method 3:
byte[] inpt = new byte[64];
DeviceConnection.ControlTransfer(UsbAddressing.In, 0, 0, 0, inpt, 64, 1000);
And finally, here is how I attempt to write data to this device:
//Method 1:
byte[] output_msg; //This variable is assigned elsewhere in the code
DeviceConnection.BulkTransfer(OutputEndpoint, output_msg, output_msg.Length, 30);
//Method 2:
byte[] output_msg; //This variable is assigned elsewhere in the code
DeviceConnection.ControlTransfer(UsbAddressing.Out, 0, 0, 0, output_msg, output_msg.Length, 1000);
//Method 3:
byte[] output_msg; //This variable is assigned elsewhere in the code
var write_request = new UsbRequest();
write_request.Initialize(DeviceConnection, OutputEndpoint);
var byte_buffer_write = ByteBuffer.Wrap(output_msg);
request.Queue(byte_buffer_write, output_msg.Length);
DeviceConnection.RequestWait();
"OutputEndpoint" is typically null because there is no output endpoint, so I often replace "OutputEndpoint" with "InputEndpoint", but with no success.
Any help would be greatly appreciated! Thanks!!!
You are dealing with HID devices which means you should do Interrupt Transfers.
In Android, you should use UsbRequest to perform Interrupt Transfers (as it does Asynchronous NonBlocking IO).
The endpoints are unidirectional and can be used for both inbounds and outbound (but not at the same time)
If the endpoint is inbound then submit the Urb using UsbRequest and queue as you tried before but using empty buffer with expected bufferLength.
The RequestWait will return UsbRequest Object back upon completion.
If the usbRequest.getEndPoint().getDirection() is inbound then your buffer variable will be updated with read buffer from the device.
If the usbRequest.getEndpoint().getDirection() is outbound then you should pass your buffer to write data to the device
To provide a little bit of context. I am trying to output live audio from a camera in my c# application. After doing some research it seems pretty obvious to do it in a c++ managed dll. I chose the XAudio2 api because it should be pretty easy to implement and use with dynamic audio content.
So the idea is to create the XAudio device in c++ with an empty buffer and push in the audio from the c# code side. The audio chunks are pushed every 50ms because I want to keep the latency as small as possible.
// SampleRate = 44100; Channels = 2; BitPerSample = 16;
var blockAlign = (Channels * BitsPerSample) / 8;
var avgBytesPerSecond = SampleRate * blockAlign;
var avgBytesPerMillisecond = avgBytesPerSecond / 1000;
var bufferSize = avgBytesPerMillisecond * Time;
_sampleBuffer = new byte[bufferSize];
Everytime the timer runs it gets the pointer of the audio buffer, reads the data from the audio, copies the data to the pointer and calls the PushAudio method.
I am also using a stopwatch to check how long the processing took and calculate the interval again for the timer to include the processing time.
private void PushAudioChunk(object sender, ElapsedEventArgs e)
{
unsafe
{
_pushAudioStopWatch.Reset();
_pushAudioStopWatch.Start();
var audioBufferPtr = Output.AudioCapturerBuffer();
FillBuffer(_sampleBuffer);
Marshal.Copy(_sampleBuffer, 0, (IntPtr)audioBufferPtr, _sampleBuffer.Length);
Output.PushAudio();
_pushTimer.Interval = Time - _pushAudioStopWatch.ElapsedMilliseconds;
_pushAudioStopWatch.Stop();
DIX.Log.WriteLine("Push audio took: {0}ms", _pushAudioStopWatch.ElapsedMilliseconds);
}
}
This is the implementation of the c++ part.
Regarding to the documentation on msdn I created a XAudio2 device and added the MasterVoice and SourceVoice. The buffer is empty at first because the c# part is responsible to push in the audio data.
namespace Audio
{
using namespace System;
template <class T> void SafeRelease(T **ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
WAVEFORMATEXTENSIBLE wFormat;
XAUDIO2_BUFFER buffer = { 0 };
IXAudio2* pXAudio2 = NULL;
IXAudio2MasteringVoice* pMasterVoice = NULL;
IXAudio2SourceVoice* pSourceVoice = NULL;
WaveOut::WaveOut(int bufferSize)
{
audioBuffer = new Byte[bufferSize];
wFormat.Format.wFormatTag = WAVE_FORMAT_PCM;
wFormat.Format.nChannels = 2;
wFormat.Format.nSamplesPerSec = 44100;
wFormat.Format.wBitsPerSample = 16;
wFormat.Format.nBlockAlign = (wFormat.Format.nChannels * wFormat.Format.wBitsPerSample) / 8;
wFormat.Format.nAvgBytesPerSec = wFormat.Format.nSamplesPerSec * wFormat.Format.nBlockAlign;
wFormat.Format.cbSize = 0;
wFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
HRESULT hr = XAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
if (SUCCEEDED(hr))
{
hr = pXAudio2->CreateMasteringVoice(&pMasterVoice);
}
if (SUCCEEDED(hr))
{
hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wFormat,
0, XAUDIO2_DEFAULT_FREQ_RATIO, NULL, NULL, NULL);
}
buffer.pAudioData = (BYTE*)audioBuffer;
buffer.AudioBytes = bufferSize;
buffer.Flags = 0;
if (SUCCEEDED(hr))
{
hr = pSourceVoice->Start(0);
}
}
WaveOut::~WaveOut()
{
}
WaveOut^ WaveOut::CreateWaveOut(int bufferSize)
{
return gcnew WaveOut(bufferSize);
}
uint8_t* WaveOut::AudioCapturerBuffer()
{
if (!audioBuffer)
{
throw gcnew Exception("Audio buffer is not initialized. Did you forget to set up the audio container?");
}
return (BYTE*)audioBuffer;
}
int WaveOut::PushAudio()
{
HRESULT hr = pSourceVoice->SubmitSourceBuffer(&buffer);
if (FAILED(hr))
{
return -1;
}
return 0;
}
}
The problem I am facing is that I always have some cracking in the output. I tried to increase the interval of the timer or increased the buffer size a bit. Everytime the same result.
What am I doing wrong?
Update:
I created 3 buffers the XAudio engine can go through. The cracking got away. The missing part now is to fill the buffers at the right time from the c# part to avoid buffers with the same data.
void Render(void* param)
{
std::vector<byte> audioBuffers[BUFFER_COUNT];
size_t currentBuffer = 0;
// Get the current state of the source voice
while (BackgroundThreadRunning && pSourceVoice)
{
if (pSourceVoice)
{
pSourceVoice->GetState(&state);
}
while (state.BuffersQueued < BUFFER_COUNT)
{
std::vector<byte> resultData;
resultData.resize(DATA_SIZE);
CopyMemory(&resultData[0], pAudioBuffer, DATA_SIZE);
// Retreive the next buffer to stream from MF Music Streamer
audioBuffers[currentBuffer] = resultData;
// Submit the new buffer
XAUDIO2_BUFFER buf = { 0 };
buf.AudioBytes = static_cast<UINT32>(audioBuffers[currentBuffer].size());
buf.pAudioData = &audioBuffers[currentBuffer][0];
pSourceVoice->SubmitSourceBuffer(&buf);
// Advance the buffer index
currentBuffer = ++currentBuffer % BUFFER_COUNT;
// Get the updated state
pSourceVoice->GetState(&state);
}
Sleep(30);
}
}
XAudio2 does not copy the source data buffer at the time you submit it via SubmitSourceBuffer. You must keep that data (which is in your application memory) valid, and the buffer allocated for the entire time that XAudio2 will need to read out of it to process the data. This is done for efficiency to avoid the need for an extra copy, but puts the multi-threaded burden of keeping the memory available until it's done playing on you. That also means you can't modify the playing buffer.
Your current code is just reusing the same buffer which is causing the popping as you change the data while it's play. You can solve this with having 2 or three buffers you rotate between. A XAudio2 Source Voice has status information you can use to determine when it's done playing a buffer, or you can register for explicit callbacks which tell you when the buffer is no longer being used.
See DirectX Tool Kit for Audio and classic XAudio2 samples for examples of using XAudio2.
Hello i am trying to map system mic audio to external sound card speaker and external sound card mic audio to system speaker. By using code
public void MapForManualCall()
{
try
{
if (db.getResultOnQuery("SELECT [Value] FROM [dbo].[SystemProperties] where property='RecordingEnabled'").Rows[0][0].ToString().Equals("YES"))
{
SystemMic = new NAudio.Wave.WaveInEvent();
SystemMic.DeviceNumber = 0;
SystemMic.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(SystemMic.DeviceNumber).Channels);
SoundcardMic = new NAudio.Wave.WaveInEvent();
SoundcardMic.DeviceNumber = 1;
SoundcardMic.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(SoundcardMic.DeviceNumber).Channels);
//NAudio.Wave.WaveInProvider waveIn = new NAudio.Wave.WaveInProvider(sourceStream);
// used to set listen property of mic on
var waveOutReceiver = new NAudio.Wave.WaveOut();
waveOutReceiver.DeviceNumber = 0;
// used to wavout caller voice on receiver speaker
NAudio.Wave.WaveInProvider waveInProviderCaller = new NAudio.Wave.WaveInProvider(SystemMic);
waveOutReceiver.Init(waveInProviderCaller);
waveOutReceiver.Play();
var waveOutCaller = new NAudio.Wave.WaveOut();
waveOutCaller.DeviceNumber = 1;
// used to wavout receiver voice on caller speaker
NAudio.Wave.WaveInProvider waveInProviderReceiver = new NAudio.Wave.WaveInProvider(SoundcardMic);
waveOutCaller.Init(waveInProviderReceiver);
waveOutCaller.Play();
//sourceStream.StartRecording();
//waveOut.Play();
// SoundcardMic.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(waveIn_DataAvailable1);
// writer1 = new NAudio.Wave.WaveFileWriter(outputFilenameReceiver, SoundcardMic.WaveFormat);
SoundcardMic.StartRecording();
//SystemMic.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(waveIn_DataAvailable);
//writer = new NAudio.Wave.WaveFileWriter(outputFilenameCaller, SystemMic.WaveFormat);
SystemMic.StartRecording();
// MapSpeakerNMic();
}
}
catch (Exception ex)
{
MessageBox.Show("Please Check Headphone and Device Cable Connected Properly!");
}
}
Code above works perfect but there is delay of 3-4 seconds between mapping. When i am trying above task using Listen functionalities of windows 7 it works perfect. According to me it can be issue of reading writing buffer. Don't know how to do it...
Latency is the issue here. There is latency at the recording and playback stage. You will find it very hard to reduce this to small values without using something like ASIO. However, all the NAudio APIs allow you to specify buffer sizes so you can see how low you can go before you get dropouts.
I want to send a file from a C# server to a AS3 Flash Client. My C# server code for sending the file is something like this:
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();
// This part gets the file and send the data in bytearray
byte[] fileData = File.ReadAllBytes("send/mypicture.jpg");
clientSock.Send(fileData);
Now I need a as3 client. I found this: http://flasharp.blogspot.pt/2010/03/socket-serverclient-chat.html and I constructed something like this:
public function Main():void {
...
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
...
}
function onResponse(e:ProgressEvent):void {
var file:File;
var fs:FileStream;
var fileData:ByteArray = new ByteArray();
// Check if socket has data
if(socket.bytesAvailable > 0) {
while(socket.bytesAvailable) {
// read the socket data into the fileData
socket.readBytes(fileData,0,0);
}
}
file = File.documentsDirectory.resolvePath("teste.jpg");
fs = new FileStream();
fs.open(file, FileMode.WRITE);
// Writing the file
fs.writeBytes(fileData);
fs.close();
}
I've managed to send and receive a file, but it only saves up to 50kbs, anything bigger and you just gest a file with that size.
Any thoughts on how to transfer a file with any size?
I managed to solve this and updated this post with a sample.
UPDATED & SOLVED:
I wanted to send files from a C# server to AS3 Clients using sockets in a Local Network. I had some trouble finding out how to do it, but I managed to do so.
Server (C#):
1 - I create a TcpListener that listens for new clients with any IP in that network to the specified port number;
2 - When a new client connects I create a Thread to handle it;
3 - In that Thread I send the data I want to. In this case that data is divided in two parts, the first is a 4 bytearray that contains the size of the file I want to send, and the second is a bytearray of the file itself;
4 - After the data is sent I close that client connection;
Client (AS3):
1 - First of all I convert my bytearrays to LITTLE_ENDIAN, since AIR is by default BIG_ENDIAN and the data I get from the server is LITTLE_ENDIAN;
2 - Add the events to the socket connection and conect to the server;
3 - On the onResponse function I receive the socket packages to a bytearray;
4 - Save that bytearray into a file;
The last part on the client was the trickiest one, because it took me some time to figure out that AIR is BIG_ENDIAN by default, and how to read the packages.
So basically, what I do is, on the first package that comes in I read the first 4 bytes to a bytearray and then convert that to an int, which gives me my total file size. I use this to know when there are no more packages to receive and therefore finish the connection and save the file. The rest of the first package and subsequent packages are added to a bytearray that will store that file data itself. The workaround here is to start writing on the beggining the first time a package is received and then add the subsequent packages where the last one left off, i.e., first time I write from the 0 to 65321, second one I'll have to write from the 65321 to XXXX, and so on.
The file is being saved to the MyDocuments folder.
I'm unsure if this is the best method to do this, since I'm rather new to socket connection, however this works for me and I tested with files up to 165MB and it works. It supports multiple client connections and is pretty basic, but this is a starting point, not a finish line.
I hope this can help others as it helped me, since I did not find anything like it on the web (regarding file transfer not C# -> AS3 connection).
If someone wants to input some info or needs clarification on something, please feel free to ask.
Last but no least, sample can be downloaded here: http://sdrv.ms/W5mSs9 (Server in C# Express 2010 and Client in Flash Builder 4.6 with Flex SDK 4.6.0)
In case the sample in the link above ever dies out here is the
ActionScript 3 Source Code:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.Socket;
import flash.system.Security;
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.text.TextField;
public class FileTransferLocal extends Sprite
{
private var socket:Socket = new Socket();
private var file:File;
private var fs:FileStream = new FileStream();
private var fileData:ByteArray = new ByteArray();
private var fileSize:ByteArray = new ByteArray();
private var fileDataPosition:int = new int();
private var fileDataFlag:int = new int();
private var fileSizeFlag:int = new int();
private var fileSizeCounter:int = new int();
private var fileDataPreviousPosition:int = new int();
private var myText:TextField = new TextField();
public function FileTransferLocal()
{
try {Security.allowDomain("*");}catch (e) { };
// Convert bytearray to Little Endian
fileSize.endian = Endian.LITTLE_ENDIAN;
fileData.endian = Endian.LITTLE_ENDIAN;
socket.endian = Endian.LITTLE_ENDIAN;
fileSizeFlag = 0;
fileDataFlag = 0;
myText.width = 150;
myText.height = 150;
myText.x = 200;
myText.y = 200;
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);
// Put the IP and port of the server
socket.connect("10.1.1.211", 5656);
}
private function onConnect(e:Event):void {
trace("onConnect\n");
}
private function onClose(e:Event):void {
trace("onClose");
socket.close();
}
private function onError(e:IOErrorEvent):void {
trace("IO Error: "+e);
}
private function onSecError(e:SecurityErrorEvent):void {
trace("Security Error: "+e);
}
private function onResponse(e:ProgressEvent):void {
if(!fileSizeFlag) {
socket.readBytes(fileSize, 0, 4);
fileSize.position = 0;
fileSizeFlag = 1;
fileSizeCounter = fileSize.readInt();
trace("fileSizeCounter -> " + fileSizeCounter);
}
trace("---- New package ----> " + socket.bytesAvailable);
if(fileSizeCounter > 0) {
fileSizeCounter -= socket.bytesAvailable;
if(fileDataPosition != 0) {
fileDataPreviousPosition += fileDataPosition;
}
if(fileData.length == 0) {
fileDataPreviousPosition = socket.bytesAvailable;
socket.readBytes(fileData, 0, socket.bytesAvailable);
} else {
fileDataPosition = socket.bytesAvailable;
socket.readBytes(fileData, fileDataPreviousPosition, socket.bytesAvailable);
}
}
// Saves the file
if(fileSizeCounter == 0) {
trace("File total size" + fileData.length);
file = File.documentsDirectory.resolvePath("test.mp3");
fs.open(file, FileMode.WRITE);
fs.writeBytes(fileData);
fs.close();
myText.text = "File successefully\nreceived!";
addChild(myText);
}
// Is still receiving packages
else {
myText.text = "Receiving file...";
addChild(myText);
}
}
}
}
In C# create a new Windows Application
add a
ListBox call it statusList
Label call it port
Label call it status
C# Source code in Sample Above:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Reflection;
namespace ServerThread
{
public partial class ServerThread : Form
{
private TcpListener tcpListener;
private Thread listenThread;
public ServerThread()
{
InitializeComponent();
// Port number
int portNumber = 5656;
port.Text = portNumber.ToString();
// Create a TcpListener to cover all existent IP addresses with that port
this.tcpListener = new TcpListener(IPAddress.Any, portNumber);
// Create a Thread to listen to clients
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
// Blocks until a client has conected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
// Create a Thread to handle the conected client communication
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
// Receive data
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
while (true)
{
try
{
// Sending data
string filePath = "send/mysong.mp3"; // Your File Path;
byte[] fileData = File.ReadAllBytes(filePath); // The size of your file
byte[] fileSize = BitConverter.GetBytes(fileData.Length); // The size of yout file converted to a 4 byte array
byte[] clientData = new byte[fileSize.Length + fileData.Length]; // The total byte size of the data to be sent
fileSize.CopyTo(clientData, 0); // Copy to the file size byte array to the sending array (clientData) beginning the in the 0 index
fileData.CopyTo(clientData, 4); // Copy to the file data byte array to the sending array (clientData) beginning the in the 4 index
// Send the data to the client
clientStream.Write(clientData, 0, clientData.Length);
clientStream.Flush();
// Debug for the ListBox
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate {
statusList.Items.Add("Client IP: " + tcpClient.Client.RemoteEndPoint.ToString());
statusList.Items.Add("Client Data size: " + clientData.Length);
}));
}
}
catch
{
//
break;
}
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate
{
statusList.Items.Add("File successefully sent!");
}));
}
// Close the client
tcpClient.Close();
}
}
}
}
I have been working with Monodroid for a few days and still can't figure out how to send a command through Bluetooth.
This is my scenario: I have a Tablet/Cellphone working with Android 2.1+ and need to send and receive data to a Bluetooth printer (in bytes).
What i managed so far:
using Android.Bluetooth; // library necessary
BluetoothAdapter bth = BluetoothAdapter.DefaultAdapter;
if (!bth.IsEnabled)
bth.Enable();
ICollection<BluetoothDevice> bthD = bth.BondedDevices;
foreach (BluetoothDevice d in bthD)
{
if (d.Name == "DPP-350")
{
Java.Util.UUID UUID = Java.Util.UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
// Get the BLuetoothDevice object
BluetoothSocket s = d.CreateRfcommSocketToServiceRecord(UUID);
s.Connect();
// Try to send command
...
s.Close()
}
}
The program asks for the pairing info, with is done correctly.
I have tried many ways to send the command:
// the command
// Self_Test = Chr(27) + Chr(84) = ESC T
byte[] dBytes = System.Text.Encoding.GetEncoding(1252).GetBytes(Self_Test);
// wont work
new Java.IO.ObjectOutputStream(s.OutputStream).Write(dBytes);
// wont work
System.IO.Stream st = s.OutputStream;
if (st.CanWrite)
{
st.Write(dBytes, 0, dBytes.Length);
st.Flush();
}
// wonk work
s.OutputStream.Write(dBytes, 0, dBytes.Length);
s.OutputStream.Flush();
No error is raised. I'm running out of options here...
Thanks in advance!
I know this is a very old thread, but I wanted to post a reply so others will know the answer. I too searched hard with no luck.
s.OutputStream.BeginWrite(buffer, 0, buffer.Length,new AsyncCallback(delegate {}), State.Connected);
Thanks.