element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum arduino .
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 46 replies
  • Answers 10 answers
  • Subscribers 394 subscribers
  • Views 2528 views
  • Users 0 members are here
Related

arduino .

Former Member
Former Member over 9 years ago

can anyone please help me with my arduino codes.

 

I am beginner with arduino. I am writing a code to control my 50hz laser externally. my code needs to be have 2 functions.

1. need to give a continues pulse of 20milliseconds.

2. when i trigger the switch, I should get one single pulse of 20ms with a required delay.

both these pulses are different. but i have tried with some coding. the problem with my code is that when i press the trigger, I will get one single pulse, but it will stop the 1st 50hz continues pulse. @

my codes are given below, If you have any idea can you please help me. also i have given the images from oscilloscope.

 

int button = 4;

 

int out = 12;

int out1 = 8;

int valueout = 0;

int val = 0;

void setup() {

 

pinMode(button, INPUT); 

pinMode(out, OUTPUT);

pinMode(out1, OUTPUT);

}

 

void loop() {

 

{

  digitalWrite(out, HIGH);

  delay(19.6);

  valueout = 1;

  digitalWrite(out, LOW);

  delayMicroseconds(400);

  valueout = 0;

  }

 

  {

val = digitalRead(button);

 

}

 

{

  val = digitalRead(button);

  if (valueout == 0 && val == HIGH){

    delayMicroseconds(1000);

    digitalWrite(out1, HIGH);

    delay(19);

     digitalWrite(out1, LOW);

     delay(1000);}

    else{

      digitalWrite(out1, LOW);}

}

}

Attachments:
image
image
  • Sign in to reply
  • Cancel

Top Replies

  • kulky64
    kulky64 over 9 years ago in reply to Former Member +2 suggested
    ATmega328 has a nice 16-bit Timer/Counter1 with two outputs OC1A and OC1B - exactly what you need. All you have to do is setup some registers and make one or two ISRs.
  • tonyboubady
    tonyboubady over 9 years ago +1 suggested
    We can achieve this with pure code... this is what shabaz said too Just use one delay function in microsecond for base loop, and use variable counter as timers for various purpose. for example... use delayMicroseconds…
