Utilizar valor de conversión del ADC del 16f877 para tomar una decisión en ASM

Buenas como se encuentran ando con un problema, bueno en realidad es que no comprendo bien que hacer ahora, dejemen explicar la situacion.

Primero ando realizando un proyecto que mida peso, después envié este valor de peso medido por medio de RS232 a la PC observándolo por el hyperteminal, después dependiendo de 4 pesos distintos se mueva a 4 posiciones distintas un motor paso a paso 0 grados, 90 grados, 180 grados y 270 grados. Ya realice el pesado haciendo uso de una celda de carga de 1kg (alimentada a 5V), la amplificacion la realice usando un INA128, a su vez la conversión ya logre realizarla, aqui es donde me encuentro confundido :confused: ya logre enviar este valor al PC por rs232 (use el max232 para esto) sin embargo tengo algunos problemas, los explicare en orden.

1- El valor de ADC no lo e transformado a gramos que es lo que deseo que vea en la PC, e recolectado varios valores y realice una tabla...

Peso (g) | Voltaje (V)
100 | 0.49
200 | 1.11
300 | 1.64
400 | 1.93
500 | 2.51
600 | 2.94
700 | 3.57
800 | 4.26
900 |4.54
1000 | 4.93

estos son los datos que obtuve (el peso muerto ya fue eliminado), ahora con estos datos, alguna idea de como hacer para que este valor de voltaje ya convertido por el ADC se vea en gramos en la PC?

2- Ahora teniendo los valores, mediré 4 pesos para realizar las cuatro posiciones del motor paso a paso, los cuales serán 100 g, 150g, 200 g, 250g, estos valores son aproximados, la exactitud no es muy necesaria. Ahora bien el problema es que al realizar la conversión la señal del valor analógico fluctúa lo cual hace que el valor de la conversión cambie un poco hacia arriba y otro poco hacia abajo, así que me pregunto alguna forma para que deje de cambiar no me sirve que cambie el valor, sera que me hace falta mejorarar la etapa de amplificación, o estas fluctuaciones son normales, las fluctuaciones son de alrededor de 20mV, pensé en tal vez modificar la resolución del ADC para que vea cambios mayores a este valor así solucionar esto, no se si es posible ya saben usando Vref+ y Vref-?

3- digamos que ya tengo todo listo, ahora la cuestión, es como se que valor en binario en 8 bits tendrá los pesos de 100g, 150g, 200g, 250g, (según mi código estoy trabajando a 8 bits con el ADRESH) para así usarlos para comparación mayor o igual y escoger la subrutina de posicionamiento correspondiente al valor

Creo que esas son mis preguntas, no se que recomendaciones puedan darme, disculpen si no me explique bien, si no entienden algo me lo dicen, les dejo el código que estoy usando (la parte de salida al puerto C era para ver el numero en 8 bits de cada peso que se usara para escoger la posición del Paso a paso, pero no fue de mucha utilidad en realidad).

Código:
LIST		P=16F877
	INCLUDE		<P16F877.INC>
	__CONFIG	_CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
	
	
	org 	0x000 	
	nop 			
	nop
	
_inicio
	bcf 	STATUS,RP0 
	bcf 	STATUS,RP1
	movlw 	b'01000001' 
	movwf 	ADCON0
	bsf 	STATUS,RP0 
	bcf 	STATUS,RP1
	clrf 	TRISA 
	clrf 	TRISB 
	clrf 	TRISC 
	clrf 	TRISD 
	clrf 	TRISE 
	movlw 	b'00000111'
	movwf 	OPTION_REG 
	movlw 	b'00001110' 
	movwf 	ADCON1
	bsf 	TRISA,0                
	bcf 	STATUS,RP0 
	bcf 	STATUS,RP1
	clrf 	PORTC 
	call	RS232_Inicializa
_bucle
	btfss 	INTCON,T0IF

	goto 	_bucle 
	bcf 	INTCON,T0IF 
	bsf 	ADCON0,GO 
_espera
	
	btfsc 	ADCON0,GO 
	goto 	_espera 
	movf 	ADRESH,W 
	movwf 	PORTC 
	movf	ADRESH,W
	call	RS232_EnviaNumero
	goto 	_bucle ;Ir bucle

	INCLUDE	<RETARDOS.INC>
	INCLUDE	<RS232_1200.INC>
	end

El código lo único que hace es la conversión, envió de este valor directamente al PC, enviar este valor al puerto C para encender unos leds, la parte de posicionamiento del Paso a paso esta por aparte ahora solo estoy intentando arreglar esta parte. Espero alguien me pueda dar algún consejo, saludos. Espero una respuesta.
 
Ok bueno, al parecer no aparecen ideas, en fin e avanzado mucho en el proyecto y ahora solo estoy teniendo un problema, veamos el valor del ADC es de 10 bits, necesito enviarlos por el rs232, ahora bien, tengo 2 preguntas.

