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.
What I plan on doing is have SUB A running then if switch B is closed monetarily then the PIC changes to Sub B. Then after X seconds the pic changes to Sub A.
If switch C is closed Monetarily then the PIC goes to SUB C then back to SUB A
Am I right in assuming that an ISR stops the running routine and starts a different routine?
Wonder if say PORTB.0 and PortB.1 be used for two different tasks?
Enabling the Rows AND doing the ISR.
 
If you put the switch code in the main you'll save yourself a headache .
Interrupt on change is not a fix all , I would learn how to keep your flow going without them.

You'll open up a whole new can of worms

We will be hearing where did my program go and almost all the code you'll need to write will have to be done using your own knowledge.

ISR read this https://www.electro-tech-online.com/custompdfs/2012/11/chap10_interrupts-1.pdf

I great coder said if you can't write code to do the task without interrupts you better wait till you can before you jump in and start using them .

Reason is your going to need to fully understand Flow.
 
Last edited:
I am hoping NOT to use an ISR as yes I understand it can open up a can of worms that I don't want.
Will read the link you posted
THANKS
 
Well I had some time to play with this today here a video and it's using your lowside driver chip powering from portA

It not really much brighter then the shift register and these leds can be seen a long way but it's better. I'm getting a full 25mA.

Code:
Device = 18F2520      // Tells whitch  chip im using
Clock =8             // tell the complier to base on a 8 Mhz clock for delays.
Config OSC = INTIO67   // sets OSC it onboard  oscillator
Include "intio8.bas"   // set's the osscon to 8 Mhz
Include "shift.bas"    //modules use 
Include "utils.bas"
Include "convert.bas"

Dim SDI As PORTB.0
Dim CLK As PORTB.1
Dim OE As PORTB.2
Dim LE As PORTB.3
Dim row1 As PORTA.0
Dim row2 As PORTA.1
Dim row3 As PORTA.2
Dim row4 As PORTA.3
Dim row5 As PORTA.4
Dim row6 As PORTA.5
Dim row7 As PORTA.6
Dim DataPin As SDI     
Dim ClockPin As CLK
Dim index As Byte 
Dim X As Byte
Dim I As Byte
Dim scan As Byte

 // data to shift out \\\
Const data(8)As Byte =(%10000001, %01000010 ,%00100100, %00011000, %00011000, %00100100, %01000010, %10000001)
Const row(8) As Byte =(%00000001, %00000010, %00000100, %00001000, %00010000, %00100000, %01000000, %00000000)
Sub StartScan()
    OE = 1      // OE is high loading data
    LE = 0      //  Is low while loading data
    Shift.Out(MSB_FIRST, X, 8) //Loads shift register 
    LE = 1     // goes high to latch data
    OE = 0    // OE goes low to sink power
End Sub
Shift.SetOutput(DataPin)   // pins for dats in the shift.bas
Shift.SetClock(ClockPin)    // sets clock in the shift.bas
ADCON1 = $07     // turns off ADC
Output(OE)       //sets pin to output
Output (LE)      //same as above
Output (row1)
Output (row2)
Output (row3)
Output (row4)
Output (row5)
Output (row6)
Output (row7)
  I=0
While true       //Loop that's forever as long as it's true
  For scan = 0 To Bound (row)
    For index = 0 To Bound (data)   //Picks byte to load
        DelayMS(40)         //  to see it happen
        X = (data(index))   //  This Loads byte into X
        StartScan     // This sends X to the TLC5916
        DelayMS(40)       // to see it happen
     Next        //Loop the const array data runs all bytes
     I = (row(scan))
     PORTA= I
  Next
  
 Wend
 End
 
Last edited by a moderator:
Bert has a key piece in his code that will prevent the mixing of colors.

Code:
Sub StartScan()
    OE = 1      // OE is high loading data
    LE = 0      //  Is low while loading data
    Shift.Out(MSB_FIRST, X, 8) //Loads shift register 
    LE = 1     // goes high to latch data
    OE = 0    // OE goes low to sink power
End Sub

Disable both outputs (OE=1) before writing any data, and enable the appropriate output (OE=0) to enable the output.
 
