Menu

mega328 50Hz interrupt

Help
2020-05-28
2020-06-04
  • stan cartwright

    stan cartwright - 2020-05-28

    I need to drive a SG90 micro servo.
    On a pic I set up a sub, that was called by an interrupt

    Dim TIME_BASE alias CCPR1H,CCPR1L AS WORD   '// Programmable "Compare" Value
    CCP1CON = b'00001011'     '// Config CCP1 for Compare:Spcl Event trigger
    ;
    TIME_BASE = 20000    '// Make period timer = 20ms (2000us)
    ;
    On Interrupt CCP1 Call Servo_Pulse ;every 20ms
    ;
    InitTimer1 OSC,PS1_4    '// Configure timer1 with Prescale of 1:4
    ClearTimer 1            '//Make Sure timer is cleared to 0
    StartTimer 1            '// Start the timer
    

    which called

    sub Servo_Pulse
       PulseOut Servo_Pin, Servo_Pos us
    end sub
    

    from memory it worked.
    The mega328p timer demos saying 50Hz are KHz.
    Please,how to get a 50 Hz interrupt sub on mega 328p.
    I want to use a nano and slc,sda is reversed compared to uno. Are there other differences between
    them as far as interrupts?
    Updating servos every 20 ms is normal. I thought it was so they don't forget their position but might be to allow for mechanical movement between pulses.

     
  • stan cartwright

    stan cartwright - 2020-05-28

    I have tried various things and timer calculators to no avail scoping a sub when it worked that turned a port on/off and measuring frequency.
    I have checked code by Kent but I could not adapt it.

     
  • stan cartwright

    stan cartwright - 2020-05-28

    I posted this for 1000ms

    these values from timercalculator for 1000ms
    I need values for 20ms
    
      #chip mega328p,16
      #option explicit
      #define LED PORTB.4
      dir LED out
        ' Add the handler for the interrupt
        On Interrupt Timer1Match1 Call InterruptHandler
        ' Initialise the timer - this is required
        ' Set prescaler and then start the timer
        InitTimer1 Osc, PS_1_1
        ' Start the timer - this is required
        StartTimer 1
    TCCR1A = 0x80;
    TCCR1B = 0x0C;
    OCR1AH = 0xF4;
    OCR1AL = 0x23;
    
    'Main routine
      Do
      Loop
      end
    'This will be called when the Timer matches
    Sub InterruptHandler
      LED = !LED
    End Sub
    
     
  • stan cartwright

    stan cartwright - 2020-05-29

    I searched the forum for interrupts and found one I wrote that is not in my files.
    It works on a nano as well it seems now.
    I must have erased the file but only remember the pic version..age?
    Would be useful in demos.

    ; A uno servo controller that refreshes the servo every 20ms
    ; servopos is the servo position
    #chip mega328p,16
    #config osc = int
    #option Explicit
    ;
    dim count as word
    dim servopos as word
    dim servodir as byte
    #define servopin portb.0 ;uno pin 8
    servopos=1500 ;us
    servodir=1
    dir servopin out
    ;
    TCCR1A = 0x80;
    TCCR1B = 0x0A;
    OCR1AH = 0x9c;
    OCR1AL = 0x3f;
    On Interrupt Timer1Match1 call ISR
    ;main program
    do
    ;
    if servodir = 1 then
      servopos = servopos + 80 ;us
      if servopos = 2220 then ;end of servo turn
        servodir = 0
      end if
    else
      servopos = servopos - 80 ;us
      if servopos = 780 then ;end of servo turn
        servodir = 1
      end if
    end if
    ;
    wait 100 ms
      loop
    ;end main program
    sub ISR
    pulseout servopin,servopos us
    end sub
    
     

    Last edit: stan cartwright 2020-05-29
  • stan cartwright

    stan cartwright - 2020-05-29

    Now here is probably the problem I had.
    The interrupt works until I add

    ;v53l0x software restart
    'HI2CStart
    'HI2CSend(0x52)
    'HI2CSend(0x89)
    'HI2CSend(0x01)
    'HI2CStop
    

    then the interrupt does not happen.Comment out and the interrupt works ok.
    I don't see the connection.

    ; A uno servo controller that refreshes the servo every 20ms
    ; servopos is the servo position
    #chip mega328p,16
    #config osc = int
    #option Explicit
    ;
    ;set up v53l0x
    #define HI2C_DATA PORTC.4 ;sda
    #define HI2C_CLOCK PORTC.5 ;scl
    #define HI2C_BAUD_RATE 400
    HI2CMode Master
    ;
    ;v53l0x software restart
    'HI2CStart
    'HI2CSend(0x52)
    'HI2CSend(0x89)
    'HI2CSend(0x01)
    'HI2CStop
    'wait 200 ms
    ;
    dim servopos as word
    dim servodir,distance_lo,distance_hi as Byte
    #define distance distance_hi*256 + distance_lo
    #define servopin portb.0 ;uno pin 8
    servopos=1500 ;us
    servodir=1
    dir servopin out
    ;
    TCCR1A = 0x80;
    TCCR1B = 0x0A;
    OCR1AH = 0x9c;
    OCR1AL = 0x3f;
    On Interrupt Timer1Match1 call ISR
    ;main program
    do
    ;
    if servodir = 1 then
      servopos = servopos + 80 ;us
      if servopos = 2220 then ;end of servo turn
        servodir = 0
      end if
    else
      servopos = servopos - 80 ;us
      if servopos = 780 then ;end of servo turn
        servodir = 1
      end if
    end if
    ;
    wait 20 ms
    
      loop
    ;end main program
    sub ISR
    pulseout servopin,servopos us
    end sub
    
     
  • stan cartwright

    stan cartwright - 2020-05-29

    It seems, for mega328p that On Interrupt Timer1Match1 call ISR and hi2c don't work together.
    Er..this is a problem?...does my head.
    Please look at this. I'll see if it is the same with pics.

     
  • stan cartwright

    stan cartwright - 2020-05-29

    I am reinstalling gcb. It is behaving odd.
    This prog works now.
    I started with v53l0x to terminal then added interrupt.
    the servo is going back fwd from an intrrupt and there's a distance from v53l0x to terminal.
    This wasn't happening before and the code looks the same.I just started with working code and added until not working. This code seems no different but works. Runs the servo and reads v53l0x.

    #chip mega328p, 16
    #option Explicit
    ;for terminal distance out
    #define USART_BAUD_RATE 9600
    #define USART_TX_BLOCKING
    #define USART_DELAY 1 ms
    ;set up v53l0x
    #define HI2C_DATA PORTC.4 ;sda portc.4 for nano portc.5 for uno
    #define HI2C_CLOCK PORTC.5 ;scl portc.5 for nano portc.4 for uno
    #define HI2C_BAUD_RATE 400
    HI2CMode Master
    ;servo 50 Hz sub
    TCCR1A = 0x80;
    TCCR1B = 0x0A;
    OCR1AH = 0x9c;
    OCR1AL = 0x3f;
    On Interrupt Timer1Match1 call ISR
    ;
    dim servopos as word
    dim servodir,distance_lo,distance_hi as Byte
    #define distance distance_hi*256 + distance_lo
    #define servopin portb.0 ;uno pin 8
    dir servopin out
    servopos=1500 ;us
    servodir=1
    HI2CStart ;software restart
    HI2CSend(0x52)
    HI2CSend(0x89)
    HI2CSend(0x01)
    HI2CStop
    wait 200 ms
    
    do ;------------------------
      HI2CStart ;Sys Range Start
      HI2CSend(0x52)
      HI2CSend(0x00)
      HI2CSend(0x01)
      HI2CStop
    
      HI2CStart ;read distance
      HI2CSend(0x52)
      HI2CSend(0x1e)
      HI2CReStart
      HI2CSend(0x53) ;set the read flag
      HI2CReceive(distance_hi)
      HI2CReceive(distance_lo, NACK) ;read one byte and conclude
      HI2CStop
    
      hserprint " Distance: "+str(distance_hi*256+distance_lo)+"  mm ";
    ;move servo left right
    if servodir = 1 then
      servopos = servopos + 80 ;us
      if servopos = 2220 then ;end of servo turn
        servodir = 0
      end if
    else
      servopos = servopos - 80 ;us
      if servopos = 780 then ;end of servo turn
        servodir = 1
      end if
    end if
    ; pulseout  servopin,servopos us ;move servo
    ;
    wait 50 ms
    
     loop
    sub ISR
      pulseout servopin,servopos us
    end sub
    
     
  • stan cartwright

    stan cartwright - 2020-05-30

    Reinstalled gcb...it took up the main windoe,had to minimise it to see compile reports and programmer preferences.back to normal and this program works. The v53l0x hi2c and the servo interrupt.Looks the same as before...more or less. I just built it from working v53l0x to terminal,added the interrupt and it still worked.
    added code for object detection...surprised how short the code was.

    ;v53l0x on servo robot
    #chip mega328p,16
    #option explicit
    
    dir portc.0,portc.1,portc.2,portc.3,portb.0 out
    #define servopin portb.0
    #define lmotfwd set portc.0 off : set portc.1 on
    #define lmotrev set portc.0 on : set portc.1 off
    #define lmotstop set portc.0 off : set portc.1 off
    #define rmotfwd set portc.2 off : set portc.3 on
    #define rmotrev set portc.2 on : set portc.3 off
    #define rmotstop set portc.2 off : set portc.3 off
    ;set up v53l0x
    #define HI2C_DATA PORTC.4 ;sda portc.4 for nano portc.5 for uno
    #define HI2C_CLOCK PORTC.5 ;scl portc.5 for nano portc.4 for uno
    #define HI2C_BAUD_RATE 400
    HI2CMode Master
    ;
    dim servopos as word
    dim servodir,distance_lo,distance_hi as Byte
    #define distance distance_hi*256 + distance_lo
    servopos=1500:servodir=1
    ;servo interrupt
    TCCR1A = 0x80;
    TCCR1B = 0x0A;
    OCR1AH = 0x9c;
    OCR1AL = 0x3f;
    On Interrupt Timer1Match1 call isr
    ;v53l0x software restart
    HI2CStart
    HI2CSend(0x52)
    HI2CSend(0x89)
    HI2CSend(0x01)
    HI2CStop
    wait 200 ms
    ;
    lmotfwd : rmotfwd ;go forward
    do ;------------
    ;is object in range?
      getdistance
      if distance < 150 then ;object close
        lmotstop : rmotstop
        if servopos < 1500 then ;is object to left
          do
            lmotfwd : rmotrev
            wait 50 ms
            lmotstop : rmotstop
            getdistance
          loop until distance > 150 ;rotate right until clear
        else
          do ;object right
            lmotrev : rmotfwd
            wait 50 ms
            lmotstop : rmotstop
            getdistance
          loop until distance > 150 ;rotate left until clear
        end if
        servopos=1500 ;point servo forward
        lmotfwd : rmotfwd
        ;go forward
      end if
      ;rotate radar Left-right
      if servodir = 1 then
        servopos = servopos +80
        if servopos = 2220 then
          servodir = 0
        end if
      else
        servopos = servopos - 80
        if servopos = 780 then
          servodir = 1
        end if
      end if
    loop ;-------------
    ;
    sub getdistance
      HI2CStart ;Sys Range Start
      HI2CSend(0x52)
      HI2CSend(0x00)
      HI2CSend(0x01)
      HI2CStop
    
      HI2CStart ;read distance
      HI2CSend(0x52)
      HI2CSend(0x1e)
      HI2CReStart
      HI2CSend(0x53) ;set the read flag
      HI2CReceive(distance_hi)
      HI2CReceive(distance_lo, NACK) ;read one byte and conclude
      HI2CStop
    end sub
    
    sub isr
      pulseout servopin,servopos us
    end sub
    
     
  • stan cartwright

    stan cartwright - 2020-05-30

    I am guessing that using

    ;v53l0x software restart
    HI2CStart
    HI2CSend(0x52)
    HI2CSend(0x89)
    HI2CSend(0x01)
    HI2CStop
    

    in a program and not having the device connected makes it hang..I don't know.
    If not for lockdown I wouldn't have had the time to find this out.
    I built the program several times and it didn't work then it finally did.
    It worked after I connected a vl53l0x so WAS that the problem?

     
    • Anobium

      Anobium - 2020-05-30

      Look at the HWI2C code, or, the Help. There is a variable you can check the will return the state of the address from memory HI2CAckPollState

       
  • stan cartwright

    stan cartwright - 2020-06-04

    Why does
    TCCR1A = 0x80;
    TCCR1B = 0x0A;
    OCR1AH = 0x9c;
    OCR1AL = 0x3f;
    On Interrupt Timer1Match1 call isr
    make ili9341 crash?
    The 50Hz interrupt works but not with ili9341..screen goes white.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.