Error Compiling for Board Arduino/Genuino Uno.

When I compile my program I get the following error...

"Error Compiling for Board Arduino/Genuino Uno." Looking at the error message, I think this is the relevant part.

"C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\libraries\SD\src\utility\SdFile.cpp:989:1: internal compiler error: Segmentation fault

}

^

Please submit a full bug report,

with preprocessed source if appropriate."

I'm assuming the problem is with one of my close brackets but everything seems fine to me. What am I missing?

Here is what I believe to be the relevant code. There is more but I had to delete some of it to make the post fit.

#include <SPI.h>                             //Serial Interface library.
#include <SD.h>                             //SD card Library.
#include <LiquidCrystal.h>                  //Liquid Crystal Dispalay library.

const int numChannels = 16;
const byte SSButtonPin = 3;
const byte CDButtonPin = 2;
const int recordLight = A5;
const int rs=A1, en=A2, d4=6, d5=7, d6=8, d7=9; //These are the pins for the LCD display
const int readTime = 15000; // This is how long we want to wait between readings. 

int temp[numChannels]; 
int tme;
int flag=0;
int r = 0;
int buttonAction;
int on = 0;
int off = 0;
int cd = 0;
int displayReading = 0;
long int lastDisplay = 0;

unsigned long lastReading = 0;
unsigned long currentReading;
unsigned long startTime;

volatile byte SSflag = 0;
volatile byte CDbuttonPress = 0;
volatile byte SSbuttonPress =0;
volatile byte lastState = 0; 

bool recording = false; // 1 = yes, 0 = no
bool initialReading = true;
bool updateDisplay = false;
bool firstCycle = true;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //Let the LCD know what pins are being used
File datafile; 

//                                              Setup FUNCTION                                                                        

void setup()
{
 analogReference(DEFAULT); 
 digitalWrite(recordLight, HIGH);  //Make sure recording light is off.
 
  
 lcd.begin(16,2); //Start the LCD
  
 pinMode(recordLight, OUTPUT);
 pinMode(SSButtonPin, INPUT_PULLUP);
 pinMode(CDButtonPin, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(SSButtonPin), StartStop, RISING);
 attachInterrupt(digitalPinToInterrupt(CDButtonPin), CDISR, RISING);
}

//                                                           main loop

void loop()
{
 if (lastState)
 {
  lastState = 0;
  if (SSbuttonPress == 1)
  {
   SSbuttonPress = 0;  //reset it.
   if (SSflag == 1)        //Are we starting
   {
    //lcd.clear();lcd.setCursor(0,0); lcd.print("Starting ");
    recording = true;
    digitalWrite(recordLight, LOW);  //Turn the recording light on.
    lastReading = millis();
    startTime = millis();
    updateDisplay = millis();
    lastDisplay = millis();
    initialReading = true;
    displayReading = 0;  //Reset display so that it goes back to channel zero.
   }
   else    // if we aren't starting then we must be stopping
   {
    lcd.clear();lcd.setCursor(0,0); lcd.print("Stopping");
    //Serial.println("stopping");
    digitalWrite(recordLight, HIGH);  //Turn the recording light off.
    recording = false;
   }
  }
 }
 cycleDisplay();
 
 if (millis()-lastDisplay >= 1000)  // Update display every second
 {
  lastDisplay = millis();
  getTemp(temp);
  cycleDisplay(); 
 }
 if (recording)
 {
  //Serial.print("Time since last reading ");Serial.println(millis()-lastReading);
  if(initialReading == true || millis() - lastReading >= readTime) //if its been longer than 15 seconds then we need to take a reading.
  {
   getTemp(temp);   //This will get the data
   updateDisplay = true;
   if (initialReading)
   {
    tme = 0;
    //Serial.print("tme");Serial.println(tme);
   }
   else
   {
    tme = (lastReading - startTime)/1000;        //convert to seconds
    //Serial.print("tme ");Serial.println(tme);
   }
   //lastReading = millis();
   writedata(temp);              //Write the data to the SD card.
   //lastReading = millis();
   initialReading = false;  //this is no longer the initial reading.
  }
 }
}

