Go Down

Topic: Arduino IDE compiling differs between linux- and Windows machine (Read 3195 times) previous topic - next topic

Byte8

Hello forum,

Hoping this time I addressed the correct forum, I am having the following problem: Compiling under Linux results in a fine working program, when I compile the same source under W10 the program has a lot of faults like resetting automatically, changing the value on the pins without cause, exiting the program when it has not yet finished.

To investigate this, I used two different Windows 10 laptops, also I did a clean install again on one of them, IDE version 1.8.10.
For Linux I use an older laptop with Ubuntu 18.04.3 LTS and IDE 2:1.05+dfsg2-4.1

As for the Arduino I use the Arduino Mega 2560.

Hoping somebody has any Ideas on this? Or must I conclude that the IDE under Windows is flawed?

Regards,

Henk van der Heijden.

Robin2

It would help a great deal if you were to post the program that is causing the problem and provide specific details of the problems that you encounter.

How is the Mega powered when it is running?

Are there any devices that draw power from the Mega?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Byte8

Hello,

I attached my source-code and the sysinfo from the laptop as wel as the technical description of the system, that controls part of a model railroad.

Further: The compiled program by Linux works perfect, so my conclusion was that it was the Windows IDE version that is wrong.

The Arduino pulls its electricity from a telephone charger that delivers a stable DC current of 5V. A servo draws power from the Arduino, but it is momentarily disabled. See also the attached Technische_Beschrijving" unfortunately in Dutch, but the schemas are self-explaining.

The Arduno further controls an L298N through a PWM-pin. Also connected tot the L298N is a transformer for model railroads.

For a summary I have a site displaying the installation, see under "Computersturing":
hvdheijd.home.xs4all.nl

I hope this post will give you the information you require.

Rgds,
Henk van der Heijden.



Byte8

can't get the technical description uploaded, "entity too large" or something!!

Robin2

Sorry, I'm lazy and I'm not going to study 17k of code or 735k of sysinfo.

Can't you provide details of the problem without needing sysinfo? For example samples of the output from the Serial Monitor or compiler error messages?


Is this the only program that behaves differently on the two operating systems.

For the Linux system you say " IDE 2:1.05" - does that mean it is using the really old version 1.05?  There have been a lot of changes between that and 1.8.10.

You could try putting the older IDE on your Windows PC - you can have several versions of the IDE on a PC.


...R
PS ... how could the technical description be big? Can't you just write a few paragraphs?
Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

I switched back and forth between Linux Mint 18 running Arduino IDE 1.8.9 and Windows 7 running Arduino IDE 1.8.9 without any issues.


.

sterretje

Under Linux, you seem to be using an IDE from the repo. It's very outdated. As this however is the one that works for you, I will not suggest to change it to one of the official ones.

Different compiler / linker versions will result in different executables. Not saying you have a bug (as I did not look at your code) but a bug in the code can cause the symptoms that you describe.


If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

sterretje

I had a look at your code. I do not immediately see a bug. The use of String (capital S) can be risky but I think that the way how it is used and the small number of String variables is safe.

But I see plenty of room for improvements ;) that will make your code easier to read and understand, smaller and maybe more solid.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Byte8

Thnx everybody for your reactions, tonight I again tried a Windows compilation, still does not work after I also  loaded the most recent Arduino-libs.

As requested by Robin2: The faulty version is the Windows version. The program runs a small model railroad, three loco's run on the track, three arrays control this and a counter keeps track of where the "timetable". The firste sequence went well. Then it seems that pin 33 is triggered and made ZERO, which leads tro the program thinking that the train has arrived over the reed-contact where is is supposed to stop, but in reality the train is only in the beginning of its travel/

Then another train starts. Now pint 34 is unintentionally made ZERO.


Tech description: Arduino controls relais that steer three points and 13 rail segments. Power is supplied by sending a PWM to an L298N unit which provides a block wave for the trains to run on.  Reed contacts are defined as INPUT_PULLUP and react when a train with a magnet is "overhead", then the accompanying pin is drawn to ZERO (GND). The Arduino is powered by a stabalized adapter like u use for telephones.

&Sterretje, always willing to learn how to improve !!
 

Robin2

Thnx everybody for your reactions, tonight I again tried a Windows compilation, still does not work after I also  loaded the most recent Arduino-libs.
The problem seems to be that you need a much older version of the IDE for your Windows PC to match your Linux PC.

...R

Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

