Strange Serial.begin (9600) requires the next serial port to work correctly

Hey guys,

This is hard to explain but here goes!

I'm using this DF1 library Here to communicate between a Micrologix 1200 plc and a Mega. I also have 2 Mega's communicating with a Max485 and this is where the strange behavior happens.

I'm using the default serial port for the DF1 and then I'm using Serial2 for the Max485 communication between the two Mega's. In my code below you will see I have my Serial2.begin(9600) but this sketch will not work unless I begin Serial3. ?????

I have nothing hooked up to 3 and do not need it anywhere in the project, so why does this only work with Serial3.begin(9600) added to the sketch.

I have even tried modifying the code and wiring up to Serial1, but I had to begin Serial2 for that to work as well. Seems like I always have to .begin the next port in line to work.

I'm clueless here!!! Any hints would be awesome!

//=======================  DF1 =============================
#include <DF1.h>
#define DF1destination 1
#define DF1baud 38400
#define DF1format SERIAL_8N1
#define DF1timeout 3000


//  Define integer holders for the incomming Port bytes from the slaves
unsigned int cl_port1; 
unsigned int cl_port2;
unsigned int cl_port3;
unsigned int el_port1;
unsigned int el_port2;
unsigned int el_port3;
unsigned int cab_port1;
unsigned int cab_port2;
unsigned int cab_port3;

enum
{ 
  DF1PACKET1,
  DF1TOTAL_NO_OF_PACKETS
};
DF1Packet DF1packets[DF1TOTAL_NO_OF_PACKETS];
DF1packetPointer DF1packet1 = &DF1packets[DF1PACKET1];
unsigned int DF1writeRegs[0];
//===================== END DF1 ==============================


#define Serial2TxControl   13   //RS485 Direction control

int incomingByte0;
int incomingByte1;
int CL_pin = 5; // C/L Status
int EL_pin = 6; // E/L Status
int CAB_pin = 7; // CAB Status

void setup()   /****** SETUP******/
{
  
//=======================  DF1 SETUP =============================  
DF1_construct(DF1packet1, DF1destination, DF1_WRITE_N7, 70, 16, DF1writeRegs);
DF1_configure(&Serial, DF1baud, DF1format, DF1timeout, DF1packets, DF1TOTAL_NO_OF_PACKETS);
 DF1writeRegs[0] = 0;
 DF1writeRegs[1] = 0;
 DF1writeRegs[2] = 0;
 DF1writeRegs[3] = 0;
 DF1writeRegs[4] = 0;

 DF1writeRegs[5] = 0;
 DF1writeRegs[6] = 0;
 DF1writeRegs[7] = 0;
 DF1writeRegs[8] = 0;
 DF1writeRegs[9] = 0;

 DF1writeRegs[10] = 0;
 DF1writeRegs[11] = 0;
 DF1writeRegs[12] = 0;
 DF1writeRegs[13] = 0;
 DF1writeRegs[14] = 0;
 DF1_update();


//----------------------END DF1 SETUP --------------------------------------


   
  //--- Status Pins-------- Added 9/20/17
  pinMode(CL_pin, INPUT_PULLUP); // C/L Status
  pinMode(EL_pin, INPUT_PULLUP); // E/L Status
  pinMode(CAB_pin, INPUT_PULLUP); // Cab Status
   
  pinMode(Serial2TxControl, OUTPUT);
  
  Serial2.begin(9600);   // set the data rate
  Serial3.begin(9600);   // set the data rate  
 //===============================SETUP@=======================================================
 

 
}//--(end setup )---

//-----------------------------------------------------------------------------------------------------------------------------
void loop() 
{
  // New feature for Status Check or Cable break to shut off outputs in case of break in cables and such
  // do an if statement to see if pin 7 is low. If yes, then only run serial read for ports A & C.  If no, then set PORTA = B00000000 (to shut off outputs) and rerun the loop until the status is good.
  // Run another if statement to check if pins 5 $ 6 are low, this will let us know the back boxes are OK.

if (digitalRead(CL_pin) == HIGH && digitalRead(CAB_pin) == HIGH) // If there are no boxes connected to C/L or CAB then turn off all outputs
  {
                         DF1writeRegs[0] = 0;
                         DF1writeRegs[1] = 0;
                         DF1writeRegs[2] = 0;
                         DF1writeRegs[3] = 0;
                         DF1writeRegs[4] = 0;                        
                          DF1_update();
  //PORTC = B00000000;
  
  }
  else if (digitalRead(CL_pin) == LOW || digitalRead(CAB_pin) == LOW)  // If there is a switch box connected to C/L or CAB controllers then run normal operations...
  {
           if (Serial2.available()>2)  //Look for 3 bytes of data from other Arduino
             {
                    incomingByte0 = Serial2.read(); // read a byte
                    cl_port1 = incomingByte0; // D22 - D29  - 1st byte of the incomming data
                       
                    incomingByte0 = Serial2.read(); // read a byte
                    cl_port2 = incomingByte0; // D30 to D37 - 2nd byte of the incomming data
                    
                  // **** Push the values to the PLC        
                    DF1writeRegs[0] = cl_port1;
                    DF1writeRegs[1] = cl_port2;
                    DF1_update();                       
             }
  }


  

}//--(end main loop )---

