#include freezes program before setup

hello,

"it worked before and i didn't change anything!" here :wink:
anyway, i have a simple sketch for testing. its only job is to let the built in led blink twice a second. works fine but when i add an #include directive it seems like even setup isn't called anymore. when i comment the include out it works fine again. the library and the sketch both compile fine and without any warnings, compiler warnings is set to all.

all the library does is defining two classes, not creating any instances. if the library would be the problem the compiler, linker or something else in the line should throw at least some warnings?
where would i look for the problem?

thanks

edit: Solution: a file in the library folder had an "int main() {}" function. deleting that file solved the problem.

#include <SE019.h>

bool l=false;

uint32_t myFrame=0;

void setup() {  
  Serial.begin(9600);
  Serial.println("Hello Setup!");

  pinMode(LED_BUILTIN, OUTPUT);
  myFrame=0;

  Serial.println("Setup done");
}

void loop() {
  myFrame++;
  
  l=!l;
  if(l==true) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
  
  Serial.print("Ping *");
  Serial.print(myFrame);
  Serial.println("*");

  delay(500);
}
#include <SE019.h>

#include is processed at compile time and should not affect setup

BUT

it depends upon what is in SE019.h which I do not have and which you have not shown.

post SE019.h

gcjr:
post SE019.h

of course, sorry. i know it's quick and dirty but it did the job before it stopped doing it...

here are the headers:

#pragma once

#ifndef SE019_h
#define SE019_h

#ifndef Arduino_h
#include "Arduino.h"
#endif

#ifndef Sample_h
#include "Sample.h"
#endif

// Microphone/Sound Sensor SE019

class SE019
{
public:
	SE019(uint8_t pinDigital, uint8_t pinAnalog, uint16_t sampleSize = 8);
	~SE019();

	void init();

	uint8_t getPinDigital();
	uint8_t getPinAnalog();

	uint16_t getDigitalValue();
	uint16_t getAnalogValue();

	Sample* getLastSample();
	Sample* getCurrentSample();

	uint16_t getSampleSize();

	void tick();

private:
	uint8_t pinDigital;
	uint8_t pinAnalog;

	uint16_t digitalValue;
	uint16_t analogValue;

	Sample *lastSample;
	Sample *currentSample;

	uint16_t sampleSize;
};

#endif

and the sample.h:

#pragma once

#ifndef Sample_h
#define Sample_h

#ifndef Arduino_h
#include "Arduino.h"
#endif

class Sample
{
public:
    Sample(uint16_t sampleSize=8);
	~Sample();

    bool commit(uint16_t value);

    uint16_t getSampleSize();

    uint16_t* getSamples();
    uint16_t getSample(uint16_t idx);

    void compute();
    uint16_t getLevelMin();
    uint16_t getLevelMax();
    uint16_t getLevelAverage();
    unsigned long getTimeLength();

    uint32_t getAmp();

private:
    uint16_t sampleSize;

    uint16_t* samples;
    uint16_t sidx;

    uint16_t levelMin;
    uint16_t levelMax;
    uint16_t levelAvg;

    unsigned long timeStart;
    unsigned long timeEnd;
    unsigned long timeLength;

    uint32_t amp;
};

#endif

can't see problems in the cpp either but here they are.

SE019.cpp:

#ifndef SE019_h
#include "SE019.h"
#endif

SE019::SE019(uint8_t pinDigital, uint8_t pinAnalog, uint16_t sampleSize) {
	this->pinDigital = pinDigital;
	this->pinAnalog = pinAnalog;

	analogValue = 0;
	digitalValue = 0;

	this->sampleSize = sampleSize;
	
	currentSample = NULL;
	lastSample = NULL;
}

SE019::~SE019() {
}

void SE019::init() {
	if (pinDigital != 0) {
		pinMode(pinDigital, INPUT);
	}

	if (pinAnalog != 0) {
		pinMode(pinAnalog, INPUT);
	}
	
	currentSample = new Sample(this->sampleSize);
}

uint8_t SE019::getPinDigital() {
	return pinDigital;
}

uint8_t SE019::getPinAnalog() {
	return pinAnalog;
}

uint16_t SE019::getDigitalValue() {
	return digitalValue;
}

uint16_t SE019::getAnalogValue() {
	return analogValue;
}

Sample* SE019::getLastSample() {
	return lastSample;
}

Sample* SE019::getCurrentSample() {
	return currentSample;
}

uint16_t SE019::getSampleSize() {
	return sampleSize;
}

void SE019::tick() {
    uint32_t r = analogRead(pinAnalog);
    
	if (currentSample->commit(r) == true) {
		if (lastSample != 0) {
			delete(lastSample);
		}

		lastSample = currentSample;
		currentSample = new Sample(sampleSize);
	}
}

and the sample.cpp

#ifndef Sample_h
#include "Sample.h"
#endif

Sample::Sample(uint16_t sampleSize) {
    this->sampleSize = sampleSize;
    samples = new uint16_t[sampleSize];

    sidx = 0;

    levelMin = 0;
    levelMax = 0;
    levelAvg = 0;

    timeStart = 0;
    timeEnd = 0;
    timeLength = 0;

    amp = 0;
}

Sample::~Sample() {
    delete [] samples;
}

