DESCRIPCION DE LA RUTINA DE LECTURA DEL ERROR
La lectura del error o desviación del péndulo de la vertical es realizado por el conversor A/D al cual le llega a través del pin AN0 del microcontrolador la señal desde el potenciómetro ubicado sobre el cabezal de la impresora. Además se ha añadido un preset de ajuste para realizar la puesta a 0 en el modo de calibración, indicando que la posición en la que el péndulo ha sido colocado se corresponde con la que debe ser interpretada como vertical por el controlador. En la siguiente figura se puede ver el detalle del circuito de calibración.

La tensión presente en le pin AN0 es procesada por el conversor A/D y puede ser leída en los registros ADRESH:ADRESL como un número de 10 bits y ser volcada en las variables ADH y AHL.
Luego se llama a la rutina que se encargará de comprobar de que el valor se encuentra dentro del rango deseado y si es necesario realizar el recorte del valor. Debido a que se va a actuar frente a desviaciones muy pequeñas, el error se restringirá al rango ±4, valor que experimentalmente ha demostrado ser el más adecuado dando los mejores resultados.
Además dentro de esta rutina se comprobará el rango para el valor de la variable ANGLE, la que será utilizada para enviar le información telemétrica al PC indicando la inclinación del péndulo. En este caso se ha tomando un rango de valores de ±128 permitiendo enviar en 1 byte tanto el ángulo como el signo.
En la siguiente figura se observa el diagrama de la rutina que lee y procesa el error y más abajo, el listado en dónde se puede consultar el código ensamblador.

Al finalizar la rutina el error devuelto se guarda en la variable ERR para ser procesado por la rutina de control la que se ejecuta periódicamente como ya se ha mencionado anteriormente. Además si el error es nulo se enciende el LED de centrado (salida RE0 del puerto E) para indicar esta situación, dejándolo apagado en caso contrario. Por último para finalizar el bucle de lectura se introduce el retardo necesario para que el conversor A/D inicie una nueva conversión.
Nótese que esta rutina será interrumpida cada 1.54mS por la rutina de control mediante la interrupción provocada por el temporizador del microcontrolador.
CODIGO DE LA RUTINA DE LECTURA DEL ERROR
bsf T0CON,TMR0ON ; activate timer
Loop
bsf ADCON0,NOT_DONE ; Begins ADC conversion
Read
btfsc ADCON0,NOT_DONE
goto Read ; Polling for ADC value
movff ADRESH,ADH ; ADRESH -> ADH
movff ADRESL,ADL ; ADRESL -> ADL
call Calc_E ; Convert ADC value in SPEED and DIRECTION
; returns error in WREG [-4 - 4]
movwf ERR ; Updates ERR
movlw 0x02
movwf LOOP ; Counter
movlw 0x00
bcf PORTE,RE0 ; Turn off Center LED (calibrating)
cpfseq ERR
goto ADCDelay ; if ERR = 0
bsf PORTE,RE0 ; Turn on Center LED (calibrating)
ADCDelay
decfsz LOOP
goto ADCDelay ; Wait a minimum of 2 TADs before another conversion
goto Loop
;**********************************************************
; Transform Error
;**********************************************************
Calc_E
;;;;;;;;;;;;;;;;;;;;;;;;; Range test (ADH value)
movlw B'00000011' ; Mask b0 & b1
andwf ADH
movlw .3
cpfslt ADH ; if ERROR > 1536 (11 00000000)
goto OutGreater ; Out of Range (Greater)
movlw .0
cpfsgt ADH ; if ERROR < 512 (01 00000000)
goto OutLower ; Out of Range (Lower)
movlw .1
cpfseq ADH ; if ERROR is positive (0x0200 - 0x02FF)
goto Greater ; move to the right (greater)
; else move to the left (lower)
; (0x01FF - 0x0100)
Lower
;;;;;;;;;;;;;;;;;;;;;;;;; Telemetry
movff ADL,ANGLE
movlw .128
cpfsgt ANGLE ; if ANGLE < -128
movwf ANGLE ; ANGLE = -128
;;;;;;;;;;;;;;;;;;;;;;;;;
movlw .252 ; Saturation Check (-4)
cpfsgt ADL ; if ADL <= -4
retlw .252 ; Saturation: return -4
movf ADL,W ; else
return ; return Error
Greater
;;;;;;;;;;;;;;;;;;;;;;;;; Telemetry
movff ADL,ANGLE
movlw .127
cpfslt ANGLE ; if ANGLE > 127
movwf ANGLE ; ANGLE = 127
;;;;;;;;;;;;;;;;;;;;;;;;;
movlw .4 ; Saturation Check
cpfslt ADL ; if ADL >= 4
retlw .4 ; Saturation: return 4
movf ADL,W ; else
return ; return error
OutGreater
;;;;;;;;;;;;;;;;;;;;;;;;; Telemetry
movlw .127
movwf ANGLE ; ANGLE = 127
;;;;;;;;;;;;;;;;;;;;;;;;;
retlw .4 ; Saturation: return 4
OutLower
;;;;;;;;;;;;;;;;;;;;;;;;; Telemetry
movlw .128
movwf ANGLE ; ANGLE = -128
;;;;;;;;;;;;;;;;;;;;;;;;;
retlw .252 ; Saturation: return -4