I found my issue with color mixing. If I disable both RED and GREEN OE then enable the desired color then no mixing issue. I was looking over the code to put the WHILE TRUE loop in the individual SUB routines and noticed my error. One line of code sure does mess things up. LOL
Good find Jon THANKS for pointing it out anyway. Just a couple days late but it was Thanks Giving day.
As far as brightness, the GREEN leds have the most improvement with the low side driver chip
 
This is my screwed up LOOP

using the same basic code as Burt has posted (been hacking at this same routine for two days off and on) but moving the WHILE TRUE loop up into the SUB. Tried eliminating the WHILE TRUE, moving the NEXT.
Looking at Burts last posted code I might tray something a little different.
Code:
Sub LEFT()

 Z = 0 
  count = 0 
 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
    Shift.Out(MSB_FIRST, X ,8)  
    LE = 1         //Latch data
    PORTB =L_TRows(Z)  
    DelaymS(500) //10  1 us for constant on
    ResetPin_G = 0  // output disable
    LE = 0
    Z = Z+1
    next
    
End Sub
 
Why no work???

curious as to WHY it dosen't work. Instead of jumping from the WHILE TRUE loop to the SUB routine then back again.
Code:
For index = 0 To Bound (Data)
      DelayMS(10)//10 500us for constant on
      X = (Data(index))
This section grabs the value of X (DATA) and only one byte of the CONST data array.
This loads the data into the shift regeister then displays it.


Code:
 LE = 0
    ResetPin_R = 1   // disable OE RED
    ResetPin_G = 1
    Shift.Out(MSB_FIRST, X ,8)  
    LE = 1         //Latch data
    PORTB =L_TRows(Z)  
    DelaymS(500) //10  1 us for constant on
    ResetPin_G = 0  // output disable
    LE = 0
    Z = Z+1
    next
 
End Sub
If I put both of these in one sub routine instead of jumping from the loop to the sub then the loop until ??
trying to figure out why the difference. One works w/ the loop but it only displays the last const data without the loop.
Tried including the WHILE TRUE loop within the sub but can't seem to get it working.
WHY??
 
MrDeb why would you want a while loop in the sub This brings you back to flow a while loop does what while it's true?

It stays there till it's false. Never false your code could never change.

Now I showed you how to make a big X a left < and a right > posted you working code that can load them and move them

Now what is a subroutine? It let's you substitute A for B.

Now if you make a sub that reads button A, B, and C and loads const stop, right or left into the main you'll get'r'done.
 
Last edited:
Thath's kinda what I was trying to do. A sub for each switch closure

I am using the code w/ some changes that you posted and it works but have yet to try your latest code?.
My question I am curious about is putting the
Code:
or index = 0 To Bound (Data)
      DelayMS(10)//10 500us for constant on
      X = (Data(index))
In the sub routine then call the routine.
Am thinking that perhaps your referring to using the above code snippet then include
if A sw=1 then sub right
if B sw = 1 then sub left
if Csw = 1 then sub stop
else
sub RIDE
 
No that's not what I said. Make a sub that has all your led data then in the main test your switch code you could even use the switch code as a test in the while loop

Code:
while button = true     //run this
      if button = false then  
         //go back and wait for true
 
Last edited:
Burt's right. The main program loop should do nothing but look for button presses. When a button press is detected, jump to a subroutine for action.

I haven't seen anything in your scraplets of code about how long you're going to blink? Do you plan to blink as long as the button is pressed? Some fixed amount of time after the button is pressed ( which seems kinda dangerous)? Until the button is pressed again ( which also seems trouble-plagued)?

Just saying 'cause however you're going to stop blinking may change the code layout. Excuse the heck out of me if you already have this figured out but it looks like this detail is lost in the woods.
 
Last edited:
No its not lost, just got sidetracked. I am confused as to WHY the WHILE TRUE loop can't go in the same sub routine as the SHIFT. Seems like the code bounces from the WHILE TRUE loop to the SUB then back again.
As far as blinking, Was contemplating say 6-8 blink routines then jump from the blink routine back to the main program. I first want to get the LOAD LED DATA and DISPLAY DATA in there proper order. It works as is but no way I can see at this point how to implement switch closures.
Going to try Burts suggestion and put the LOAD DATA in the sub route and display elsewhere. At least that's what I think Burt described?
I kinda see where he is going with the code flow, I just need to try it out.
 