Unsure but, on the Mega there is no Serial, Serial0 thru Serial3. Your line

DF1_configure(&Serial, DF1baud, DF1format, DF1timeout, DF1packets, DF1TOTAL_NO_OF_PACKETS);

is trying to pass the address of Serial, which doesn't exist, and perhaps it's defaulting to the last serial port, Serial3.

As a side note. you know that DF1writeRegs[] has fifteen entries so instead of zeroing all in setup, change your declaration to

unsigned int DF1writeRegs[15] = {};

and they'll all be zeroed for you.

Just as another aside, we can copy your code into an editor and look at it, only. If you use a non-standard library (DF1) it helps to attach it so at least we can try to compile your code.

DKWatson:
on the Mega there is no Serial, Serial0 thru Serial3.

The correct part of that statement is "on the Mega there is no Serial0".

Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX); Serial 2: 17 (RX) and 16 (TX); Serial 3: 15 (RX) and 14 (TX).

Whandall:
The correct part of that statement is "on the Mega there is no Serial0".

I was under the impression that Serial0 and Serial are the same thing?

...R

If you try to use it you get (on my clone Mega)

Whatever:24: error: 'Serial0' was not declared in this scope

Serial0.begin(250000);

I stand corrected. I guess that means my solution won't work either?

I don't understand any of that DF1_whatever stuff.

Whandall:
If you try to use it you get (on my clone Mega)

You are quite correct. I guess the code where I saw it used must have had this at the top

#define Serial0 Serial

...R

Watson,

Thanks for the heads up on DF1writeRegs[]. I'm just getting a little more advanced in this language and trying to push a bit deeper to learn... Thank You. That sure cleans up the code a lot!

I also never knew about Serial vs Serial0! Another "Learn" for the day! I'm taking all these suggestions and hints to the memory bank ... Thanks a lot

Here is the library code: DF1.h

#ifndef DF1_H
#define DF1_H



#include "Arduino.h"


#define DF1_READ_N7 0xA1 
#define DF1_WRITE_N7 0xAA

const char ACK[2] = {0x010,0x06}; 

const char ENQ[2] = {0x010,0x05}; 

const char STX[2] = {0x010,0x02}; 

const char NAK[2] = {0x010,0x15}; 

const char EOT[2] = {0x010,0x04}; 


