Maker Pro
Maker Pro

Walking LEDs Up & Down

Hey Everyone,

I'm fairly new to PICs and so I hope that a few of you may help me in that regard.

I am composing several initiatives that will help me exercise my knowledge in C programming. I've been able to shift LEDs so that they walk up or down, but that was with only 8 LEDs. I have the possibility of using 10 LEDs, which I would like to use, and so I can't use the simple "char" that I used previously for only 8 bits. Therefore, I have concluded that 10 bits is evidently necessary to resolve this issue, and with a "int" variable instead. The problem lies within the fact that "int" is 16 bits, while I only need 10. I was told by someone else that I need to use the AND operation in C to have the remaining 6 bits idle, but I'm not sure I quite understand how to do that. I completely understand the AND operation (I think) but I am not sure how it applies to my code.

Below you'll find the code, I am using MPLAB with the C18 compiler and PIC18F1320.

Code:
Code: 
// 
// WalkingLEDCombo3.C 
// 

   #include <p18f1320.h> 
   #include <delays.h> 
   #include <stdlib.h> 
   #pragma config OSC=INTIO2, WDT=OFF, LVP=OFF, DEBUG=ON 
   #define PAUSE 75 

void main() 
{ 
   unsigned int pat;         // Variable for TRISA 
   unsigned int patstopBits;   // Variable for TRISB 
   OSCCONbits.IRCF0=1; 
   OSCCONbits.IRCF1=1; 
   OSCCONbits.IRCF2=1; 
   while(!OSCCONbits.IOFS); 
   TRISA = 0b11110000; 
   TRISB = 0b11000000; 
while(1) 
{ 
   pat=0b0000000000000001; 
   while(pat>0)            // Loop for shifting LEDs UP 
   { 
      patstopBits=pat>>4;      // patstopBits is a function of pat. 
      LATA = pat;             
      LATB = patstopBits;       // patstopBits is for TRISB. 
      Delay10KTCYx(PAUSE); 
      pat=pat<<1;            // Shift pat once to the right. 
   } 

   pat=0b1000000000000000; 
   while(pat>0)            // Loop for shifting LEDs DOWN. 
   { 
      patstopBits=pat>>4;      // patstopBits is a function of pat. 
      LATA = pat;             
      LATB = patstopBits;      // patstopBits is for TRISB.    
      Delay10KTCYx(PAUSE); 
      pat=pat>>1;            // Shift pat once to the left. 
   } 
} 
}

The code above does work, but since I have 6 extra bits, I have to wait till my variable "pat" shifts through 6 bits before it shifts the LEDs back down again.

I would appreciate any help concerning this matter!

Thanks!
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
The code above does work, but since I have 6 extra bits, I have to wait till my variable "pat" shifts through 6 bits before it shifts the LEDs back down again.

In that case you need to look at your start and/or stop conditions for your inner loops, or perhaps consider another type of loop.

It sounds like you're using 8 (or 10?) outputs to control 8 (or 10) LEDs.

If you get this working correctly, I would next look at charlieplexing the LEDs (google it) using only 4 outputs for up to 12 LEDs.

If you want to try that, I would recommend you define a function that turns on LED 'n' (extinguishing all others) and you call that in your loops.
 
In the first inner while loop, change the while statement to:

while(pat<0x400)

Get rid of the pat=0b1..... statement between the two while loops. In its place, add the statement:

pat >>= 1;

Then figure out why it works and explain it back to me.

---55p
 
In that case you need to look at your start and/or stop conditions for your inner loops, or perhaps consider another type of loop.

It sounds like you're using 8 (or 10?) outputs to control 8 (or 10) LEDs.

If you get this working correctly, I would next look at charlieplexing the LEDs (google it) using only 4 outputs for up to 12 LEDs.

If you want to try that, I would recommend you define a function that turns on LED 'n' (extinguishing all others) and you call that in your loops.

Thanks Steve, I'll look into it.
 
In the first inner while loop, change the while statement to:

while(pat<0x400)

Get rid of the pat=0b1..... statement between the two while loops. In its place, add the statement:

pat >>= 1;

Then figure out why it works and explain it back to me.

---55p


Hi 55pilot,

Thank you very much for replying, I've fixed my code and it works perfectly. I am tentative about how the "0x400" and don't quite understand how that correlates with my previous 0b1... statement. I believe it's hex? Would you please explain how that works? :)

I think that pat>>=1; suggests that pat is equal to itself and that it shifts once. Therefore, I may conclude that the following code performs the same function:

pat=pat>>1;

As such, and if my assumptions are correct, I believe that the very same "pat=pat>>1" within both of the inner while loops are not necessary anymore?
 
Last edited:
Well I've studied hex now and I do believe I know it well enough. Instead of having:

pat<0x400

I changed it to:

pat<0x3FF

They both perform the same thing, although I would still like to know about how the "0x400" works.

The greater than sign indicates that "while 10 bits is greater than pat (inversly meaning that while pat is less than 10 bits), perform the code in the loop.

Thanks!
 
Top