MichaelJonker / HardwareSerialRS485

Arduino Software for RS485 support with collision detection and message handling capabilities
MIT License
107 stars 29 forks source link

Adapting boards.txt #5

Closed admiral-fairbanks-ExtolInc closed 3 years ago

admiral-fairbanks-ExtolInc commented 7 years ago

Hey there, this library looks really great, but I'm running into a compiling problem that I can't for the life of me figure out. My application is relatively simple. I have an Arduino Mega 2560 that is going to function as the master to two Uno slaves. The data I'm looking to pass between master/slaves is fairly straightforward, just start/stop signals and status bits. I am programming in the PlatformIO IDE. The program compiles just fine without including the library, but when I include "HardwareSerialRS485.h" I get following error: lib\HardwareSerialRS485-master\src/HardwareSerialRS485.h:59:38: error: conflicting declaration 'HardwareSerialRS485_1 Serial1'

I tried to port this over to the standard Arduino IDE, and get a different error message:

In file included from 
C:\Users\david.webster\Documents\Arduino\libraries\HardwareSerial_RS485\src\HardwareSerialRS485.h:42:0,
             from C:\Users\david.webster\Documents\Arduino\libraries\HardwareSerial_RS485\src\HardwareSerialRS485.cpp:21:

C:\Users\david.webster\Documents\Arduino\libraries\HardwareSerial_RS485\src\utility/HardwareSerialRS485_configuration.h:63:6: warning: #warning "No definition of RS485configuration_TRxControl was given, a possibly defunct default is now used." [-Wcpp]

     #warning "No definition of RS485configuration_TRxControl was given, a possibly defunct default is now used."
      ^
HardwareSerial0.cpp.o (symbol from plugin): In function `Serial':

(.text+0x0): multiple definition of `__vector_25'

libraries\HardwareSerial_RS485\HardwareSerialRS485.cpp.o (symbol from plugin):(.text+0x0): first defined here

c:/users/david.webster/appdata/local/arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions

HardwareSerial0.cpp.o (symbol from plugin): In function `Serial':

(.text+0x0): multiple definition of `__vector_26'

libraries\HardwareSerial_RS485\HardwareSerialRS485.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

The libraries I've included are listed below in their entirety

#include "HardwareSerialRS485.h"
#include "Arduino.h"
#include <Ethernet.h> // Ethernet Comm Library
#include <EthernetUdp.h> // Ethernet UDP Comm Library
#include "Fill_With_Template.h" // Template function for filling arrays
#include <MsTimer2.h> // Millisecond timer
#include <PID_v1.h> // PID controller
#include <SPI.h> // SD Card related
#include <SD.h> // SD Card Related

Now, I've read quite a bit into the installation instructions, and have made the subdirectory for the 'boards' and 'DisableHardwareSerial' files. I know I need to modify the 'boards' file, and I tried to do SOME of it, but I'm a little lost as to what exactly I need to be putting in there.

Do you have any clues as to why I could be getting conflicting Serial1 declarations? Have I incorrectly set up some of these files? I apologize if this is a novice question. I'm really stumped.

I've attached the .zip program folder of the Arduino IDE version. LMP_Prototype_Punch_Actuation_8_9_17_Arduino.zip

MichaelJonker commented 7 years ago

Hello David (?)

Thanks for your interest in my library and raising the issue.

It has been a while I worked on this code and I will have to do some more investigations. I am not familiar with the PlatformIO IDE, neither did I tested any implementation on the Arduino Mega. However, I think I should be able to solve the compilation/linkage issues you reported. At least as a starter for the Arduino IDE.

At first glans I think there might be a double inclusion of the HardwareSerialRS485 module (conflicting declaration of HardwareSerialRS485_Serial1) and the messages about multiple definitions on __vector_25 & _26.

My code in one of the header files also complains about a missing definition of RS485configuration_TRxControl, which could be an indication that something is not yet correctly setup with in the environment.

I will have some time next week to look into all this in more detail. In the meantime, can you tell me what version of the Arduino IDE you are using? Can you also activate the checkbox “Show verbose output during compilation” and send me the full error output produced? You can find this checkbox on the Preferences panel that you can open from the file menu from the Arduino IDE.

Another thing I want to point out, is that after having added the boards.txt file to the Arduino IDE environment in the indicated folder, one should also select one of the defined boards corresponding to your configuration from the Arduino IDE menu for it to become active.

I will get back to later next week.

Best regards

Michael Jonker

MichaelJonker commented 7 years ago

oops closed the issue by accident

MichaelJonker commented 7 years ago

