PIC16f877A

Thread Starter

kkbanton

Joined Jan 20, 2011
10
Good day guys!

I have my PIC16f877A with a 4x3 keypad as an input, LCD and 8LEDs [RC0-RC7] as my output. I can already display my outputs on LCD and 8LEDs. And I also interfaced a potentiometer in RA1 as an analog input and I just want to control the delay of the 8LEDs using the analog potentiometer but I don't know how. Do you have some ideas? Thanks in advance.:)
 

DumboFixer

Joined Feb 10, 2009
217
Can't you use the value from the ADC as a delay factor in a delay loop. For example, each count of the ADC could represent 5ms so assuming that the ADC returns 0 - 1023 then you could have a delay from 0ms (is that a delay?) to around 5 seconds in 5ms steps.
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
Thanks DumboFixer. I already have that 0-1023 value. But how will the programs flows? I'm using Proton and here is my current program on that. Thanks.

Rich (BB code):
LEDTEST:     
    Print At 1,1, "     LED TEST       "
    Print At 2,1, "[1]Running [4]Blink " 
    Print At 3,1, "[2]Meeting [5]Step  "
    Print At 4,1, "[3]Alternating #-Esc"
    GoSub KEYPAD
    If NUMERIC = 12 Then GoSub BEEP : GoTo MAIN
    If NUMERIC = 1 Then GoSub BEEP : GoTo RUN
    If NUMERIC = 2 Then GoSub BEEP : GoTo MEET
    If NUMERIC = 3 Then GoSub BEEP : GoTo ALTERNATE
    If NUMERIC = 4 Then GoSub BEEP : GoTo BLINK
    If NUMERIC = 5 Then GoSub BEEP : GoTo STEF
    GoTo LEDTEST               

RUN:
    Print At 1, 1, "     LED TEST       "
    Print At 2, 1, "--------------------"     
    Print At 3, 1, "   RUNNING LIGHTS   "                  
    Print At 4, 1, "               #-Esc"
    GoTo RUNNING 

RUNNING:
    GoSub KEYPAD
    If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED1
     DelayMS 200
     Low LED1
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED2
     DelayMS 200
     Low LED2
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP :  GoTo LEDTEST
     High LED3
     DelayMS 200
     Low LED3
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED4
     DelayMS 200
     Low LED4 
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED5
     DelayMS 200
     Low LED5
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED6
     DelayMS 200
     Low LED6
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED7
     DelayMS 200
     Low LED7
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo LEDTEST
     High LED8
     DelayMS 200
     Low LED8
     DelayMS 200
     GoTo RUNNING


 
Last edited by a moderator:

DumboFixer

Joined Feb 10, 2009
217
First of all I'd completely rewrite the program to get rid of those GOTO statements and make it more structured - it currently resembles a plate of spaghetti. Try drawing a flowchart or similar for it.One way of introducing your variable delay is to change your
Rich (BB code):
DelayMS 200
with
Rich (BB code):
DelayMS ADC-VALUE
where ADC_VALUE is the value you've read from the ADC. This should give you a delay of between 0 and 1sec (approx).
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
This is my declarations, is is right? By the way, I also have an LM35 on RA0 and it works well. I have no problem about that.


Declare ADIN_RES 10
Declare ADIN_TAD FRC
Declare ADIN_STIME 10
Dim Result1 As Float
Dim Result2 As DWord
Dim NUMERIC As Byte

This is my ADC program:

ADCREAD:
GoSub READSENSOR
GoSub KEYPAD
If NUMERIC = 12 Then GoSub BEEP : GoTo MAIN
Print At 1, 1, " ADC TEST "
Print At 2, 1, "Temp:[",DEC1 Result1,"C] "
Print At 3, 1, "ADC:[",DEC4 Result2,"] "
Print At 4, 1, " #-Esc"
GoTo ADCREAD

READSENSOR:
Result1 = ADIn 0
Result1 = Result1 * 5 / 1023
Result1 = Result1 * 100
Result1 = Result1 - 2
DelayUS 10
Result2 = ADIn 1
DelayUS 10
Return


Is is right that I used:

DelayMs DEC4 Result2

