Continue to Site

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.

  • 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.

programming a byte on one pin

Status
Not open for further replies.
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:
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:
YES I have pullup resistors but I can't get the code to reconize the switch closure.
Will try out your suggestion
THANKS
 
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
 
He removed the
shared global variables
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.
 
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
 
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'
 
Well that looks like it works

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.
 
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.
 
Video of what it does.

Need to tweek the delays and look at how to conserve battery power.
**broken link removed**
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
 
small addition to code

I wanted to be able to jump from the RIDE subroutine during execution so I tried adding this.
Code:
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:
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
 
Seems to work rather well
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.
 
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
 
Thank you for the simple analysis Tumbleweed. A minute spent following the program flow saves a lot of testing.
 
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:
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
 
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:
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
 
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
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).
 
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.

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)...
 
Last edited:
$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??
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top