Hi again, Apart from the version and the build output in the Arduino IDE that I asked you above, can show me the file/folder structure under your project directory (i.e. the directory that is set in the Arduino IDE preferences)? Can you also ensure that the folder \hardware\HardwareSerialRS485\avr contains the files boards.txt and a file DisableHardwareSerial.h The boards.txt file should have added an adapted entry for the Arduino Mega (adapted from the version in the boards file from the Arduino IDE). Can you send me a copy of the boards.txt file?

How did you install the HardwareSerialRS485 library, using the Arduino IDE or by hand? I am not sure (yet) if there will be things missing in the latter case.

Related to the PlatformIO IDE, do you know how the build is done, and can you get any detailed feedback from the build process and/or do you have any control over the build process. I will do some research but if you know this it may simplify things for me. Specifically it would be handy if there are provisions to add switches to the compilation step (like –D someMacro)

MichaelJonker commented 7 years ago

Hello,

if you are still interested in solving the issue with the HardwareSerialRS485 configuration, I think I have some useful information here:

For background, the mechanism with the boards.txt file serves two purposes:

1) Define the RS485configuration through options that can be selected from the Arduino IDE menu (which is convenient one develops for a variety of board configurations).

2) Disable the inclusion of the normal HardwareSerial.h before the inclusion of HardwareSerialRS485.h. This became necessary with the Arduino IDE version 1.6.6. Starting from this version the building procedure adds the include directive of Arduino.h right in front before any other include directives in the sketch file. It could have been fixed with a -DHardwareSerial_h compiler option, however, this would leave out other code. Now there is the file DisableHardwareSerial.h which is included (before Arduino.h ) through a compiler option.

The boards.txt file has not (yet) been set up for dealing with boards other than UNO / Micro /Leonardo, this can be done. However, I do not know whether this mechanism will also work for the PlatformIO IDE, and whether there is the same problem of the ‘forced’ inclusion of Arduino.h before any other include directive. So, I propose here a simpler mechanism. It will not give you the flexibility of the boards.txt method for selecting from the IDE the RS485 options, but it might be simpler to setup.

Please create a header file with all the RS485configuration definitions that you need in addition to some extra stuff following this example:

// My_RS485_configuration.h definition of my RS485 configuration for project xyz

ifdef IsIncluded_My_RS485_configuration_h

define IsIncluded_My_RS485_configuration_h

define HardwareSerial_h // required!! This disables the inclusion of HardwareSerial.h

// However, we now still need to weak define a serialEventRun as this might be needed by main.cpp extern void serialEventRun(void) attribute((weak)); // also required!!

// and we have to make up for a missing include directive in "USBAPI.h"

include "Stream.h" // unless this was fixed in the Arduino USBAPI.h header, also may also be required !!

// Define the configuration of the Serial1, Serial2, etc. devices (See HardwaSerialRS485.h). Adapt these to your needs // // define the HardwareSerialRS485 class for the Serial1 device associated with USART1

define RS485configuration_HardwareSerialRS485_1 \

    HardwareSerialRS485< USART1, 6, 7, ' ', RS485serial< TRxControl< 'B', 2, 3 > >, MFP< '{', '}' > >

// defines the HardwareSerialRS485 class for the Serial2 device associated with USART2

define RS485configuration_HardwareSerialRS485_2 \

    HardwareSerialRS485< USART2, 6, 7, ' ', RS485serial< TRxControl< 'C', 6, 6 >, Transaction_dummy > >

// defines the HardwareSerialRS485 class for the Serial3 device associated with USART3

define RS485configuration_HardwareSerialRS485_3 \

    HardwareSerialRS485< USART3, 6, 7, ' ' >

endif // ifdef IsIncluded_My_RS485_configuration_h

//eof My_RS485_configuration.h

Now you should force include this file before the Arduino.h file. If the PlatformIO build process is not messing around with you code, than you have full control and this will be straight forward. If you are working with the Arduino IDE (or an IDE with messes around with you code) then you have to add some tricks, like using the board.txt file in case of the Arduino IDE. I can elaborate on this in a separate post if needed.

Good luck! -- Michael

p.s. For info: The above definitions for the Serial classes emphasis, as an example, some of the possible options:

1) The device Serial1 will implement RS485 handling with transaction handling and message recognition and handling. The TxE and RxE* pins of the RS485 chip are expected to be connected to port B2 and B3 respectively.

2) The device Serial2 will be a simple RS485 without transaction or message handling. The TxE and RxE* pins of the RS485 chip are expected to be connected to port C6 and (resistively) to ground respectively.

3) The device Serial3 will be a simple USART device without provisions for RS485 handling.

