Modbus 20 (0x14) Read File Record - How long is the file - protocols

I am implementing Modbus function 20 (0x14) Read File Record.
Modbus Spec - function 20 (0x14) Read File Record.
-------------------------------------------------------------------
Request:
| Name | Size | Example BYTES
*-------------------------------*-----------*----------------------
| Function code | 1 Byte | 0x14
| Byte Count | 1 Byte | 0x07 to 0xF5 bytes
| Sub-Req. x, Reference Type | 1 Byte | 06
| Sub-Req. x, File Number | 2 Bytes | 0x0001 to 0xFFFF
| Sub-Req. x, Record Number | 2 Bytes | 0x0000 to 0x270F
| Sub-Req. x, Record Length | 2 Bytes | N
Response:
| Name | Size | Example BYTES
*-------------------------------*-----------*----------------------
| Function code | 1 Byte | 0x14
| Resp. data Length | 1 Byte | 0x07 to 0xF5
| Sub-Req. x, File Resp. length | 1 Byte | 0x07 to 0xF5
| Sub-Req. x, Reference Type | 1 Byte | 6
| Sub-Req. x, Record Data | N*2 Bytes |
Error
| Name | Size | Example
*-------------------------------*-----------*----------------------
| Error code | 1 Byte | 0x94
| Exception code | 1 Byte | 01 ILLEGAL FUNCTION
02 ILLEGAL DATA ADDRESS
03 ILLEGAL DATA VALUE
04 SERVER DEVICE FAILURE
08 MEMORY PARITY ERROR
Source: http://www.modbus.org/specs.php
The file that I am requesting is 100 long.
I made a file request that has a offset (Record Number) of 89 for 20 bytes long (Record Length). This should cause an error as I am requesting more bytes then are in the file.
What error will I get?
How do I determine how long the file is?
I am hoping I do not have to make a request for a file, and if there is an error, try again with a smaller length until I get a successful response.

This is old, but I'll answer, because I'm just implementing a Modbus slave, so...
You will most likely get 02. Standards conforming Modbus will only return 03 with this command if bytecount is off bounds, that is less than 7 or more than 245. The standard is quite vague with this command, and it only really makes sense with Modicon PLC's, anyway. Other suppliers either don't implement these or "do whatever the eff they want".
I for example mapped our string registers into these.

Related

Can you select the MIN row to display across all "Results Grid" values? (Generic Inquiry)

I have the following tables:
(Example data)
PMProjects
| ContractID | ContractCD | Customer |
| :-------- | :----------| :------- |
| 01 | PR00001 | ABC-Customer |
| 02 | PR00002 | XYZ-Customer |
PMTasks
| Task ID | Project ID| Task CD | Description |
| :--------| :---------| :---------| :-------- |
| 39 | 01 | 01 First | Zulu |
| 40 | 01 | 02 Second | Foxtrot |
| 41 | 01 | 03 Third | Delta |
| 42 | 01 | 04 Fourth | Alpha |
| 55 | 02 | 01 First | Zulu |
| 56 | 02 | 02 Second | Foxtrot |
| 57 | 02 | 03 Third | Delta |
| 58 | 02 | 04 Fourth | Alpha |
I have successfully joined PMTasks to PMProjects on PMProjects.ContractID = PMTasks.ProjectID.
And, I am grouping by PMProjects.ContractID
On the GI, I need to display the MIN TaskID row for each Project.
My GI - Aggregate Functions by MIN value
Result -
When I use the MIN value on the PMTasks.Description field it pulls the value "Alpha".
GI Results
| ContractID | ContractCD | Customer | Task ID | Task CD | Description |
| :--------- | :--------- | :----------- | :------- | :-------- | :---------- |
| 01 | PR00001 | ABC-Customer | 39 | 01 First | Alpha |
| 02 | PR00002 | XYZ-Customer | 55 | 01 First | Alpha |
Documentation - Aggregate Function Descriptions
I see from the documentation that the MIN aggregate function, "Returns the minimum value of all values of the group."
Has anyone found a way to join many-to-one in an Acumatica Generic Inquiry using the MIN (or MAX) value of a row?
Or to put it a different way - has anyone found a way to join one of many rows to a table and have the results grid display only the values from the same row?
I hope this makes sense. Please feel free to ask any clarification questions.
Thanks for any and all feedback.
Example GI related to the question. Please excuse the error under Results Grid - PMProjects.CustomerCD_Description does not need to be aggregated.
You need to add a group by PMContract.ContractID and then add the Min() function in the Data Field

Marking "Ambidextrous" in Excel

This is an example that illustrates my problem
So I have a table of participants, each with their own unique ID number. They all do a writing test and their time, in minutes, is recorded in the fourth column as an integer. Some patients have repeated the test, there is no maximum number of repeats.
+============+===========+===============+======+
| Patient ID | Hand Used | Ambidextrous? | Time |
+============+===========+===============+======+
| 01 | Right | Yes | 12 |
+------------+-----------+---------------+------+
| 01 | Right | Yes | 10 |
+------------+-----------+---------------+------+
| 01 | Right | Yes | 11 |
+------------+-----------+---------------+------+
| 01 | Left | Yes | 13 |
+------------+-----------+---------------+------+
| 01 | Right | Yes | 12 |
+------------+-----------+---------------+------+
| 02 | Right | No | 9 |
+------------+-----------+---------------+------+
| 02 | Right | No | 7 |
+------------+-----------+---------------+------+
| 02 | Right | No | 8 |
+------------+-----------+---------------+------+
| 03 | Left | Yes | 8 |
+------------+-----------+---------------+------+
| 03 | Right | Yes | 8 |
+------------+-----------+---------------+------+
I want the "Ambidextrous?" column to be a formula. I've been trying to accomplish this with INDEX() and MATCH(), to no avail. It needs to check the "Hand Used" column, if there is both a Right handed and Left handed test for a particular Patient ID, we say "Yes".
Use:
=IF(COUNTIFS(A:A,A2,B:B,IF(B2="Right","Left","Right")),"Yes","No")

How to average difference between many value pairs by index

and thanks for your help! Without helper columns/rows I'm trying to find the average difference in LVEDi between first and last visits of the patients.
E.g., by hand you would work it out as:
(diff for patient a + diff for pt b + diff for pt c)/3 =
((55-45) + (40-31) + (25-31))/3 =
(10 + 9 + (-6))/3 =
13/3 =
4.333
I'm sure the answer involves indexing with an array function, but I can't get started on how to tackle it!
Any help?
Thanks!
A | B | C | D | E
01 Patient ID | Date | First-Last | LVEDi | LOTS of similar cols
02 a | 3/3/03 | LAST | 55
03 a | 1/1/01 | FIRST | 45
04 a | 2/2/02 | | 65
05 b | | |
06 b | 3/2/16 | LAST | 40
07 b | | |
08 b | | |
09 b | 2/1/12 | FIRST | 31
10 c | 1/7/14 | LAST | 25
11 c | | |
12 c | 2/2/03 | FIRST | 31
13 c | 2/2/08 | | 46
You can use the * as and AND criterion in arrays, so with MATCH you search for the instance, where both conditions multiplied are TRUE (i.e. 1). The rest is just filling in your calculation:
{=((INDEX(D2:D13,MATCH(1,(A2:A13="a")*(C2:C13="LAST"),0))-INDEX(D2:D13,MATCH(1,(A2:A13="a")*(C2:C13="FIRST"),0)))+(INDEX(D2:D13,MATCH(1,(A2:A13="b")*(C2:C13="LAST"),0))-INDEX(D2:D13,MATCH(1,(A2:A13="b")*(C2:C13="FIRST"),0)))+(INDEX(D2:D13,MATCH(1,(A2:A13="c")*(C2:C13="LAST"),0))-INDEX(D2:D13,MATCH(1,(A2:A13="c")*(C2:C13="FIRST"),0))))/3}
And remember to use CTRL + SHIFT + ENTER to enter the array.
Found a slightly less verbose method:
=SUM(SUMIFS(D:D,C:C,"LAST",A:A,{"a","b","c"})-SUMIFS(D:D,C:C,"FIRST",A:A,{"a","b","c"}))/3
EDIT 1
Building on Lukas' comment:
=(SUMIF(C:C,"LAST",D:D)-SUMIF(C:C,"FIRST",D:D))/COUNTIF(C:C,"LAST")

