Announcement

Collapse
No announcement yet.

help required related to pulse generation.

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

  • help required related to pulse generation.

    Hello everyone
    I am currently working on a metal detector in which I want to convert all PWM/pulses generated by different timing ICs in an analog circuit and replace them all with a microcontroller. For this purpose I am using atmega328p for now. I have replicated couple of pulses but the only problem I am facing with these pulses. when the CLK pulse turns off immediately the MOSFET pulse should turn on as shown in (clk and mosfet.jpeg).but my pulses generated using atmega have all parameters same, everything is good except this problem I am having 10us-12us delay between pulses as shown in (clk and mosfet 2.jpeg).

    These are pulses I am trying to generate
    1)clk ("ON" time 84us and period is variable min 8.10ms and max 10.73ms)
    2)MOSFET pulse (Pulse delay reference to clk is 0 when clk ends the mosfet pulse should appear immediately as shown in (clk and mosfet.jpeg) and "ON" time is variable min is 110us and max is 454us)
    3)Delay pulse (pulse delay reference to mosfet pulse is variable min is 50us and max is 131us and "ON" time is 50us)
    4)ground balance pulse (pulse delay reference to "DELAY pulse" is variable min is 120us and max is 960us and "ON" time is 50us)

    Right now I have only generated clk and mosfet but I am trying to rectify this issue first and then move forward.



    Code:
    //assigning pinsconst byte clk = 3;
    const byte mosfet = 5;
    //const byte delaypin = 6;
    //const byte groundB_pin = 9;
    const byte clk_pot = A0;
    //const byte mosfet_pot = A1;
    //const byte delay_pot = A2;
    //const byte groundB_pot = A3;
    
    
    //constants
    
    
    const float clockcycle = 62.5E-9; //one clock cycle time (1/16Mhz)62.5nS
    const unsigned long maxcount = 65535; // value of 2^16-1
    const float prescalar = 8.0;
    const byte readsettinglimit =25;
    const byte clkon = HIGH;
    const byte clkoff = LOW;
    const byte mosfeton = HIGH;
    const byte mosfetoff =  LOW;
    
    
    //value to multiply pot with to achieve desired timing
    const float clk_multiply_value = 41.2;  
    const float  mosfet_multiply_value = 5.3764;
    
    
    
    
    
    
    //setting timings
    float clk_on_time = 84E-6;                                      //84us is clk "ON" time 
    float mosfet_pulse_delay =0;                                 //mostfet delay reference to clk 
    float mosfetdefault_on_time = 110E-6;                         // 110us on time on lowest value of POT
    float mosfet_on_time = mosfetdefault_on_time;               // variable from POT
    float clkperiod_default = 8.10E-3;                    //8.10mS
    float clk_period = clkperiod_default ;              //varibale from POT
    
    
    //timing offsets to get our desired timing pulses right (can only be set while real time testing of pulses)
    
    
    float clkOnOffset = 3E-6;
    float mosfetDelayOffset =0;
    float mosfetOnOffset =4E-6;
    float clkPeriodOffset = 20E-6;
    
    
    // program variables
    float cal1,cal2,cal3,cal4,cal5,cal6,cal7;      // variables just for calculations
    word clkOnCount;                              // clk pulse
    word mosfetDelayCount;
    word mosfetOnCount;
    word clkPeriodCount;
    byte readsettingscounter =0;
    byte readsettingstate =0;
    byte intState = 0;                         //interrupt routine state machine
    boolean readsettings= false;
    
    
    
    
    void setup() {
      //Serial.begin(115200);
     pinMode (clk , OUTPUT);
     pinMode (mosfet,OUTPUT);
     //pinMode (delaypin,OUTPUT);
     //pinMode (groundB_pin,OUTPUT);
     calcTimerValues();                    //calculate all timer values in start first 
     cli();                               //to stop interrupts
     TCCR1A = 0;                         //Timer 1 registers
     TCCR1B = 0;
     TIMSK0 = 0;                        // clearing timer0 to eliminate jitter if occurs in wave (important :delay() function wont work now)
     TCNT1 = clkOnCount;                // loading timer1 with clk On value
     TCCR1B |= (1<<CS11);               // setting prescalar to 8 
     TIMSK1 |= (1<<TOIE1);              // enabling timer1 overflow interrupt
     sei();                             //enable interrupts
    }
    
    
    
    
    void calcTimerValues()
    {
      cal1 = (clk_on_time - clkOnOffset) / (clockcycle * prescalar);  
      clkOnCount = maxcount - int(cal1);                                 //clkOnCount for timer1 
    
    
      cal2 = (mosfet_pulse_delay - mosfetDelayOffset) / (clockcycle * prescalar);
      mosfetDelayCount = maxcount - int(cal2);                            //mosfetdelaycount for timer1
    
    
      cal3 = (mosfet_on_time - mosfetOnOffset) / (clockcycle * prescalar);
      mosfetOnCount = maxcount - int(cal3);
    
    
      cal7 = (clk_period - clkPeriodOffset) / (clockcycle * prescalar);
      cal7 -=cal1+cal2+cal3;
      clkPeriodCount = maxcount - int(cal7);
    
    
    }
    
    
    ISR(TIMER1_OVF_vect)
    {
      switch (intState)
      {
        case 0:
         TCNT1 = clkOnCount;
         digitalWrite(clk , clkon);
         intState = 1;
         break;
    
    
        case 1:
         TCNT1 = mosfetDelayCount;
         digitalWrite(clk ,clkoff);
         intState = 2;
         break;
    
    
        case 2:
         TCNT1 = mosfetOnCount;
         digitalWrite(mosfet ,mosfeton);
         intState = 3;
         break;
    
    
        case 3:
         TCNT1 = clkPeriodCount;
         digitalWrite(mosfet ,mosfetoff);
          if (readsettings == false)
         {
          readsettingscounter++;
          if (readsettingscounter >=readsettinglimit)
          {
            readsettings=true;
            readsettingscounter=0;
          }
         }
         intState = 0;
                    
         break;
    
    
        default:
         intState = 0;
         break;
        
    
    
     }
    }
    
    
    void loop() {
    
    
    if(readsettings == true)
    {
      switch(readsettingstate)
      {
       case 0:
        clkpotValue = analogRead(clk_pot) * clk_multiply_value;
        clk_period = clkperiod_default + (clkpotValue * clockcycle);
        calcTimerValues();
        break;
    
    
       case 1:
        mosfetpotValue = analogRead(mosfet_pot) * mosfet_multiply_value; 
        mosfet_on_time = mosfetdefault_on_time + (mosfetpotValue * clockcycle);
        calcTimerValues();
        break;
        
        
      }
      readsettingstate++;
      if(readsettingstate == 2) 
      {
        readsettingstate = 0;
        readsettings = false;
      }
    }
    
    }[FONT=Open Sans][/FONT]

    Attached Files

  • #2
    Have you looked at this project which uses an Arduino Nano (ATmega328 ) to perform the functions you describe?
    Arduino Nano Pulse Induction Metal Detector Project - Published March 2021
    Last edited by Qiaozhi; 08-21-2021, 10:13 AM.

    Comment


    • #3
      Look at this example Atmega328P code I posted a while ago: https://www.geotech1.com/forums/show...400#post257400
      It is possible to generate pulses without interrupts by configuring the PWM waveforms.

      Comment

      Working...
      X