//                                           getTemp FUNCTION                                                                           

void getTemp(int * t)
{
 Serial.println("Taking a Reading");
 int numSamples = 10;
 const int analogPin = 0; // replace 0 with analog pin
 const float invBeta = 1.00 / 3950.00;   // replace "Beta" with beta of thermistor
 const  float adcMax = 1023.00;
 const float invT0 = 1.00 / 298.15;   // room temp in Kelvin
 double adcVal[numChannels];
 int adcAvg;
 int i, x, z, A, B, C, D;
 //long int numSamples = 0;
 int  K, DC, F;
 int addressA = A3;      //A3 and A4 were moved from pins 2 and 3. Those pins are needed for interrupts.
 int addressB = A4;    
 int addressC = 4;
 int addressD = 5;
 pinMode(addressA, OUTPUT);
 pinMode(addressB, OUTPUT);
 pinMode(addressC, OUTPUT);
 pinMode(addressD, OUTPUT);
 A = 0;      //Address pin A
 B = 0;      //Address pin B
 C = 0;      //Address pin C
 D = 0;      //Address pin D
 
 for (z=0; z < numChannels; z++)
 {
  //Serial.print("z ");Serial.print(z);Serial.print(" ");
  adcVal[z] = 0;                                         //zero the adcVal array
 }
 //Serial.println();
 for (int y = 1; y <= numSamples; y++) 
 {
  //Serial.print("Reading# ");Serial.println(y);
  for (x = 0; x < numChannels; x++)                   //take a reading for each channel
  {
   A = bitRead(x,0);                                //Take first bit from binary value of x channel.
   B = bitRead(x,1);                                //Take second bit from binary value of x channel.
   C = bitRead(x,2);                                //Take third bit from value of x channel.
   D = bitRead(x,3);                                //Take fourth bit from value of i channel
 
   digitalWrite(addressA, A);
   digitalWrite(addressB, B);
   digitalWrite(addressC, C);
   digitalWrite(addressD, D);
   //delay (1);                                       //Delay a few milliseconds between readings.
                                                                  
   adcVal[x] = adcVal[x] + analogRead(analogPin);    //accumulate the reading for that channel.
   //Serial.print("adcVal[");Serial.print(x);Serial.print("] ");Serial.println(adcVal[x]);
   currentReading = millis();
  } 
 } 
       
 lastReading = millis();                                                   //update last reading to current time.    
    
 for (i=0; i < numChannels; i++)                                           //Now that we have all the readings, let's calculate the temperature for each channel.
 {
  adcVal[i] = adcVal[i]/numSamples;          // get the average reading for this channel.
  
  K = 1.00 / (invT0 + invBeta*(log (adcMax / (float) adcVal[i] - 1.00))); //Calculate the temp in deg Kelvin
  DC = K - 273.15;                      // convert to Celsius
  F = ((9.0*DC)/5.00) + 32.00;   // convert to Fahrenheit
  t[i] = DC;
  //Serial.print (t[i]);Serial.print(" ");
 } 
  //Serial.println();Serial.print("Number of Samples ");Serial.println(numSamples);
 return t;
}

//                      WRITE DATA FUNCTION
void writedata(int *t)
{
 datafile = SD.open("Temp.txt", FILE_WRITE);                                      //Open file

 if (datafile)                                                                    //If the file opened thene we can write to it.
 {
  //Serial.println("Writing to temp.txt...");
  //lcd.clear();lcd.setCursor(0,0); lcd.print("Writing Data    ");
  datafile.print(tme);datafile.print(",");
  for (int j=0; j < numChannels; j++)                                         //Write the temperature for each channel.
  {
   //Serial.print("tme ");Serial.println(tme);
   //Serial.print("t[");Serial.print(j);Serial.print("] ");Serial.println(t[j]);
   if (t[j] < 0)
   {
    t[j] = 999;
   }
   datafile.print(t[j]); datafile.print(",");
  }
  datafile.println();                                                           //End the record and start a new line for the next readings?
  datafile.close();                                                             //Close the file:
  //Serial.println("...done.");
  //lcd.clear();lcd.setCursor(0,0); lcd.print("Done");
 } 
 else 
 {
  //Serial.println("error opening temp.txt");                                      // if the file didn't open, print an error:
  lcd.clear();lcd.setCursor(0,0); lcd.print("Error Opening Fle");
 }
 return;
}


}

