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?

  • 2
    Because normally main() initializes all the appropriate hardware and timers. You're circumventing that with your own main() so nothing Ardunioy works. – Majenko Aug 9 at 15:33
  • I should be most grateful if you could elaborate that in an answer. – ASWIN VENU Aug 9 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 – jsotola Aug 9 at 15:58
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.

| improve this answer | |
  • Could you explain the significance of "serialEventRun"? – ASWIN VENU Aug 9 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. – Majenko Aug 9 at 16:53
  • What is the purpose of initVariant()? – ASWIN VENU Aug 9 at 16:55
  • 1
    That is the bit where I say then board-specific ones (normally nothing) – Majenko Aug 9 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? – ASWIN VENU Aug 9 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.