/* Table of CRC values for CRC16 */
const unsigned int CRC16table[] = {0x0,0xc0c1,0xc181,0x140,0xc301,0x3c0,0x280,	0xc241,
	                        0xc601,	0x6c0,	0x780,	0xc741,	0x500,	0xc5c1,	0xc481,	0x440,
	                        0xcc01,	0xcc0,	0xd80,	0xcd41,	0xf00,	0xcfc1,	0xce81,	0xe40,
	                        0xa00,	0xcac1,	0xcb81,	0xb40,	0xc901,	0x9c0,	0x880,
	                        0xc841,	0xd801,	0x18c0,	0x1980,	0xd941,	0x1b00,	0xdbc1,	0xda81,
	                        0x1a40,	0x1e00,	0xdec1,	0xdf81,	0x1f40,
	                        0xdd01,	0x1dc0,	0x1c80,	0xdc41,	0x1400,	0xd4c1,	0xd581,	0x1540,
	                        0xd701,	0x17c0,	0x1680,	0xd641,	0xd201,	0x12c0,	0x1380,	0xd341,
	                        0x1100,	0xd1c1,	0xd081,	0x1040,	0xf001,	0x30c0,	0x3180,	0xf141,
	                        0x3300,	0xf3c1,	0xf281,	0x3240,	0x3600,	0xf6c1,	0xf781,	0x3740,
	                        0xf501,	0x35c0,	0x3480,	0xf441,	0x3c00,	0xfcc1,	0xfd81,
	                        0x3d40,	0xff01,	0x3fc0,	0x3e80,	0xfe41,	0xfa01,	0x3ac0,	0x3b80,
	                        0xfb41,	0x3900,	0xf9c1,	0xf881,	0x3840,	0x2800,
	                        0xe8c1,	0xe981,	0x2940,	0xeb01,	0x2bc0,	0x2a80,	0xea41,	0xee01,
	                        0x2ec0,	0x2f80,	0xef41,	0x2d00,	0xedc1,	0xec81,	0x2c40,	0xe401,
	                        0x24c0,	0x2580,	0xe541,	0x2700,	0xe7c1,	0xe681,	0x2640,	0x2200,
	                        0xe2c1,	0xe381,	0x2340,	0xe101,	0x21c0,	0x2080,	0xe041,	0xa001,
	                        0x60c0,	0x6180,	0xa141,	0x6300,	0xa3c1,	0xa281,	0x6240,	0x6600,
	                        0xa6c1,	0xa781,	0x6740,	0xa501,	0x65c0,	0x6480,	0xa441,	0x6c00,
	                        0xacc1,	0xad81,	0x6d40,	0xaf01,	0x6fc0,	0x6e80,	0xae41,	0xaa01,
	                        0x6ac0,	0x6b80,	0xab41,	0x6900,	0xa9c1,	0xa881,	0x6840,	0x7800,
	                        0xb8c1,	0xb981,	0x7940,	0xbb01,	0x7bc0,	0x7a80,	0xba41,	0xbe01,
	                        0x7ec0,	0x7f80,	0xbf41,	0x7d00,	0xbdc1,	0xbc81,	0x7c40,	0xb401,
	                        0x74c0,	0x7580,	0xb541,	0x7700,	0xb7c1,	0xb681,	0x7640,	0x7200,
	                        0xb2c1,	0xb381,	0x7340,	0xb101,	0x71c0,	0x7080,	0xb041,	0x5000,
	                        0x90c1,	0x9181,	0x5140,	0x9301,	0x53c0,	0x5280,	0x9241,	0x9601,
	                        0x56c0,	0x5780,	0x9741,	0x5500,	0x95c1,	0x9481,	0x5440,	0x9c01,
	                        0x5cc0,	0x5d80,	0x9d41,	0x5f00,	0x9fc1,	0x9e81,	0x5e40,	0x5a00,
	                        0x9ac1,	0x9b81,	0x5b40,	0x9901,	0x59c0,	0x5880,	0x9841,	0x8801,
	                        0x48c0,	0x4980,	0x8941,	0x4b00,	0x8bc1,	0x8a81,	0x4a40,	0x4e00,
	                        0x8ec1,	0x8f81,	0x4f40,	0x8d01,	0x4dc0,	0x4c80,	0x8c41,	0x4400,
	                        0x84c1,	0x8581,	0x4540,	0x8701,	0x47c0,	0x4680,	0x8641,	0x8201,
	                        0x42c0,	0x4380,	0x8341,	0x4100,	0x81c1,	0x8081,	0x4040};

typedef struct
{
	unsigned char DST;
	unsigned char FNC;
	unsigned int ADDR;
	unsigned int SIZE; 
	unsigned int* DATA_ARRAY;
  
  // DF1 information counters
	unsigned int DF1requests;
	unsigned int DF1successful_requests;
	unsigned int DF1failed_requests;
	unsigned int DF1error;
  	
  // DF1connection status of DF1packet
	unsigned char DF1connection; 
  
}DF1Packet;

typedef DF1Packet* DF1packetPointer;


void DF1_update();

void DF1_construct(DF1Packet *_DF1packet, 
											unsigned char DST, 
											unsigned char FNC, 
											unsigned int ADDR, 
											unsigned int SIZE, 
											unsigned int* DATA_ARRAY);
											
void DF1_configure(HardwareSerial* SerialPort,
											long DF1baud, 
											unsigned char DF1byteFormat,
											unsigned int _DF1timeout,
											DF1Packet* _DF1packets, 
											unsigned int _DF1total_no_of_packets);

#endif

The .cpp file exceeds the 9000 character limit, Going to post a link shortly

Here is a link to the full DF1 Library File... DF1

vin7102:
Here is a link to the full DF1 Library File... DF1

A link to the documentation for the library would probably be more useful.

...R

Robin,

Sure here is the blog where I found the library. He only had a video demo and posted some sample I/O code.

You have to jump through a few loops and whatnot to finally get to the downloads part of the blog so I figured I would save everyone the hassle.

Here is where I found the library, not much instruction with it but I was able to get it to work fine with the Micrologix 1200. Other than this "begin" mystery.