Menu

Table too slow?

2017-12-31
2018-01-04
  • stan cartwright

    stan cartwright - 2017-12-31

    I have stepper motor code that works using case but not reading from a table.
    When I use case the program works and the motors do as told but when using a table they just go in one direction.
    The motor control is 100Hz interrupt. Is reading table too slow for interrupt or is there an error in my prog.
    This snip works but uncomment ReadTable lmot,lmotor,lmotval and comment select case lmotor to End select doesn't. They should do the same but is the 100Hz interrupt to short?

    ;  ReadTable lmot,lmotor,lmotval
        select case lmotor
          case 1
          lmotval=128
          case 2
          lmotval=192
          case 3
          lmotval=64
          case 4
          lmotval=96
          case 5
          lmotval=32
          case 6
          lmotval=48
          case 7
          lmotval=16
          case 8
          lmotval=144
        End Select
    ;
    table lmot
    128,192,64,96,32,48,16,144
    end table
    

    The complete program that works as is but not if table is used.

    ;328p nano controlling two 28BYJ-48 Stepper Motors using interrupt
    #chip mega328p,16
    #option Explicit
    dir portb out
    dir portd out
    
    dim lmotdir,lmotor,rmotdir,rmotor,lmotval,rmotval as byte
    lmotdir=255:lmotor=1:rmotdir=1:rmotor=1
    
    ;interrupt drives motor 100 Hz
        On Interrupt Timer0Match1 Call motors
    
        Dim OCR0  AS byte alias OCR0A
        Dim TCCR0 AS  byte alias TCCR0B
        WGM01 = 1                'Timer in CTC mode - required
    
        OCR0 = 19
        TCCR0 = 0x28
        TCCR0 = TCCR0 or 0x05
    
    ;
    
    do ; move motors
    lmotdir=255:rmotdir=255
    wait 2 s
    lmotdir=1:rmotdir=255
    wait 2 s
    lmotdir=255:rmotdir=1
    wait 2 s
    lmotdir=1:rmotdir=1
    wait 2 s
    loop
    ;----- end
    
    Sub motors ;This will be called when the Timer overflows
    ;left stepper motor
      if lmotdir>0 then
        if lmotdir=1 Then
          lmotor++
          if lmotor=9 then lmotor=1
        else
          lmotor---
          if lmotor=0 then lmotor=8
        end if
      ;
    ;  ReadTable lmot,lmotor,lmotval
        select case lmotor
          case 1
          lmotval=128
          case 2
          lmotval=192
          case 3
          lmotval=64
          case 4
          lmotval=96
          case 5
          lmotval=32
          case 6
          lmotval=48
          case 7
          lmotval=16
          case 8
          lmotval=144
        End Select
      Else
        lmotval=0
      end if
    ;right stepper motor
      if rmotdir>0 then
        if rmotdir=1 Then
          rmotor++
          if rmotor=9 then rmotor=1
        else
          rmotor---
          if rmotor=0 then rmotor=8
        end if
      ;
    ;    ReadTable rmot,rmotor,rmotval
        select case rmotor
          case 1
          rmotval=1
          case 2
          rmotval=3
          case 3
          rmotval=2
          case 4
          rmotval=6
          case 5
          rmotval=4
          case 6
          rmotval=12
          case 7
          rmotval=8
          case 8
          rmotval=9
        End Select
      else
        rmotval=0
      end if
    
      portd=(portd and 15)+lmotval
      portb=(portb and 240)+rmotval
    
    End Sub
    ;
    table lmot
    128,192,64,96,32,48,16,144
    end table
    ;
    table rmot
    1,3,2,6,4,12,8,9
    end table
    
     
  • stan cartwright

    stan cartwright - 2018-01-01

    For some reason it works now. I rebuilt the mcp23017 stepper driver and it's fine, instead of case I read from a table..looks neater. Can't work out why

     
  • stan cartwright

    stan cartwright - 2018-01-02

    I take it back! Using a table for 28BYJ-48 Stepper Motor with ULN2003a driver is iffy.
    This code works and moves the motors but if I uncomment the readtable and comment select case to end select, the motors just go in one direction.(there's a band called that)
    annoying me. read table should do the same as case.
    Using one table makes both motors just go in one direction.
    Working using case https://youtu.be/jxKymWoiZ2k

    #chip mega328p,16
    #include <MCP23017.h>
    #option Explicit
       #define I2C_MODE Master
       #define I2C_DATA PORTC.4
       #define I2C_CLOCK PORTC.5
       #define I2C_DISABLE_INTERRUPTS ON
       'Optionally, you can reduce the I2C timings.
       #define I2C_BIT_DELAY 0 us
       #define I2C_CLOCK_DELAY 1 us
       #define I2C_END_DELAY 0 us
    
    #define MCP23017_addr 0x4e
    ;#define MCP23017_IODIRA 0; make porta output
    MCP23017_sendbyte (MCP23017_addr,MCP23017_IODIRA,0)
    dim lmotdir,lmotor,rmotdir,rmotor,lmotval,rmotval as byte
    lmotdir=1:lmotor=1:rmotdir=1:rmotor=1
    
    dir portb.0 out ;scope
    
    ;interrupt drives motors
        On Interrupt Timer1Overflow Call motors
        ' Initialise the timer - this is required
        ' Set prescaler to 1 and then start the timer
        InitTimer1 Osc, PS_1_1
        ' Start the timer - this is required
        StartTimer 1
    
        SetTimer 1, 40000
    ;
    ;-------------------------
    ;
    MCP23017_sendbyte( MCP23017_addr,MCP23017_GPIOA,0) ;set port a to out
    wait 1 s
    ;
    do
    lmotdir=255:rmotdir=255
    wait 2 s
    lmotdir=1:rmotdir=1
    wait 2 s
    lmotdir=0:rmotdir=0
    wait 1 s
    lmotdir=255:rmotdir=1
    wait 2 s
    lmotdir=0:rmotdir=0
    wait 1 s
    lmotdir=1:rmotdir=255
    wait 2 s
    loop
    ;----- end
    'This will be called when the Timer overflows
    Sub motors
    
      SetTimer 1, 40000 ;reset timer faster
    
     ;left stepper motor
      if lmotdir>0 then
        if lmotdir=1 Then
          lmotor++
          if lmotor=9 then lmotor=1
        else
          lmotor---
          if lmotor=0 then lmotor=8
        end if
    ;  ReadTable lmot,lmotor,lmotval
        select case lmotor
          case 1
          lmotval=128
          case 2
          lmotval=192
          case 3
          lmotval=64
          case 4
          lmotval=96
          case 5
          lmotval=32
          case 6
          lmotval=48
          case 7
          lmotval=16
          case 8
          lmotval=144
        End Select
      Else
        lmotval=0
      end if
    ;right stepper motor
      if rmotdir>0 then
        if rmotdir=1 Then
          rmotor++
          if rmotor=9 then rmotor=1
        else
          rmotor---
          if rmotor=0 then rmotor=8
        end if
    ;    ReadTable rmot,rmotor,rmotval
        select case rmotor
          case 1
          rmotval=1
          case 2
          rmotval=3
          case 3
          rmotval=2
          case 4
          rmotval=6
          case 5
          rmotval=4
          case 6
          rmotval=12
          case 7
          rmotval=8
          case 8
          rmotval=9
        End Select
      else
        rmotval=0
      end if
      portb.0=!portb.0 ;scope pin
      MCP23017_sendbyte (MCP23017_addr,MCP23017_GPIOA,lmotval+rmotval) ;sets porta to lmotval+rmotval
    End Sub
    ;
    table lmot
    128,192,64,96,32,48,16,144
    end table
    ;
    table rmot
    1,3,2,6,4,12,8,9
    end table
    
     
  • mmotte

    mmotte - 2018-01-03

    Stan,

    I see your playing with a 28BYJ-48 Stepper.

    So was I about a year ago. It needed to be minature so i used a 12f683. This worked real slick for positioning a magic trick. Maybe you can get some ideas off of this?

    'A program to Run a 4096 step geared step motor 28BYJ-48
    'actually this is doing full step mode in which 2 coils are active at a Time
    ' so it only has 2048 steps/turn (seems like a couple less)
    'Another array could be built to do eight half steps
    'The outputs run a ULN2003 like supplied by so many chinese suppliers
    'The input Port GPIO.4 has a pushbutton
    'Setup: routine allows the operator to align the shaft on start up
    'MainLoop: routine rotates the motor one full turn
    'If you change the MainLoop in line 41 to MainLoop2 then it
    'will demo a 5 station/position pattern
    'by Mike Otte
    '2013 ,,,upgraded  2016
    
    'Chip model
    #chip 12F683, 8
    
      dim Full(5)
          Full(0) = b'00000110'
          Full(1) = b'00000011'
          Full(2) = b'00001001'
          Full(3) = b'00001100'
    
    'Set the pin directions
    dir GPIO.0 out  'These are  wired to the uln2003 inputs
    dir GPIO.1 out
    dir GPIO.2 out
    dir GPIO.5 out
    
    dir GPIO.4 IN   'pushbutton input
    
    Dim position as Word  'Could be integer if we go below 0 position
    position =0
    
    'Main routine
    Setup:
      If GPIO.4 = 1 Then StepCW
    
      If GPIO.4 = 0 Then
        position =0
        wait 500 ms
        goto MainLoop ' to demo 5 position
      end if
      goto Setup
    
    'One turn MainLoop ,get here from 3 lines above ,line41
    MainLoop:
      If GPIO.4 = 1 Then goto MainLoop
    
      StepTo(2040)  'one turn
    
      position =0   'resets position counter for next move
      wait 500 ms   'Gives time for button release if only a few steps
    
     goto MainLoop
    
    ' Example of going to 5 different positions and waiting for the button to be pushed
    'Button is a pull down
    MainLoop2:
      If GPIO.4 = 1 Then goto MainLoop2
      If GPIO.4 = 0 Then
        station++
        If station > 5 then station = 1
    
        wait 500 ms
        goto newstation
      end if
      goto MainLoop2
    newstation:
      Select case station
        case 1
            StepTo(500) 'station position 1
            wait 500 ms   'Gives time for button release if only a few steps
        case 2
            StepTo(1500)  'station position 2
            wait 500 ms   'Gives time for button release if only a few steps
        case 3
            StepTo(2500)  'station position 3
            wait 500 ms   'Gives time for button release if only a few steps
        case 4
            StepTo(3000)  'station position 4
            wait 500 ms   'Gives time for button release if only a few steps
        case 5
            StepTo(3100)  'station position 5
            wait 500 ms   'Gives time for button release if only a few steps
        end Select
     goto MainLoop2
    
    Sub StepTo(newpos as word)
        EnMotor
       Do until Position = newpos
        If newpos < position then StepCCW
    
        If newpos > position then StepCW
    
       loop
       DisEnMotor
    end sub
    
    Sub EnMotor
      dir GPIO.0 out
      dir GPIO.1 out
      dir GPIO.2 out
      dir GPIO.5 out
    end sub
    
    Sub DisEnMotor
      dir GPIO.0 in 'disables motor so it converves energy and don't heat up
      dir GPIO.1 in
      dir GPIO.2 in
      dir GPIO.5 in
    end sub
    
    Sub StepCW
        Position++
        myStep = position mod 4
        thisStep = Full(myStep)
        GPIO.0 = thisStep.0
        GPIO.1 = thisStep.1
        GPIO.2 = thisStep.2
        GPIO.5 = thisStep.3
        wait 2 ms
    end sub
    
    Sub StepCCW
        Position--
        myStep = position mod 4
        thisStep = Full(myStep)
        GPIO.0 = thisStep.0
        GPIO.1 = thisStep.1
        GPIO.2 = thisStep.2
        GPIO.5 = thisStep.3
        wait 2 ms
    end sub
    
    End
    

    BR
    73
    Mike

     
  • stan cartwright

    stan cartwright - 2018-01-03

    You turn off motor with gpio in, I just set motor lines to 0.
    My code works fine using case but read table,the same values and motors don't change direction or stop. So obvious I can't see the wood for trees thing.
    The motors are carp but cheap and for a "robot" cheaper than geared dc motor and h-bridge.
    Data sheet says run at 100Hz but I'm rubbish at interrupt calc so used a scope to test portb.0=!portb.0 so guess frequency is half shown.
    I'm using as uni-polar but there's another way I saw that doesn't use the common,the guy cut tracks on the motor but a reply said not necessary.
    For a "table top robot" I can change motor speeds with interrupt freq or turn intoff and single step.
    Not a "real" steppper but interesting. Cheers.

     
  • stan cartwright

    stan cartwright - 2018-01-03

    Interesting Mike you wait 2 ms between next phase. I marked the wheels and 4096 phases give one revolution. I changed it to 1 ms and it doesn't go 360 deg ??
    ps I tried
    Full(0) = b'00000110'
    Full(1) = b'00000011'
    Full(2) = b'00001001'
    Full(3) = b'00001100'
    but seemed familiar and didn't work ie motors buzzed not move. The phase pattern that is

     

    Last edit: stan cartwright 2018-01-03
  • stan cartwright

    stan cartwright - 2018-01-04

    I also tried an array but the motors didn't even move. I'll stick with case that works fine, just annoying I can't see my error.

    'dim lmotvalph(8) as byte
    'lmotvalph(1)=b'10000000
    'lmotvalph(2)=b'11000000
    'lmotvalph(3)=b'01000000
    'lmotvalph(4)=b'01100000
    'lmotvalph(5)=b'00100000
    'lmotvalph(6)=b'00110000
    'lmotvalph(7)=b'00010000
    'lmotvalph(8)=b'10010000
    '
    'dim rmotvalph(8) as byte
    'rmotvalph(1)=b'00000001
    'rmotvalph(2)=b'00000011
    'rmotvalph(3)=b'00000010
    'rmotvalph(4)=b'00000110
    'rmotvalph(5)=b'00000100
    'rmotvalph(6)=b'00001100
    'rmotvalph(7)=b'00001000
    'rmotvalph(8)=b'00001001
    
    ;lmotval=lmotvalph(lmotor)
    ;rmotval=rmotvalph(rmotor)
    
     
  • stan cartwright

    stan cartwright - 2018-01-04

    This is getting silly. Why don't bin vals work ie use bin vals in prog instead of decimal?
    These little motors work fine with case.

       select case lmotor
          case 1
          lmotval=128 ;b'10000000 ;128
          case 2
          lmotval=192 ;b'11000000 ;192
          case 3
          lmotval=64 ;b'01000000 ;64
          case 4
          lmotval=96 ;b'01100000 ;96
          case 5
          lmotval=32 ;b'00100000 ;32
          case 6
          lmotval=48 ;b'00110000 ;48
          case 7
          lmotval=16 ;b'00010000 ;16
          case 8
          lmotval=144 ;b'10010000 ;144
        End Select
    
     

Log in to post a comment.