I have #include <Arduino.h>
at the top of my main file, but when I make a call delay(1000)
in my code, it just freezes at that point.
The exact same code works in the Arduino IDE, so maybe the Arduino framework isn’t linking properly? What makes it weirder is that Serial.print(...)
works just fine!
Does anyone know if I need to explicitly link against the Arduino framework or something?
It does work for me, so please share the minimal code snippet that demonstrates the problem, including platformio.ini
file.
Platform.ini
:
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
Code snippet:
#include <Arduino.h>
int main(void)
{
Serial.begin(9600);
while (1)
{
Serial.print("hi\n");
delay(1000);
}
}
"hi"
only prints one time when I monitor it using the Serial Monitor in VS Code. When I run the exact same code in Arduino IDE however, it prints "hi"
once every second as expected.
UPDATE: I updated Platform.ini
(specifically the env
parameter) to look like this:
[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
And I still get the same issue that delay()
just freezes the program…
The [env:nanoatmega328] just gives a name to your environment definition and has no impact on the actual configuration. The environment name just has to be unique across your platform.ini file as soon as there would be more than one environment definiton.
Since you are using the Arduino framework I suspect having a main function is not a good idea.
The Arduino framework just implements the main function behind the scenes and calls the setup() and loop() functions in your sketch / platformio main source file:
int main(void)
{
setup();
while (1)
{
loop();
}
}
So you just have to implement a setup() and a loop() function:
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print("hi\n");
delay(1000);
}
1 Like
The above post is right. Do not overwrite the main
function if you don’t need to.
There is more to the main()
function: It initializes the Timer0
of the ATMega328P. This will cause an ISR to be called every millisecond which will update the elapsed milliseconds variable.
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
void init()
{
// this needs to be called before setup() or some functions won't
// work there
sei();
// on the ATmega168, timer 0 is also used for fast hardware pwm
// (using phase-correct PWM would mean that timer 0 overflowed half as often
// resulting in different millis() behavior on the ATmega8 and ATmega168)
#if defined(TCCR0A) && defined(WGM01)
sbi(TCCR0A, WGM01);
sbi(TCCR0A, WGM00);
#endif
// set timer 0 prescale factor to 64
#if defined(__AVR_ATmega128__)
// CPU specific: different values for the ATmega128
sbi(TCCR0, CS02);
#elif defined(TCCR0) && defined(CS01) && defined(CS00)
// this combination is for the standard atmega8
sbi(TCCR0, CS01);
sbi(TCCR0, CS00);
#elif defined(TCCR0B) && defined(CS01) && defined(CS00)
// this combination is for the standard 168/328/1280/2560
sbi(TCCR0B, CS01);
sbi(TCCR0B, CS00);
#elif defined(TCCR0A) && defined(CS01) && defined(CS00)
// this combination is for the __AVR_ATmega645__ series
sbi(TCCR0A, CS01);
sbi(TCCR0A, CS00);
#else
#error Timer 0 prescale factor 64 not set correctly
#endif
//lots of more stuff
}
If you overwrite main
but don’t set that timer, you will hang up on a delay
call because there is no timer set-up to update the ellapsed millisecond. It just waits there forever.
1 Like