For information: the parameters of the HardwareSerialRS485 template are (see HardwareSerialRS485_Enabled.h) template < class TUSART, // one of the USART classes USART0, USART1, ... (predefined in utility/USARTdef.h) int TTX_BufferSize=6, // Transmit buffer size, given by 1<< TTX_BufferSize int T__RX_BufferSize=6, // Receive buffer size, given by 1<< TRX_BufferSize unsigned char TRX_OverRunMarker=' ', // Receive buffer overrun character (space / default) => no overrun character inserted) class T__RS485=RS485_dummy, // RS485 protocol helper. class TMessageFilter=MessageFilter_dummy // Message filter control class.

If the T__RS485 parameter is omitted, a dummy protocol implementation provides a ‘classical’ HardwareSerial implementation (no RS485). However note that this ‘classical’ implementation does not allow for a buffer size over 128 characters.

To implement the RS485 control, this template parameter should be set to a template instance of the template class RS485serial (see below).

The template parameter T__MessageFilter points to a message filter class. If omitted no message recognition is provided. To activate message recognition and message filtering you are advised to set it to MFP< '{', '}' >, where '{' and '}' are the start of message / end of message characters (or use any characters of your choice).

The template parameters of the class RS485serial are:

template<class TTRxControl=TRxControl<>, class TTransaction=Transaction >

The only important parameter is the TTRxControl class. You are advised to set this to a template instance of the template class TRxControl The TTransaction parameter allow you to remove transaction handling by setting it to Transaction_dummy

The template parameters of the class TRxControl are (See HardwareSerialRS485_Helper.h) template< char T__TRx_PORT = 'B', // port B digital pin D8 - D13 unsigned char TTxEnable = 2, // TxE : PB2 shield D10, SS, pin 16, (pwm) unsigned char TRxDisable = 3 // RxE* : PB3 shield D11, MOSI, pin 17, (pwm)

I.e. if you want to use port C4 and C2 for TxE and RxE control, you specify TRxControl<’C’, 4, 2> If you do not need RS232 compatibility, you can leave the receive mode permanently enabled by connecting the RxE pin of the RS485 chip permanently with a resistor to ground. In that case you specify TRxControl<’C’, 4, 4> assuming TxE is connected to pin C4.

admiral-fairbanks-ExtolInc commented 7 years ago

Hey Michael, Apologies for not responding sooner. Last week I got completely sidetracked with debugging more critical aspects of the code and did not have time to circle back around to this issue until today. First, thanks for your extremely lengthy and informative responses.

I have started with your most recent response. I copied the code into a file named My_RS485_configuration.h, added it to my program's source code directory, and included it. Now the header on my main program looks as follows: `#include "My_RS485_configuration.h"

include "HardwareSerialRS485.h"

include "Arduino.h"

include

include

include

include <utility/Adafruit_MCP23017.h>

include

include "Fill_With_Template.h" // Template function for filling arrays

include // PID controller

include // SD Card related

include // SD Card Related`

However, when I attempt to compile this, I still get an error very similar to what I was getting before. I have attached the full verbose error output from the Arduino IDE. I am using version 1.8.2 of the IDE.

The boards.txt file is correctly set up now, so the two options show up as available boards.

RS485_Error_Msg_Verbose.txt

I'm wondering if maybe you can detail the method for adding the Mega2560 to boards.txt?

MichaelJonker commented 7 years ago

Hello, Thanks for all the info. The results correspond to what I would expect with the Arduino IDE, because despite putting the `#include "My_RS485_configuration.h" right up front in your source file before the "#include Arduino.h.", the Arduino build tool will insert a #include Arduino.h directive at the first line of the code and this is the source of the problem. But I wondered what the error message would be with the platformIO IDE. Can you test what this gives?

For Arduino IDE one should prepare a proper board.txt file. I stsrted with this but the complication is that one has to copy and addapt many lines of the standard boards.txt file. While looking at this I got an idea for a simpler and more generic approach which I would like to try out first. I will let you know in a few days.

M

MichaelJonker commented 7 years ago

Hello, I have prepared a board.txt file and a configuration file that you can adapt for use with the mega.

As the mega with its three USART's is slightly more complex to configure, I have delegated all configuration to a RS485configuration.h header file. You can define more than one RS485 configuration header file and use the ARDUINO IDE menu option to select the one you want to use. (This is useful if you work with several boards configurations). The new boards.txt can be copied from here. An example of a RS485 configuration header file (which also matches the example in the boards.txt file) can be copied from My_RS485configuration.h. This file should be copied to the same directory where you store your boards.txt file. (IMPORTANT you should remove the .txt from the end of the file name after loading. The .txt was added as github does not allow upload a .h file into this post...). Also note that you should further adapt the RS485 configuration header file to your hardware reality. Let me know if you need help for this

Please let me know it this solution is satisfactory. In that case I will upload the boards.txt and the RS 485 example configuration to the project repository.

Michael