I'm new here and I'm a beginner in python programming. I need to convert C# code to python but I stuck when I wanted to read serial data as byte array. I used extend() and bytearray() functions but nothing is working.
Bellow is the C# code which I want to convert to Python 3.x
do
{
int _byteToRead = P._serialPort.BytesToRead;
byte[] inBuffer = new byte[_byteToRead];
P._serialPort.Read(inBuffer, 0, _byteToRead); //Reads a number of characters from the System.IO.Ports.SerialPort input buffer and writes them into an array of characters at a given offset.
byte MatchStart = 242; // HEX: F2
byte MatchEnd = 248; // HEX: F8
try
{
for (int j = 0; j < inBuffer.Length; j++)
{
if (inBuffer[j] == MatchStart)
I don't know how to convert the first 3 lines.
I tried:
bytedata=ser.read(10000) # I need to
b=bytearray()
b.extend(map(ord, bytedata))
or:
bytedata+=ser.read(ser.inWaiting())
z=bytearray(bytedata)
Thanks.
Related
I'm writing an RLE algorithm in C# that can work on any file as input. The approach to encoding I'm taking is as follows:
An RLE packet contains 1 byte for the length and 1 byte for the value. For example, if the byte 0xFF appeared 3 times in a row, 0x03 0xFF would be written to the file.
If representing the data as raw data would be more efficient, I use 0x00 as a terminator. This works because the length of a packet can never be zero. If I wanted to add the bytes 0x53 0x2C 0x01 to my compressed file it would look like this:
0x03 0xFF 0x00 0x53 0x2C 0x01
However a problem arises when trying to switch back to RLE packets. I can't use a byte as a terminator like I did for switching onto raw data because any byte value from 0x00 to 0xFF can be in the input data, and when decoding the bytes the decoder would misinterpret the byte as a terminator and ruin everything.
What can I do to indicate that I have to switch back to RLE packets when it can't be written as data in the file?
Here is my code if it helps:
private static void RunLengthEncode(ref byte[] bytes)
{
// Create a list to store the bytes
List<byte> output = new List<byte>();
byte runLengthByte;
int runLengthCounter = 0;
// Set the RLE byte to the first byte in the array and increment the RLE counter
runLengthByte = bytes[0];
// For each byte in the input array...
for (int i = 0; i < bytes.Length; i++)
{
if (runLengthByte == bytes[i] || runLengthCounter == 255)
{
runLengthCounter++;
}
else
{
// RLE packets under 3 should be written as raw data to avoid increasing the file size
if (runLengthCounter < 3)
{
// Add a 0x00 to indicate raw data
output.Add(0x00);
// Add the bytes that were skipped while counting the run length
for (int j = i - runLengthCounter; j < i; j++)
{
output.Add(bytes[j]);
}
}
else
{
// Add 2 bytes, one for the number of bytes and one for the value
output.Add((byte)runLengthCounter);
output.Add(runLengthByte);
}
runLengthCounter = 1;
runLengthByte = bytes[i];
}
// Add the last bytes to the list when finishing
if (i == bytes.Length - 1)
{
// Add 2 bytes, one for the number of bytes and one for the value
output.Add((byte)runLengthCounter);
output.Add(runLengthByte);
}
}
// Set the bytes to the RLE encoded data
bytes = output.ToArray();
}
Also if you want to comment and say that RLE isn't very efficient for binary data, I know it isn't. This is a project I'm doing to implement many kinds of compression to learn about them, not for an actual product.
Any help would be appreciated! Thanks!
There are many ways to unambiguously encode run-lengths. One simple way is, when decoding: if you see two equal bytes in a row, then the next byte is a a count of repeats of that byte after those first two. I.e. 0..255 additional repeats, so encoding runs of 2..257. (There's no point in encoding runs of 0 or 1.)
I'm trying to port this C# code to PHP:
var headerList = new List<byte>();
headerList.AddRange(Encoding.ASCII.GetBytes("Hello\n"));
headerList.AddRange(BitConverter.GetBytes(1));
byte[] header = headerList.ToArray();
If I output header, what does it looks like?
My progress so far:
$in_raw = "Hello\n";
for($i = 0; $i < mb_strlen($in_raw, 'ASCII'); $i++){
$in.= ord($in_raw[$i]);
}
$k=1;
$byteK=array(8); // should be 16? 32?...
for ($i = 0; $i < 8; $i++){
$byteK[$i] = (( $k >> (8 * $i)) & 0xFF); // Don't known if it is a valid PHP bitwise op
}
$in.=implode($byteK);
print_r($in);
Which gives me this output: 721011081081111010000000
I'm pretty confident that the first part of converting the string to ASCII bytes is correct, but these BitConverter... I don't know what to expect as output...
This string (or byte array) is used as an handshake for an socket connection. I know that the C# version does work, but my refurnished code doesn't.
If you don't have access to a machine/tool that can run C#, there are a couple of REPL websites that you can use. I've taken your code, qualified a couple of the namespaces (just for convenience), wrapped it in a main() method to just run once as a CLI and put it here. It also includes a for loop that writes the contents of the array out so that you can see what is at each index.
Here's the same code for reference:
using System;
class MainClass {
public static void Main (string[] args) {
var headerList = new System.Collections.Generic.List<byte>();
headerList.AddRange(System.Text.Encoding.ASCII.GetBytes("Hello\n"));
headerList.AddRange(System.BitConverter.GetBytes(1));
byte[] header = headerList.ToArray();
foreach(byte b in header){
Console.WriteLine(b);
}
}
}
When you run this code, the following output is generated:
72
101
108
108
111
10
1
0
0
0
Encoding.ASCII.GetBytes("Hello\n").ToArray()
gives byte[6] { 72, 101, 108, 108, 111, 10 }
BitConverter.GetBytes((Int64)1).ToArray()
gives byte[8] { 1, 0, 0, 0, 0, 0, 0, 0 }
BitConverter.GetBytes((Int32)1).ToArray()
byte[4] { 1, 0, 0, 0 }
the last one is default compiler conversion of 1.
if PHP code please try $byteK=array(4); and $i < 4
The string "Hello\n" is already encoded in ASCII so you have nothing to do.
BitConverter.GetBytes() gives the binary representation of a 32-bit integer in machine byte order, which can be done in PHP with the pack() function and the l format.
So the PHP code is simply:
$in = "Hello\n";
$in .= pack('l', 1);
I am trying to print stored bitmap images in some printers.
The program is a Windows Form.
The command to print the logo (bitmap)-(if there is one stored) is:
port.Write("\x1C\x70\x01\x00");
('port' being my name for new serial port object).
There can be from 0 to 255 DEC (00 to FF HEX) different locations in the
printers memory.
I need a for loop or while loop that will increment the above line of code so,
port.Write("\x1C\x70\x01\x00"); would become
port.Write("\x1C\x70\x02\x00");
port.Write("\x1C\x70\x03\x00"); up to FF
port.Write("\x1C\x70\xFF\x00");
etc etc.
I looked on MSDN & Search Stack Overflow:
https://msdn.microsoft.com/en-us/library/bb311038.aspx
int to hex string in C#
Also, as an alternative to Coriths solution. The SerialPort object lets you write a byte array directly, rather than converting your bytes to a string that the SerialPort then converts back into bytes again.
for (byte i = 0; i < 255; i++)
{
var bytes = new byte[] { 0x1C, 0x70, i, 0x00 };
port.Write(bytes, 0, 4);
}
This loop should work for you. You can always use 0x to work in hexadecimal numbers in your loops.
for(var c = 0x01; c <= 0xFF; c++)
{
port.Write($"\x1C\x70\x{c:X2}\x00");
}
I am trying to print each byte in an array (Byte Array) using a for loop. However since I am using the String.Format, it converts the 0x00 in the byte array to a 0. How can I print it as 00.
Trace.Write("\n--->");
for (int K = 1; K <= j; K++)
Debug.Write(string.Format("{0:X}", FrameByteArray[K]));
I know it should be simple, but I have a hard time figuring it out.
Please advice.
Just use {0:X2} instead - this will ensure the number will always have at least two characters.
I work in a c# wpf application in which I want to do several things. I'm working with byte arrays to compose MIDI Show Control messages (specified in the MSC Specification 1.0).
The structure of this message is that a 0x00 byte is like a comma between all the parts of the message. I compose a message like this:
byte[] data =
{(byte)0xF0, // SysEx
(byte)0x7F, // Realtime
(byte)0x7F, // Device id
(byte)0x02, // Constant
(byte)0x01, // Lighting format
(commandbyte), // GO
(qnumber), // qnumber
(byte)0x00, // comma
(qlist), // qlist
(byte)0x00, // comma
(byte)0xF7, // End of SysEx
};
I want the user to fill in unsigned integers (like 215.5) and I want to convert these numbers to bytes (without 0x00 bytes because then the message is interpreted wrong).
What is the best way to convert the numbers and place the byte array in the places mentioned above?
You might want to take a look at the BitConverter class, which is designed to convert base types into byte arrays.
http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx
But I'm not sure what guidance you are seeking for placing the items into your array. Array.Copy can work to simply copy the bytes in, but maybe I am misunderstanding.
Found it out like this:
Used someone else's converter code like this:
static byte[] VlqEncode(int value)
{
uint uvalue = (uint)value;
if (uvalue < 128)
return new byte[] { (byte)uvalue };
// simplest case
// calculate length of buffer required
int len = 0;
do
{
uvalue >>= 7;
} while (uvalue != 0);
// encode
uvalue = (uint)value;
byte[] buffer = new byte[len];
int offset = 0;
do { buffer[offset] = (byte)(uvalue & 127);
// only the last 7 bits
uvalue >>= 7; if(uvalue != 0) buffer[offset++] |= 128;
// continuation bit
} while (uvalue != 0);
return buffer;
}
Then I use this to convert the integer:
byte[] mybytearray = VlqEncode(integer);
I then make a new arraylist in which I add each item in sequence:
ArrayList mymessage = new ArrayList();
foreach(byte uvalue in mymessage)
{
mymessage.Add((byte)uvalue);
}
mymessage.Add((byte)0x00);
`
and so on until I have the correct message. I then only have to convert this a byte array like this:
byte[] data = new byte[mymessage.count];
data = (byte[])mymessage.ToArray(typeof(byte));`