I usually get this when I'm loading stuff onto my Nanos and haven't switched the Build Options to a Nano. You are using an Arduino Uno, correct? If not, in the IDE go to Tools -> Boards -> Your Arduino type. Edit - if I counted correctly, it looks like there is an extra } at the very end of your code.

Here is the complete code:

#include <SPI.h>                             
#include <SD.h>                             
#include <LiquidCrystal.h>                  
const int numChannels = 16;
const byte SSButtonPin = 3;
const byte CDButtonPin = 2;
const int recordLight = A5;
const int rs=A1, en=A2, d4=6, d5=7, d6=8, d7=9; 
const int readTime = 15000; 

int temp[numChannels]; 
int tme;
int flag=0;
int r = 0;
int buttonAction;
int on = 0;
int off = 0;
int cd = 0;
int displayReading = 0;
long int lastDisplay = 0;

unsigned long lastReading = 0;
unsigned long currentReading;
unsigned long startTime;

volatile byte SSflag = 0;
volatile byte CDbuttonPress = 0;
volatile byte SSbuttonPress =0;
volatile byte lastState = 0; 

bool recording = false; // 1 = yes, 0 = no
bool initialReading = true;
bool updateDisplay = false;
bool firstCycle = true;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 
File datafile; 

void setup()
{
 analogReference(DEFAULT); 
 digitalWrite(recordLight, HIGH);  
 Serial.begin(9600); 
  
 lcd.begin(16,2);
 lcd.setCursor(0,0); //
 lcd.print("Init SD card..."); 
  
 if (!SD.begin(10)) // Changed from pin 4 to pin 8. Changed from pin 8 to pin 10
 { 
  lcd.setCursor(0,0);
  lcd.print("SD Init FAILED...");
  while (1);
 }
 lcd.setCursor(0,0);
 lcd.print("SD Init done.");
 
 pinMode(recordLight, OUTPUT);
 pinMode(SSButtonPin, INPUT_PULLUP);
 pinMode(CDButtonPin, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(SSButtonPin), StartStop, RISING);
 attachInterrupt(digitalPinToInterrupt(CDButtonPin), CDISR, RISING);
}


void loop()
{
 if (lastState)
 {
  lastState = 0;
  if (SSbuttonPress == 1)
  {
   SSbuttonPress = 0;  //reset it.
   if (SSflag == 1)        //Are we starting
   {
    //lcd.clear();lcd.setCursor(0,0); lcd.print("Starting ");
    recording = true;
    digitalWrite(recordLight, LOW);  //Turn the recording light on.
    lastReading = millis();
    startTime = millis();
    updateDisplay = millis();
    lastDisplay = millis();
    initialReading = true;
    displayReading = 0;  
   }
   else    
   {
    lcd.clear();lcd.setCursor(0,0); lcd.print("Stopping");
    //Serial.println("stopping");
    digitalWrite(recordLight, HIGH);  //Turn the recording light off.
    recording = false;
   }
  }
 }
 cycleDisplay();
 
 if (millis()-lastDisplay >= 1000)  // Update display every second
 {
  lastDisplay = millis();
  getTemp(temp);
  cycleDisplay(); 
 }
 if (recording)
 {
  //Serial.print("Time since last reading ");Serial.println(millis()-lastReading);
  if(initialReading == true || millis() - lastReading >= readTime) //if its been longer than 15 seconds then we need to take a reading.
  {
   getTemp(temp);   //This will get the data
   updateDisplay = true;
   if (initialReading)
   {
    tme = 0;
    //Serial.print("tme");Serial.println(tme);
   }
   else
   {
    tme = (lastReading - startTime)/1000;        //convert to seconds
    //Serial.print("tme ");Serial.println(tme);
   }
   //lastReading = millis();
   writedata(temp);              //Write the data to the SD card.
   //lastReading = millis();
   initialReading = false;  //this is no longer the initial reading.
  }
 }
}