as the delay of my running lights? Because there is a compilation error when I used that.:(
 

DumboFixer

Joined Feb 10, 2009
217
I'm not familiar with this version of BASIC but your compilation error will be due to you giving the DelayMS function 2 parameters when it requires only 1.

I suspect that you want to use
Rich (BB code):
DelayMS Result2
The DEC4 looks more like a print formating parameter and not needed in the delay call.

Help File said:

Syntax


DelayMs Length

Overview
Delay execution for length x milliseconds (ms). Delays may be up to 65535ms (65.535 seconds) long.

Operators
Length can be a constant, variable, or expression.
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
You're right, because I really don't know what variable will I call for my DelayMs. I've tried ADCON1 and ADIn 1. But it's not working yet.
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
I'm sorry. The speed of LEDs doesn't change even if I rotates the poterntiometer.

Rich (BB code):
 Device = 16F877A
XTAL = 4
ADCON1 = %10000000    ' Set analogue input, Vref is Vdd
TRISA = %111111                ' SETS ALL PORTA PINS TO 1 input , 0 = out
TRISD = %00000111              ' ALL OUTPUT
TRISB = %00000000              '         
TRISC = %00000000              '         
TRISE = %000 
PORTC = 0

'-----------------------------------------------------------------
' HARDWARE DEFINES
'-----------------------------------------------------------------
Declare LCD_TYPE 0
Declare LCD_DTPIN PORTB.0
Declare LCD_ENPIN PORTB.5
Declare LCD_RSPIN PORTB.4
Declare LCD_INTERFACE 4
Declare LCD_LINES 4
PORTB_PULLUPS True
'---------------------------------------------------------------------
'     Define Osc 4                   ' We're using a 4 MHz oscillator
'---------------------------------------------------------------------
Symbol SEGMENTclear = PORTE.2
Symbol SEGMENTinc   = PORTE.0
Symbol SEGMENTdec   = PORTE.1
Symbol BUZZ = PORTB.7
Symbol LED1 = PORTC.0
Symbol LED2 = PORTC.1
Symbol LED3 = PORTC.2
Symbol LED4 = PORTC.3
Symbol LED5 = PORTC.4
Symbol LED6 = PORTC.5
Symbol LED7 = PORTC.6
Symbol LED8 = PORTC.7


Declare ADIN_RES 10      
Declare ADIN_TAD FRC      
Declare ADIN_STIME 10  
Dim Result1 As Float
Dim Result2 As DWord
Dim NUMERIC As Byte
    PORTE = %011
    DelayMS 500

GoSub BEEP
     PORTE = %111
    DelayMS 500


;---------------------------------------------------   
;             MCU DEVELOPMENT BOARD 
;---------------------------------------------------
MAIN:  
    Print At 1, 1, "   MCU Dev't Board  "
    Print At 2, 1, "[1]Test ADC  [4]SEG "  
    Print At 3, 1, "[2]Test Keypad      "
    Print At 4, 1, "[3]Test LED         "                                                               
    DelayMS 300
    GoSub KEYPAD
    If NUMERIC = 1 Then GoSub BEEP : GoTo ADCREAD
    If NUMERIC = 2 Then GoSub BEEP : GoTo KEYPADTEST
    If NUMERIC = 3 Then GoSub BEEP : GoTo LEDTEST
    If NUMERIC = 4 Then GoSub BEEP : GoTo SEGMENTTEST
    Print At 1, 1, "   MCU Dev't Board  "
    Print At 2, 1, "[ ]Test ADC  [ ]SEG "  
    Print At 3, 1, "[ ]Test Keypad      "
    Print At 4, 1, "[ ]Test LED         "                                                               
    DelayMS 300
    GoSub KEYPAD
    If NUMERIC = 1 Then GoSub BEEP : GoTo ADCREAD
    If NUMERIC = 2 Then GoSub BEEP : GoTo KEYPADTEST
    If NUMERIC = 3 Then GoSub BEEP : GoTo LEDTEST
    If NUMERIC = 4 Then GoSub BEEP : GoTo SEGMENTTEST
    GoTo MAIN    
;-------------------------------------------------
;            SEGMENT TEST 
;-------------------------------------------------
SEGMENTTEST:
    Print At 1, 1, " SEVEN SEGMENT TEST "
    Print At 2, 1, "[1]Increment        "     
    Print At 3, 1, "[2]Decrement        "                  
    Print At 4, 1, "               #-Esc"                           
    GoSub KEYPAD
    If NUMERIC = 12 Then GoSub BEEP : GoTo MAIN
    If NUMERIC = 1 Then GoSub BEEP : GoTo INCCE
    If NUMERIC = 2 Then GoSub BEEP : GoTo DECCE
    GoTo SEGMENTTEST 

INCCE:
    Print At 1, 1, " SEVEN SEGMENT TEST "
    Print At 2, 1, "     Increment      "     
    Print At 3, 1, "                    "                  
    Print At 4, 1, "               #-Esc"                           
    High SEGMENTclear
GT:
    GoSub KEYPAD
    If NUMERIC = 12 Then GoSub BEEP : GoTo SEGMENTTEST
    PORTE = %110
    DelayMS 300
    PORTE = %111
    DelayMS 300
    GoTo GT
     
DECCE:
    Print At 1, 1, " SEVEN SEGMENT TEST "
    Print At 2, 1, "     Decrement      "     
    Print At 3, 1, "                    "                  
    Print At 4, 1, "               #-Esc"                           

FT:
    GoSub KEYPAD
    If NUMERIC = 12 Then GoSub BEEP : GoTo SEGMENTTEST
    PORTE = %101
    DelayMS 300
    PORTE = %111
    DelayMS 300
    GoTo FT
;-------------------------------------------------
;             READ ADC    
;-------------------------------------------------
ADCREAD:    
    GoSub READSENSOR
    GoSub KEYPAD
    If NUMERIC = 12 Then GoSub BEEP : GoTo MAIN
    Print At 1, 1, "     ADC TEST       "
    Print At 2, 1, "Temp:[",DEC1 Result1,"]ßC       "     
    Print At 3, 1, "ADC:[",DEC4 Result2,"]          "                  
    Print At 4, 1, "               #-Esc"                           
    GoTo ADCREAD  

READSENSOR:
    Result1 = ADIn 0   
    Result1 = Result1 * 5 / 1023      
    Result1 = Result1 * 100
    Result1 = Result1 - 2
    DelayUS 10            
    Result2 = ADIn 1      
    DelayUS 10            
    Return

;------------------------------------------------
;                LED TEst          
;------------------------------------------------
LEDTEST:              
    Print At 1,1, "     LED TEST       "
    Print At 2,1, "--------------------" 
    Print At 3,1, "                    "
    Print At 4,1, "               #-Esc"
HERE:
    GoSub KEYPAD
    If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED1
     DelayMS 200
     Low LED1
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED2
     DelayMS 200
     Low LED2
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP :  GoTo MAIN
     High LED3
     DelayMS 200
     Low LED3
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED4
     DelayMS 200
     Low LED4 
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED5
     DelayMS 200
     Low LED5
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED6
     DelayMS 200
     Low LED6
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED7
     DelayMS 200
     Low LED7
     DelayMS 200
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED8
     DelayMS 200
     Low LED8
     DelayMS 200
     GoTo LEDTEST

;-------------------------------------------------------------------------
;                    KEypad  Test
;-------------------------------------------------------------------------
KEYPADTEST:
  Print At 1,1, "    KEYPAD TEST     "
  Print At 2,1, "--------------------" 
  Print At 3,1, "Key:[ ]             "
  Print At 4,1, "               #-Esc"
  DelayMS 100               
CHER1:
  Print $FE, $0F 
  Cursor 3 , 6    
  GoSub KEYPAD
  If NUMERIC= 12 Then GoSub BEEP : GoTo CCANCEL 
  If NUMERIC = 30 Then GoTo CHER1  
  Print At 3,6, DEC1 NUMERIC 
  GoSub BEEP
  GoTo CHER1
CCANCEL:  
  Print $FE, $0C  
  GoTo MAIN 
;-------------------------------------------------------------------------
;                     SOUNDER          
;-------------------------------------------------------------------------
BEEP:
    High BUZZ
    DelayMS 200
    Low BUZZ
    DelayMS 100
    Return
;-------------------------------------------------------------------------
;                      Keypad Scanning
;-------------------------------------------------------------------------
KEYPAD:
     NUMERIC = 30
     PORTD=%01110000
     DelayMS 1   
     If PORTD.0=0 Then GoTo one
     If PORTD.1=0 Then GoTo two
     If PORTD.2=0 Then GoTo three

     PORTD=%01101000
     DelayMS 1   
     If PORTD.0=0 Then GoTo four
     If PORTD.1=0 Then GoTo five
     If PORTD.2=0 Then GoTo six

     PORTD=%01011000
     DelayMS 1    
     If PORTD.0=0 Then GoTo seven
     If PORTD.1=0 Then GoTo eight
     If PORTD.2=0 Then GoTo nine

     PORTD=%00111000
     DelayMS 1   
     If PORTD.0=0 Then GoTo aste
     If PORTD.1=0 Then GoTo zero
     If PORTD.2=0 Then GoTo pound
     PORTD=0
     Return

 one:
     If PORTD.0=0 Then GoTo one
     NUMERIC = 1 
     Return
 two:
     If PORTD.1=0 Then GoTo two
     NUMERIC = 2
     Return
 three:
     If PORTD.2=0 Then GoTo three
     NUMERIC = 3
     Return
 four:
     If PORTD.0=0 Then GoTo four
     NUMERIC = 4 
     Return
 five:
     If PORTD.1=0 Then GoTo five
     NUMERIC = 5
     Return
 six:
     If PORTD.2=0 Then GoTo six
     NUMERIC = 6 
     Return
 seven:
     If PORTD.0=0 Then GoTo seven
     NUMERIC = 7
     Return
 eight:
     If PORTD.1=0 Then GoTo eight
     NUMERIC = 8
     Return
 nine:
     If PORTD.2=0 Then GoTo nine
     NUMERIC = 9
     Return
 aste:
      If PORTD.0=0 Then GoTo aste
     NUMERIC = 11
     Return
 pound:
     If PORTD.2=0 Then GoTo pound
     NUMERIC = 12
     Return
 zero:
     If PORTD.1=0 Then GoTo zero
     NUMERIC = 0
     Return

End
 

DumboFixer

Joined Feb 10, 2009
217
In your display does the value of Result2 change when you adjust the potentiometer ?

In your section of code that deals with turning the LEDs on and off, LEDtest, try changing all the
Rich (BB code):
DelayMS 200
to
Rich (BB code):
DelayMS Result2
You should end up with something like this:

Rich (BB code):
;------------------------------------------------
;                LED TEst          
;------------------------------------------------
LEDTEST:              
    Print At 1,1, "     LED TEST       "
    Print At 2,1, "--------------------" 
    Print At 3,1, "                    "
    Print At 4,1, "               #-Esc"
HERE:
    GoSub KEYPAD
    If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED1
     DelayMS Result2
     Low LED1
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED2
     DelayMS Result2
     Low LED2
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP :  GoTo MAIN
     High LED3
     DelayMS Result2
     Low LED3
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED4
     DelayMS Result2
     Low LED4 
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED5
     DelayMS Result2
     Low LED5
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED6
     DelayMS Result2
     Low LED6
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED7
     DelayMS Result2
     Low LED7
     DelayMS Result2
     GoSub KEYPAD
     If NUMERIC = 12 Then  GoSub BEEP : GoTo MAIN
     High LED8
     DelayMS Result2
     Low LED8
     DelayMS Result2
     GoTo LEDTEST
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
Thanks for that. I tried DelayMs Result2 but the speed doesn't change when I'm rotating the potentiometer. Actually, it now slower than 200ms delay. But the potentiometer works when I'm in ADC mode of the program. It has 0-1023 value.
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
Microchip PIC16f877A
Compiler? What do you mean? As I installed Proton IDE, it compiles already. And I'm using PicKit2 to load my program on PIC.
 

DumboFixer

Joined Feb 10, 2009
217
What happens if you go into ADC mode, set the potentiometer to maximum and then go into LEDtest mode ?

Now go back into ADC mode, set the potentiometer to minimum and then go back into LEDtest mode ?

What I believe is happening is that the LEDtest code is using whatever value is left over from the ADC mode. If this is the case then add
Rich (BB code):
Result2 = ADIn 1
to the begining of LEDtest so that it is recalculated each time the LEDs start a new cycle.
 

Thread Starter

kkbanton

Joined Jan 20, 2011
10
Hi DumboFixer, thank you sir! It works, the only thing is that, when I placed

Rich (BB code):
Result2 = ADIn 1
in the LEDTEST program, it will update the speed every after its 1 complete loop. If I have the maximum rotation in potentiometer, I'm waiting for too long to change its speed. So I do it this way,

Rich (BB code):
     High LED1
     Result2 = ADIn 1
     DelayMS Result2
     Low LED1
     Result2 = ADIn 1
     DelayMS Result2
     High LED2
     Result2 = ADIn 1
     DelayMS Result2
     Low LED2
     Result2 = ADIn 1
     DelayMS Result2
so that the rotation of the potentiometer updates the speed every after each LED blinks. I also applied it on the speed of counting of my 7Segment. Thank you so much sir! Thanks also to thatoneguy. Thank you guys. You really helped me a lot! Thanks!:D:D:D:D:D:)
 
Top