void Sample::compute() {
    timeLength = timeEnd - timeStart;

    levelMax = 0;
    levelMin = 65535;

    levelAvg = samples[0];

    if (samples[0] > levelMax) {
        levelMax = samples[0];
    }

    if (samples[0] < levelMin) {
        levelMin = samples[0];
    }

    for (uint16_t i = 1; i < sampleSize; i++) {
        levelAvg = (levelAvg + samples[i]) / 2;

        if (samples[i] > levelMax) {
            levelMax = samples[i];
        }

        if (samples[i] < levelMin) {
            levelMin = samples[i];
        }
    }

    amp = levelMax - levelMin;
}

uint32_t Sample::getAmp() {
    return amp;
}

unsigned long Sample::getTimeLength() {
    return timeLength;
}

uint16_t Sample::getLevelMin() {
    return levelMin;
}

uint16_t Sample::getLevelMax() {
    return levelMax;
}

uint16_t Sample::getLevelAverage() {
    return levelAvg;
}

uint16_t Sample::getSampleSize() {
    return sampleSize;
}

uint16_t* Sample::getSamples() {
    return samples;
}

uint16_t Sample::getSample(uint16_t idx) {
    if (idx >= sampleSize) {
        return 0;
    }

    return samples[idx];
}

bool Sample::commit(uint16_t value) {
    if (sidx >= sampleSize) {
        sidx = 0;
        timeEnd = millis();

        compute();

        return true;
    }

    if (sidx == 0) {
        timeStart = millis();
    }

    samples[sidx] = value;
    sidx++;

    return false;
}

the #include for the arduino.h links in visual studio to a wrapper i made so i can see if compilation works. but it's not copied to the arduino library folder. tests have shown that this include is just ignored by the arduino ide. if i understood right the ide includes the native arduino.h by default so it's ignored because of the #ifndef.

thanks for the help

This will surely get you into trouble if samples has not actually been allocated:

    delete [] samples;

And, since you never check to see if the new actually succeeded....

Giving a function argument the same name as a member variable in the same scope is a terrible practice. Re-name one or the other, and get rid of all the "this->".

RayLivingston:
This will surely get you into trouble if samples has not actually been allocated:

    delete [] samples;

And, since you never check to see if the new actually succeeded....

thanks, i will certainly have take a look on that.

Giving a function argument the same name as a member variable in the same scope is a terrible practice. Re-name one or the other, and get rid of all the "this->".

know what's funny? when i just started i learned it like that from books but someone said the same about your proposed style, back in the days it was on freenode. are there good reasons or is it just taste?

but both doesn't seem to be related to why the program freezes my arduino even before setup when all i do is #include'ing the file?

frozenrat:
where would i look for the problem?

Build with the include. How much program storage space and dynamic (sic) memory is used?

Build without the include. How much program storage space and dynamic (sic) memory is used?

If the program storage space values are different then the source code you posted is not the source code used to build your application.

If the dynamic (sic) memory values are different then the source code you posted is not the source code used to build your application.

without the include:
Sketch uses 2234 bytes (6%) of program storage space. Maximum is 32256 bytes.
Global variables use 223 bytes (10%) of dynamic memory, leaving 1825 bytes for local variables. Maximum is 2048 bytes.

and with the include it's:
2332 bytes (7%) / 297 bytes (14%)

also the exported binaries differ.

so how do i make sure arduino uses the code i feed to it?

frozenrat:
so how do i make sure arduino uses the code i feed to it?

You're asking the wrong question. The compiler is not an imp messing with you.

The question to ask is "How many copies of Sample.cpp are on my computer?" Repeat that question for the other three files.

i downloaded your files: Fro.ino, sample.cpp sample.h se019.h se019.cpp.

i changed the '#include <se019.h>' to '#include "se019.h', and i see output

Hello Setup!
Setup done
Ping *1*
Ping *2*
Ping *3*
Ping *4*
Ping *5*
Ping *6*
Ping *7*

[quote author=Coding Badly date=1612256120 link=msg=4882020]
You're asking the wrong question. The compiler is not an imp messing with you.

The question to ask is "How many copies of Sample.cpp are on my computer?" Repeat that question for the other three files.[/quote]
it is! it does! well, maybe not an imp but a demon! if it would just do as i say there would be only two copies, one in my visual studio directory and one in my arduino lib. but i discovered the arduino IDE messes it all up, saving different versions in many places, uses caches or not or maybe, ... short: i would consider this the behaviour of a demon! and scientifically... considering how complex computers are these days it can't be finally proven that there aren't some demons in the system :smiley:

anyway, i found the problem. my library has a file with an int main() {} (sic! without any return, neither visual studio nor arduino complained about the lack of the return...) but that function seemed to have overwritten some other main and since it's empty it gave the board some free time.

next questions: what exactly was overwritten and why didn't the arduino IDE complain about that? and why was that .cpp file used at all while i never included it anywhere? how do arduino libraries work, like what and how is processed of them? does arduino just swallow and compile the whole folder when i use just a single file or two??

frozenrat:
...what exactly was overwritten...

frozenrat:
...and why didn't the arduino IDE complain about that?

Why would it? You provided a strong linkage main. The linker is just doing what linkers do: favouring strong linkage over weak.

frozenrat:
...and why was that .cpp file used at all while i never included it anywhere?

You did. The IDE, by design, compiles all source files in a library then uses all the resultant object files when linking.

frozenrat:
...does arduino just swallow and compile the whole folder when i use just a single file or two??

Yes.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.