Autor Tema: como unir un dato parte alta y baja despues de usar make8 si no es ccs  (Leído 5142 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado juancho056

  • PIC10
  • *
  • Mensajes: 35
Hola!

Estoy realizando un programa en el cual uso la funcion make8 o bien corrimientos y una and para sacar la parte alta y baja de un dato capturado por el adc de 10 bit que poseen los microcontroladores, esta parte alta y la baja del dato las envio en 2 registro en al memoria eeprom a VB6, y hasta y todo de maravilla.
El problema es que no entiendo como volver a unir la parte alta y baja del dato para saber el valor del voltaje capturado, el voltaje que estoy capturando con el adc es de 0-5V, si alguien tiene conocimientos respecto al tema o sabe como volvera  unir ambos datos con una formula estare muy agradecido.

Feliz dia!   :)

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #1 en: 06 de Abril de 2015, 07:25:27 »
int datoCompleto

datoCompleto = (ParteAlta << 8) + ParteBaja;

algo así?

sds.
-
Leonardo Garberoglio

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #2 en: 06 de Abril de 2015, 08:06:21 »
También sirve con matemáticas tradicionales:

datoCompleto = ParteAlta *256 + ParteBaja;

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #3 en: 06 de Abril de 2015, 11:20:41 »
Citar
datoCompleto = (ParteAlta << Cool + ParteBaja;
.

Estas desplazando la parte alta, un numero equivalente a un emoticono con gafas xd, haha ;-)
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado juancho056

  • PIC10
  • *
  • Mensajes: 35
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #4 en: 06 de Abril de 2015, 12:54:54 »
Hola gracias por sus respuestas  ((:-)), pero el caso es el siguiente:

La simulacion la estoy haciendo en proteus, al medir el valor suministrado al adc es 3.40 v, el programa al cual me llegan ls datos como entreos se visualiza este valor como parte alta 2 y parte baja 184 entonces

(2*256)+184=696

Todo esto dividido por 2 me esta dando 348 que es un valor con una tolerancia aceptable.

El problema ya vi que radica en que cuando los voltajes disminuyen por debajo de 1v la parte alta toma el valor de 0 y la parte baja siempre toma un valor de 138 sin importar cual sea el voltaje  0.85, o 0.25v los 2 registros simepre son los mismos. Es posible que este valor se de por la manera en que estoy imprimiendo el mensaje desde CCS %U, o cual puede ser el motivo?

Gracias por responder  :mrgreen:

 


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #5 en: 06 de Abril de 2015, 13:21:02 »
El problema ya vi que radica en que cuando los voltajes disminuyen por debajo de 1v la parte alta toma el valor de 0 y la parte baja siempre toma un valor de 138 sin importar cual sea el voltaje  0.85, o 0.25v los 2 registros simepre son los mismos. Es posible que este valor se de por la manera en que estoy imprimiendo el mensaje desde CCS %U, o cual puede ser el motivo?

Si parece que tu problema es esem es que se esta enviando mal. Deberias enviar el hexadecimal a la PC o aunque sea en 2 partes.

Si usas una referencia de 5V deberia variar la lectura de 0 a 5V significa que el AD  varia desde 0 a 1023 (0x000 a 0x3FF ). Para obtener el valor que da el AD en voltios es simplemente:

Voltios = (AD * 5) / 1023

Si seguimos con la misma referencia de tension 5V. cada bit del ADC reprentaria 5 /1023 aproximadamente 4.88mV

Citar
Todo esto dividido por 2 me esta dando 348 que es un valor con una tolerancia aceptable.

Por que dividirlo por 2 ? no entiendo cual es tu objetivo ahi.

Desconectado juancho056

  • PIC10
  • *
  • Mensajes: 35
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #6 en: 06 de Abril de 2015, 14:21:57 »
Hola KILLERJC, gracias por responder.

Al estar enviando los datos de forma entera desde CCS el planteamineto era el siguiente (Parte alta*256)+parte baja que al ser dividido por 2 me da un valor bastante aproximado al valor dc medido sin el punto flotante por estar trabajando en entero:

Valor DC medido: 3.40V

valor parte alta enviando los datos como entero:2 y parte baja:184

Utilizando la formula  (2*256)+184=696     donde 696/2=348 me da un valor aproximado sin el punto, que con funciones de VB6 pensaba acomodar para que graficara 3.48v
(trabajo inecesario  8)), valores similares se aprecian con diferentes voltajes.

Cuando envio los datos en hexadecimal desde ccs osea %x,  5v es parte alta 3 y parte baja FF como explicas, pero sigue ocurriendo lo mismo para valores inferiores a 1.25v los registros siempre toman el mismo valor para este caso 00 parte alta y 8a parte baja,  no varian.