1- Para enviar el dato ando usando un registro de solo 8 bits, como hago para enviar los 10 bits por el rs232 ? no se como hacerle, digamos como dije pensaba usar solo el AdresH pero no me suena, aunque en teoria segun entiendo, si no peso mas de 500 g no deberia nunca tocar mas de 8 bits. Pero no estoy muy seguro de ello.

2- Tengo que envia este numero al hyperterminal, sin embargo si lo envio nada mas simplemente me salen un monton de caracteres que no tienen nada que ver con este valor, lo que se me ocurrio era sumarle 0x30 H para transformarlo a ASCII pero el problema fue que ahora no tira caractes raros si no que letras y algunos numeros, el problema es que solo debo enviar el valor numerico, no letras, alguna solucion a este punto que debo hacer para que el valor se vea solo en numeros en la hyperterminal.

... bueno gracias de antemano.
 
Ok bueno, al parecer no aparecen ideas, en fin e avanzado mucho en el proyecto y ahora solo estoy teniendo un problema, veamos el valor del ADC es de 10 bits, necesito enviarlos por el rs232, ahora bien, tengo 2 preguntas.

1- Para enviar el dato ando usando un registro de solo 8 bits, como hago para enviar los 10 bits por el rs232 ? no se como hacerle, digamos como dije pensaba usar solo el AdresH pero no me suena, aunque en teoria segun entiendo, si no peso mas de 500 g no deberia nunca tocar mas de 8 bits. Pero no estoy muy seguro de ello.

2- Tengo que envia este numero al hyperterminal, sin embargo si lo envio nada mas simplemente me salen un monton de caracteres que no tienen nada que ver con este valor, lo que se me ocurrio era sumarle 0x30 H para transformarlo a ASCII pero el problema fue que ahora no tira caractes raros si no que letras y algunos numeros, el problema es que solo debo enviar el valor numerico, no letras, alguna solucion a este punto que debo hacer para que el valor se vea solo en numeros en la hyperterminal.

... bueno gracias de antemano.


Saludos

Para la primera pregunta, si estas seguro de que NUNCA habrá una medida que sobrepase un número de 8 bits puedes entonces solamente utilizar el dato en ADRESL y enviarlo a la PC

Para la segunda pregunta debes de hacer una rutina de conversión Binario-BCD-ASCII para enviar un correcto formato al PC. Creo tener una por allí, deja busco
 
Saludos

Para la primera pregunta, si estas seguro de que NUNCA habrá una medida que sobrepase un número de 8 bits puedes entonces solamente utilizar el dato en ADRESL y enviarlo a la PC

Para la segunda pregunta debes de hacer una rutina de conversión Binario-BCD-ASCII para enviar un correcto formato al PC. Creo tener una por allí, deja busco

En verdad me seria de gran utilidad si, tuvieras uno por ahí en si solo me hace falta eso, para poder terminar esto. (y)
 
Acá dejo una rutina que hice hace algún tiempo para lograr la conversión de binario a BCD, tiene la desventaja que es solo para un máximo de 7 bits pero siguiendo la idea se puede expandir a cualquier número de bits.

La idea consiste en ir sumando la ponderación que cada bit tiene respecto a su posición en binario. Por ejemplo el binario 5:

0101 que en su correspondiente decimal es 2^2 + 2^0=5.
Entonces lo único que tenemos que hacer es ir revisando bit por bit el número binario a convertir e ir sumando en otro registro la ponderación correspondiente dependiendo si el bit es 1 o 0, (si es cero obviamente se ignora y se pasa al siguiente bit).

Acá una rutina que hace esta operación:

Código:
Conv_Bin_BCD				   ;Subrutina de conversión de un dato binario a BCD

movlw	LOW T_ConvBin_BCD
movwf	FLPuntL	                    ;Direcciona tabla de ctes de conversión Bin->BCD
movlw	HIGH T_ConvBin_BCD
movwf	FLPuntH					
clrf		BCDL
clrf		BCDH		            ;Inicia registros de almacenamiento del # BCD
movlw	.7
movwf	Cont1		            ;El # binario a convertir tiene un máximo de 7 bits
	
Bucle_Conv

btfss		BINBCD,.0			    ;Revisa bit 0 del registro de conversión
goto		$+.17			    ;El bit es 1, suma a la cuenta su valor de ponderación	
call		Lee_FLASH		    ;Obtiene dato de la memoria FLASH del MCU
movwf      Temp1		            ;y lo almacena temporalmente
andlw		0x0F					;Considera solamente nibble inferior
addwf		BCDL,F
movlw		0x0A
subwf		BCDL,W
btfss		        STATUS,C			     ;¿Hubo desborde en registro de unidades?
goto		        $+.6				  ;No
movlw		.6
addwf	BCDL,F			;Ajusta registro de unidades
movlw	0x0F
andwf	BCDL,F					
incf		BCDH,F		      ;Ajusta registro de decenas
swapf	Temp1,W		;Obtiene cifra del registro de decenas
andlw	0x0F
addwf	BCDH,F		;Suma registro de decenas al valor anterior
rrf		BINBCD,F	       ;Recorre sgte bit de ponderación del valor binario a convertir
incf		FLPuntL,F		;Actualiza apuntador de constantes ponderadas
decfsz	Cont1,F					
goto		Bucle_Conv	;Bucle de conversión de código
return				;Número binario convertido, retorno de la subrutina