MrDeb I didn't say you can't you just don't want a while (1) or true in a sub and your going to us a for next loop which can pop up and check the main fast enough with a

Is button still pressed and go back and run the loop if so
 
making headway

My switch routine SUCKS but I got the sub routines to work as desired.
The code down in the switch routine tends to combine all three subs together in a order.
Started using CASE SELECT, might give it another try?
Code:
Device = 18F2420
Clock = 20
//Config OSC = INTIO67    delete this as I am using crystal oscilliator
//Include "InternalOscillator.bas " 
Include "shift.bas"
Include "utils.bas"
Include "convert.bas"
//Include "InternalOscillator.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
Dim index As Byte 
Dim X As Byte
Dim I As Byte
{
Dim row0 As PORTB.0
Dim row1 As PORTB.6 
Dim row2 As PORTB.1 
Dim row3 As PORTB.2
Dim row4 As PORTB.3
Dim row5 As PORTB.4
Dim row6 As PORTB.5
Dim led As PORTA.0
} 
Dim count As Word
Dim colum_buffer(5) As Byte
Dim Z As Byte
dim s1 as porta.3
dim s2 as porta.4

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()
  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(Z)  
    DelayUS(200) //20 us
    ResetPin_G = 0  // output LOW = ON HIGH = OFF
    ResetPin_R = 1
    LE = 0
    Z = Z+1
   Next
  

   
End Sub

Sub RIGHT()

     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(Z)  
    DelayUS(20) //20 us
    ResetPin_R = 0  // output LOW = ON HIGH = OFF
    ResetPin_g = 1
    LE = 0
    Z = Z+1
   Next
  
End Sub
Sub LEFT()

     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
    Shift.Out(MSB_FIRST, X ,8)  
    LE = 1         //Latch data
    PORTB =L_TRows(Z)   // display byte on matrix
    DelayUS(200) //10  1 us for constant on
    ResetPin_R = 0  // output disable
    ResetPin_g = 1
    Z = Z+1
   Next
   
End Sub

Shift.SetOutput(DataPin)
Shift.SetClock(ClockPin)
ADCON1 = $07 
Output(ResetPin_R)
Output(ResetPin_G)
Output (LE)
count = 0
// start of main

TRISB = %00000000
 s1 = 1
 s2 = 1  
// start of main
SetAllDigital
While true
 Z = 0

 count = 0
 index = 0
If s1 = 0 Then // sw 1 closed
   DelayMS(3)//debounce
Repeat   
LEFT
 DelayMS(200)
   //ResetPin_G = 1  // output LOW = ON HIGH = OFF   this shuts off trailing byte in shifter reg.
   Until count = 10   // total of 11 arrows
 End If 
 
If s2 = 0 Then
DelayMS(3)
Repeat
RIGHT
 Inc(count)
   DelayMS(200)
  // ResetPin_G = 1  // output LOW = ON HIGH = OFF   this shuts off trailing byte in shifter reg.
   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
 
OUPS!! I forgot 4 bit input

While laying in bed last night, I got to thinking about the switch routine and it dawned on me, The HT12D decoder chip outputs a 4 bit nibble.
Will get that connected up then back to the posted code.
 
most of my projects tend to do that.
I find I often come up with solutions while laying in bed either before going to sleep or first thing in the morning.
 
trying lots of solutions but no cigar

I still get all the sub routines to execute one after another instead of going with what the SW status is.
WHY??
Going to try a repeat until loop
Code:
sub check_Rturn()
      if SW1 = 0
      then RIGHT
      delayms(50)  //sw debounce
     
      
      end if
end sub

sub check_Lturn()

    if SW2 = 0
    
      then LEFT
      delayms(50)  //sw debounce
     
      end if 
end sub
sub check_Ride()
    if SW2 = 1 and SW2 = 1
      then LEFT
      delayms(50)  //sw debounce
     
      end if 


end sub

Shift.SetOutput(DataPin)
Shift.SetClock(ClockPin)
ADCON1 = $07 
Output(ResetPin_R)
Output(ResetPin_G)
Output (LE)
count = 0
// start of main
SW1 = 1
SW2 = 1
TRISB = %00000000

While true 

  Z = 0 
  count = 0 
check_RTurn
check_LTurn
check_Ride
Wend
 End
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top