La idea de tomar todos estos valores es graficar el comportamiento de unos sensores, como los registros toman el mismo valor siempre que bajen de 1.25 v, el comportamiento de la grafica seria el mismo para 1v, 0.85v o 0.25v.  Mientras el voltaje sea menor de 1.25v no podre saber cual fue le voltaje minimo que registro el sensor  :(

Gracias por responder lo aprecio bastante  :mrgreen:



Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #7 en: 06 de Abril de 2015, 15:23:15 »
No te fíes de Proteus trabajando con analógica, pruébalo en real.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #8 en: 06 de Abril de 2015, 23:13:40 »
La idea de tomar todos estos valores es graficar el comportamiento de unos sensores, como los registros toman el mismo valor siempre que bajen de 1.25 v, el comportamiento de la grafica seria el mismo para 1v, 0.85v o 0.25v.  Mientras el voltaje sea menor de 1.25v no podre saber cual fue le voltaje minimo que registro el sensor  :(

Entiendo perfectamente. el AD como dije da un numero de 0 a 1023 asi que siempre trabajas con enteros, luego si lo convertis a flotante para saber el voltaje.
Tu problema pasaria a otro. me parece raro que el ADC no este dandote los valores como corresponde. O el mismo printf te lo esta convirtiendo en un mal valor o hay un problema de simulacion si lo estas haciendo por simulacion. Ya que deberia variar, sino puede haber algo raro en el programa ( pero esto no lo creo por que te da el maximo como 0x3FF ).

Citar
Al estar enviando los datos de forma entera desde CCS el planteamineto era el siguiente (Parte alta*256)+parte baja que al ser dividido por 2 me da un valor bastante aproximado al valor dc medido sin el punto flotante por estar trabajando en entero:

Si da un aproximado pero es un error mas cuando queres graficar lo de un sensor y a la PC no le cuesta nada hacer una multiplicacion y division para dar con el resultado en coma flotante.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #9 en: 06 de Abril de 2015, 23:40:54 »
Citar
El problema ya vi que radica en que cuando los voltajes disminuyen por debajo de 1v la parte alta toma el valor de 0 y la parte baja siempre toma un valor de 138 sin importar cual sea el voltaje  0.85, o 0.25v los 2 registros simepre son los mismos. Es posible que este valor se de por la manera en que estoy imprimiendo el mensaje desde CCS %U, o cual puede ser el motivo?

Coloca el codigo del pic que estas programando en ccs, para ver como tienes configurado el printf.
Ya que, tal como lo indicas arriba no es posible que te esten dando esos valores  :?
Si lo muestras por la lcd o por RS232, la parte baja del resultado, deberia estar disminuyendo a medidas que reduces el voltaje.

Desconectado Daikataro

  • PIC10
  • *
  • Mensajes: 22
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #10 en: 07 de Abril de 2015, 01:31:34 »
Si tu compilador tiene la opción de manipular los bits individuales que forman cada byte o word, tienes la vida hecha. En PSI sería así:

Resultado_ADC.LB = Parte_baja
Resultado_ADC.HB = Parte_alta

En PSI el .LB significa el byte menos significativo de un Word (2 bytes) y HB el byte más significativo. Simplemente escribes el valor de cada byte en un solo word y tienes tu resultado ADC.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #11 en: 07 de Abril de 2015, 19:14:49 »
Código: [Seleccionar]
#include <18f252.h>
#device adc= 10
#fuses XT,NOWDT,PUT,NOBROWNOUT,NOWRTB,NOWRTD
#use delay (crystal= 4000000)

#use RS232(baud=9600,xmit= pin_b0,rcv=pin_b1)


void main()
{
   long res_adc;
   int h_adc, l_adc;
   
   setup_adc_ports(an0);
   setup_adc(adc_clock_internal);
   set_adc_channel(0);
   
   while(true)
   {
      res_adc= read_adc();
      h_adc= make8(res_adc,1);
      l_adc= make8(res_adc,0);
     
      printf("El valor del adc= %lu\r",res_adc);
      printf("Parte alta del adc= %u\r",h_adc);
      printf("Parte baja del adc= %u\r",l_adc);
     
      delay_ms(1500);
   }   
}

El codigo adjunto lo probe y funciona a la perfeccion con el ccs  :mrgreen:
Pruebalo y nos das tus impresiones.  ;-)

Desconectado juancho056

  • PIC10
  • *
  • Mensajes: 35
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #12 en: 08 de Abril de 2015, 14:17:03 »
Hola a todos Gracias por responder, pero el problema persiste, lo explicare paso a paso.

Inicialmente realice todo el montaje para descartar que fuese problemas de simulacion en proteus como indicaba Nocturno, pero proteus y el monatje me funcionan exactamente igual. Actualemente estoy trabajando con el pic16f1936 que es la gama avanzada del pic16f886 que ya no sale, osea tiene muchas mas funciones, mas memoria, pero en sintesis es lo mismo obviamente mucho mas caro.

El problema es que los datos que estoy tomando del adc al ser de 10 bits los tengo que enviar en 2 registros con lo cual uso la funcion make8(dato,1) parte alta y make8(dato,0) parte baja o lo que es lo mismo (dato>>8) y (dato&255), de igual manera lo estoy haciendo para un encoder que me estara contando lo metros (3500)  se hace lo mismo divido el dato en la parte alta y baja para guardarlo en 2 registros de la eeprom y poder contar hasta 65535, hasta ahi todo muy bien.

Los datos los estoy guardando en diercciones de la memoria eeprom, una vez se active una bandera  asi :

 if(flagcommand) {
     commad_process(); // Hay algo pendiente de procesar y lo procesa.
     write_eeprom(0,voltL1);
     delay_us(150);   // minimo de tiempo que se debe esperar para guardar el dato en al eeprom
     write_eeprom(3,voltH1);
     delay_us(150);
     write_eeprom(6,voltL2);
     delay_us(300);
     write_eeprom(9,voltH2);
     delay_us(300);
     write_eeprom(12,metrosH);
     delay_us(200);
     write_eeprom(15,metrosL);
     delay_us(200);
     }
Todo funciona perfecto al recibir y enviar la trama, los datos toman la posicion que requiero, los estoy enviando en entero que la respresentacion ps no tiene mucha importancia en entero 5 v es (3-255) en hexa (3-ff) parte alta y parte baja.

Luego de explicar todo y que todo funciona bien el error es!

en la trama no se visualizan los valores por debajo de 1.25v para el adc captado siempre me muestra parte alta (0) y parte baja (138), para ponerlo mas claro en el contador de metros que empieza en 0 hasta 3500 cuando empieza se visualiza (0) parte alta y (137) parte baja.
Para visualizar que este contando bien estoy imprimendo los metros despues de que envio la trama asi:

 printf("%x-%x-%x-%U-%U-%U-%U-%U-%U-%x-%x\r\n",cmd[0],cmd[1],cmd[2],cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]cmd[8],cmd[9],cmd[10]); // ... y lo muestro
  printf("%lU Metros: \r\n",metros);

