Adding 1 to a byte in Structured Text - automation

I'm trying to implement the logic below:
if bcc = STX or
bcc = CR, then bcc := +1 (increment
of 1).
bcc is a byte and i'm trying to increment it by 1 if this condition above is true.
my code is:
IF message_byte[11] = 16#0D OR message_byte[11] = 16#02 THEN
message_byte[11] := message_byte[11] + TO_BYTE(1);
END_IF
where message_byte is an array of bytes and I want to access a specific one. However, it gives me an error when saying it can't be added.
any help is appreciated

I believe the error is telling you that message_byte[11] (left operant of your addition) is not a type BYTE, so the compiler can’t figure out how to add a BYTE to it - as commented by dwpessoa. I also don’t know what a data type “BYTES” is - maybe that should just be BYTE.
When you get these types of errors, try breaking apart your task and just try the absolute basics - just try adding 1 to message_byte[11]. Then it will be easier to solve the error.

Related

Pine throws syntax error on first line of for loop

I have a pine strategy:
//#version=5
strategy("Elie's strategy", overlay=true, margin_long=100, margin_short=100)
var float[] overSRLs = na
var IDCounter = 0
int[] removeFromOver = na
for int i = 0 to (array.size(overSRLs) - 1) // line 8
if low < array.get(overSRLs, i)
orderID = str.tostring(IDCounter)
exitID = str.tostring(IDCounter + 1)
IDCounter += 2
strategy.order(orderID, strategy.long, 1)
strategy.exit(exitID, from_entry=orderID, stop = (array.get(overSRLs, i) * (1 - ATR5[1])), limit = (array.get(overSRLs, i) * (1 + ATR5[1]))
array.push(removeFromOver, i)
I know it's not much of a strategy, but I cut out the irrelevant parts to make a smaller reproductible example. When just the code above is saved, it throws the following error:
line 8: Syntax error at input 'int'.
Now, even though line 8 is the init of the for, I think the problem is in the code block in the for, and the compiler/interpreter just has bad error handling. Is there something I'm missing here? Everything looks fine to me
I think the problem is in the code block in the for, and the compiler/interpreter just has bad error handling.
Yes, the issue is in the strategy.exit -- you need one extra closing bracket in the end there. Compiler does not always provide correct lines for errors in loops. Comment out the loop and move everything one tab to the left and you'll see that the new error is line 14: Syntax error at input '('., which indicates that there is an issue with the opening bracket (because it can't find its pair).
P.S. The script will not compile after that because of the undeclared ATR5 variable, but I assume it's due to the fact that you trimmed the example code for readability.

Fail at sending byte array through serial port excel-vba

I am trying to get information from an Excel worksheet and send it through a serial port as a byte array, using Windows API. This is just a small part of it:
lngSize = UBound(byteData) - LBound(byteData)
WriteFile(udtPorts(intPortID).lngHandle, byteData, lngSize, _lngWrSize, udtCommOverlap)
My current problem: when I am sending a byte array of length 1 (just one byte), I receive it correctly (I am using a hyperterminal to check what I'm sending), but when I send an array of length > 1, here comes the problem; instead of receiving it like this:
letter = 65
For i = 0 To 5
dataToSend(i) = letter
letter = letter + 1
Next
what I should receive
what I get is this:
what I receive
I really cannot figure out what could be the problem and I would be grateful if someone had a clue. Thank you!
First, the correct number of elements in an array is:
lngSize = UBound(byteData) - LBound(byteData) + 1 ' <-- add 1
More importantly, your code is not applying the call convention for the WriteFile API. Namely, the second parameter should be a LPCVOID pointer to the first Byte to transfer. Passing the array's name byteData to the function wont achieve that, because the array is a complex COM data structure, not like a C array. What you should do is:
First get the address of the array's data structure, using VarPtrArray:
Then add 12 to it to get the address of the first byte.
.
Private Declare Function VarPtrArray Lib "VBE7" Alias "VarPtr" (var () As Any) As Long
...
WriteFile(udtPorts(intPortID).lngHandle, VarPtrArray(byteData()) + 12, lngSize, _lngWrSize, udtCommOverlap)
' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For information about handling arrays' data and their pointers, excellent examples can be found [on this page].(https://www.codeproject.com/Articles/729235/VB-and-VBA-Array-Buffering)
Also make sure that you declared you array as a Byte array, like
Redim byteData(someSize) As Byte
' ^^^^^^^
There might be other errors in the parts of code you didn't show (possibly the settings of udtCommOverlap), but hopefully these corrections will put you on the right track.

sprintf hex number deleted

I am trying to get and send my MCU's IP Adress, SubnetMask and Gateway adress.
I got them but problem is merging them. I want to merge them with array and send for one step..
For example:
my values are
e2promIpAddress = 0A020705 // represents 10.2.7.5
e2promSubnetMask = FFFF0000 // represents 255.255.0.0
e2promGateway = 0A02070F // represents 10.2.7.15
When I add with sprintf()
char buffer[64];
sprintf(buffer,"%x%x%x",e2promIpAddress,e2promSubnetMask,e2promGateway);
Output is A020705FFFF00000A02070F
Unfortunatelly array must start with 0 but it goes away..
Thanks in advance
I finally find my answer and want to post here..
My values for example e2promIpAddress = 0A020705 is 4 bytes.
When I wrote this with;
sprintf(buffer,"%02x%02x%02x",e2promIpAddress,e2promSubnetMask,e2promGateway);
it did not pad "0"
when I wrote this with;
sprintf(buffer,"%08x%08x%08x",e2promIpAddress,e2promSubnetMask,e2promGateway);
all values which starts with "0" pad with "0"
Have a good day..

vb xor checksum

This question may already have been asked but nothing on SO actually gave me the answer I need.
I am trying to reverse engineer someone else's vb.NET code and I am stuck with what a Xor is doing here. Here is 1 line of the body of a soap request that gets parsed (some values have been obscured so the checksum may not work in this case):
<HD>CHANGEDTHIS01,W-A,0,7753.2018E,1122.6674N, 0.00,1,CID_V_01*3B</HD>
and this is the snippet of vb code that checks it
LastStar = strValues(CheckLoop).IndexOf("*")
StrLen = strValues(CheckLoop).Length
TransCheckSum = Val("&h" + strValues(CheckLoop).Substring(LastStar + 1, (StrLen - (LastStar + 1))))
CheckSum = 0
For CheckString = 0 To LastStar - 1
CheckSum = CheckSum Xor Asc(strValues(CheckLoop)(CheckString))
Next '
If CheckSum <> TransCheckSum Then
'error with the checksum
...
OK, I get it up to the For loop. I just need an explanation of what the Xor is doing and how that is used for the checksum.
Thanks.
PS: As a bonus, if anyone can provide a c# translation I would be most grateful.
Using Xor is a simple algorithm to calculate a checksum. The idea is the same as when calculating a parity bit, but there is eight bits calculated across the bytes. More advanced algorithms like CRC and MD5 are often used to calculate checksums for more demanding applications.
The C# code would look like this:
string value = strValues[checkLoop];
int lastStar = value.IndexOf("*");
int transCheckSum = Convert.ToByte(value.Substring(lastStar + 1, 2), 16);
int checkSum = 0;
for (int checkString = 4; checkString < lastStar; checkString++) {
checkSum ^= (int)value[checkString];
}
if (checkSum != transCheckSum) {
// error with the checksum
}
I made some adjustments to the code to accomodate the transformation to C#, and some things that makes sense. I declared the variables used, and used camel case rather than Pascal case for local variables. I use a local variable for the string, instead of getting it from the collection each time.
The VB Val method stops parsing when it finds a character that it doesn't recognise, so to use the framework methods I assumed that the length of the checksum is two characters, so that it can parse the string "3B" rather than "3B</HD>".
The loop starts at the fourth character, to skip the first "<HD>", which should logically not be part of the data that the checksum should be calculated for.
In C# you don't need the Asc function to get the character code, you can just cast the char to an int.
The code is basically getting the character values and doing a Xor in order to check the integrity, you have a very nice explanation of the operation in this page, in the Parity Check section : http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/xor.html

Specifying variable range in Verilog using for loop

I am trying to write this code:
for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
begin : loop_inst
if (i < 3)
begin
if (changed[i] & !done_q[i])
begin
writedata[3-i] = en[i];
writedata[2-i:0] = readdata[2-i:0];
writedata[15:4-i] = readdata[15:4-i];
end
end
else
...
Basically, the location of the bit I am trying to write to (en) changes depending on which address I am talking to, depending on i. This code is not synthesizable because i is not a constant.
Is there any other workaround to this? The only workaround I know is writing out those three statements CONST times. I am hoping I DON'T have to do that in the end. Is there any other solution?
It looks like you're trying to copy readdata to writedata all the time, but fill in the LSBs with en if certain special case conditions are met. I'm also going to assume that the for loop you have is in an always block, and that you're intending to build combo logic.
The for loop as you've it written doesn't make much sense to me from a hardware perspective. A for loop is used for building arrays of logic, and as you've
written it you'll have at least 3 logic cones trying to set values on the entire writedata bus. (If it generates anything at all, it'll be some weird priority structure).
That said, it's probably the range selects that your compiler is complaining about, ie the writedata[2-i:0] rather than the writedata[3-i] = en[i]; (anything with : in the part select). If you want to do something along those lines, you can use 'indexed part selects' ( +: or -:) but there are better solutions in this case.
I'd rewrite it as follows - assuming I've assumed correctly :)
always #( /*whatever*/ ) begin
// default assignment
writedata = readdata;
// overwrite some bits in writedata for special cases
for(i=0; i<3; i++) begin
if( changed[i] & !done_q[i] )
writedata[3-i] = en[i];
end
end
In this code, I'm setting writedata to readdata, and then tweaking the resulting value of writedata if the special cases are in play. The for loop is building 3 logic cones, one for each of the bits in writedata[3:1]. I'd double-check if the bit mapping is what you intend -ie, mapping en[2:0] on to writedata[1:3].