Since I use IDE 1.6.0 I have a problem with my code and I don't understand.
Error:
In function 'void checkTemp()'
internal compiler error: Segmentation fault
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Manchester.h>
#include <stdlib.h>
// #include <Time.h>
// #include <DateTime.h>
// #include <DateTimeStrings.h>
// ADD FOR NRF24L01+
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
// ############ UTILISE POUR RECUPERER VALEUR TEMPERATURE EXTERIEUR ###################
String StrTemperatureExt;
float TemperatureExt;
unsigned long difference=0;
unsigned long difference1;
unsigned long time;
unsigned long time1;
float StrToFloat(String str){
char carray[str.length() + 1]; //determine size of the array
str.toCharArray(carray, sizeof(carray)); //put str into an array
return atof(carray);
}
template <class storageType>
class ValueBuffer
{
public:
ValueBuffer(const int bufferSize, const storageType initValue = 0);
~ValueBuffer();
void operator<<(const storageType input);
storageType operator[](int wantedN) const;
void reset(int resetValue);
private:
const int _bufferSize;
storageType* _buffer;
int _bufferIndex;
};
template <class storageType>
ValueBuffer<storageType>::ValueBuffer(const int bufferSize, const storageType initValue)
:
_bufferIndex(0), _bufferSize(bufferSize)
{
_buffer = (storageType*)calloc(bufferSize, sizeof(storageType));
for (int i = 0; i < bufferSize; i++)
_buffer[i] = initValue;
}
template <class storageType>
ValueBuffer<storageType>::~ValueBuffer()
{
free(_buffer);
}
template <class storageType>
void ValueBuffer<storageType>::operator<<(const storageType input)
{
_buffer[_bufferIndex] = input;
if (_bufferIndex == _bufferSize - 1)
{
_bufferIndex = 0;
}
else
{
++_bufferIndex;
}
}
template <class storageType>
void ValueBuffer<storageType>::reset(int resetValue)
{
for (int i = 0; i < _bufferSize; i++)
_buffer[i] = resetValue;
}
template <class storageType>
storageType ValueBuffer<storageType>::operator[](const int wantedN) const
{
int index = _bufferIndex - 1;
if (index - wantedN >= 0)
{
return _buffer[index - wantedN];
}
else
{
return _buffer[index - wantedN + _bufferSize];
}
}
//start of program
typedef unsigned short recordtype;
//new buffer with 110 items, fill with 0's
ValueBuffer<recordtype> recording(110, 0);
//todo: move temperature to external file/class
//-4.8:010000010010000001000011000
struct temperatureData {
unsigned char checksum : 4;
unsigned char thirdNumber : 4;
unsigned char secondNumber : 4;
unsigned char firstNumber : 3;
unsigned char padding : 1; // not used, could be used for a "-" boolean in the future
};
#define IS_IN_RANGE(var,min,max) (var>min&&var<max)
#define IS_HIGH_PULSE(var) IS_IN_RANGE(var,1250,1600)
#define IS_LOW_SHORT_PULSE(var) IS_IN_RANGE(var,150,540)
#define IS_LOW_LONG_PULSE(var) IS_IN_RANGE(var,1800,2400)
#define SET_BIT(var,bitnum) (*((unsigned long*)&var) |= 1 << bitnum)
#define CLEAR_BIT(var,bitnum) (*((unsigned long*)&var) &= ~(1 << bitnum))
void checkTemp() // ############## RECUPERATION DE LA TEMPERATURE EXTERIEUR
{
if (recording[0] > 5000 && millis() >= difference1)
{
if (IS_HIGH_PULSE(recording[1]) &&
IS_LOW_SHORT_PULSE(recording[2]) &&
IS_HIGH_PULSE(recording[3]))
{
int bitCount = 0;
struct temperatureData receivedTemperature;
//parse the data(from the last pulse to the first pulse)
for (int i = 4; i <= 107 - 15; i += 2) //+2: skip the highs since high pulses don't differ in length
{
if (IS_LOW_LONG_PULSE(recording[i]) && !IS_LOW_SHORT_PULSE(recording[i + 2]))
{
//Serial.print(0);
CLEAR_BIT(receivedTemperature, bitCount);
bitCount++;
}
else if (IS_LOW_LONG_PULSE(recording[i]) &&
IS_LOW_SHORT_PULSE(recording[i + 2]) &&
IS_LOW_SHORT_PULSE(recording[i + 4]) )
{
//Serial.print(1);
SET_BIT(receivedTemperature, bitCount);
bitCount++;
i += 4;
}
else
{
//Serial.print("DC");
//Serial.println(recording[i]);
return;
}
if (bitCount == 15) // we got all the bits (was 15)
{
StrTemperatureExt = "";
// Serial.print("{\"TempExt\":\"");
Serial.print("Temp_Exterieur:");
if (IS_LOW_SHORT_PULSE(recording[i + 8]))
Serial.print('-');
if (receivedTemperature.firstNumber)
StrTemperatureExt.concat((String)receivedTemperature.firstNumber);
StrTemperatureExt.concat((String)receivedTemperature.secondNumber);
StrTemperatureExt.concat('.');
StrTemperatureExt.concat((String)receivedTemperature.thirdNumber);
Serial.println(StrTemperatureExt);
TemperatureExt = StrToFloat(StrTemperatureExt);
i = 999;
time1 = millis();
difference1 = time1 + 10000;
return;
}
}
}
else {
}
}
/* Receipt_data();*/
}
void interruptHandler()
{
static recordtype previousTime = 0;
recordtype currentTime = micros();
recordtype difference = currentTime - previousTime;
if (difference < 100) //filter noise, received signals should never be shorter than 100(in this case...)
return;
recording << difference;
previousTime = currentTime;
checkTemp();
}
void setup() {
//interrupt for receiving the data, connect receiver to pin 2
attachInterrupt(0, interruptHandler, CHANGE);
//attachInterrupt(1,check_state,CHANGE);
//pinMode(13, OUTPUT);
Serial.begin(9600);
difference = millis();
difference1 = millis();
}
void loop()
{
}
I have a problem with my code
And that problem is . . ?
Error:
In function 'void checkTemp()'
internal compiler error: Segmentation fault
It looks like a gcc bug. If you remove the -Os flag (optimize for size) it compiles fine. Not something we can handle, though
Ok, how remove -Os flag ?
thanks
you have to change platform.txt, it's a file that describes how the compiler has to be called
however, the compiled sketch won't probably work as expected, since one of the core files (utils/delay.h) requires optimization to be on
I'll ask my colleague for an advice
Same error after change platform.txt
This is a bug in avr-gcc there is nothing we can do for that (only waiting for avr-gcc developers fix the bug).
Also removing the optimization flag is not going to work, since the delay function rely on that.
@ffissore: the latest avr-gcc shows the same issue?
Yes it does :(
Then No solution for this moment ?
Unfortunately, no. I've opened an issue https://github.com/arduino/Arduino/issues/2639 so we may come back as soon as the issue is solved
Since I use IDE 1.6.0 I have a problem with my code and I don't understand.
Error:
In function 'void checkTemp()'
internal compiler error: Segmentation fault
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Manchester.h>
#include <stdlib.h>
// #include <Time.h>
// #include <DateTime.h>
// #include <DateTimeStrings.h>
// ADD FOR NRF24L01+
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
// ############ UTILISE POUR RECUPERER VALEUR TEMPERATURE EXTERIEUR ###################
String StrTemperatureExt;
float TemperatureExt;
unsigned long difference=0;
unsigned long difference1;
unsigned long time;
unsigned long time1;
float StrToFloat(String str){
char carray[str.length() + 1]; //determine size of the array
str.toCharArray(carray, sizeof(carray)); //put str into an array
return atof(carray);
}
template <class storageType>
class ValueBuffer
{
public:
ValueBuffer(const int bufferSize, const storageType initValue = 0);
~ValueBuffer();
void operator<<(const storageType input);
storageType operator[](int wantedN) const;
void reset(int resetValue);
private:
const int _bufferSize;
storageType* _buffer;
int _bufferIndex;
};
template <class storageType>
ValueBuffer<storageType>::ValueBuffer(const int bufferSize, const storageType initValue)
:
_bufferIndex(0), _bufferSize(bufferSize)
{
_buffer = (storageType*)calloc(bufferSize, sizeof(storageType));
for (int i = 0; i < bufferSize; i++)
_buffer[i] = initValue;
}
template <class storageType>
ValueBuffer<storageType>::~ValueBuffer()
{
free(_buffer);
}
template <class storageType>
void ValueBuffer<storageType>::operator<<(const storageType input)
{
_buffer[_bufferIndex] = input;
if (_bufferIndex == _bufferSize - 1)
{
_bufferIndex = 0;
}
else
{
++_bufferIndex;
}
}
template <class storageType>
void ValueBuffer<storageType>::reset(int resetValue)
{
for (int i = 0; i < _bufferSize; i++)
_buffer[i] = resetValue;
}
template <class storageType>
storageType ValueBuffer<storageType>::operator[](const int wantedN) const
{
int index = _bufferIndex - 1;
if (index - wantedN >= 0)
{
return _buffer[index - wantedN];
}
else
{
return _buffer[index - wantedN + _bufferSize];
}
}
//start of program
typedef unsigned short recordtype;
//new buffer with 110 items, fill with 0's
ValueBuffer<recordtype> recording(110, 0);
//todo: move temperature to external file/class
//-4.8:010000010010000001000011000
struct temperatureData {
unsigned char checksum : 4;
unsigned char thirdNumber : 4;
unsigned char secondNumber : 4;
unsigned char firstNumber : 3;
unsigned char padding : 1; // not used, could be used for a "-" boolean in the future
};
#define IS_IN_RANGE(var,min,max) (var>min&&var<max)
#define IS_HIGH_PULSE(var) IS_IN_RANGE(var,1250,1600)
#define IS_LOW_SHORT_PULSE(var) IS_IN_RANGE(var,150,540)
#define IS_LOW_LONG_PULSE(var) IS_IN_RANGE(var,1800,2400)
#define SET_BIT(var,bitnum) (*((unsigned long*)&var) |= 1 << bitnum)
#define CLEAR_BIT(var,bitnum) (*((unsigned long*)&var) &= ~(1 << bitnum))
void checkTemp() // ############## RECUPERATION DE LA TEMPERATURE EXTERIEUR
{
if (recording[0] > 5000 && millis() >= difference1)
{
if (IS_HIGH_PULSE(recording[1]) &&
IS_LOW_SHORT_PULSE(recording[2]) &&
IS_HIGH_PULSE(recording[3]))
{
int bitCount = 0;
struct temperatureData receivedTemperature;
//parse the data(from the last pulse to the first pulse)
for (int i = 4; i <= 107 - 15; i += 2) //+2: skip the highs since high pulses don't differ in length
{
if (IS_LOW_LONG_PULSE(recording[i]) && !IS_LOW_SHORT_PULSE(recording[i + 2]))
{
//Serial.print(0);
CLEAR_BIT(receivedTemperature, bitCount);
bitCount++;
}
else if (IS_LOW_LONG_PULSE(recording[i]) &&
IS_LOW_SHORT_PULSE(recording[i + 2]) &&
IS_LOW_SHORT_PULSE(recording[i + 4]) )
{
//Serial.print(1);
SET_BIT(receivedTemperature, bitCount);
bitCount++;
i += 4;
}
else
{
//Serial.print("DC");
//Serial.println(recording[i]);
return;
}
if (bitCount == 15) // we got all the bits (was 15)
{
StrTemperatureExt = "";
// Serial.print("{\"TempExt\":\"");
Serial.print("Temp_Exterieur:");
if (IS_LOW_SHORT_PULSE(recording[i + 8]))
Serial.print('-');
if (receivedTemperature.firstNumber)
StrTemperatureExt.concat((String)receivedTemperature.firstNumber);
StrTemperatureExt.concat((String)receivedTemperature.secondNumber);
StrTemperatureExt.concat('.');
StrTemperatureExt.concat((String)receivedTemperature.thirdNumber);
Serial.println(StrTemperatureExt);
TemperatureExt = StrToFloat(StrTemperatureExt);
i = 999;
time1 = millis();
difference1 = time1 + 10000;
return;
}
}
}
else {
}
}
/* Receipt_data();*/
}
void interruptHandler()
{
static recordtype previousTime = 0;
recordtype currentTime = micros();
recordtype difference = currentTime - previousTime;
if (difference < 100) //filter noise, received signals should never be shorter than 100(in this case...)
return;
recording << difference;
previousTime = currentTime;
checkTemp();
}
void setup() {
//interrupt for receiving the data, connect receiver to pin 2
attachInterrupt(0, interruptHandler, CHANGE);
//attachInterrupt(1,check_state,CHANGE);
//pinMode(13, OUTPUT);
Serial.begin(9600);
difference = millis();
difference1 = millis();
}
void loop()
{
}
Is this 1.6.0 official release only problem and /or definitely gcc problem ?
I could try to run in on 1.6.0 Nov 4 build if it would help.
It's a gcc issue
No new solution?
Unfortunately no, there hasn't been a gcc release in the meanwhile
Ok, always the same problem with 1.6.1
have you an idea for the next update of gcc?
I need made an update have you Solution for my problem?
It's not liking the CLEAR_BIT and SET_BIT macros:
#define SET_BIT(var,bitnum) (*((unsigned long*)(&var)) |= 1UL << bitnum)
They ARE a bit "wonky" re-casting the struct to a long. I suspect that the optimizer is putting the struct into registers, and then getting confused when it needs the address (although it shouldn't: registers of an avr do have an address!)
This particular program can be made compilable by adding "static" to the definition of temperatureData in checkTemp:
static struct temperatureData receivedTemperature;
Do the other people having problems have similar code structures?
(it didn't like an assignment to the cast structure either, although that resulted in a different error:)
*(unsigned long *)(&receivedTemperature) = tmp;
I'm not seeing a bug submitted against gcc for this particular code.
I haven't submit error, I don't know make it.
I have make this modification :
#define SET_BIT(var,bitnum) (*((unsigned long*)(&var)) |= 1UL << bitnum)
static struct temperatureData receivedTemperature;
I haven't upload the sketch on arduino uno but I have check the code and this seems ok
alb12 does it compile? or gcc keeps on crashing?
compile is ok
so westfw was right then. thank you :)