void getTemp(int * t)
{
 Serial.println("Taking a Reading");
 int numSamples = 10;
 const int analogPin = 0; // replace 0 with analog pin
 const float invBeta = 1.00 / 3950.00;   // replace "Beta" with beta of thermistor
 const  float adcMax = 1023.00;
 const float invT0 = 1.00 / 298.15;   // room temp in Kelvin
 double adcVal[numChannels];
 int adcAvg;
 int i, x, z, A, B, C, D;
 //long int numSamples = 0;
 int  K, DC, F;
 int addressA = A3;      //A3 and A4 were moved from pins 2 and 3. Those pins are needed for interrupts.
 int addressB = A4;    
 int addressC = 4;
 int addressD = 5;
 pinMode(addressA, OUTPUT);
 pinMode(addressB, OUTPUT);
 pinMode(addressC, OUTPUT);
 pinMode(addressD, OUTPUT);
 A = 0;      //Address pin A
 B = 0;      //Address pin B
 C = 0;      //Address pin C
 D = 0;      //Address pin D
 
 for (z=0; z < numChannels; z++)
 {
  //Serial.print("z ");Serial.print(z);Serial.print(" ");
  adcVal[z] = 0;                                         //zero the adcVal array
 }
 //Serial.println();
 for (int y = 1; y <= numSamples; y++) 
 {
  //Serial.print("Reading# ");Serial.println(y);
  for (x = 0; x < numChannels; x++)                   //take a reading for each channel
  {
   A = bitRead(x,0);                                //Take first bit from binary value of x channel.
   B = bitRead(x,1);                                //Take second bit from binary value of x channel.
   C = bitRead(x,2);                                //Take third bit from value of x channel.
   D = bitRead(x,3);                                //Take fourth bit from value of i channel
 
   digitalWrite(addressA, A);
   digitalWrite(addressB, B);
   digitalWrite(addressC, C);
   digitalWrite(addressD, D);
   //delay (1);                                       //Delay a few milliseconds between readings.
                                                                  
   adcVal[x] = adcVal[x] + analogRead(analogPin);    //accumulate the reading for that channel.
   //Serial.print("adcVal[");Serial.print(x);Serial.print("] ");Serial.println(adcVal[x]);
   currentReading = millis();
  } 
 } 
       
 lastReading = millis();                                                   //update last reading to current time.    
    
 for (i=0; i < numChannels; i++)                                           //Now that we have all the readings, let's calculate the temperature for each channel.
 {
  adcVal[i] = adcVal[i]/numSamples;          // get the average reading for this channel.
  
  K = 1.00 / (invT0 + invBeta*(log (adcMax / (float) adcVal[i] - 1.00))); //Calculate the temp in deg Kelvin
  DC = K - 273.15;                      // convert to Celsius
  F = ((9.0*DC)/5.00) + 32.00;   // convert to Fahrenheit
  t[i] = DC;
  //Serial.print (t[i]);Serial.print(" ");
 } 
  //Serial.println();Serial.print("Number of Samples ");Serial.println(numSamples);
 return t;
}

