Announcement

Collapse
No announcement yet.

Arduino code learning

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Arduino code learning

    I didn't know how properly to name this topic...
    Ok, i am still novice in programming the AVR's this way.
    I am using Arduino and C++ programming because it's much easier for a starter.
    So i am trying various methods of coding to see the advantages and disadvantages of various approaches.
    I came across this interesting thing and am pretty confused with it.
    There are two codes here doing practically the very same basic thing; flashing the LED diode.
    Yet! The first one is working in proper timings and LED flashes to correct rate, while the second one seems somehow corrupts the timings and LED flashes at somewhat slower rate!??
    How can it be? What i am missing here?

    First one:

    Code:
    void setup() 
    {  
      pinMode(LED_BUILTIN, OUTPUT);
    }
    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);  
      delay(100);                      
      digitalWrite(LED_BUILTIN, LOW);   
      delay(100);                       
    }
    Second one:

    Code:
    volatile byte state = HIGH;
    void setup() 
    {
        pinMode(LED_BUILTIN, OUTPUT);
    }
    void loop() {
      digitalWrite(LED_BUILTIN, state);  
      delay(100);                      
      state = !state;  
      delay(100);                       
    }

    My main aim is to examine the behavior (accuracy and speed) when global variable is pulled out of RAM instead out of register.
    Obviously something is going wrong and corrupts the timings, what?


  • #2
    If i strip the second delay:

    Code:
    [COLOR=#333333]volatile byte state = HIGH;
    [/COLOR]void setup() 
    {
        pinMode(LED_BUILTIN, OUTPUT);
    }
    void loop() {
      digitalWrite(LED_BUILTIN, state);  
      delay(100);                      
      state = !state;  
      // [U][B][COLOR=#ff0000]delay(100);[/COLOR][/B][/U]                      
    [COLOR=#333333]}[/COLOR]
    Everything comes on the place.
    Question is why?
    What takes the extra time comparing to first code?

    Comment


    • #3
      Originally posted by ivconic View Post
      I didn't know how properly to name this topic...
      Ok, i am still novice in programming the AVR's this way.
      I am using Arduino and C++ programming because it's much easier for a starter.
      So i am trying various methods of coding to see the advantages and disadvantages of various approaches.
      I came across this interesting thing and am pretty confused with it.
      There are two codes here doing practically the very same basic thing; flashing the LED diode.
      Yet! The first one is working in proper timings and LED flashes to correct rate, while the second one seems somehow corrupts the timings and LED flashes at somewhat slower rate!??
      How can it be? What i am missing here?

      First one:

      Code:
      void setup() 
      {  
        pinMode(LED_BUILTIN, OUTPUT);
      }
      void loop() {
        digitalWrite(LED_BUILTIN, HIGH);  
        delay(100);                      
        digitalWrite(LED_BUILTIN, LOW);   
        delay(100);                       
      }
      Second one:

      Code:
      volatile byte state = HIGH;
      void setup() 
      {
          pinMode(LED_BUILTIN, OUTPUT);
      }
      void loop() {
        digitalWrite(LED_BUILTIN, state);  
        delay(100);                      
        state = !state;  
        delay(100);                       
      }

      My main aim is to examine the behavior (accuracy and speed) when global variable is pulled out of RAM instead out of register.
      Obviously something is going wrong and corrupts the timings, what?


      In the second code, remove the second delay because you're delaying twice with the LED pin in the same state.

      Code:
      volatile byte state = HIGH;
      void setup() 
      {
          pinMode(LED_BUILTIN, OUTPUT);
      }
      void loop() {
        digitalWrite(LED_BUILTIN, state);  
        delay(100);                      
        state = !state;                   
      }

      Comment


      • #4
        Originally posted by ivconic View Post
        What takes the extra time comparing to first code?
        Although the variable "state" is changed the output pin is not. The instruction "state = !state;" does not write the new state to the LED output pin, you must use digitalWrite().

        The code "delay(100); state = !state; delay(100)" applies twice a 100 delay with the LED pin in the same state.

        Comment


        • #5
          Originally posted by Teleno View Post
          Although the variable "state" is changed the output pin is not. The instruction "state = !state;" does not write the new state to the LED output pin, you must use digitalWrite().

          The code "delay(100); state = !state; delay(100)" applies twice a 100 delay with the LED pin in the same state.
          Correct!
          Logical mistake!

          Comment


          • #6
            Originally posted by Teleno View Post
            ...you must use digitalWrite()...

            Actually it was unfortunate choice that i made; to use flashing LED as "indicator" when examining quite different thing ...
            A Murphy strikes again!
            I am examining use of global variables separately taken from RAM and from registers while there is interrupt involved in overall timings.
            Obviously it would not be any problem... i have only to pay attention on "logical thinking" more in future!
            BTW...
            Here is little example of something which i will try to evolve further.
            Again; LED example is only there so loop not to stay empty.


            Code:
            #include "TimerOne.h"
            volatile int pps=1666; 
            volatile byte state = HIGH;
            void setup()
            {
              Timer1.initialize(); 
              Timer1.attachInterrupt(pwm_ic01);
              pinMode(LED_BUILTIN, OUTPUT); 
            }
            void loop()
            {
             digitalWrite(LED_BUILTIN, state);  
             delay(100);                     
             state = !state; 
            }
            void pwm_ic01(void)
            {
              Timer1.pwm( 9, 256, pps); // 25% duty cycle
              Timer1.pwm(10, 512, pps); // 50% duty cycle
            }

            Comment


            • #7
              I bought a couple of Nano's and Uno's two months ago and still trying to Wrap my brain around what they can and can't do. They sure seem limited on doing Voltage Measurements yet can do stuff like Frequency quite well.

              Comment


              • #8
                Originally posted by homefire View Post
                I bought a couple of Nano's and Uno's two months ago and still trying to Wrap my brain around what they can and can't do. They sure seem limited on doing Voltage Measurements yet can do stuff like Frequency quite well.
                Yes they can do much things very well. But most significant thing is compatibility. Once you evolve good code; you can migrate it to more powerful platform.
                However that will need more advance C programming, use of classes and global definitions. Exactly for the reason of compatibility.
                In previous example above i examined behavior of global variables, exactly for the same reason.
                The other day i got two Pro Micros with Atmega32U4. Now i have several Mini Pro's, Nano's, Mega's and those two 32U4's too.
                Also i have one Particle Photon. Pretty nice thing. WiFi ready, standalone. Can do lot of stuff. Already made local server on it.

                Comment


                • #9
                  now for a bit of fun you should convert the code for direct port manipulation and compare the two running and see what you think

                  Comment


                  • #10
                    Code:
                    int Coil =  13;      // the number of the Coil pin
                    // diode erray
                    int D1 = 2;
                    int D2 = 3;
                    int D3 = 4;
                    int D4 = 5;
                    int D5 = 6;
                    int D6 = 7;
                    int D7 = 8;
                    
                    int CoilState = LOW;
                    unsigned long pMicros = 0;
                    long OnTime = 150;           // micro_seconds of on-time
                    long OffTime = 5000;          // micro_seconds of off-time
                    
                    int analogPin = 0;   //Analog pin to read
                    int Maxval = 0;
                    int val = 0;
                    
                    int calibrate = 0;
                    bool set_calabration = false;
                    
                    void setup() 
                    {
                      pinMode(Coil, OUTPUT);
                      
                      pinMode(D1, OUTPUT);
                      pinMode(D2, OUTPUT);
                      pinMode(D3, OUTPUT);
                      pinMode(D4, OUTPUT);
                      pinMode(D5, OUTPUT);
                      pinMode(D6, OUTPUT);
                      pinMode(D7, OUTPUT);
                      
                      Serial.begin(9600);
                    }
                     
                    void loop()
                    {
                      /////////////////////////////////////////////////////////////////
                      // coil switch
                      unsigned long cMicros = micros();
                      if((CoilState == HIGH) && (cMicros - pMicros >= OnTime))
                      {
                        CoilState = LOW;
                        pMicros = cMicros;
                        digitalWrite(Coil, CoilState);
                      }
                      else if ((CoilState == LOW) && (cMicros - pMicros >= OffTime))
                      {
                        CoilState = HIGH;
                        pMicros = cMicros;
                        digitalWrite(Coil, CoilState);
                      }
                      ///////////////////////////////////////////////////////////////////
                      // clabration cycle
                      if( calibrate < 100 && set_calabration == false )
                      {
                        if( val > Maxval)
                        {
                          Maxval = val;
                        }
                        calibrate+=1;
                      } else if( set_calabration == false ) set_calabration=true;
                      
                      ///////////////////////////////////////////////////////////////////
                      // when setting the on/off state use 1023 - val and divide by 7, the val + is to account for coil recovery
                      val = analogRead(analogPin);
                      if( (val+200) < Maxval )
                      {
                        if( val > 100 ) {digitalWrite(D1, HIGH);} else if ( val < 50 ){ digitalWrite(D1, LOW);}
                        if( val > 200 ) {digitalWrite(D2, HIGH);} else if ( val < 100 ){ digitalWrite(D2, LOW);}
                        if( val > 300 ) {digitalWrite(D3, HIGH);} else if ( val < 200 ){ digitalWrite(D3, LOW);}
                        if( val > 400 ) {digitalWrite(D4, HIGH);} else if ( val < 300 ){ digitalWrite(D4, LOW);}
                        if( val > 500 ) {digitalWrite(D5, HIGH);} else if ( val < 400 ){ digitalWrite(D5, LOW);}
                        if( val > 600 ) {digitalWrite(D6, HIGH);} else if ( val < 500 ){ digitalWrite(D6, LOW);}
                        if( val > 800 ) {digitalWrite(D7, HIGH);} else if ( val < 600 ){ digitalWrite(D7, LOW);}
                      }
                    }
                    this is what im using just now for testing it basic just to get it running, but it will show you the basic to get you started

                    Comment


                    • #11
                      Originally posted by c_batchelar View Post
                      now for a bit of fun you should convert the code for direct port manipulation and compare the two running and see what you think
                      Yes i tried that. Funny thing that i noticed on scope; direct port manipulation sometimes causes pretty noisy output, depending on settled params.
                      Looks like quite different timings involved!? (still novice)
                      ...
                      Not directly related to this topic, but...
                      The other day i got two "blue pills" with stm32f103c8t6 controller.
                      I can't make it flash through USB and Arduino IDE, despite the numerous hints and tips i founded over the net.
                      Flashing previously compiled bin through uart works quite smooth though.
                      So it is doable through uart.
                      Yet i am confused about one more thing; simple blink sketch previously successfully compiled in Arduino IDE (STM32_master properly installed) and later flashed through uart and with Demonstrator GUI; is not blinking!?
                      I assume it's because bootloader is erased in process of flashing blink.hex.
                      Meaning further that it will not run with bare sketch code and without bootloader.
                      Why? How come?
                      Arduino UNO (Atmega328P) will run the same; flashed sketch with or without bootloader included.
                      Something i am missing here...

                      Comment


                      • #12
                        Pre-formulated question would be;
                        how to include basic bootloader in custom code?
                        Fer example; i write blink code and want to run it on blue pill.
                        How to make it work?
                        So far it is not working.
                        But "generic_boot20_pc13.bin" i got already compiled from a library; is working just fine.
                        WTF?!
                        I also tried DSO138 compiled hex, flashed it successfully and according to led behavior (still hooked nothing else on it) seems it is working just fine and smooth.
                        What i am missing here damn!?
                        How to make simple blink to work?

                        Comment


                        • #13
                          https://www.youtube.com/watch?v=B4ZqeHZicnw
                          this is the problems you get without direct access or the serial port is not fast enough, my program starts to detect when it drops off you will notice it will not detect till the wave is stretched out, it should be detecting when the spike starts to rise but it is totally missing it out, mind you its the first time i have messed about with a arduino so hopefully direct access will fix it

                          Comment


                          • #14
                            What is this code associated with ?

                            Comment


                            • #15
                              Originally posted by kosacid View Post
                              Code:
                              int Coil =  13;      // the number of the Coil pin
                              // diode erray
                              int D1 = 2;
                              int D2 = 3;
                              int D3 = 4;
                              int D4 = 5;
                              int D5 = 6;
                              int D6 = 7;
                              int D7 = 8;
                              
                              int CoilState = LOW;
                              unsigned long pMicros = 0;
                              long OnTime = 150;           // micro_seconds of on-time
                              long OffTime = 5000;          // micro_seconds of off-time
                              
                              int analogPin = 0;   //Analog pin to read
                              int Maxval = 0;
                              int val = 0;
                              
                              int calibrate = 0;
                              bool set_calabration = false;
                              
                              void setup() 
                              {
                                pinMode(Coil, OUTPUT);
                                
                                pinMode(D1, OUTPUT);
                                pinMode(D2, OUTPUT);
                                pinMode(D3, OUTPUT);
                                pinMode(D4, OUTPUT);
                                pinMode(D5, OUTPUT);
                                pinMode(D6, OUTPUT);
                                pinMode(D7, OUTPUT);
                                
                                Serial.begin(9600);
                              }
                               
                              void loop()
                              {
                                /////////////////////////////////////////////////////////////////
                                // coil switch
                                unsigned long cMicros = micros();
                                if((CoilState == HIGH) && (cMicros - pMicros >= OnTime))
                                {
                                  CoilState = LOW;
                                  pMicros = cMicros;
                                  digitalWrite(Coil, CoilState);
                                }
                                else if ((CoilState == LOW) && (cMicros - pMicros >= OffTime))
                                {
                                  CoilState = HIGH;
                                  pMicros = cMicros;
                                  digitalWrite(Coil, CoilState);
                                }
                                ///////////////////////////////////////////////////////////////////
                                // clabration cycle
                                if( calibrate < 100 && set_calabration == false )
                                {
                                  if( val > Maxval)
                                  {
                                    Maxval = val;
                                  }
                                  calibrate+=1;
                                } else if( set_calabration == false ) set_calabration=true;
                                
                                ///////////////////////////////////////////////////////////////////
                                // when setting the on/off state use 1023 - val and divide by 7, the val + is to account for coil recovery
                                val = analogRead(analogPin);
                                if( (val+200) < Maxval )
                                {
                                  if( val > 100 ) {digitalWrite(D1, HIGH);} else if ( val < 50 ){ digitalWrite(D1, LOW);}
                                  if( val > 200 ) {digitalWrite(D2, HIGH);} else if ( val < 100 ){ digitalWrite(D2, LOW);}
                                  if( val > 300 ) {digitalWrite(D3, HIGH);} else if ( val < 200 ){ digitalWrite(D3, LOW);}
                                  if( val > 400 ) {digitalWrite(D4, HIGH);} else if ( val < 300 ){ digitalWrite(D4, LOW);}
                                  if( val > 500 ) {digitalWrite(D5, HIGH);} else if ( val < 400 ){ digitalWrite(D5, LOW);}
                                  if( val > 600 ) {digitalWrite(D6, HIGH);} else if ( val < 500 ){ digitalWrite(D6, LOW);}
                                  if( val > 800 ) {digitalWrite(D7, HIGH);} else if ( val < 600 ){ digitalWrite(D7, LOW);}
                                }
                              }
                              this is what im using just now for testing it basic just to get it running, but it will show you the basic to get you started





                              What is this code associated with ?

                              Comment

                              Working...
                              X