Online compiler - is it a bug or a feature

Hi all Sakura owners (all 3 and half of you),


I'm sure you all "like" the online compiler same as I do. But still, it's good enough for beginners. And I'm not a professional programmer.

Recently I've discovered one thing which is confusing me in this compiler, here's the description.

So, you know, new v2.0 template for Sakura allows you to use all the Arduino code with only minimal changes. For example, this UDP NTP client project works just fine: http://arduino.cc/en/Tutorial/UdpNtpClient

To illustrate the bug in the online compiler, let's do the following:

1) cut off serial and all we don't need

2) enable LED0 to signal when UDP packet is received

Then the main looks like that:

void loop(){

     sendNTPpacket(timeServer); // send an NTP packet to a time server
     delay(1000);
     
     if ( Udp.parsePacket() ) {     // We've received a packet, read the data from it       
            Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
            digitalWrite (PIN_LED0, HIGH);
       }

}

And it works just fine (all the rest like setup() is the same as on that Arduino page except no serial). After several packets sent, NTP server answers, LED0 is shinning, everyone is happy.

Then, if we don't need that loop to turn forever, only till we get the time and then do some other stuff (light on LED1, for example), the code will be changed:

int x=1;  //Yes, I know global variables are bad, but for now on it's OK

void loop(){

    while (x){

         sendNTPpacket(timeServer); // send an NTP packet to a time server
         delay(1000);
     
         if ( Udp.parsePacket() ) {  
               // We've received a packet, read the data from it
               Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
               digitalWrite (PIN_LED0, HIGH);
              x=0; // With x=0 we now should escape the while loop
       }

   //     Now let's do some other stuff

    digitalWrite (PIN_LED1, HIGH);

   }

}

Of course, setup should enable both LED0 and 1 as outputs.

And.... This doesn't work! The NTP answer is never received. The thing is just sending requests forever with no answer.

Let's simplify it even more: add forever while loop inside the void loop(), theoretically that should change nothing, void loop() is already a forever-turning loop. Here's the code:

void loop(){

    while (1){

         sendNTPpacket(timeServer); // send an NTP packet to a time server
         delay(1000);
     
         if ( Udp.parsePacket() ) {  
               // We've received a packet, read the data from it
               Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
               digitalWrite (PIN_LED0, HIGH);
              x=0; // With x=0 we now have to escape the while loop
       }

   }

}

And... It doesn't work! The only change with working version - added while(1){} forever loop with all the code inside.

The bug is that void loop(){ //code// } is not working the same way as void loop(){ while(1){ //code// }} though it should.

Any ideas, what could be wrong here?

Thanks in advance,

Ivan

Parents
  • Hi Ivan,

    This is not a bug nor a feature. And loop(){} is different to loop(){while(1){}}.

    The Arduino do some hidden step to build the program.

    Arduino code is actually a C program. And of course the main() function is the entry point.

    You can image the setup() and loop() function will be called from the main() function.

    Something like this (Not really but nearly):

    void main(void)

    {

       /* Hardware initialization */

       ...

       /* Now setup() is called */

       setup();

       /* Main loop */

       while (1)

      {

           /* some pre-process first, serial e.g */

           ...

           /* Then call loop() function */

           loop();

           /* Some other post process */

           ...

      }

    }


    In case of GR-SAKURA, it does some processes for serial and net service after the loop() is called inside the main loop.

    If you just put an infinite while loop inside the loop() function, the serial and ethernet driver will not work properly.

    You can take yourself a look at Arduino main.c source code for this. It is located under:

    Arduino\hardware\arduino\cores\arduino\main.cpp

    ------------------

    #include <Arduino.h>

    int main(void)
    {
        init();

    #if defined(USBCON)
        USBDevice.attach();
    #endif
       
        setup();
       
        for (;;) {
            loop();
            if (serialEventRun) serialEventRun();
        }
           
        return 0;
    }

    ------------------

    You can see that serial will not run properly if an infinite while loop is put inside the loop() function since the serialEventRun() process is never be called.

    Hope this is helpful.

    Best regards,

    Khanh

Reply
  • Hi Ivan,

    This is not a bug nor a feature. And loop(){} is different to loop(){while(1){}}.

    The Arduino do some hidden step to build the program.

    Arduino code is actually a C program. And of course the main() function is the entry point.

    You can image the setup() and loop() function will be called from the main() function.

    Something like this (Not really but nearly):

    void main(void)

    {

       /* Hardware initialization */

       ...

       /* Now setup() is called */

       setup();

       /* Main loop */

       while (1)

      {

           /* some pre-process first, serial e.g */

           ...

           /* Then call loop() function */

           loop();

           /* Some other post process */

           ...

      }

    }


    In case of GR-SAKURA, it does some processes for serial and net service after the loop() is called inside the main loop.

    If you just put an infinite while loop inside the loop() function, the serial and ethernet driver will not work properly.

    You can take yourself a look at Arduino main.c source code for this. It is located under:

    Arduino\hardware\arduino\cores\arduino\main.cpp

    ------------------

    #include <Arduino.h>

    int main(void)
    {
        init();

    #if defined(USBCON)
        USBDevice.attach();
    #endif
       
        setup();
       
        for (;;) {
            loop();
            if (serialEventRun) serialEventRun();
        }
           
        return 0;
    }

    ------------------

    You can see that serial will not run properly if an infinite while loop is put inside the loop() function since the serialEventRun() process is never be called.

    Hope this is helpful.

    Best regards,

    Khanh

Children
No Data