0
votes

I'm trying to communicate with some industrial hardware, on ModBusRTU, from my Intel Galileo Gen2 board. I use this board to convert UART to RS485 http://linksprite.com/wiki/index.php5?title=RS485_Shield_V2.1_for_Arduino and I can talk serially between Arduino (with SoftwareSerial on pin 2/3) and Galileo (with Serial1 on pin 0/1). So I know the RS485's link is working.

With Arduino Uno I can talk with my devices using ModBusRTU, thanks to this library https://github.com/4-20ma/ModbusMaster

On galileo gen2 I receveid this warning "WARNING: library ModbusMaster claims to run on [avr, sam] architecture(s) and may be incompatible with your current board which runs on [i586] architecture(s). " because of the different architecture.

Now I'm trying to use the examples of cooking hack's tutorial about modbus and rs485 for arduino, raspberry and galileo but I can't make it works for me. I receveid tons of compiling errors like these:

C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp: In member function 'uint8_t ModbusMaster485::ModbusMasterTransaction(uint8_t)': C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp:701:50: error: '_crc16_update' was not declared in this scope

C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp:814:52: error: '_crc16_update' was not declared in this scope

C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp: At global scope:

C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp:881:14: error: prototype for 'unsigned int ModbusMaster485::makeWord(unsigned int)' does not match any in class 'ModbusMaster485'

In file included from C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp:25:0: C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.h:302:11: error: candidates are: uint16_t ModbusMaster485::makeWord(uint8_t, uint8_t)

C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.h:301:14: error: uint16_t ModbusMaster485::makeWord(uint16_t) C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp:887:14: error: prototype for 'unsigned int ModbusMaster485::makeWord(uint8_t, uint8_t)' does not match any in class 'ModbusMaster485'

In file included from C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.cpp:25:0: C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.h:302:11: error: candidates are: uint16_t ModbusMaster485::makeWord(uint8_t, uint8_t) C:\Intel\arduino-1.6.4\libraries\ModBusMaster485\ModbusMaster485.h:301:14: error: uint16_t ModbusMaster485::makeWord(uint16_t) Error compiling.

Did someone has got ModBus working on Galileo Gen2?

Thank you, Aldo

1

1 Answers

1
votes

a few reasons why it fails

  • crc16 library code

the ModbusMaster485 code assumes the use of the avr header file util/crc16.h file - which is in fact, if you look closely full of avr assembly instructions - first step is to remove this dependency.

--- ModbusMaster485.h.orig  2015-09-28 13:55:48.000000000 +0200
+++ ModbusMaster485.h   2015-09-28 13:56:00.000000000 +0200
@@ -92,7 +92,7 @@

 /* _____PROJECT INCLUDES_____________________________________________________ */
 // functions to calculate Modbus Application Data Unit CRC
-#include <util/crc16.h>
+//#include <util/crc16.h>

of course; you need to provide the relevant crc16 code in C - will get to that later

  • sizeof(int) != 16, in fact it is 32

the last error you have complains about the candidates for the compiler to figure out which method to use. it comes down to the use of "unsigned int" instead of "uint16_t" - so, a simple change and you'll need to also add the missing crc16 function that is referenced.

--- ModbusMaster485.cpp.orig    2015-09-12 04:35:05.000000000 +0200
+++ ModbusMaster485.cpp 2015-09-28 13:56:54.000000000 +0200
@@ -29,7 +29,22 @@

 /* _____PROJECT INCLUDES_____________________________________________________ */

+uint16_t
+_crc16_update(uint16_t crc, uint8_t a)
+{
+    int i;

+    crc ^= a;
+    for (i = 0; i < 8; ++i)
+    {
+        if (crc & 1)
+            crc = (crc >> 1) ^ 0xA001;
+        else
+            crc = (crc >> 1);
+    }
+
+    return crc;
+}

 /* _____PUBLIC FUNCTIONS_____________________________________________________ */

@@ -878,13 +893,13 @@
 }


-unsigned int ModbusMaster485::makeWord(unsigned int w)
+uint16_t ModbusMaster485::makeWord(uint16_t w)
 {
    return w;
 }


-unsigned int ModbusMaster485::makeWord(uint8_t h, uint8_t l)
+uint16_t ModbusMaster485::makeWord(uint8_t h, uint8_t l)
 {
    return (h << 8) | l;
 }

and you should be able to compile the project now :)

i had to do this even to get the project compiling on the Arduino Due - i am just about to test it now to see if this is sufficient to get this happening :) ... confirmed; functions as expected on the Arduino Due - should be the same for the Intel Gallileo