/* Programa con el 18f13k50 que se utiliza como sensor de intensidad de luz, temperatura y voltaje,
a traves de dos entradas analógicas, enviando la información por USB a una PC o Laptop,
desde donde se podrá consultar dichos valores a petición de un usuario o de manera periodica
en forma automática. Se usa un LED blanco, como sensor de luz, ya que este dispositivo,
cuando es iluminado presenta en sus terminales un voltaje, proporcional a la intensidad de la luz incidente.
Se pone un botón en rc5 para enviar desde el PIC18 hacia la PC la información delos sensores.
(El modo de envío automático se deshabilita). En la aplicación de VB6 se coloca un botón para solicitar
datos al PIC18, enviando un valor numérico en el packet el cual debe ser reconocido por el PIC18.
VendorID = 6019, ProductID = 2003 Alfredo Segura, Queretaro, Mexico, noviembre de 2020.*/
#include <18F13k50.h>
#fuses HS,NOWDT,NOPROTECT,NOCPB,NOLVP,NODEBUG,MCLR,CPUDIV1,PLLEN,USBDIV1,NOIESO,PUT
#use delay(clock = 48000000)
//utiliza un XTAL de 12 MHz, para que con PLL arroje 48MHz
#define USB_HID_DEVICE TRUE // Deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK // Activa EP1(EndPoint1) para las transferencias IN Bulk/Interrupt
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK // Activa EP1(EndPoint1) para las transferencias OUT Bulk/Interrupt
#define USB_EP1_TX_SIZE 8 // Tamaño reservado para el Buffer Tx EndPoint1
#define USB_EP1_RX_SIZE 8 // Tamaño reservado para el Buffer Rx EndPoint1
#include <pic18_usb.h>
#include <hid_analog2.c> // Configuración del USB y los descriptores para este dispositivo
#include <usb.c> // Handles usb ,tokens y descriptores
// Se declara el nombre a cada uno de los 8 elemento del vector recibe[8]
#define dato0 recibe[0]
#define dato1 recibe[1]
#define dato2 recibe[2]
#define dato3 recibe[3]
#define dato4 recibe[4]
#define dato5 recibe[5]
#define dato6 recibe[6]
#define dato7 recibe[7]
// Se declara el nombre a cada uno de los 8 elemento del vector envia[8], enviar_n
#define enviar_0 envia[0]
#define enviar_1 envia[1]
#define enviar_2 envia[2]
#define enviar_3 envia[3]
#define enviar_4 envia[4]
#define enviar_5 envia[5]
#define enviar_6 envia[6]
#define enviar_7 envia[7]
#use fast_io(A) // LATA=0xF89 PORTA=0xF80, 5 I/O pins
#use fast_io(B) // LATB=0xF8A PORTB=0xF81, 4 I/O pins
#use fast_io(C) // LATC=0xF8B PORTC=0xF82, 8 I/O pins
#byte ptoa = 0xf80#byte ptob = 0xf81
#byte ptoc = 0xf82
#byte lata = 0xf89
#byte latb = 0xf8a
#byte latc = 0xf8b
#bit ra0 = 0xf89.0 // D+ de USB
#bit ra1 = 0xf89.1 // D- de USB
// ra3 es MCLR
// ra4 y ra5 XTAL 12MHz
#bit rb6 = 0xf8a.6 // rb6 salida LED de conexión establecida
#bit rb7 = 0xf8a.7 // rb7 salida LED de actividad
#bit rc3 = 0xf82.3 // Sensor Luz con LED Blanco
#bit rc5 = 0xf82.5 // Botón para iniciar envío de datos a una PC
#bit rc6 = 0xf82.6 // Sensor Voltaje#bit rc7 = 0xf82.7
// Sensor Temperatura int8 recibe[8];
// Declaramos la variable recibe de 8 bytes
//int info0 = 0, info1, info2, info3, info4, info5, info6, info7;
int8 envia[8]; // Declaramos la variable envia de 8 bytes
int info[8] = {0,0,0,0,0,0,0,0};
int i, j, volts = 0, tempe = 0, luz = 0;
int volts_ant, tempe_ant, luz_ant;
int1 flag = 0, flag2 = 0;long k = 0;
#int_timer0void actividad(void) {
i++;
k++;
if (i >= 190) {
rb7++; // LED de actividadi = 0;
}
if (k >= 1500) {
flag2 = 1;
k = 0;
}
set_timer0(0);
}
void ini(void) {
enable_interrupts(global);
disable_interrupts(int_timer0);
setup_timer_0(t0_internal | t0_div_1);
setup_adc(adc_clock_internal);
setup_adc_ports(sAN7 |sAN8 | sAN9 | vss_vdd);
set_tris_a(0b11101111); // XTAL, D+, D-, MCLRset_tris_b(0b00001111);
// rb6 Enumerado, rb7 LED de actividadset_tris_c(0b11101000);
// rc3, rc6 y rc7 entradas analogicas.
usb_init(); // Inicializa USB
delay_ms(100);
ptoa = 0x00, ptob = 0x00, ptoc = 0xbf;
set_timer0(0);
}
void main(void) {
ini();
delay_ms(100);
usb_task(); ///habilita USB
usb_wait_for_enumeration(); ///Espera hasta que la PC reconozca este dispositivo
rb6 = 1;
enable_interrupts(int_timer0);
while(true) {
if(usb_kbhit(1)) { // Se reciben dati[0,2,4,6,8,10,12] de una sola vez
usb_get_packet(1, recibe, 8);
info[0] = dato0;
info[1] = dato1;
info[2] = dato2;
info[3] = dato3;
info[4] = dato4;
info[5] = dato5;
info[6] = dato6;
info[7] = dato7;
delay_us(10);
flag = 1;
}
if (flag == 1) { // Se ha recibido un MSG USB válido
if (info[2] == 49) { // Verificar si infa[2] == 49, indica petición de informe
flag = 0;
goto DISPARO;
}flag = 0;
}
if (rc5 == 0) {
DISPARO:set_adc_channel(7); // Prepara AN8 para leer Votaje
luz = read_adc();
delay_us(50);
set_adc_channel(8); // Prepara AN8 para leer Votaje
volts = read_adc();
delay_us(50);
set_adc_channel(9); // Prepara AN9 para leer Temperatura
tempe = read_adc();
delay_us(50);
enviar_0 = 255;
enviar_1 = volts;
enviar_2 = 255;
enviar_3 = Tempe;
enviar_4 = 255;
enviar_5 = luz;
enviar_6 = 255;
enviar_7 = 255;
//usb_put_packet(int8 endpoint, int8 * ptr, unsigned int16 len, USB_DTS_BIT tgl)
usb_put_packet(1, envia, 8, usb_dts_toggle);
do {
delay_us(50);
j++;
} while (rc5 == 0);
}
if (flag2 == 1) { // Monitorea sensores en forma automática
set_adc_channel(7); // Prepara AN8 para leer Votaje
luz = read_adc();
delay_us(50);
set_adc_channel(8); // Prepara AN8 para leer Votaje
volts = read_adc();
delay_us(50);
set_adc_channel(9); // Prepara AN9 para leer Temperatura
tempe = read_adc();
delay_us(50);
if (luz != luz_ant) {
luz_ant = luz;
flag2 = 0;
goto DISPARO;
}
if (volts != volts_ant) {
volts_ant = volts;
flag2 = 0;
goto DISPARO;
}
if (tempe != tempe_ant) {
tempe_ant = tempe;
flag2 = 0;
goto DISPARO;
}flag2 = 0;
} delay_us(100);
}
}