Parents
  • kulky64
    0 kulky64 over 9 years ago

    Of course MCU stops generating pulses on first output after pressing the button because he is busy generating pulse (mostly wasting time in delay loops) on the second output. These two processes doesn't run concurrently. You need to use timers and interrupts.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    thank you,

    Can I use Scheduler for this multitasking. or the timer and interrupts are easy

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to Former Member

    int pulse_periodic_50hz = 9;

    int secondpulse = 8;

    int out2 = 2;

     

     

    void setup()  

    {

      pinMode (out2, INPUT);

      pinMode(pulse_periodic_50hz, OUTPUT);

      pinMode(secondpulse, OUTPUT);

      TCCR1A = 0x82;

      TCCR1B = 0x1A;

      ICR1 = 39999;

      OCR1A = 39199;

      OCR1B = 799;

    } 

     

    void loop()  

    { 

    attachInterrupt(0, qswitch, RISING);

    }

     

     

    void qswitch(){

     

     

      digitalWrite(secondpulse, HIGH);

      delayMicroseconds(19000);

       digitalWrite(secondpulse, LOW);

     

     

     

      }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to Former Member

    this is working some how, but how can i adjust the timing of second pulse, how i will adjust the rising and falling time with respect to 1st pulse

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    Try this. Dunno if it works.

    int pulse_periodic_50hz = 9;
    int pulse_20ms = 8;
    int button = 2;
    
    void setup()
    {
      pinMode(pulse_periodic_50hz, OUTPUT);
      pinMode(pulse_20ms, OUTPUT);
      pinMode(button, INPUT);
        
      TCCR1A = 0x82;
      TCCR1B = 0x1A;
      ICR1 = 39999;
      OCR1A = 39199;
      OCR1B = 799;
    }
      
    void loop()
    {
      if(digitalRead(button))
      {
        delay(10);                    // debounce
        while(digitalRead(button));   // wait for release
            
        TIFR1 |= (1<<OCF1B);         // clear OCF1B flag
        while(!(TIFR1&(1<<OCF1B)));   // wait till OCF1B flag is set
            
        digitalWrite(pulse_20ms, HIGH);
        delay(20);
        digitalWrite(pulse_20ms, LOW);
        }
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    second pulse is occurring at the middle of the 1st pulse

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    My fault again. I forgot, that OCF1B is cleared by writing a logic one instead of logic zero. Modify line 25 to:

    TIFR1 |= (1<<OCF1B);

    instead of

    TIFR1 &= ~(1<<OCF1B);

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    Thats works fine, so if i change these

    OCR1A = 39199;

      OCR1B = 799;

    to can change the pulse duration.

    thanks for the code.

     

    I will definitely learn these. its very useful in lab

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    ICR1 register defines frequency of the periodic signal (50Hz in this case).

    OCR1A defines duration in high state and OCR1B delay between rising edge of periodic signal and rising edge of one-shot pulse. Duration of one-shot pulse is defined by delay loop on line 29.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to kulky64

    You can see that ratio

    (1+OCR1A)/(1+ICR1)=0.98 is your duty cycle (and equals 19.6ms / 20ms ).

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    why this ICR1 and OCR1A everything in odd numbers, why you are giving the value  as 40000, 39200, 800

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    Because counter counts from zero to this values. So for example if you count from 0 to 5:

    0, 1, 2, 3, 4, 5

    thats together 6 states.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    Because counter counts from zero to this values. So for example if you count from 0 to 5:

    0, 1, 2, 3, 4, 5

    thats together 6 states.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    can you please tell me why you give ICR1 as 39999 to get 50hz.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    16000000/2*(16 or 8)*50= 20000 or 10000

     

    i didn't understand  how that 40000 comes in the code.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    I got it, the clock is divided by 8 (TCCR1B = 1A)

    so 16000000/50/8 = 40000(0 to 39999)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago in reply to kulky64

    TIFR1 |= (1<<OCF1B);     

    while(!(TIFR1&(1<<OCF1B))); 

     

    I don't understand these two lines.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    Bingo. Output frequency is given by this formula in the datasheet:

    image

    f_clk_IO = 16 MHz

    N = 8 as you already figured out is the prescaler

    TOP is given by value in ICR1 in mode 14 (notice how value in TOP is increased by 1 for reason discussed above, so 39999 is increased to round 40000)

    This gives:

    f_OCnxPWM = 16E+6 / (8*(1+39999)) = 50 Hz

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • kulky64
    0 kulky64 over 9 years ago in reply to Former Member

    The way counter is set up with the prescaler=8, the content of TCNT1 register is incremented every half microsecond ( (16 MHz / 8)^-1 = 0.5us ) and it counts from zero to 39999 and then restarts from zero again. As counter counts, the content of TCNT1 is constanly compared to values in registers OCR1A and OCR1B. When there is compare match between TCNT1 and OCR1A or OCR1B, the corresponding flag (bits OCF1A or OCF1B in TIFR1 register) is set. Normally these flags are used to trigger an interrupt, when corresponing interrupt enable bits in TIMSK1 register are set. OCF1A and OCF1B flags are automatically cleared by hardware when the corresponding ISR is executed. We have set OCR1B = 799, so compare match will occur 0.5us*(1+799) = 400 us after counter rolls over from 39999 to 0. Since we didn't use interrupts in our program, the corresponding OCF1B flag is not automatically cleared by harware every period and is constantly set to 1. Until the button is pressed. Then we clear this flag manually by writing a logical one to it. This is done by this line:

    TIFR1 |= (1<<OCF1B);

    And then we wait until it is set again on the nearest compare match between TCNT1 and OCR1B and we generate our 20 ms pulse.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube