Ik ben bezig met een modbus implementatie, maar ik loop vast op het implementeren van meerdere datatypes. Met normale integers werkt het goed, maar met doubles krijg ik het nog niet helemaal lekker werkend.
Eerst wat algemene info: Ik gebruik de lwIP stack met de netconn API. Momenteel stel ik op de volgende manier het modbus bericht samen. (Een simpel voorbeeld om het goed begrijpbaar te maken):
De API functie om het bericht te verzenden:
aNetConn : the netconn object the data is written to
aData : address of beginning of the data to write
aSize : the length of the data in bytes
aApiFlags : settings
bron: http://lwip.wikia.com/wiki/Netconn_write
Ik maak nu een array aan met de grote van mijn hele modbus bericht. Een modbus bericht bestaat uit een aantal headervelden en een variabel aantal datavelden. Bijvoorbeeld:
uint8_t is gekozen omdat het kleinste "veld" een byte (8-bit) is. De velden kan ik dan eenvoudig vullen met data. Daarnaast kan ik bijvoorbeeld een 32 bit waarde ook eenvoudig verzenden door middel van een bitmask de juiste data in te laden. Echter gaat dit niet met een float getal omdat dit een heel ander type is.
Nu weet ik niet hoe ik dit werkend kan krijgen. Eigenlijk moet ik een soort type hebben die alle datatypes accepteert. Een soort void type oid, want aan de ontvangde kant moet het gewoon gecast worden naar het goede type (staat in de documentatie welk type het is).
Als ik dit verzend komt er keurig twee 16 bit waardes binnen via de modbus (modbus werkt namelijk met 16 bit registers, maar twee 16-bit registers kan samengevoegd worden tot een 32 bit register. Dit wil ik ook met een 32 bit float kunnen doen, maar dan gebeurd er dit:
Ik hoop dat het duidelijk is en dat iemand raad weet hoe ik dit kan aanpakken
Eerst wat algemene info: Ik gebruik de lwIP stack met de netconn API. Momenteel stel ik op de volgende manier het modbus bericht samen. (Een simpel voorbeeld om het goed begrijpbaar te maken):
De API functie om het bericht te verzenden:
code:
1
| err_t netconn_write ( struct netconn * aNetConn, const void * aData, size_t aSize, u8_t aApiFlags ); |
aNetConn : the netconn object the data is written to
aData : address of beginning of the data to write
aSize : the length of the data in bytes
aApiFlags : settings
bron: http://lwip.wikia.com/wiki/Netconn_write
Ik maak nu een array aan met de grote van mijn hele modbus bericht. Een modbus bericht bestaat uit een aantal headervelden en een variabel aantal datavelden. Bijvoorbeeld:
code:
1
| uint8_t response[13]; // response modbus message |
uint8_t is gekozen omdat het kleinste "veld" een byte (8-bit) is. De velden kan ik dan eenvoudig vullen met data. Daarnaast kan ik bijvoorbeeld een 32 bit waarde ook eenvoudig verzenden door middel van een bitmask de juiste data in te laden. Echter gaat dit niet met een float getal omdat dit een heel ander type is.
Nu weet ik niet hoe ik dit werkend kan krijgen. Eigenlijk moet ik een soort type hebben die alle datatypes accepteert. Een soort void type oid, want aan de ontvangde kant moet het gewoon gecast worden naar het goede type (staat in de documentatie welk type het is).
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| uint32_t test = 500; response[0] = pcRxByte[0]; // Transaction indentifier wordt gekopieerd van het request bericht response[1] = pcRxByte[1]; // Transaction indentifier wordt gekopieerd van het request bericht response[2] = 0; // protocol indentifier -> modbus ( waarde 0 staat voor het modbus protocol ) response[3] = 0; // protocol indentifier -> modbus ( waarde 0 staat voor het modbus protocol ) response[4] = 0; // length following bytes (most significant bit) response[5] = 3 + 4; // length following bytes -> 3 standaard bytes + variabel afhankelijk van de hoeveelheid data) response[6] = pcRxByte[6]; // unit indentifier wordt gekopieerd van het request bericht response[7] = pcRxByte[7]; // Function code wordt gekopieerd van het request bericht response[8] = 4; // Byte count response[9] = (test >> 24); // most significant bit response[10] = (test >> 16); response[11] = (test >> 8); response[12] = (test >> 0); |
Als ik dit verzend komt er keurig twee 16 bit waardes binnen via de modbus (modbus werkt namelijk met 16 bit registers, maar twee 16-bit registers kan samengevoegd worden tot een 32 bit register. Dit wil ik ook met een 32 bit float kunnen doen, maar dan gebeurd er dit:
code:
1
| Error 9 invalid operands to binary >> (have 'float' and 'int') |
Ik hoop dat het duidelijk is en dat iemand raad weet hoe ik dit kan aanpakken