I've been trying to write a C# application that send data to a stage light using the Enttec DMX USB Pro box. There are provided C# wrappers that I'm using and I've gotten the light to respond as expected but it very rarely works. I seem to have to switch between using from off the shelf application to "reset" the connection a few times before I can get it to start responding to my writes.
My DMX Code is
class DmxDriver
{
const int DMX_PACKET_SIZE = 513;
private bool connected;
private FTDI device;
private int startAddr;
private byte[] packet;
public DmxDriver(int baseDmxAddr)
{
startAddr = baseDmxAddr;
device = new FTDI();
FTDI.FT_STATUS result = device.OpenByIndex(0);
if (result == FTDI.FT_STATUS.FT_OK)
{
connected = true;
Console.WriteLine("DMX connected");
}
else
{
connected = false;
Console.WriteLine("DMX CONNECTION FAILED");
}
packet = new byte[DMX_PACKET_SIZE];
for (int i = 0; i < DMX_PACKET_SIZE; i++)
{
packet[i] = 0;
}
}
~DmxDriver()
{
device.Close();
}
public bool deviceConnected()
{
return connected;
}
public void sendData()
{
if (packet.Length != 513)
{
return;
}
uint written = 0;
FTDI.FT_STATUS result;
byte[] header = new byte[4];
header[0] = 0x7E; //start code
header[1] = 6; //DMX TX
header[2] = 255 & 0xFF; //pack length logical and with max packet size
header[3] = 255 >> 8; //packet length shifted by byte length? DMX standard idk
result = device.Write(header, 4, ref written);//send dmx header
Console.WriteLine(result);
Console.WriteLine(written);
result = device.Write(packet, 513, ref written);//send data array
Console.WriteLine(result);
Console.WriteLine(written);
byte[] endcode = new byte[1];
endcode[0] = 0xE7;
device.Write(endcode, 1, ref written);//send dmx end code
}
Related
I have a wpf gui that I want to upload files from and send to a C client .
I want to send 3 files and for some reason 1 of them is being sent and written (but it adds 8 nulls in the end and removes 4 of the first letters in the file)
and in the other two when I try to receive the size it says their size is 0
I've been stuck on this problem for a while now and i'm becoming depserate as i'm probably missing a small thing , if any of u could give a hand that'll mean a lot ! I really wanna know whats the problem in my code.
I have the files paths in an array and sending it in main like so
C# Main
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);//switch the port
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(ipPoint);
listenSocket.Listen(1);
Socket clientSocket = listenSocket.Accept();
for (int i = 0; i < 1; i++)
{
SendFile(clientSocket, filePaths[i]);
}
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
SendFile(C# side)
public static void SendFile(Socket clientSocket, string filePath)
{
if (File.Exists(filePath))
{
FileInfo fi = new FileInfo(filePath);
long file_size = fi.Length;
byte[] preBuffer;
using (var memoryStream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(memoryStream))
{
writer.Write(file_size);
}
preBuffer = memoryStream.ToArray();
byte[] fixedBuffer = new byte[4];
Array.Copy(preBuffer, 0, fixedBuffer, 0, 4);
Console.WriteLine(BitConverter.ToString(preBuffer));
Console.WriteLine(BitConverter.ToString(fixedBuffer)); //fixing the problem i had with the converting to array that it added 4 useless zeros.
clientSocket.Send(fixedBuffer); // sending size
}
byte[] data = new Byte[4096];
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
int actualRead;
do
{
actualRead = fs.Read(data, 0, data.Length);
clientSocket.Send(data);
file_size -= actualRead;
} while (file_size - filePath.Length > 0);
}
}
else
{
MessageBox.Show("File for the program is missing! lua/pcap/csv");
}
}
C Receive(built from 3 functions)
/*
============================================
General : function is responsible for receiving a length of data from the client
Parameters : sock - client socket to receive the data from
*buf - holds a pointer to the buffer that needs to update
bufsize - the length of the buffer
Return Value : returns TRUE when the data is read correctly
else, FALSE when there was a socket error or no bytes are received.
============================================
*/
bool recv_raw(SOCKET sock, void* buf, int bufsize)
{
unsigned char* pbuf = (unsigned char*)buf;
while (bufsize > 0) {
int num = recv(sock, pbuf, bufsize, 0);
if (num <= 0) { return false; }
pbuf += num;
bufsize -= num;
}
return true;
}
/*
===================================================
General : receives the length of the file and updates it
Parameters : sock - client socket to receive the data from
*filesize - holds a pointer to the size of the buffer that needs to update
filesize_len - the length of the file size pointer
Return Value : returns TRUE when the size is read correctly
else, FALSE when there was a socket error or no bytes are received.
===================================================
*/
bool recv_file_len(SOCKET sock, long* filesize)
{
if (!recv_raw(sock, filesize, sizeof(*filesize))) { return false; }
return true;
}
/*
================================================== =
General : writes to the lua file the data from the file
that was received in the socket
Parameters : sock - the socket between the client and server
*f - the file to write the data received to
Return Value : returns TRUE when everything was written to the file.
returns FALSE if there's no data received or detected a socket problem.
================================================== =
*/
bool write_data(SOCKET sock, FILE *f)
{
long filesize;//size of address
char buffer[BUFFER_SIZE];
if (!recv_file_len(sock, &filesize)) { return false; }
printf("file size (From C#) : %ld\n", filesize);
int n = recv_raw(sock, buffer, 8); // need to get the size of the name
if (filesize > 0)
{
do {
int num = min(filesize, BUFFER_SIZE);
if (!recv_raw(sock, buffer, num)) {
return false;
}
int offset = 0;
do
{
size_t written = fwrite(&buffer[offset], 1, num - offset, f);
if (written < 1) { return false; }
offset += written;
} while (offset < num);
filesize -= num;
} while (filesize > 0);
}
return true;
}
C Main
FILE* luafhandler = fopen("test.lua", "wb");//the new lua file
if (luafhandler == NULL)
{
fclose(luafhandler);
printf("GUI CONNECT lua file failed to open!\n");
}
FILE* pcapfhandler = fopen("test.pcap", "wb");//the new lua file
if (pcapfhandler == NULL)
{
fclose(pcapfhandler);
printf("GUI CONNECT pcap file failed to open!\n");
}
FILE* csvfhandler = fopen("AlgoTest.csv", "wb");//the new lua file
if (csvfhandler == NULL)
{
fclose(csvfhandler);
printf("GUI CONNECT csv file failed to open!\n");
}
else {
SOCKET sock1 = open_socket(5555, SERVER_IP);
bool check = write_data(sock1, luafhandler);
bool check1 = write_data(sock1, pcapfhandler);
bool check2 = write_data(sock1, csvfhandler);
fclose(luafhandler);
fclose(pcapfhandler);
fclose(csvfhandler);
}
Faced a problem. There is a 0x03 function, but I need to redo it in 0x06, I don’t understand how to do it.
I know that function 06 does not have a variable part. The value of one register is always transferred to it. But I can not understand what needs to be corrected. Please, help.
Here I create a package for functions:
private void BuildMessage(byte address, byte type, ushort start, ushort registers, ref byte[] message)
{
if (type == 3 || type == 16)
{
//Array to receive CRC bytes:
byte[] CRC = new byte[2];
message[0] = address;
message[1] = type;
message[2] = (byte)(start >> 8);
message[3] = (byte)start;
message[4] = (byte)(registers >> 8);
message[5] = (byte)registers;
GetCRC(message, ref CRC);
message[message.Length - 2] = CRC[0];
message[message.Length - 1] = CRC[1];
}
else if (type == 6)
{
byte[] CRC = new byte[2];
message[0] = address;
message[1] = type;
message[2] = (byte)(start >> 8);
message[3] = (byte)start;
message[4] = (byte)(registers >> 8);
message[5] = (byte)registers;
GetCRC(message, ref CRC);
message[6] = CRC[0];
message[7] = CRC[1];
}
}
This is my function number 3:
public bool SendFunc(int funcNumer, string connectType, byte address, ushort start, ushort registers, ref short[] values)
{
#region №3
if (funcNumer == 3)
{
#region serial-port
if (connectType.Equals("COM"))
{
//Ensure port is open:
if (sp.IsOpen)
{
//Clear in/out buffers:
sp.DiscardOutBuffer();
sp.DiscardInBuffer();
//Function 3 request is always 8 bytes:
byte[] message = new byte[8];
//Function 3 response buffer:
byte[] response = new byte[5 + 2 * registers];
//Build outgoing modbus message:
BuildMessage(address, (byte)3, start, registers, ref message);
//Send modbus message to Serial Port:
try
{
sp.Write(message, 0, message.Length);
GetResponse("COM", ref response);
}
catch (Exception err)
{
modbusStatus = "" + err.Message;
return false;
}
//Evaluate message:
if (CheckResponse(response))
{
//Return requested register values:
for (int i = 0; i < (response.Length - 5) / 2; i++)
{
values[i] = response[2 * i + 3];
values[i] <<= 8;
values[i] += response[2 * i + 4];
}
modbusStatus = "";
return true;
}
else
{
modbusStatus = "";
return false;
}
}
else
{
modbusStatus = "";
return false;
}
}
And here I am trying to implement function number 6:
if (funcNumer == 6)
{
#region serial-port
if (connectType.Equals("COM"))
{
//Ensure port is open:
if (sp.IsOpen)
{
//Clear in/out buffers:
sp.DiscardOutBuffer();
sp.DiscardInBuffer();
//Function 3 request is always 8 bytes:
byte[] message = new byte[8];
//Function 3 response buffer:
byte[] response = new byte[5 + 2 * registers];
//Build outgoing modbus message:
BuildMessage(address, (byte)6, start, registers, ref message);
//Send modbus message to Serial Port:
try
{
sp.Write(message, 0, message.Length);
GetResponse("COM", ref response);
}
catch (Exception err)
{
modbusStatus = "" + err.Message;
return false;
}
//Evaluate message:
if (CheckResponse(response))
{
//Return requested register values:
for (int i = 0; i < (response.Length - 5) / 2; i++)
{
values[i] = response[2 * i + 3];
values[i] <<= 8;
values[i] += response[2 * i + 4];
}
modbusStatus = "";
return true;
}
else
{
modbusStatus = "";
return false;
}
}
else
{
modbusStatus = "";
return false;
}
}
This is my function to check the response:
private bool CheckResponse(byte[] response)
{
//Perform a basic CRC check:
byte[] CRC = new byte[2];
GetCRC(response, ref CRC);
if (CRC[0] == response[response.Length - 2] && CRC[1] == response[response.Length - 1])
return true;
else
return false;
}
This is my function for get response:
private void GetResponse(string connect, ref byte[] response)
{
if (connect.Equals("COM"))
{
for (int i = 0; i < response.Length; i++)
{
response[i] = (byte)(sp.ReadByte());
}
}
else if (connect.Equals("TCP"))
{
NetworkStream stream = tcpClient.GetStream();
for (int i = 0; i < response.Length; i++)
{
response[i] = (byte)(stream.ReadByte());
}
}
else
{
}
}
The difference between Modbus function 0x03 and 0x06 is actually the part of the code you did not show on your question: CheckResponse(response).
Function 0x03 reads a number of registers, and the values in those registers (coming from the slave) are included in the response.
Function 0x06 writes a single register and gives an echo back. So the response is the same as the query.
With that information, it should be easy to modify your code: remove the for loop where you retrieve the register values.
Other than that you might need to modify your CheckResponse() function too, but that should also be quite straight forward: just check the response is exactly the same as the query (message).
EDIT: if your CheckResponse()` function only checks for the correct CRC on the responses I suppose you can keep it as it is.
Im trying to read the port COM3 with C# serialport class.
When reading from serial port occasional weird characters is pulling from the serial port ?
Why is this problem occurring?
foreach (USBDeviceInfo info in devices)
{
if (info.Description.Contains("Arduino"))
{
Name = info.Description;
if (info.PnpDeviceID.Contains("(COM"))
{
ComPort = info.PnpDeviceID.Split('(')[1].Split(')')[0];
using (SerialPort Port = new SerialPort())
{
Port.BaudRate = 9600;
Port.PortName = ComPort;
//rt.DataReceived += Port_DataReceived;
try
{
if (!Port.IsOpen)
Port.Open();
string output = Port.ReadTo("end");
Value = output;
Port.Close();
}
catch (Exception ex)
{
Value = ex.Message;
}
// this.SetText(message);
}
break;
}
}
Controller code
#include <OneWire.h>
int SensorPin = 7;
OneWire ds(SensorPin);
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
float temp = getTemp();
Serial.println(temp);
Serial.println("end");
delay(100);
}
float getTemp(){
byte data[12];
byte addr[8];
if (!ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;
}
if (addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1);
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE);
for (int i = 0; i < 9; i++) {
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float TRead = ((MSB << 8) | LSB);
float Temperature = TRead / 16;
return Temperature;
}
I tried doing this but I receive many errors since I'm new to C# coding.
My actual purpose is I want to ping a static ip which is constantly receiving data from a temperature sensor. I want to see the data from my home and save the data.
using System;
using System.Net;
using System.Net.Sockets;
public class Pinger
{
public static int GetPingTime(string host)
{
int dwStart = 0, dwStop = 0;
// Create a raw socket.
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.Icmp);
// Get the server IPEndPoint, and convert it to an EndPoint.
IPHostEntry serverHE = Dns.GetHostByName(host);
IPEndPoint ipepServer = new IPEndPoint(serverHE.AddressList[0], 0);
EndPoint epServer = (ipepServer);
// Set the receiving endpoint to the client machine.
IPHostEntry fromHE = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);
EndPoint EndPointFrom = (ipEndPointFrom);
// Construct the packet to send.
int PacketSize = 0;
IcmpPacket packet = new IcmpPacket();
for (int j = 0; j < 1; j++)
{
packet.Type = ICMP_ECHO;
packet.SubCode = 0;
packet.CheckSum = UInt16.Parse("0");
packet.Identifier = UInt16.Parse("45");
packet.SequenceNumber = UInt16.Parse("0");
int PingData = 32;
packet.Data = new Byte[PingData];
for (int i = 0; i < PingData; i++)
packet.Data[i] = (byte)'#';
PacketSize = PingData + 8;
Byte[] icmp_pkt_buffer = new Byte[PacketSize];
int index = 0;
index = Serialize(packet, icmp_pkt_buffer, PacketSize, PingData);
// Calculate the checksum for the packet.
double double_length = Convert.ToDouble(index);
double dtemp = Math.Ceiling(double_length / 2);
int cksum_buffer_length = Convert.ToInt32(dtemp);
UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
int icmp_header_buffer_index = 0;
for (int i = 0; i < cksum_buffer_length; i++)
{
cksum_buffer[i] = BitConverter.ToUInt16(icmp_pkt_buffer,
icmp_header_buffer_index);
icmp_header_buffer_index += 2;
}
UInt16 u_cksum = CheckSum(cksum_buffer, cksum_buffer_length);
packet.CheckSum = u_cksum;
// Now that we have the checksum, serialize the packet again.
byte[] sendbuf = new byte[PacketSize];
index = Serialize(packet, sendbuf, PacketSize, PingData);
// Start timing.
dwStart = System.Environment.TickCount;
socket.SendTo(sendbuf, PacketSize, 0, epServer);
// Receive the response, and then stop timing.
byte[] ReceiveBuffer = new byte[256];
socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom);
dwStop = System.Environment.TickCount - dwStart;
}
// Clean up and return the calculated ping time in seconds
socket.Close();
return (int)dwStop;
}
private static int Serialize(IcmpPacket packet, byte[] buffer,
int packetSize, int pingData)
{
// (Private method for serializing the packet omitted.)
}
private static UInt16 CheckSum(UInt16[] buffer, int size)
{
// (Private method for calculating the checksum omitted.)
}
public class PingTest
{
private static void Main()
{
int GetPingMS(string hostNameOrAddress);
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
return Convert.ToInt32(ping.SendAddress.RoundtripTime);
// How to call this function (IP Address).
MessageBox.Show ( GetPingMs("122.198.1.1"));
}
}
use This Sample because the Sample from Microsoft is not ready tu use...
http://www.codeplanet.eu/tutorials/csharp/4-tcp-ip-socket-programmierung-in-csharp.html?start=4
in this "german" Tutorial is the full code avaible for sending IP.
packet.Type = ICMP_ECHO; --> ICMP_ECHO must be set with a number (8) manual
{
private static int Serialize(IcmpPacket packet, byte[] buffer, int packetSize, int pingData)
{
// (Private method for serializing the packet omitted.)
}
private static UInt16 CheckSum(UInt16[] buffer, int size)
{
// (Private method for calculating the checksum omitted.)
}
}
<--mustbe create by your own
private static void Main()
{
int GetPingMS(string hostNameOrAddress);
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
return Convert.ToInt32(ping.SendAddress.RoundtripTime);
// How to call this function (IP Address).
MessageBox.Show ( GetPingMs("122.198.1.1"));
}
I think you never reach this Messagebox because you jump aut with
"return Convert.ToInt32(ping.SendAddress.RoundtripTime);"
set the meassagebox befor the return..
I'm trying to stream a video feed form the Xbox Kinect from a client to a server. I got it working with TCP but I could only get about 5 fps so now I'm trying it with UDP. UDP should be faster because of how the protocol works but it seems to be slower. Here is my post about the TCP (http://stackoverflow.com/questions/9627242/c-sharp-streaming-video-over-networkstream-tcpclient)
I can send this all the data I want over my LAN but I start losing a lot of packets if I push them out too fast. That is why I am using the Thread.Sleep(20); Increasing the chuck size speeds it up a lot but I'm at my max for sending over my LAN and if I understand correctly the max chunk size for sending over the internet is about 1500 bytes. If I only sent 1500 bytes at a time this would go really slow. I must be doing something wrong.
Here is the code.
private const int constChunkSize = 38400;
protected UdpClient udpObject;
private void HandleComm()
{
byte[] fullMessage = new byte[1228800];
byte[] byteReceived;
int currentIndex = 0;
IPEndPoint remoteIPEndPoint = new IPEndPoint(ip, port);
while (true)
{
byteReceived = udpObject.Receive(ref remoteIPEndPoint);
if (currentIndex + byteReceived.Length > 1228800)
{
int wtf = 0;
}
Array.Copy(byteReceived, 0, fullMessage, currentIndex, byteReceived.Length);
currentIndex += byteReceived.Length;
//Console.WriteLine("Recieved: " + currentIndex);
if (currentIndex == 1228800)
{
if (OnDataReceived != null)
{
FrameReceivedArgs args = new FrameReceivedArgs();
args.frame = new byte[fullMessage.Length];
fullMessage.CopyTo(args.frame, 0);
OnDataReceived(this, args);
}
currentIndex = 0;
Console.WriteLine("Done receiving" + DateTime.Now.Ticks);
}
}
}
public void sendData(byte[] data)
{
sending = true;
sendThread = new Thread(sendDataThread);
sendThread.Priority = ThreadPriority.Highest;
sendThread.Start(data);
}
private void sendDataThread(object tempData)
{
byte[] data = (byte[]) tempData;
int totalBytes = data.Length;
int currentBytes = 0;
int bufferLength = constChunkSize;
byte[] sendBytes = new byte[constChunkSize];
while (currentBytes < totalBytes)
{
if (totalBytes - currentBytes < constChunkSize)
bufferLength = totalBytes - currentBytes;
Array.Copy(data, currentBytes, sendBytes, 0, bufferLength);
currentBytes += bufferLength;
udpObject.BeginSend(sendBytes, bufferLength, new AsyncCallback(sendingData), udpObject);
Thread.Sleep(20);
//Console.WriteLine("Sent: " + currentBytes);
}
Console.WriteLine("done sending" + DateTime.Now.Ticks);
sending = false;
}
private void sendingData(IAsyncResult ar)
{
udpObject.EndSend(ar);
}