The problem seems to be that you need a much older version of the IDE for your Windows PC to match your Linux PC.

...R


Or upgrade to the newest Linux IDE and see the problem replicate itself.

 :)

Robin2

Or upgrade to the newest Linux IDE and see the problem replicate itself.

 :)
I'm very reluctant to recommend that because there is a risk the OP will have an unusable system on both PCs. We don't know how competent the OP is and this seems like a good case for "if it works, don't fix it"

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

I am wondering whether there is a warning that is showing up that may point to the problem.

sterretje

&Sterretje, always willing to learn how to improve !!
A simple thing to reduce code size

Recognise patterns in spoorLetter() and readLetter().

Your pins for the tracks are even numbered pins from 22 .. 46, the output of spoorLetter is 1 .. 13. Divide localSpoor by 2 ( result 11 .. 23) and subtract 10. Print the result.
Your pins for the reed contacts are odd numbered pins from 23 to 47, the output of reedLetter is A .. M. Subtract 1 and divide by 2 (result as above). Subtract 11 (0 .. 12) and add the ascii value for 'A'; print the result.

Using this approach, you can save about 60 lines (around 700 charaters) of code for each.
Code: [Select]
void loop()
{
}

/*
  'translate' a track pin number to a track number
  In:
    spoor pin number
*/
void spoorLetter(int spoorPin)
{
  int letter = spoorPin / 2;
  Serial.print(F("Debug spoorLetter: step 1 -> "));
  Serial.print(letter);

  letter -= 10;
  Serial.print(F(", step 2 -> "));
  Serial.println(letter);
}

/*
  'translate' a reed contact pin number to a reed contact letter
  In:
    reed contact pin nummer
*/
void reedLetter(int reedPin)
{
  int letter = (reedPin - 1) / 2;
  Serial.print(F("Debug reedLetter: step 1 -> "));
  Serial.print(letter);

  letter -= 11;
  Serial.print(F(", step 2 -> "));
  Serial.print(letter);

  letter += 'A';
  Serial.print(F(", step 3 -> "));
  Serial.println((char)letter);
}

Disadvantage: you will always need to adhere to the pattern when you add new tracks and reed contacts.

The above code is not hardened so you can pass a non-existing track or reed contact number and it will still happily give you something back.

The more important changes that you can make are in 'rijweg', 'spoorboek' and 'locInfo'. Each row in those arrays seems to contain related information for something (e.g. for the four locomotives). You can look at structs (or classes) to combine it with sensible names. E.g.
Code: [Select]
struct LOCINFO
{
  int snelheidVooruit;
  int snelheidAchteruit;
  int gereserveerd_1;
  int gereserveerd_2;
};

LOCINFO locInfo[] =
{
  {82, 81, 0, 0},                       //loc 0
  {79, 80, 0, 0},                         //loc 1
  {98, 92, 0, 0},                       //loc 2
  {0, 0, 0, 0},                           //loc 3
};

Note that you're not limited to integers, you can add floats, c-strings, booleans and so on in the struct.

This allows you to access the fields by name which will improve the readability; it's also less prone to errors due to incorrect indexing. A modified snippet of your code below
Code: [Select]
  if (richting == 0) {
    digitalWrite(dirPin1, HIGH);
    digitalWrite(dirPin2, LOW);
    speedControl = locInfo[spoorboek[cycleCount][0]].snelheidAchteruit;
    analogWrite(pwmPin, speedControl);
    Serial.print("richting 0 pwm = ");
    Serial.println(speedControl);
  }


Note that I did not specify the number of elements (4) of the locInfo array; this makes it esier if you ever want to add an additional locomotive as the array will grow automatically.

Now, if you want to know the number of elements in an array (any array, it does not matter what the type is), you can use a macro to calculate it at compile time; place the below near the top of your code.
Code: [Select]
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))

And demo code below
Code: [Select]
void setup()
{
  Serial.begin(57600);
  Serial.print(F("Aantal locomotieven is "));
  Serial.println(NUMELEMENTS(locInfo));

  for (uint8_t cnt = 0; cnt < NUMELEMENTS(locInfo); cnt++)
  {
    Serial.print(F("Loc: ")); Serial.println(cnt);
    Serial.print(F("\tvooruit: ")); Serial.println(locInfo[cnt].snelheidVooruit);
    Serial.print(F("\tachteruit: ")); Serial.println(locInfo[cnt].snelheidAchteruit);
  }
}