Como se observa envio una trama los %U son los dos sensores y el encoder para los metros en sus partes altas y bajas
En la trama tomando las dos ultimas (%U-%U) es la respresentacion del encoder, mientras la variable  metros que la imprimo abajo no llega hasta 255 se ve asi (0)-(137) parte alta y baja en la trama

lo cual me daria mal para tomar el metraja inicial osea

(0*256)+137=137 ese seria el valor siempre desd 1 hasta que supere 255 una vez los lo supera la trama se visualiza asi

(1)-(0) para los registros del encoder, por lo que se puede calcular el metraje
1*256+0=256

(1)-(3)

1*256+3=259

Mientras no se supere el valor de 255 los registros del encoder se veran (0)-(137), lo mismo sucede para el adc que los estoy haciendo para varoles de 0 a 5v, cuando esta por debajo de 1.25 v el valor del registro siempre es (0)-(138), minetras el valor sea >=1.25v todo funciona a la mil maravillas en el adc y mientras el valor sea mayor a 255 funcioan perfecto para llevar el calculo de los metros.

Espero haber expresado bien la idea y que me puedan ayudar, yo vengo rebentando cabeza y no entiendo por uqe se da eso.
Gracias por sus aportes  :mrgreen:

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #13 en: 08 de Abril de 2015, 14:49:13 »
Pega la parte del código de inicialización y lectura del ADC, por favor.

Desconectado juancho056

  • PIC10
  • *
  • Mensajes: 35
Re: como unir un dato parte alta y baja despues de usar make8 si no es ccs
« Respuesta #14 en: 08 de Abril de 2015, 14:53:14 »
Claro Nocturno, gracias,
 va asi:

void main()             //Principal
{
  //setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  ext_int_edge(H_TO_L);  // para contar pulsos de encoder
  setup_adc_ports(sAN0);
  setup_adc_ports(sAN1);
  setup_adc(adc_clock_internal);

  delay_ms(100);
 
  init_cbuff();               // Borra buffer al inicio
  enable_interrupts(int_ext);
  enable_interrupts(int_rda); // Habilita Interrupción RDA
  enable_interrupts(global);  // Habilita interrupciones

 
  do {
  set_adc_channel(0);
   delay_us(20);
   adc1=read_adc();
   voltL1=adc1>>8;
   voltH1=adc1&255;
   voltaje1=(5.0*adc1)/1024.0;
   
  set_adc_channel(1);
   delay_us(20);
   adc2=read_adc();
   voltL2=adc2>>8;
   voltH2=adc2&255;
   voltaje2=(5.0*adc2)/1024.0;

   
     if(flagcommand) {
     commad_process(); // Hay algo pendiente de procesar y lo procesa.
     write_eeprom(0,voltL1);
     delay_us(150);
     write_eeprom(3,voltH1);
     delay_us(150);
     write_eeprom(6,voltL2);
     delay_us(300);
     write_eeprom(9,voltH2);
     delay_us(300);
     write_eeprom(12,metrosH);
     delay_us(200);
     write_eeprom(15,metrosL);
     delay_us(200);
     }
  } while (TRUE);
 
}