1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

programming a byte on one pin

Discussion in 'Microcontrollers' started by MrDEB, Nov 4, 2012.

  1. tumbleweed

    tumbleweed Member

    Joined:
    Jan 25, 2007
    Messages:
    66
    Likes:
    19
    This is too painful to watch.

    Do you have pullup resistors on PORTA.3 and PORTA.4 for the switches, and do the switches ground the input pins when pressed?

    Here's a version of the code you posted with all the extra junk and shared global variables removed, counters corrected, etc (but I'm sure the hardware has changed since you posted this)
    Code (text):

    Device = 18F2420
    Clock = 20

    // external xtal
    config OSC = HS

    // uncomment next line to use internal osc
    //Include "InternalOscillator.bas"          // module sets Config OSC = INTIO7 for you

    Include "shift.bas"
    Include "utils.bas"
    Include "convert.bas"

    Dim SDI As PORTC.4
    Dim CLK As PORTC.5
    Dim LE As PORTC.3
    Dim RED_OE As PORTC.0
    Dim GREEN_OE As PORTC.1
     
    Dim DataPin As SDI  
    Dim ClockPin As CLK
    Dim ResetPin_R As RED_OE
    Dim ResetPin_G As GREEN_OE

    // pushbutton switches inputs S1 and S2
    dim s1 as PORTA.3
    dim s2 as PORTA.4

    dim count as byte
     
    Const Data(15)As Byte = (%00010001, %00001010 ,%00000100, %00010001, %00001010, %00000100,
    %00010001, %000001010 ,%00000100, %000010001,%00001010, %00000100, %000010001,%00001010, %00000100)
     
    Const Rows(15) As Byte =(%00000001, %000000010 ,%00000100, %000000010, %00000100, %00001000,
     %00000100 ,%000001000 ,%00010000 ,%00001000,%00010000 ,%00100000, %00010000 ,%00100000, %01000000)
     
    Const L_TRows(15) As Byte =( %01000000,%00100000,%00010000,%00100000,%000010000, %00001000,
    %00010000, %00001000, %00000100 ,%00001000, %000000100,%00000010,%00000100, %000000010,%00000001)
     
    Const Ride_Data(15)As Byte = (%00011111, %00000100 ,%00011111, %00000100, %00011111, %00000100,
    %00011111, %00000100 ,%00011111, %00000100,%00011111, %00000100, %00011111,%00000100, %00011111)
     
    Const R_Rows(15) As Byte =(%00001000, %011111110 ,%00001000, %011111110, %00001000, %01111110,
     %00001000 ,%011111110 ,%00001000 ,%01111110,%00001000 ,%01111110, %00001000 ,%01111110, %00001000)
     
    Sub RIDE()
        Dim index As Byte
        Dim X As Byte

        For index = 0 To Bound (Ride_Data)
            DelayMS(100)//10 500us for constant on
            X = Ride_Data(index)
     
            LE = 0
            ResetPin_R = 1   // disable OE RED
            ResetPin_G = 1  // disable OE Green
            Shift.Out(MSB_FIRST, X ,8)  
            LE = 1         //Latch data
            PORTB = R_Rows(index)  
            DelayUS(200) //20 us
            ResetPin_G = 0  // output LOW = ON HIGH = OFF
            ResetPin_R = 1
            LE = 0
        Next

    End Sub
     
    Sub RIGHT()
        Dim index As Byte
        Dim X As Byte
     
        For index = 0 To Bound (Data)
            DelayMS(10)//10 500us for constant on
            X = Data(index)
     
            LE = 0
            ResetPin_R = 1   // disable OE RED
            ResetPin_G = 1  // disable OE Green
            Shift.Out(MSB_FIRST, X ,8)  
            LE = 1         //Latch data
            PORTB = Rows(index)  
            DelayUS(20) //20 us
            ResetPin_R = 0  // output LOW = ON HIGH = OFF
            ResetPin_G = 1
            LE = 0
        Next
     
    End Sub

    Sub LEFT()
        Dim index As Byte
        Dim X As Byte
     
        For index = 0 To Bound (Data)
            DelayMS(10)//10 500us for constant on
            X = Data(index)
     
            LE = 0  // move to top
            ResetPin_R = 1   // disable OE RED
            ResetPin_G = 1  // disable OE Green
            Shift.Out(MSB_FIRST, X ,8)  
            LE = 1         //Latch data
            PORTB = L_TRows(index)   // display byte on matrix
            DelayUS(200) //10  1 us for constant on
            ResetPin_R = 0  // output LOW = ON HIGH = OFF
            ResetPin_G = 1
        Next
     
    End Sub
     
    // start of main
    SetAllDigital

    Shift.SetOutput(DataPin)
    Shift.SetClock(ClockPin)

    high(ResetPin_R)        // make output and set high
    high(ResetPin_G)        // make output and set high
    low(LE)                 // make output and set low
     
    PORTB = 0
    TRISB = %00000000       // make PORTB outputs
     
    // make S1 and S2 switch inputs (assumes there are external pullups on the pins)
    input(s1)
    input(s2)


    While true

        If s1 = 0 Then          // sw 1 closed
            count = 0
            Repeat  
                LEFT()
                DelayMS(200)
                //ResetPin_G = 1  // output LOW = ON HIGH = OFF   this shuts off trailing byte in shifter reg.
                Inc(count)
            Until count = 10   // total of 11 arrows
        End If
     
        If s2 = 0 Then          // sw 2 closed
            count = 0
            Repeat
                RIGHT()
                DelayMS(200)
                // ResetPin_G = 1  // output LOW = ON HIGH = OFF   this shuts off trailing byte in shifter reg.
                Inc(count)
            Until count = 10   // total of 11 arrows
        End If  

        If s1 = 1 And s2 = 1 Then
            RIDE()
            DelayMS(200)
            //  ResetPin_G = 1  // output LOW = ON HIGH = OFF   this shuts off trailing byte in shifter reg.
        End If  
    Wend

    End
     
     
    Last edited: Nov 27, 2012
  2. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,197
    Likes:
    109
    Location:
    Seattle, WA
    ONLINE
    Amen to that!
     
  3. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    YES I have pullup resistors but I can't get the code to reconize the switch closure.
    Will try out your suggestion
    THANKS
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23

    Well that looks like it works THANKS
    now comparing your code with what I had and couple questions arise
    I had DIM index in the beginning but you have DIM index and DIM x as byte in each sub route. Why the difference?
    I think I see why my switches wouldn't recognize, I failed to declare them as inputs.
    My recent attempt looks similar but its not correct as is yours. Going to styudy your code some more and I might experiment as to why certain code is done in the way you posted.
    THANKS again
     
  6. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    He removed the
    It's like taking out the trash you don't bring it back in full do you ?

    Your way they still have leftovers in them.
     
  7. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    pouring over Tumbleweeds code I see in my recent revision I was close but that only counts in hand-gernades and atom bombs.
    I see where I was using Z in my subs which was a duplication in a sense as the index. Perhaps inserting DIM INDEX and DIM X in each sub is why my present code doesn't work, well one of several reasons why.
    am making changes to my present code w/ ???? next to everything I had to change or remove, for my reference
     
  8. tumbleweed

    tumbleweed Member

    Joined:
    Jan 25, 2007
    Messages:
    66
    Likes:
    19
    I moved DIM INDEX and DIM X into each sub because that's where they're used. They're local to the subroutine, so there's no need to have them declared globally. Each sub initializes them, uses them, and then they're not needed anymore when you leave the sub.

    I got rid of Z for two reasons. First off, it wasn't needed. Everywhere you used it you had to go out of your way to make sure that Z=0 before you called the subs, and all it did was track the 'for index = 0 to xxx' loop. Secondly, it's always best if you can have your sub not rely on the state of a global variable if you can get away with it. That way your sub won't break when you screw up something in your main code.

    The other changes were mostly getting rid of unneeded code, and fixing how you used 'count'
     
  9. Pigskin Tony

    Pigskin Tony New Member

    Joined:
    Aug 20, 2012
    Messages:
    18
    Likes:
    0
    I won't claim to be as smart as an old hound dog, but answer me this.

    If tumbleweed's code works, why do you insist on FIXING it by making chances you don't understand???

    I know, I know, "learning by doing." Yeah, yeah, whatever. It doesn't seem like it's worked very well for you.
     
  10. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    It has worked to some extent as I am dissecting the code to see what each statement does. IMO I am learning a-lot. It may not seem like it to seasoned programers. I am not schooled in this subject as most if not all members. The only schooling I ever had was in H.S some 40+ years ago in my senior year. Vacuum tube era. Not once was transistors discussed. Bought a Forest Mims engineers note book back in mid 80s. That's about it. First transistor I ever connected up was ten years ago.
    By dissecting the code and comparing to what I have written I can learn what I messed up of failed to include. I see why Tumbleweed put the DIM statements in each sub routine (Burt pointed this out). I found that I failed to declare the switch inputs as inputs. Putting ???? next to each item I didn't have or have wrong.
    I never said I was fixing what Tumblweed posted, Just trying to understand what and why.
     
  11. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    Video of what it does.

    Need to tweek the delays and look at how to conserve battery power.
    http://s992.beta.photobucket.com/user/MrDEB/media/Video5.mp4.html
    The video was shot in direct sunlight through window so its not as pronounced as in darkness but the display is BRIGHT. Each segment draws 26ma.
    I know its not much to look at. BUT its a work in progress.
    THANKS to Burt for direction using the SHIFT.bas and Tumbleweed for getting the code back on track.
    Jon suggested using the SHIFT.bas instead of the SPI
     
  12. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    small addition to code

    I wanted to be able to jump from the RIDE subroutine during execution so I tried adding this.
    Code (text):
    Sub RIDE()
        Dim index As Byte
        Dim X As Byte
     
        For index = 0 To Bound (Ride_Data)
            DelayMS(50)//10 500us for constant on
            X = Ride_Data(index)
     
            LE = 0
            ResetPin_R = 1   // disable OE RED
            ResetPin_G = 1  // disable OE Green
           if switch = 1 then exit            // jumps out if switch is closed mid execution of sub
            end if
            Shift.Out(MSB_FIRST, X ,8)  
            LE = 1         //Latch data
            PORTB = R_Rows(index)  
            DelayUS(20) //20 us
            ResetPin_G = 0  // output LOW = ON HIGH = OFF
            ResetPin_R = 1
            LE = 0
       
        Next
     
    End Sub
     
    In the WHILE WEND loop to poll the switches I inserted SWITCH = 1 if s1 or s2 are closed.
    Seems to work rather well.
    I contemplated putting the switch=0 in the beginning of the RIDE sub?
    Code (text):
    While true
       
        If s1 = 0 Then          // sw 1 closed
            count = 0
            switch = 1          // for RIDE over ride
            Repeat  
                LEFT()
                DelayMS(200)
               
                Inc(count)
            Until count = 10   // total of 11 arrows
        End If
     
        If s2 = 0 Then          // sw 2 closed
            count = 0
            switch = 1          // for RIDE override exit
            Repeat
                RIGHT()
                DelayMS(200)
               
                Inc(count)
            Until count = 10   // total of 11 arrows
     
        End If  
     
        If s1 = 1 And s2 = 1 Then
            RIDE()
            DelayMS(20)
        switch = 0  
        End If  
    Wend
     
    End
     
  13. tumbleweed

    tumbleweed Member

    Joined:
    Jan 25, 2007
    Messages:
    66
    Likes:
    19
    I doubt that. Think about this for a moment.

    You set switch = 1 when either S1 or S2 are pressed. When do you call RIDE()? When neither S1 or S2 are pressed (when s1=1 and s2=1).

    So, after pressing a switch and doing either RIGHT() or LEFT(), the first time it's released (s1=1 and s2=1) you'll call RIDE and 'switch = 1' will be true, so you'll exit RIDE and set switch = 0. The second time through the loop S1=1, S2=1 and switch=0, so you'll call RIDE() and it'll execute. Now, while you're inside RIDE(), is there any way to set 'switch=1'? No, so you'll never see a new press while inside it.
     
  14. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    Poll the switches in the main they don't take much time and if ride is the normal mode you could use it as the debounce code check sw1 and sw2 ride run the ride code if switch change states test for press and keep on riding
     
  15. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,197
    Likes:
    109
    Location:
    Seattle, WA
    ONLINE
    Thank you for the simple analysis Tumbleweed. A minute spent following the program flow saves a lot of testing.
     
  16. tumbleweed

    tumbleweed Member

    Joined:
    Jan 25, 2007
    Messages:
    66
    Likes:
    19
    You're inside the sub routines so long that I wouldn't bother with debouncing

    Get rid of the 'switch' variable entirely, and if you want RIDE to exit when a switch is pressed then just check for a switch to be pressed...

    Code (text):

    Sub RIDE()
        Dim index As Byte
        Dim X As Byte
     
        For index = 0 To Bound (Ride_Data)
            DelayMS(50)//10 500us for constant on
            X = Ride_Data(index)
     
            LE = 0
            ResetPin_R = 1   // disable OE RED
            ResetPin_G = 1  // disable OE Green
            if (s1 = 0) or (s2 = 0) then            // jumps out if switch is closed mid execution of sub
                exit            
            end if
            Shift.Out(MSB_FIRST, X ,8)  
            LE = 1         //Latch data
            PORTB = R_Rows(index)  
            DelayUS(20) //20 us
            ResetPin_G = 0  // output LOW = ON HIGH = OFF
            ResetPin_R = 1
            LE = 0
     
        Next
     
    End Sub
     
     
  17. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    Maybe I failed to understand?

    I thought about what Tumbleweed is saying and after I posted the code I was wondering the same thing.
    I put an led routine right immediately after the WHILE TRUE statement.
    After each RIDE routine is done (15 clock cycles the LED blinks on then off. which indicate that after the RIDE routine is finished, the code goes back to the beginning of the switch polling.
    I did this all the while I was writing the code I posted, right or wrong, but it showed me that the SHIFT.bas routine in the code posted goes through 15 cycles then jumps back to the subroutine call.
    Code (text):
     
    While true
         led=1
         delayms(100)
         toggle(led)
        If s1 = 0 Then          // sw 1 closed
            count = 0
            switch = 1          // for RIDE over ride
            Repeat  
                LEFT()
                DelayMS(200)
               
                Inc(count)
            Until count = 10   // total of 11 arrows
        End If
     
  18. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    No wonder we have $1500.00 dollar hammers
     
  19. tumbleweed

    tumbleweed Member

    Joined:
    Jan 25, 2007
    Messages:
    66
    Likes:
    19
    And does the LED ever show you that you left RIDE in the middle of the 15 iterations?

    When you release a button, you'll see the led flash twice rapidly since the first time RIDE just exits, after which it runs again for the full 15 iterations like normal which takes approx 750ms.

    During that 750ms that RIDE is running, if you press a button does the LED immediately flash? It pretty much should if you're actually leaving RIDE early (well, within 150ms or so with the various delays you have).
     
  20. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,642
    Likes:
    109
    Location:
    Michigan, USA
    With apologies to Mr Deb for having a little fun at his expense, I'd just like to say to Tony that I believe Mr Deb has come up with a fascinating approach to hardware/software development and I always look forward to checking in on his progress every week (after week, after week...)(grin)...

    [​IMG]
     
    Last edited: Nov 28, 2012
  21. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,414
    Likes:
    23
    $1500 hammers?? This is not the space shuttle or the White House--lol
    I will check the led flashing if I am leaving early. Thinking about this while taking the dog for her and my exercise I wonder if perhaps insert a switch poll in the RIDE routine. This might be better but will check what is going on now .
    In the end I want to be able to exit RIDE anytime. Seems like a button press takes a long time to react.Might change with the Receiver input but then why should it?
    scenario -- If while riding I want to turn BUT its in the middle of the RIDE routine. Maybe a longer button press using a LC/transistor circuit to HOLD it for a longer button press and switch poll in the middle of the RIDE routine??
     

Share This Page