0

I recently decided to learn direct port manipulation instead of builtin arduino routines.

First I tried this piece of code

void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("on");
delay(500); 
digitalWrite(LED_BUILTIN, LOW); 
Serial.println("off");
delay(500); 
} 

This program on running instantly established connection with the serial monitor on my arduino IDE.

But when I try this code

int main(void)
{
Serial.begin(9600);
DDRB = B11111111;
while(1)
{
PORTB = PORTB | 0x20;
Serial.println("off");
_delay_ms(500);
PORTB = PORTB & 0xDF;
Serial.println("on");
_delay_ms(500);
}
}

But this program is taking some time, about 5-10 seconds to establish serial connection. Also delay() is not working too. When I use delay() instead of _delay_ms(), the entire arduino board freezes like a computer and stops blinking the LED instead LED is fully ON.

I tried is on several programs, while "setup-loop" program connects instantly, AVR C programs does not.

why does it happen?

asked Aug 9, 2020 at 15:27
3
  • 2
    Because normally main() initializes all the appropriate hardware and timers. You're circumventing that with your own main() so nothing Ardunioy works. Commented Aug 9, 2020 at 15:33
  • I should be most grateful if you could elaborate that in an answer. Commented Aug 9, 2020 at 15:50
  • please indent your code correctly .... beginners that might be browsing the quetions should be exposed to correctly formatted code no matter how simple the code listing is Commented Aug 9, 2020 at 15:58

1 Answer 1

2

By defining your own main() you are circumventing the Arduino startup procedures.

Normally with Arduino code main() first runs an init() function before setup() and (repeatedly) loop(). This init() function will configure, amongst other things, the timer for millis() and delay().

This is the normal main() for a basic AVR-based board:

int main(void)
{
 init();
 initVariant();
#if defined(USBCON)
 USBDevice.attach();
#endif
 
 setup();
 
 for (;;) {
 loop();
 if (serialEventRun) serialEventRun();
 } 
 
 return 0;
}

It first initializes common functions, then board-specific ones (normally nothing), and if applicable, the USB interface (for ATMega32U4 based boards, like the Leonardo).

Only then does it go on to run your sketch.

If you want to use both your own main() and Arduino functions like delay() then you will have to call those initialization routines before running the rest of your code.

answered Aug 9, 2020 at 16:16
7
  • Could you explain the significance of "serialEventRun"? Commented Aug 9, 2020 at 16:45
  • If you haven't defined a serialEvent() function then it has no significance at all. If you have defined one then it runs it. Commented Aug 9, 2020 at 16:53
  • What is the purpose of initVariant()? Commented Aug 9, 2020 at 16:55
  • 1
    That is the bit where I say then board-specific ones (normally nothing) Commented Aug 9, 2020 at 17:03
  • I just rewrote my code to include just init() and nothing else, the serial communication, both read and write, is now working. So my question, is USBDevice.attach() necessary? Commented Aug 9, 2020 at 17:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.