T_ConvBin_BCD

	DT			0x01,0x02,0x04,0x08,0x16,0x32,0x64

El dato a convertir se recibe en el registro BINBCD y el resultado es devuelto en dos registros BCDH y BCDL. Para obtener el correspondiente ASCII a cada dígito basta con sumar 0x30 a cada registro BCDH y BCDL.

Las instrucciones goto $+.x son saltos de x instrucciones después (+) o antes (-) del goto

Lo de la rutina de "Lee FLASH" se tiene en este post

https://www.forosdeelectronica.com/f26/aporte-otra-forma-manejar-tablas-algunos-pic16f-103760/
 
Última edición:
Acá dejo una rutina que hice hace algún tiempo para lograr la conversión de binario a BCD, tiene la desventaja que es solo para un máximo de 7 bits pero siguiendo la idea se puede expandir a cualquier número de bits.

La idea consiste en ir sumando la ponderación que cada bit tiene respecto a su posición en binario. Por ejemplo el binario 5:

0101 que en su correspondiente decimal es 2^2 + 2^0=5.
Entonces lo único que tenemos que hacer es ir revisando bit por bit el número binario a convertir e ir sumando en otro registro la ponderación correspondiente dependiendo si el bit es 1 o 0, (si es cero obviamente se ignora y se pasa al siguiente bit).

Acá una rutina que hace esta operación:

Código:
Conv_Bin_BCD				   ;Subrutina de conversión de un dato binario a BCD

movlw	LOW T_ConvBin_BCD
movwf	FLPuntL	                    ;Direcciona tabla de ctes de conversión Bin->BCD
movlw	HIGH T_ConvBin_BCD
movwf	FLPuntH					
clrf		BCDL
clrf		BCDH		            ;Inicia registros de almacenamiento del # BCD
movlw	.7
movwf	Cont1		            ;El # binario a convertir tiene un máximo de 7 bits
	
Bucle_Conv

btfss		BINBCD,.0			    ;Revisa bit 0 del registro de conversión
goto		$+.17			    ;El bit es 1, suma a la cuenta su valor de ponderación	
call		Lee_FLASH		    ;Obtiene dato de la memoria FLASH del MCU
movwf      Temp1		            ;y lo almacena temporalmente
andlw		0x0F					;Considera solamente nibble inferior
addwf		BCDL,F
movlw		0x0A
subwf		BCDL,W
btfss		        STATUS,C			     ;¿Hubo desborde en registro de unidades?
goto		        $+.6				  ;No
movlw		.6
addwf	BCDL,F			;Ajusta registro de unidades
movlw	0x0F
andwf	BCDL,F					
incf		BCDH,F		      ;Ajusta registro de decenas
swapf	Temp1,W		;Obtiene cifra del registro de decenas
andlw	0x0F
addwf	BCDH,F		;Suma registro de decenas al valor anterior
rrf		BINBCD,F	       ;Recorre sgte bit de ponderación del valor binario a convertir
incf		FLPuntL,F		;Actualiza apuntador de constantes ponderadas
decfsz	Cont1,F					
goto		Bucle_Conv	;Bucle de conversión de código
return				;Número binario convertido, retorno de la subrutina

T_ConvBin_BCD

	DT			0x01,0x02,0x04,0x08,0x16,0x32,0x64

El dato a convertir se recibe en el registro BINBCD y el resultado es devuelto en dos registros BCDH y BCDL. Para obtener el correspondiente ASCII a cada dígito basta con sumar 0x30 a cada registro BCDH y BCDL.

Las instrucciones goto $+.x son saltos de x instrucciones después (+) o antes (-) del goto

Lo de la rutina de "Lee FLASH" se tiene en este post

https://www.forosdeelectronica.com/f26/aporte-otra-forma-manejar-tablas-algunos-pic16f-103760/

Increible lo implementare a ver como sale, ahi te aviso como me fue, solo una pregunta ya que el resultado queda en 2 registros a la hora de enviarlos por el RS232 debo enviar uno primero(ya pasado a ascii) y luego enviar el segundo registro (tambien en ascii), no es asi?
Gracias por la ayuda :)
 
Correcto, primero se tiene que enviar el resultado más significativo y después de este el menos significativo. Cualquier duda con respecto ala rutina de conversión acá ando
 
Atrás
Arriba