Excel: sort column with mixed numbers and letters?

I am working of the dataset in Excel that I obtained from an experiment. Since I needed some ratings (and I wanted the raters to be blind) I completely randomized the answers and now I can't put them back in order!
This is what I have:
1A
38R
22R
7A
41R
64A
etc...
And this is what I need in the end:
1A
2A
3A
...
99R
100R
101R
Thank you!
I have created two new columns (B and C in this case, as in the other example posted).
I have typed LEFT(A1,LEN(A1)-1) in column B to get the number; then =RIGHT(A1,1) in column C to get the letter; finally I can sort by B and C.
You will not get your desired output by sorting alphabetically, because 100R would come before 2A.
If your values will always be in the format of a number followed by a single character and will be at most 5 characters long, you can use #Scott Craner's formula =RIGHT("00000"&A1,5) to pad the left of your value with "0" so that you can alphabetize correctly. 100R will become 0100R. 2A will become 0002A. These will now alphabetize correctly.
Now you can simply sort your range by column B ascending alphabetically.
If you need more characters, just add as many zeroes as characters to the formula, and change the 5 in the formula to your new number of characters.
Here is an example excel file.
INPUT
+---+-----+-------+
| | A | B |
+---+-----+-------+
| 1 | 1A | 0001A |
+---+-----+-------+
| 2 | 38R | 0038R |
+---+-----+-------+
| 3 | 22R | 0022R |
+---+-----+-------+
| 4 | 7A | 0007A |
+---+-----+-------+
| 5 | 41R | 0041R |
+---+-----+-------+
| 6 | 64A | 0064A |
+---+-----+-------+
RESULT
+---+-----+-------+
| | A | B |
+---+-----+-------+
| 1 | 1A | 0001A |
+---+-----+-------+
| 2 | 7A | 0007A |
+---+-----+-------+
| 3 | 22R | 0022R |
+---+-----+-------+
| 4 | 38R | 0038R |
+---+-----+-------+
| 5 | 41R | 0041R |
+---+-----+-------+
| 6 | 64A | 0064A |
+---+-----+-------+

How do I find value of register and flags in Assembler?

Programmcode | Zero-Flag | Sign-Flag | Register A | Register HL
| 0 | 0 | 00h | 00 00h
--------------|-----------|-----------|------------|------------
MOV HL, 00ffh | | | |
DEC HL | | | |
ADD 81h | | | |
CP A | | | |
SUB 02h | | | |
I have part of program in MC8-Assembler (The CPU of the MC8 is formed by the 8bit processor Zilog Z80 of the Training Board) What value is going to have flag after execution and whatvalue is being found in register? Values before execution are given in first column.
Can someone do it + write an explanation?
What Intel calls MOV, Zilog calls LD; otherwise you can work out the answer by looking at e.g. this instruction table.
MOV HL, 00ffh is LD HL, 00ffh in Zilog terms, so look up the appropriate LD HL. It's instruction 0x21 and it tells you that it loads the value into HL and doesn't affect any flags. So that's row one sorted. DEC HL over at 0x2b also doesn't affect any flags (which almost always catches me out, for the record) but ADD A,* does so that's where sign and zero might change, depending on what you think happens to A.
Just look up each instruction in turn, see what it does, do that thing, then consider what the flags will be if that's an instruction that affects the flags.

Resources