How do I set which input pins are active and how do I distinguish which is which (ASSEMBLY)?

Thread Starter

specs365

Joined Mar 14, 2019
45
Hi everyone, for one of my University courses we are building a line following robot. We have 5 LD transistors acting as sensors. In the code below we have one input set up to work, but now we want to know how we can continue with the program so that each sensor is seperate. For example, we want tp program pin RA1 to be input one with a subroutine of instructions as well as RA2 to be input 2 with its own set of insrtuctions. But we cant see how to actually set up the different pins to sense different things. I really hope that makes sense. For now the code is only switching on LEDs for different detected voltage levels.

Here is the code:

Code:
  list     p=PIC18F45K22
  #include   "p18f45k22.inc"

;========== Configuration bits ==========
;--- Configuration bits ---
  CONFIG  FOSC = INTIO67  ; Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
  CONFIG  WDTEN = OFF  ; Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
   
;========== Definition of variables ==========
  cblock 0x00
  Delay
  RESULTHI
  endc

  org 0x00
; ========== Setup ADC ==========
   
  clrf   ADRESH
  clrf   RESULTHI
  MOVLW    B'00101111'     ; left justify, Frc,
  MOVWF    ADCON2        ; & 12 TAD ACQ time
  MOVLW    B'00000000'     ; ADC ref = Vdd,Vss
  MOVWF    ADCON1        ;
  BSF    TRISA,0      ; Set RA0 to input
  BSF    ANSELA,0     ; Set RA0 to analog
   movlw   b'00000101'
  movwf   ADCON0       ; Enable AN0 of ADC       ;

; ========== Initialise PORTD ==========
   CLRF    PORTD        ; Initialize PORTD
   CLRF    TRISD        ; and set RD<7:0> as outputs

Poll   ;=== Poll for conversion ===
   BSF    ADCON0,GO      ; Start conversion
   BTFSC    ADCON0,GO      ; Is conversion done?
   BRA    $-2        ; No, test again
      ; Note the $-2: $-1 gives a linker error because the
        ; address is not word-aligned

Display   ;=== Read & display result ===
   MOVF    ADRESH,W      ; Read upper 8 bits only, i.e. in this example we
             ; throw away the lower two bits and use in effect
           ; an 8 bit conversion
           ; ADRESH stands for AD RESult High
   MOVWF    RESULTHI      ; store in GPR space
     
Zero   MOVLW   b'00000000'     ; switch off all LEDs on PortD  to indicate 0
   MOVWF   PORTD
   CPFSGT   RESULTHI     ; Test for zero (content of W is 0 at this stage). If RESULTHI > W = 0
   GOTO    Poll       ; GOTO Poll will be skipped and the next comparison will be performed.

Less31   MOVLW   b'00000001'     ; Switch on one LED if answer > 0 and continue.
   MOVWF   PORTD
   MOVF   RESULTHI,0
   SUBLW   D'31'       ; Check if answer is less than 31 by subtracting 31 from it.
   BTFSC   STATUS,C     ; If RESULTHI > 31, the answer is + the C bit is clear and next comparison is done
    ; If RESULTHI < 31, the answer is - the C bit is set and next value is converted
   GOTO   Poll       

;---------Alternative comparison 1-----------
;Les31_alt1
;   MOVLW   b'00000001'     ; Switch on next LED
;   MOVWF   PORTD
;   MOVLW   D'31'
;   CPFSGT   RESULTHI     ; 31 is now in W. If content of RESULTHI > W = 31, GOTO Poll will
;   GOTO   Poll       ; be skipped.     

;---------Alternative comparison 2-----------
; If we only switch on 8 LEDs, we actually do a 3-bit conversion, i.e. we need only look at the
; 3 MSBs.
;
;Les31_alt2
;   MOVLW   b'00000001'     ; Switch on next LED
;   MOVWF   PORTD
;   MOVLW   b'00100000'     ; First step in 3-bit conversion. For next comparison one must use
           ; b'01000000', then b'01100000', etc.
;   CPFSGT   RESULTHI     ; '00100000' is now in W. If content of RESULTHI > W, GOTO Poll will
;   GOTO   Poll       ; be skipped.     
;--------------------------------------------