void writedata(int *t)
{
 datafile = SD.open("Temp.txt", FILE_WRITE);                                      //Open file

 if (datafile)                                                                    //If the file opened thene we can write to it.
 {
  //Serial.println("Writing to temp.txt...");
  //lcd.clear();lcd.setCursor(0,0); lcd.print("Writing Data    ");
  datafile.print(tme);datafile.print(",");
  for (int j=0; j < numChannels; j++)                                         //Write the temperature for each channel.
  {
   //Serial.print("tme ");Serial.println(tme);
   //Serial.print("t[");Serial.print(j);Serial.print("] ");Serial.println(t[j]);
   if (t[j] < 0)
   {
    t[j] = 999;
   }
   datafile.print(t[j]); datafile.print(",");
  }
  datafile.println();                                                           //End the record and start a new line for the next readings?
  datafile.close();                                                             //Close the file:
  //Serial.println("...done.");
  //lcd.clear();lcd.setCursor(0,0); lcd.print("Done");
 } 
 else 
 {
  //Serial.println("error opening temp.txt");                                      // if the file didn't open, print an error:
  lcd.clear();lcd.setCursor(0,0); lcd.print("Error Opening Fle");
 }
 return;
}

void cycleDisplay()
{
 if (CDbuttonPress == 1)
 {
  //Serial.println("Cycling Display...");
  displayReading = displayReading + 4;
  if (firstCycle || displayReading > 15)
  {
   displayReading = 0; //reset it. 
   firstCycle = false; //It's no longer the first cycle.
  }
 }
 //LINE 0
 if (updateDisplay || CDbuttonPress == 1)
 {
  CDbuttonPress = 0;      //reset CD button press
  updateDisplay = false;  //reset update display
  lcd.clear();lcd.setCursor(0,0);lcd.print("C");lcd.print(displayReading);lcd.setCursor(3,0);lcd.print(":");lcd.print(temp[displayReading]);
  lcd.setCursor(7,0);lcd.print(" C");lcd.print(displayReading +1);lcd.setCursor(11,0);lcd.print(":");lcd.print(temp[displayReading + 1]);lcd.print(" ");
  //LINE 1
  lcd.setCursor(0,1);lcd.print("C");lcd.print(displayReading + 2);lcd.setCursor(3,1);lcd.print(":");lcd.print(temp[displayReading + 2]);lcd.setCursor(7,1);lcd.print(" C");
  lcd.print(displayReading +3);lcd.setCursor(11,1);lcd.print(":");lcd.print(temp[displayReading + 3]);lcd.print(" ");
 }
return;
}

// ISRs                                                          
void StartStop()
{
 lastState = 1;
 SSbuttonPress = 1;
 CDbuttonPress = 0;
 SSflag = !SSflag;
 return;
}

void CDISR()
{
  lastState = 1;
  CDbuttonPress = 1;
  SSbuttonPress = 0;
  cycleDisplay();
  return;
}

Upon further research, I think it's more likely that it's the incorrect build version. Maybe try the steps suggested in this post. https://forum.arduino.cc/index.php?topic=572746.0

Thanks for your response. I have the correct board selected and I copied the program into Word and counted the braces. Word said I have 28 of each.

Segmentation fault means you are highly skilled at making *nix systems access memory ad infinitum. In perl, this usually meant that you had a functionally recursive piece of code, that (never) terminated. *never is loosely defined.

THIS IS NOT A SYNTAX ERROR which would have been the case if you forgot brackets somewhere.

Try turning "millis()-lastDisplay" into an actual value before you turn it into a quasi-self referencing loop. Something in there somewhere is making the brain think it needs to think again before it's done thinking the first time.

Rl4ndom's suggestion worked like a charm. Thanks! :slight_smile: :slight_smile: :slight_smile: :slight_smile:

The instructions at GCC compiler segmentation fault (?!) - Installation & Troubleshooting - Arduino Forum do work but they are now outdated. Instead of rolling back to Arduino AVR Boards 1.6.21 for a good compiler version, we can now update Arduino AVR Boards to the latest version instead. Much better to use a modern version of the compiler than a super old one. Here are the updated instructions:

  • Tools > Board > Boards Manager
  • Wait for downloads to finish.
  • From the list of available packages, click on “Arduino AVR Boards”.
  • Click "Update".
  • Wait for the update to finish.
  • Click "Close".