I'm not sure how many tracks and turnouts you have in the 'rijweg' records; I think it's seven tracks and three turnouts. A struct could look like
Code: [Select]
struct RIJWEG
{
  const int sporen[7];
  const int wissels[3];
};

Note that I made the arrays constant; if you ever try to modify them in your code, the compiler will warn you or throw an error. You can do the same for your locInfo struct if you will never have a need the need to change the settings from e.g. a PC.

And the definition of the array (only two records shown, you can add the others)
Code: [Select]
RIJWEG rijweg[] =
{
  { //#00
    {sp2, sp3, sp4, sp5, sp6, 0, 0},
    {w10, w20, 9},
  },
  { //#01
    {sp2, sp3, sp4, sp5, sp6, sp7, 0},
    {w10, w20, 9},
  },
};

And some demo code to show the use
Code: [Select]
void setup()
{
  Serial.begin(57600);
  Serial.print(F("Aantal rijwegen is "));
  Serial.println(NUMELEMENTS(rijweg));

  for (uint8_t rijwegTeller = 0; rijwegTeller < NUMELEMENTS(rijweg); rijwegTeller++)
  {
    Serial.println(F("====="));
    Serial.print(F("Rijweg: ")); Serial.println(rijwegTeller);
    Serial.println(F("Sporen"));
    for (uint8_t spoorTeller = 0; spoorTeller < NUMELEMENTS(rijweg[rijwegTeller].sporen); spoorTeller++)
    {
      if (rijweg[rijwegTeller].sporen[spoorTeller] != 0)
      {
        // print
        Serial.print(F("\tspoor #"));
        spoorLetter(rijweg[rijwegTeller].sporen[spoorTeller]);
        // set pin to output
        pinMode(rijweg[rijwegTeller].sporen[spoorTeller], OUTPUT);
      }
    }
    Serial.println(F("Wissels"));
    for (uint8_t wisselTeller = 0; wisselTeller < NUMELEMENTS(rijweg[rijwegTeller].wissels); wisselTeller++)
    {
      if (rijweg[rijwegTeller].wissels[wisselTeller] != 9)
      {
        // print
        Serial.print(F("\twissel pin "));
        Serial.println(rijweg[rijwegTeller].wissels[wisselTeller]);
        // set pin to output
        pinMode(rijweg[rijwegTeller].wissels[wisselTeller], OUTPUT);
      }
    }
  }
}

Please note that this not only prints for demo purposes but also sets the pinMode of the pins; a number of pins will be set numerous times. I'm not quite sure of the side effects; you might have to add some code to power off the tracks so trains don't start running and turnouts coils don't burn out.

You can figure out a struct for 'spoorboek' yourself ;)

The next improvement can be the use of names for the possible values 'richting' and 'rijrichting'; you're currently using 0 and 1 for 'weg' and 'terug'. Place the below near the top of your code
Code: [Select]
enum RICHTING
{
  TERUG,
  WEG
};

This 'creates' a type with 2 possible values. TERUG will translate to 0 and WEG will translate to 1 if you print them but that is actually irrelevant.
You can create and initialise variables as shown below
Code: [Select]

RICHTING richting =  WEG;
RICHTING rijrichting = TERUG;

And in the earlier snippet that I used to demonstrate the use of the struct
Code: [Select]
  if (richting == TERUG) {
    digitalWrite(dirPin1, HIGH);
    digitalWrite(dirPin2, LOW);
    speedControl = locInfo[spoorboek[cycleCount][0]].snelheidAchteruit;
    analogWrite(pwmPin, speedControl);
    Serial.print("richting 0 pwm = ");
    Serial.println(speedControl);
  }
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Byte8

Still experience differences between Linux compile on an old version IDE, which works fine, and the latest Windows IDE which still produces problems (I tried several versions btw). I had some additional findings I want to share with you.

But first of all: everybody thnx very much!! Also sterretje: I will incorporate on a later dat your improvements, I need to find a solution for my urgent problem first.

Today I again installed the latest version of the IDE on my Windows machine. I also experimented with several sizes of the array "spoorBoek". Spoorboek in effect controls the movement of the trains and uses locinfo and "rijweg" (combinations of track). When this array was increased to 36 rows one of the problems returned: an unscheduled and unexplainable "reset", the prgm started a new.

I wil be working on trying to find the problem, but it sits so deep in the compiler and source. In the latest version on Windows one can export the hex object code, but unfortunately the older Linux version does not have this function.

And that is it for today folks :)

Go Up