Less63   MOVLW   b'00000011'     ; Same principle applies as in Less31.
   MOVWF   PORTD
   MOVF   RESULTHI,0     
   SUBLW   D'63'
   BTFSC   STATUS,C
   GOTO   Poll
     
     
Less95   MOVLW   b'00000111'
   MOVWF   PORTD
   MOVF   RESULTHI,0
   SUBLW   D'95'
   BTFSC   STATUS,C
   GOTO   Poll
         
Less127   MOVLW   b'00001111'
   MOVWF   PORTD
   MOVF   RESULTHI,0
   SUBLW   D'127'
   BTFSC   STATUS,C
   GOTO   Poll
     
Less159   MOVLW   b'00011111'
   MOVWF   PORTD
   MOVF   RESULTHI,0
   SUBLW   D'159'
   BTFSC   STATUS,C
   GOTO   Poll
     

Less191   MOVLW   b'00111111'
   MOVWF   PORTD
   MOVF   RESULTHI,0
   SUBLW   D'191'
   BTFSC   STATUS,C
   GOTO   Poll
     
Less223   MOVLW   b'01111111'
   MOVWF   PORTD
   MOVF   RESULTHI,0
   SUBLW   D'223'
   BTFSC   STATUS,C
   GOTO   Poll
     
Less255   MOVLW   b'11111111'
   MOVWF   PORTD        ; No need to test since this is the last range.
   GOTO   Poll
   
   end
 

LesJones

Joined Jan 8, 2017
4,174
You would need to test which input pin is set (Or clear or changed from the last state.)
If you were testing which bit is set you would do something like.
Code:
Start:
   BTFSC    PORTA,1   ;
   GOTO   Action_RA1_set     ;Or call a subroutine
   BTFSC   PORTA,2
   GOTO   Action_RA2_set     ;Or call a subroutine
   BTFSC   PORTA,3
   GOTO   Action_RA3_set     ;Or call a subroutine

;And so on.
If you were looking for a change of state I would read the state of the port and XOR it with the stored value from the past read of the port. The result of the XOR would have the bit (Or bits) set that had changed since the last read of the port.
If looking for a change I suggest using a port that has the interrupt on change function and put the code to see which bit had changed in the interrupt handler.

Edit. I had not read you post properly and assumed you were using digital inputs.
As you are using analogue inputs you would just have to read each analogue input in sequence and see if it's value had changed more than a set amount since the last read and if it had take the required action.

Les.
 
Last edited:

jpanhalt

Joined Jan 18, 2008
11,087
Where did that code come from and what attempts have you made to accommodate other inputs?

You may want to review the ADC section in the datasheet (17.0) and in particular Figure 17-1 should help. Notice, there is only one ADC as already pointed out by LesJones.
 
Last edited:

jpanhalt

Joined Jan 18, 2008
11,087
Line followers like proposed seem to be a common project. I have often wondered whether any groups have tried to make a digital version.

Early in aviation, AN beacons were used (Morse code A = • - , N = - • ). When the pilots were centered on the "beam," they got a monotonous tone (http://www.navfltsm.addr.com/ndb-nav-history.htm ). In theory, one might put IRED's transmitting A's on one side and N's on the other side. Then listen to reflections from the white line.

An IR seeker published by the DPRG (Dallas Personal Robotics Group, dprg.org) several years ago was based on distinguishing IR pulses received from left and right receivers. That is digital, not analog. I cannot find that report any longer, but this code appears to be similar: http://www.airobotnews.com/Make/Robot_make/make11/11.pdf
 

Thread Starter

specs365

Joined Mar 14, 2019
45
Thanks everyone, so I found out you cant read all the sensors at once. You have to step through each one and save its value in a different register.
 

jpanhalt

Joined Jan 18, 2008
11,087
Thanks everyone, so I found out you cant read all the sensors at once. You have to step through each one and save its value in a different register.
Study Les Jones' example. No result is saved per se. That action might involve a save, but likely, it does not.
 

LesJones

Joined Jan 8, 2017
4,174
You can read all of the sensors connected to one ports at once. (MOVFW PORTA) This copies the contents (8 bits.) of PORTA to the W register but Your question was to test which bit (And thus which sensor.) has changed.

Les.
 
Top