Professional Documents
Culture Documents
microcontrolador
CONTENIDOS 3
FIGURAS 6
TABLAS 7
ÍNDICE DE CONTENIDOS
2
1.9 ENTORNO DE TRABAJO __________________________________________ 32
1.9.1 Compilador ___________________________________________________________ 32
1.9.2 Software de grabación ___________________________________________________ 35
1.9.3 Hardware de grabación___________________________________________________ 38
2 MEMORIA DE CÁLCULO __________________________________________40
2.1 SUMINISTRO NECESARIO ________________________________________ 41
2.2 REGULACIÓN DEL SENSOR CNY70 ________________________________ 42
2.2.1 Calculo de resistencias de polarización del CNY70 ______________________________ 42
2.2.2 Sistema nuevo de lectura para la distinción de barras y espacios ____________________ 44
2.2.2.1 Calculo experimental de las resistencias en el nuevo sistema de lectura __________ 45
2.3 REGULACIÓN DE LA LECTURA DE CÓDIGOS DE BARRAS ___________ 51
2.3.1 Características de los códigos de barras_______________________________________ 51
2.3.2 Muestreo _____________________________________________________________ 51
2.3.3 Precisión del sensor y anchura de las barras ___________________________________ 51
2.3.4 Tamaño de los códigos de barras____________________________________________ 53
2.3.5 Reflectancia del material y los códigos de barras________________________________ 53
2.3.6 Conclusiones finales sobre la lectura de códigos de barras_________________________ 54
2.4 CORRIENTE POR LOS DIODOS LED SEÑALIZADORES _______________ 54
2.5 CALCULO TEORICO EL CONSUMO DE CORRIENTE DEL DISPOSITIVO 56
2.5.1 Consumo de los diferentes elementos del dispositivo_____________________________ 56
2.5.2 Consumo de corriente máximo del dispositivo _________________________________ 57
2.5.3 Consumo de corriente medio del dispositivo ___________________________________ 57
2.5.4 Duración de la pila ______________________________________________________ 58
2.5.5 Calculo del número de lecturas que el dispositivo es capaz de realizar con una pila ______ 59
3 DESARROLLO DEL SISTEMA FÍSICO _______________________________61
3.1 ALIMENTACIÓN EXTERNA _______________________________________ 62
3.1.1 Aplicación y propósito de la conexión de pilas en paralelo en el proyecto _____________ 62
3.1.2 Montaje de las pilas en el lector ____________________________________________ 62
3.1.3 Conexión de la doble alimentación __________________________________________ 63
3.2 SENSOR _________________________________________________________ 64
3.2.1 Conexionado del sensor con la placa PCB_____________________________________ 64
3.2.2 Conexión del sensor con las resistencias de polarización y el microcontrolador_________ 66
3.2.3 Motivos de diseño del conexionado con la placa PCB ____________________________ 67
3.2.4 Modo de empleo del sensor en las lecturas ____________________________________ 68
3.3 ENTORNO DEL MICROCONTROLADOR ____________________________ 70
3.3.1 Cristal oscilador de cuarzo ________________________________________________ 71
3.3.2 Pulsadores e interruptores_________________________________________________ 72
3.4 COMUNICACIÓN MICROCONTROLADOR-PC _______________________ 73
3.5 DISEÑO PCB _____________________________________________________ 74
3.5.1 Diseño del circuito impreso _______________________________________________ 75
3.5.2 Fabricación y montaje del PCB_____________________________________________ 78
4 DESARROLLO DEL SISTEMA INFORMÁTICO ________________________79
4.1 ESQUEMA Y DIAGRAMAS DEL SISTEMA ___________________________ 80
4.1.1 Flujograma general______________________________________________________ 80
4.1.2 Flujograma de la adquisición de datos del PIC a través del sensor ___________________ 81
4.1.3 Detección del inicio y final del código de barras ________________________________ 82
4.1.4 Decodificación de los datos obtenidos para obtener los números EAN________________ 84
4.1.4.1 Explicación general de la decodificación _________________________________ 84
4.1.4.2 Obtención de los máximos y mínimos valores _____________________________ 85
4.1.4.3 Clasificación de los máximos y mínimos en grupos _________________________ 86
4.1.4.4 Asociación de cada par de números a números del estándar EAN _______________ 90
3
4.1.4.5 Detección y corrección de errores ______________________________________ 91
4.1.5 Transferencia de datos del PIC al PC ________________________________________ 93
4.2 PROGRAMACIÓN DE LA APLICACIÓN EN EL PIC ___________________ 94
4.2.1 El compilador y las librerías _______________________________________________ 94
4.2.2 Funciones utilizadas para la lectura y comunicación USB _________________________ 94
4.2.3 Funciones utilizadas para la comunicación USB ________________________________ 96
4.3 PROGRAMACIÓN DE LA APLICACIÓN EN EL PC ___________________ 101
4.3.1 El compilador utilizado y las librerías ______________________________________ 101
4.3.2 Funciones importantes del programa para la gestión y comunicación USB____________ 101
4.3.3 Proceso de instalación del programa y drivers necesarios ________________________ 105
4.3.4 Estética del programa ___________________________________________________ 107
5 PRESUPUESTO _________________________________________________108
5.1 Introducción _____________________________________________________ 109
5.2 Coste de recursos hardware _________________________________________ 109
5.3 Coste de recursos software__________________________________________ 110
5.4 Coste de componentes y fabricación del PCB ___________________________ 110
5.5 Coste de recursos humanos _________________________________________ 112
5.6 Coste total del proyecto ____________________________________________ 113
5.7 Estudio del coste del dispositivo en el mercado __________________________ 113
6 CONCLUSIONES Y TRABAJO FUTURO _____________________________116
6.1 Conclusiones_____________________________________________________ 117
6.2 Trabajo futuro ___________________________________________________ 118
7 ANEXOS _______________________________________________________119
7.1 CÓDIGO FUENTE _______________________________________________ 120
7.1.1 Código del microcontrolador _____________________________________________ 120
7.1.2 Fichero .INF__________________________________________________________ 140
7.1.3 Código de la aplicación en el PC___________________________________________ 142
7.2 MANUAL DE USUARIO___________________________________________ 155
7.2.1 Instalación del dispositivo________________________________________________ 155
7.2.2 Utilización del dispositivo _______________________________________________ 156
7.2.3 Instalación de la aplicación_______________________________________________ 157
7.2.4 Utilización de la aplicación_______________________________________________ 157
7.3 BIBLIOGRAFÍA _________________________________________________ 160
7.3.1 Libros_______________________________________________________________ 160
7.3.2 Páginas web __________________________________________________________ 161
7.3.3 Datasheet’s___________________________________________________________ 162
4
ÍNDICE DE FIGURAS
5
Figura 3.16. Esquema del tipo de cable USB utilizado.......................................................................................73
Figura 3.17. Conectores tipo A (izquierda) y tipo B (derecha) del cable USB..................................................73
Figura 3.18. Vista alzada y frontal del conector macho USB de los dos tipos..................................................74
Figura 3.19. Vista frontal de los conectores USB macho y hembra de los dos tipos........................................74
Figura 3.20. Diseño PCB con las pistas y los componentes................................................................................76
Figura 3.21. Diseño PCB con solo las pistas en las dos capas...........................................................................77
Figura 3.22. Diseño PCB con las pistas y el plano de masa...............................................................................78
Figura 3.23. Diseño del fotolito final que va a la insoladora .............................................................................78
Figura 4.1. Ejemplo gráfico de la diferenciación entre distintos grosores de barras.......................................86
Figura 4.2. Ejemplo gráfico de la corrección de picos máximos y mínimos con “Window moving”..............88
Figura 4.3. Ejemplo gráfico de la corrección de ciertos errores de lectura......................................................92
Figura 4.4. Flujo de comunicaciones entre un dispositivo USB y el host..........................................................96
Figura 4.5. Jerarquía de descriptores...................................................................................................................97
Figura 4.6. Flujo de comunicaciones entre un dispositivo USB y el host a través de los endpoints................98
Figura 4.7. Configuración eléctrica para el USB connection sense pin ............................................................99
Figura 4.8. Conexión de los pines del puerto USB con los pines del PIC 18F2550 .......................................100
Figura 4.9. Vista del “Administrador de tareas” con el dispositivo USB reconocido y funcionando...........106
Figura 4.10. Vista del programa que guarda y gestiona los datos recibidos del dispositivo USB.................107
Figura 7.1 Ventana de administrador de dispositivos con el lector Codematic reconocido por el sistema..155
Figura 7.2 Ventana principal de la aplicación CODEMATIC..........................................................................158
ÍNDICE DE TABLAS
6
1 MEMORIA DESCRIPTIVA
1.1 ANTECEDENTES
1.2 OBJETIVOS DEL PROYECTO
1.3 RESUMEN
1.4 TITULAR
1.5 CÓDIGOS DE BARRAS
1.6 POSIBLES SOLUCIONES Y SOLUCIÓN ADOPTADA
1.7 DESCRIPCIÓN GENERAL
1.8 PRESCRIPCIONES TÉCNICAS
1.9 ENTORNO DE TRABAJO
1.10 RESUMEN DE PRESUPUESTO
7
1.1 ANTECEDENTES
El microcontrolador es uno de los logros más sobresalientes del siglo XX, año tras
año, estos dispositivos se acercan más a nuestras vidas, haciéndose un sitio en el centro de
cada máquina, de cada equipo electrónico. Dada su alta versatilidad, su facilidad de
programación y su alto grado de integración, es posible dotar a casi cualquier objeto de
cierta “inteligencia”, de sensorización y reacción con el entorno.
Los elementos básicos de los que puede constar este dispositivo son un sensor que
capte las barras, un microcontrolador que gestione toda la información recibida de la señal
del sensor y un ordenador que disponga de puerto USB por el cual se transmitirá la
información leída por el lector y se muestre dicha información por pantalla.
A parte del ordenador, en la selección de los elementos se buscará una buena relación
calidad/precio, utilizando elementos de bajo coste como son el sensor y el
microcontrolador.
8
1.3 RESUMEN
1 - MEMORIA DESCRIPTIVA
Se exponen los motivos y objetivos del proyecto, así como una visión global de las
diferentes partes del proyecto.
2 - MEMORIA DE CÁLCULO
Se muestran los cálculos previos antes de realizar el montaje, así como los rangos de
funcionamiento ideales, etc.
Se presenta y explica el funcionamiento del prototipo el cual consta de tres partes, la parte
sensadora, la de alimentación, y la microcontrolada.
Se explican los algoritmos realizados para el control del sistema y se muestra el código
desarrollado y las librerías utilizadas para tal propósito.
5 - PRESUPUESTO
Se muestra el coste total del proyecto, tanto por el precio del material utilizado, por el
tiempo de trabajo en la realización del prototipo y el precio que tendría en el mercado.
Se sacan conclusiones sobre el proyecto realizado y se proponen ideas para futuras mejoras
o variantes que puede o podría tener el proyecto.
7 - ANEXOS
1.4 TITULAR
9
1.5 CÓDIGOS DE BARRAS
1.5.1 Introducción
Podría decirse que los códigos de barras vienen en muchas formas o presentaciones.
Muchos nos son familiares porque los hemos visto en las tiendas, pero existen algunos
otros que son estándares en varias industrias. La industria de la salud, manufacturas,
almacenes, etc. tienen terminologías únicas para su industria y que no son intercambiables.
10
Figura 1.2. Código EAN-13.
11
También existen tipos de simbologías llamadas códigos de barras de dos
dimensiones o bidimensionales, los cuales son más seguros y pueden albergar mucha más
información que los códigos de barras de una dimensión o unidimensionales. Los tipos de
códigos de barras bidimensionales que existen son el PDF 417, MAXICODE,
DATAMATRIX, etc.
Para más información mirar en el apartado 7.3.2 del anexo, o visitar las siguientes paginas
web:
http://www.metrologicmexico.com/contenido/archivos/000054.shtml
http://ciberhabitat.gob.mx/comercio/textos/texto_codbarras.htm
http://www.monografias.com/trabajos11/yantucod/yantucod.shtml
http://www.azalea.com/Spanish/UPC.html
12
1.5.3 Código EAN/UPC
Debido a que la estructura de los códigos UPC y EAN siguen las mismas reglas
solo trataremos el caso más general que es el código EAN.
Por definición un símbolo está compuesto por barras de color oscuro y espacios
claros de diferentes anchos a los ojos del lector. Es importante mencionar que lo oscuro y
lo claro es función del lector, ya que este necesita cierto contraste para poder decodificarlo.
13
1.5.3.1 Prefijo del País
Eholn la estructura EAN, dentro del código de barras se encuentra un prefijo que
determina el país origen de las mercancías. Este prefijo lo asigna la organización EAN
internacional. La tabla siguiente presenta una lista de los prefijos de países asignados y
estará sujeta a cambio conforme se sumen más a la lista. A parte de los países, también
están los prefijos utilizados para revistas, libros y cupones.
14
1.5.3.2 Número de Fabricante y Número de Articulo
En la realidad se encuentra que son muy pocos los fabricantes que requieren esta
gran cantidad de números. Por lo general la gran mayoría de empresas tienen menos de
1,000 productos en toda su existencia. Sin embargo hay ciertos giros industriales que
requieren una cantidad muy grande de números. Entre ellos se encuentran los fabricantes
de ropa donde se puede llegar a codificar por modelo, estilo, color y talla. Esta numeración
ha determinado que las Autoridades Reguladoras hayan determinado diferentes esquemas
de asignación de números para atender a una mayor cantidad de requerimientos.
Posición 13 12 11 10 9 8 7 6 5 4 3 2 1
Código sin V 9 7 0 1 2 3 4 5 6 7 8 9 V
Posiciones
7 + 1 + 3 + 5 + 7 + 9 =(7+1+3+5+7+9)*3=96
pares
Resta decena
V = 130 - 125 = 5
superior
Tabla 1.3. Ejemplo de calculo del digito verificador para un código EAN/UPC
15
1.5.3.4 Especificaciones
Figura 1.12. Código EAN13 donde se separan los diferentes elementos para su comprensión
16
Los juegos de codificación usados están determinados por el decimotercer dígito
del código según se encuentra en la tabla siguiente. Para nuestro ejemplo 9701234567895,
el decimotercer dígito es 9 por lo que la codificación de cada dígito del lado izquierdo del
código sea con los juegos de codificación ABBABACCCCCC.
Tabla 1.4. Asignación de los juegos de codificación para los dígitos de acuerdo al valor del décimo tercer digito.
Tabla 1.5. Juegos de codificación para cada digito de acuerdo a las combinaciones determinadas por el
decimotercer digito del código. En el caso del UPC el decimotercer digito es cero.
17
En el ejemplo de la figura 13 se pueden identificar todos los números con las tablas
de codificación. Se ha amplificado un símbolo normal para poder identificarlo más
fácilmente.
Las zonas mudas son áreas en blanco que se deben dejar en ambos lados del código
como mínimo. Estas áreas permiten que un lector de código de barras pueda determinar sin
lugar a dudas donde empieza y donde termina un código. Es importante respetar estas áreas
cuando se pone un código de barras en un objeto, sea un libro, una caja, etc. El código
EAN/UPC define que debe de haber 11 módulos como mínimo del lado izquierdo del
código de barras y 7 módulos mínimo del lado derecho del código de barras.
1.5.3.7 Separadores
Datos Datos
1.5.3.8 Magnificación
18
1.5.4 Conclusiones
Por ejemplo, el CÓDIGO 39, CÓDIGO 93 y CÓDIGO 128 es usado para inventarios
y aplicaciones industriales. El ENTRELAZADO 2 de 5 para la industria de los envíos, el
CODABAR es aplicado mayormente en los bancos de sangre. El POSTNET solo es usado
para el servicio postal de EEUU. El PHARMACODE es utilizado en la industria
farmacéutica.
En este proyecto solo nos centraremos en este tipo de código de barras, por ser el
más extendido comercialmente.
1.6.1 Entorno
Para el entorno con el que tendría que interactuar el usuario se podría haber optado
por uno de los siguientes:
1) LINUX
2) UNIX
3) MS-DOS
4) Microsoft WINDOWS
Se podría haber optado por utilizar un entorno en LINUX o UNIX pero dado que su
tasa de implantación en el mercado aun no esta consolidada no se podría llegar a la
mayoría de la población.
19
1.6.2 Lenguaje de programación
Se ha optado por utilizar Microsoft Visual Basic, dado que el realizar entornos
amigables para el usuario es una tarea bastante sencilla, con lo que se gana tiempo de
programación para implementar las tareas realmente necesarias. Además gestionan
eficientemente las comunicaciones con dispositivos externos mediante el puerto serie.
1) Puerto paralelo
2) Puerto PS/2
3) Puerto serie
4) Puerto Fire Wire
5) IrDA
6) Puerto USB
Se podría haber usado un puerto PS/2, pero habitualmente están ocupados por teclado y
ratón, por lo que resultaría bastante complicada su implantación en un sistema doméstico
normal.
Usar puerto serie sería la opción más idónea que nos vendría primero a la mente, ya
que es un puerto muy extendido en las comunicaciones entre dispositivos, pero poco a
poco ha ido cediendo terreno al novedoso y ahora extendido puerto USB, que proporciona
mejores prestaciones.
El puerto Fire Wire es un puerto creado por Apple y Sony, que comúnmente se utiliza
para dispositivos digitales como videocámaras, cámaras de fotos digitales, etc. Es un
puerto más rápido que el USB y proporciona más energía a los dispositivos conectados a
él, hasta 45W, aunque el número de dispositivos que se pueden conectar es un total de 63,
menos que el USB que se pueden conectar hasta 127. Hoy por hoy es un puerto no tan
conocido que el USB, pero ofrece mejores prestaciones.
El puerto IrDA es un puerto que está experimentando un auge dada la amplia gama de
dispositivos portátiles que disponen de la posibilidad de comunicar mediante infrarrojos,
pero de todos modos aun no cuenta con una implantación elevada y la interfaz de la
adaptación a los PC’s convencionales es sustancialmente más cara que otras posibles
soluciones.
Por lo tanto, la solución adoptada es utilizar puerto USB, por que es un puerto muy
extendido y hace que la practica con el ordenador sea muy fácil para el usuario. Solo tienes
que conectar el dispositivo y el sistema operativo (si es Windows XP) reconocerá el
dispositivo. Esto es una buena idea para nuestro lector, ya que dará más facilidad de
utilización. Además, ahora con la aparición de USB2.0 se ha convertido en un puerto de
comunicación muy rápido, y no presenta problema de compatibilidad con el
20
microcontrolador, ya que existe una familia de microcontroladores PIC que soportan este
tipo de conexión serie, una compatibilidad que no he encontrado con el FireWire.
Para leer los códigos de barras hay diferentes sistemas. Todos se basan básicamente
en la diferencia de reflexión de luz que incide sobre el blanco y el negro. Los tipos de
lectores son los siguientes:
1) Tipo pluma
2) De ranura
3) Tipo rastrillo o CCD
4) CCD de proximidad
5) Láser de proximidad
6) Láser tipo pistola
7) Láser fijos
8) Láser omnidireccionales
El lector de tipo pluma o lápiz tiene la ventaja que tiene un tamaño reducido y bajo
coste, pero requieren una cierta habilidad por parte del usuario, a veces se requiere hacer
más de una lectura hasta llegar a leer el código. Van bien en códigos impresos de gran
calidad. Los sensores utilizados en los de tipo pluma podrían ser los utilizados en los
robots rastreadores que siguen una línea negra o blanca por ejemplo.
Los lectores de tipo rastrillo o CCD son lectores de contacto que emplean un
fotodetector CCD (Dispositivo de Carga Acoplada) formado por una fila de LED’s que
emite múltiples fuentes de luz y forma un dispositivo similar al encontrado en las cámaras
de video. En los lectores CCD de proximidad el escaneo es completamente electrónico,
como si se tomase una fotografía al código. No se requiere hacer contacto físico con el
código pero debe hacerse a corta distancia. Tiene problemas de lectura en superficies
curvas o irregulares. A diferencia de los tipo pluma no hay movimiento que degrade la
imagen al escanearla.
Los lectores láser de proximidad requieren poca distancia del lector al objeto pero
tienen mejor “performance” que los CCD debido a su potente luz láser. Estos dispositivos
láser tienen mejores resultados en superficies curvas o irregulares.
Los lectores láser tipo pistola usan un mecanismo activador el escáner para prevenir
la lectura accidental de otros códigos dentro de su distancia de trabajo. Un espejo rotatorio
u oscilatorio dentro del equipo mueve el haz de un lado a otro a través del código de
barras, de modo que no se requiere movimiento por parte del operador, éste solo debe
apuntar y disparar. Por lo general pueden leer códigos estropeados o mal impresos, en
superficies irregulares o de difícil acceso, como el interior de una caja. Más resistentes y
aptos para ambientes más hostiles. El lector puede estar alejado de 2 a 20 cm del código,
21
pero existen algunos lectores especiales que pueden leer a una distancia de hasta 30 cm,
1,5 metros y hasta 5 metros.
Los lectores láser fijos son básicamente lo mismo que el tipo anterior, pero
montados en una base. La ventana de lectura se coloca frente al código a leer
(generalmente se orientan hacia abajo) y la lectura se dispara al pasar el artículo que
contiene el código frente al lector y activarse un censor especial.. Esta configuración se
encuentra frecuentemente en bibliotecas ya que libera las manos del operador para que
pueda pasar el libro frente al lector. También se utiliza en sistemas automáticos de fábricas
y almacenes, donde el lector se coloca sobre una banda transportadora y lee el código de
los artículos que pasan frente a él.
Los lectores láser fijos omnidireccionales se encuentran normalmente en las cajas
de supermercados. El haz de láser se hace pasar por un conjunto de espejos que generan un
patrón ominidireccional, otorgando así la posibilidad de pasar el código en cualquier
dirección. Los productos a leer se deben poder manipular y pasar a mano frente al lector.
Recomendados cuando se requiere una alta tasa de lectura.
La solución adoptada en este caso es el lector de tipo pluma, debido a su reducido
coste y practicidad, puesto que los lectores de tipo láser son relativamente caros si
comparamos con el objetivo del proyecto que es construir un lector económico, practico,
eficaz y eficiente. Eso lo conseguiremos con un sensor de reflexión de infrarrojos famoso
en la robotica, el CNY70. Los sensores CCD podrían haber sido una buena solución, pero
al montar el aparato habría que construirlo en las dimensiones de los códigos de barras que
vayan a leer, esto reduce el rango de variedad de códigos de barras a leer, y también habría
que tener en cuenta que se debe utilizar un sensor de imagen y tratar la imagen capturada,
que conlleva mucho software de tratamiento de imagen.
1) Microprocesador
2) Microcontrolador con juego reducido de instrucciones
22
1.6.6 Microcontroladores
Hoy en día hay una enorme cantidad de productos que funcionan en base de un
microcontrolador o varios. La variedad de microcontroladores es grande, y debemos elegir
bien el nuestro para nuestro dispositivo.
1) MICROCHIP
2) NATIONAL SEMICONDUCTOR
3) MOTOROLA
4) ZILOG
5) INTEL
6) THOMSON
23
otro tipo de microcontroladores. Además, puedo programarlos en un lenguaje que domino,
como es el C.
PC
CÓDIGO DE BARRAS
24
1.7.2 Composición del sistema
1.7.2.1.1 Descripción
Esta es la primera etapa de todo el conjunto, y de las partes más importantes, por
que serán nuestros ojos, y tenemos que cerciorarnos de que no nos engañe lo que ve, hay
que calibrarlo bien.
25
1.7.2.1.2 Características
El CNY70 esta conectado por dos pines a la tensión de alimentación y los otros dos
a resistencias de polarización. Para calibrar el sensor nos ayudamos de estas dos
26
resistencias de polarización, una (R 1) conectada entre el cátodo del fotodiodo y tierra, y
otro (R 2) entre el colector del fototransistor y tierra tal como muestra la figura siguiente:
VCC
R1 R2
GND
Figura 1.19. Esquema electrónico básico del sensor con una superficie reflectante
27
1.7.2.2 Circuito del microcontrolador PIC
Este es el esquema del circuito del lector de código de barras, hecho con EAGLE
Layout Editor 4.15.
Usando las librerías que tiene EAGLE y añadiendo la que contiene el PIC 18F2550
con el encapsulado ISP, se ha hecho el conexionado de los diferentes elementos que
compone el circuito general.
28
1.7.2.4 Entorno del PC
El programa utilizado para mostrar los datos por pantalla esta creado en Visual C#
de Microsoft Visual Studio 2005. Visual C# es un lenguaje de programación orientado a
objetos. Posee una sintaxis que se asemeja a C++ y ofrece la posibilidad de desarrollar
aplicaciones para tu propio uso. Además, otra cosa importante, es que se pueden usar las
funciones de los drivers subministrados por MICROCHIP y ofrece un aspecto visual más
bonito y como de usar.
El aspecto visual del programa pretende ser lo más simplificado posible y bien
estructurado para que el usuario no tenga ningún tipo de problema a la hora de usar la
aplicación. Su función será la de guardar y gestionar los datos leídos por el lector. En el
apartado 7.2 del anexo está el manual de usuario.
1.8.1 Entorno
- La segunda es que disponga de las librerías estándar utilizadas por Visual Basic C#
para ejecutar la aplicación. Por eso se incluyen las librerías de Visual Basic C#
necesarias para que, en caso de que sea necesario, se habilite la ejecución de rutinas
no contenidas en el sistema operativo y que permitan la ejecución normal del
programa.
1.8.2 Interfaz
29
El dispositivo electrónico utilizado para adaptar la señal de 9 voltios provinente de la
pila para ajustarla y regularla a 5 V es el regulador de tensión 78L05.
PARÁMETROS 78L05
Voltaje de entrada 7V < V IN < 20V
Voltaje de salida 4,8V < V IN < 5,2V
0 mA < IO < 70 mA
Corriente de salida
(tipicamente 40 mA)
Temperatura de operatividad -20 ºC < T < 80 ºC
Tipo de carcasa o encapsulado TO-92
Tabla 1.7. Parámetros operativos del 74L05
PARÁMETROS PILA 9V
Designación CEI /IEC
6LF22
(Normas de ensayo según la Comisión Electrotécnica Internacional)
Sistema Alcalino
Tensión nominal 9V
Capacidad nominal 560 mAh
Máxima intensidad 100mA
Dimensiones 26,3 x 17,3 x 48,2 mm
Peso aproximado 50 g.
Conservación en condiciones normales de almacenamiento
4 años
(según CEI/IEC – 60086-1)
30
1.8.4 Microcontrolador
1.8.5 Sensor
El sensor utilizado para detectar y leer los códigos de barras es el CNY70, conocido
por su aplicación en robots rastreadores o sigue líneas. Lo hemos elegido por su buena
relación calidad/precio. Cuando hablamos de calidad nos referimos a su precisión.
PARÁMETROS CNY70
Tensión de alimentación 5V
Rango de temperatura operativa ambiente -55 ºC < T < +100 ºC
Dimensiones 7 x 7 x 6 mm
Potencia máxima disipada 200 mW
Distancia de resolución optima 0,2 mm
Distancia optima de trabajo De 0,2 mm a 3 mm
Factor de acoplamiento* 5%
*El factor de acoplamiento es la relación entre la corriente del colector del fototransistor y
la corriente del fotodiodo (IC/IF).
31
1.8.6 Códigos de barras
Según el estándar de EAN, las dimensiones que debe tener un código de barras son
las siguientes:
Una vez determinados los componentes que forman el sistema, se debe programar el
microcontrolador para que cumpla las condiciones para las que está previsto el sistema.
Para ello es necesario utilizar varias herramientas tanto de software como de hardware para
generar el archivo que será grabado en el microcontrolador.
1.9.1 Compilador
Los lenguajes más extendidos son el ASM, Basic y C, aunque también se pueden
encontrar para lenguajes de programación basados en objetos, como son C++ y java,
aunque estos compiladores no están lo suficientemente desarrollados y optimizados como
para que puedan ser considerados como opción valida para el desarrollo de una aplicación
de este tipo.
32
A continuación se hará una breve explicación de los procedimientos realizados para
crear el programa y compilarlo.
Una vez ejecutado, se crea un nuevo fichero o se abré uno ya creado. Como ya
hemos comentado, es un compilador de C y, por lo tanto, la extensión de dichos archivos
es *.c .
33
Figura 1.22. Editor de código
Una vez escrito el código hay que compilarlo para crear el archivo .HEX que se
necesita para grabar el programa en el PIC. Además, el compilador crea otros archivos
como el ERR, SYM, LST, COF, PJT, TRE y STA, destinados a otros usos.
34
Para escribir el código, a parte de tener conocimientos de programación, hay un
manual de CCS se adjunta en el anexo, apartado 7.3.3.
Una vez se ha compilado el programa de aplicación para el PIC, haciéndose uso del
compilador de la empresa CCS, se obtiene un archivo hexadecimal (.hex) que se debe
grabar en la memoria Flash del PIC. Para realizar esta labor se pueden encontrar multitud
de programas tanto comerciales, como con licencia freeware. Pueden encontrarse tanto
para plataformas UNIX como Windows. Entre esta variedad de software cabe destacar
uno, tanto por sus características, como o su facilidad de uso, así como la gran cantidad de
PIC’s y Hardware para grabación que soporta, el WinPIC800.
35
Para grabar un programa en el microcontrolador primero hay que elegir el tipo de
microcontrolador en el que se va a grabar el programa:
36
Después se abre el archivo .HEX compilado y se mostraran todos los datos en
hexadecimal por pantalla:
Por último se pulsa el botón de grabar y si todo sale bien, se grabara en pocos
segundos el programa en el microcontrolador:
37
1.9.3 Hardware de grabación
Para llevar a cabo la grabación hay que tener en cuenta una serie de aspectos del
WinPIC800. Para grabar el PIC podemos hacerlo de dos maneras, por el ZIF SOCKET,
que es un zocalo específicamente montado para poder grabar cualquier tipo de PIC, solo
has de conectar correctamente el PIC según el numero de pines que tenga en el zócalo y
conectarlo a la salida del grabador que poner ZIF SOCKET. La otra manera, que es la que
he utilizado en el proyecto es por la salida ICSP (In Circuit Serial Programming), donde se
conectan 5 pines de esta salida a los correspondientes pines del PIC.
38
La siguiente figura muestra un esquema de cómo se conectan los pines del ICSP a los
pines del microcontrolador PIC de 28 pines, es un montaje muy sencillo.
1 28
MCLR/VPP Data
Clock
GTP-USB+
VPP
I Clock
Data
C VDD VSS
S VDD
P VSS
VSS
PIC18F2550
14 15
Figura 1.30. Conexión del GTP-USB+, a través del ICSP, con los pines del PIC 18F2550
39
2 MEMORIA DE CÁLCULO
40
2.1 SUMINISTRO NECESARIO
Un dispositivo electrónico para que funcione necesita tensión y corriente para poder
funcionar, necesita una fuente que le suministre la energía para llevar a cabo su función.
Ahora tenemos que el dispositivo se puede alimentar por dos fuentes., la del USB y
de la pila. Con intención de ahorrar el máximo el consumo de la pila se ha creado un
sistema que mientras el dispositivo este conectado al puerto USB para gestionar los datos
con el PC, la pila deje de consumirse
El circuito que realice este sistema consta de dos diodos y un transistor MOSFET
negado, que es el siguiente:
VCC
OUT
REGULADOR
78L05 DE TENSIÓN
GND
IN
VUSB
+ PILA 9V
41
El funcionamiento de este circuito es bastante sencillo, basta con poner dos diodos
polarizados directamente con las fuentes de tensión, y en paralelo entre ellos, para que sus
cátodos se unan en un mismo nodo, nodo que será el de la alimentación general del circuito
del dispositivo, es decir, microcontrolador y todos los demás componentes que lo
constituyan. Con esto conseguimos que la corriente de una fuente no afecte a la otra
dañándola. El elemento que va seguido de la pila es un estabilizador de tensión que
regulará la tensión de la pila a 5 V, que es la tensión a la que queremos alimentar el
dispositivo. Luego, el elemento más importante, es el transistor MOSFET (con la entrada
del GATE negada), cuya función es la siguiente: Cuando se conecte el dispositivo al USB,
la fuente del USB alimentará al circuito, y hará que se corte el camino entre el drenador y
surtidor del MOSFET, consiguiendo así desconectar la pila de 9 V del circuito. La entrada
GATE del MOSFET ha de estar negada, para que cuando no haya tensión del USB, haga
que se establezca un camino por el que la pila pueda alimentar al circuito.
Para ajustar el sensor a nuestras necesidades, en este caso lectura de barras blancas y
negras, habrá que calcular los valores idóneos de las resistencias R 1 y R 2.
VCC
IF IC
R1 R2
GND
42
sensor, la corriente máxima que puede pasar por el fotodiodo es de 50 mA y la tensión
típica en el fotodiodo es de 1,25 V. Entonces, para obtener la resistencia mínima a colocar,
se realiza el siguiente cálculo:
5 V − 1,25 V
R1 MIN = = 75 Ω (1)
50 mA
Con esto sabemos que con una resistencia de 0,25 W no va haber problema.
Típicamente, el funcionamiento normal de este sensor ronda los 20 mA, por lo que
la resistencia será de:
5 V − 1,25 V
R1 TIP = = 187 ,5 Ω (3)
20 mA
El valor comercial que más se le aproxima es de 180 Ω . Este valor supone una
corriente de 20,83 mA, como se muestra a continuación:
5 V − 1,25 V
IF = = 20,83 mA (4)
180 Ω
Por otra parte, hay que polarizar el fototransistor con la resistencia R2, para que
trabaje en la zona de trabajo idonea. Esta resistencia es la que nos dará la sensibilidad del
sensor hacia la raciadión recibida. Sabemos que la tensión colector-emisor del
fototransistor cuando se encuentre en el estado de saturación será de 0,3 V, es decir en el
caso de máxima transferencia de señal entre el emisor y el receptor. Y también pasará por
ella una corriente de colector de 0,1 mA, por lo que el valor de la resistencia R2 una vez se
saben estos valores será el siguiente:
5 V − 0,3 V
R2 SAT = = 47 kΩ (5)
0,1 mA
43
Una vez realizado pruebas con diferentes resistencias se ha llegado a un
compromiso con las resistencias de polarización del fotodiodo y del fototransistor. Dicho
compromiso consistía en llegar a diferenciar con la máxima claridad posible los diferentes
grosores de barras, ya que según el grosor de la barra se refleja más o menos radiación y se
podía apreciar. Los valores son los siguientes:
R1 = 180 Ω
R2 = 33 k Ω
Estos son valores de resistencias comerciales, y los que mejor resultado dan, pero la
distinción de las barras blancas entre dos grosores concretos no se hacía muy patente, por
lo que se ha razonado otra idea.
Se trata de usar un valor de resistencia cuando lee una barra y usar otro valor de
resistencia cuando se lee un espacio. El objetivo es tener la máxima claridad en diferenciar
los distintos grosores de barras y los distintos grosores de espacios. Usando una R 2 grande,
supone más sensibilidad y más claridad a la hora de leer barras negras. En cambio, para los
espacios en blanco, conviene usar una R2 más pequeña hasta el punto de llevar al
fototransistor a trabajar en la zona lineal, ya que el reflejo del color blanco tiende a saturar
el fototransistor frecuentemente.
Para cumplir ese objetivo se ha diseñado un sistema que permita conmutar entre
una resistencia y otra a la hora de la lectura.
VCC
CNY70 PIN 2 à ENTRADA A/D (AN1)
PIN 24 à E/S (RB3)
1 28
2
R1 R2 R3 24
PIC
18F2550
2N7000
GND
GND 14 15
Figura 2.3 Esquema eléctrico del sensor con el microcontrolador y el transistor de conmutación
44
Cuando el lector ha leído una barra, el microcontrolador pone a nivel alto el pin 24,
que es un pin de entrada/salida, y deja en cortocircuito el transistor. Esto provoca que la
resistencia R2 y R3 se configuren en paralelo y el valor total de la resistencia disminuya
haciendo que el fototransistor del CNY70 trabaje en la zona lineal y diferencie bien los
grosores de los espacios en blanco del código de barras.
Este sistema se ha basado en el caso real del ojo humano. La pupila se autorregula
para controlar la entrada de luz en la retina. Cuando hay mucha luz la pupila se estrecha y
cuando hay poca luz la pupila se ensancha para captar más luz y poder ver mejor el
entorno. Pues eso es parecido al sistema anterior, por que cuando se refleja un blanco,
quiere decir que el fototransistor recibe mucha luz, para eso hay que disminuir la
resistencia de polarización, es decir, la sensibilidad para que pueda percibir mejor la señal
sin saturarse, es como si se estrechase la pupila, y viceversa en el caso de una barra negra.
Para adecuar las resistencias al sistema anterior, hay que realizar un experimento que
se trata de realizar muchas lecturas y comprobar su comportamiento. En este experimento
se intenta buscar una buena relación entre la sensibilidad del fototransistor y la radiación
emitida por el fotodiodo.
Para empezar hay que evitar que el fototransistor de sature con facilidad, por lo que
la emisión de infrarrojos por parte del fotodiodo debería ser moderada para que el
fototransistor no se sature frecuentemente. Para el experimento se han escogido varias
resistencias para poder escoger la más adecuada.
Luego hay que contrastar la radiación que emitirá el fotodiodo con la sensibilidad del
receptor. Para eso hay que elegir las dos resistencias adecuadas que polarizan el
fototransistor. Primero sabemos que R 2, que ajusta la sensibilidad para las barras negras es
de 47k Ω , porque con este valor hace que el fototransistor se sature con gran cantidad de
luz, es decir, es más sensible a captar las barras negras, ya que cuando detecta un espacio
blanco rápidamente se satura.
Por otro lado, para captar los espacios en blanco hay que experimentar con la otra
resistencia, inferior a la de antes, para que no se sature fácilmente y obtener buena
diferenciación entre grosores de diferentes espacios en blanco. Para ello se ha probado
siempre con la resistencia R2 de 47k Ω , y variando la resistencia R3 mirando los resultados
del conversor A/D obtenidos de la salida del sensor al leer los diferentes grosores de
barras. Los grosores se clasifican numéricamente del 1 al 4, siendo el 1 el más fino, y el 4
el más grueso. Dichos grosores son proporcionales entre si, siendo el 4 cuatro veces más
grande que el 1, dos veces más grande que el 2 y el 3 tres veces más grande que el 1.
45
Para cada caso, el sensor capta un nivel de tensión diferente, que viene representado
en la tabla 2.1 de a continuación, con números del 0 al 1023, ya que divide la tensión de 5
V con un conversor A/D de 10 bits.
5V
Re solución = = 4,8828125 V / cuenta ≅ 4,88 V / cuenta
1024 cuentas
Primero probamos con mucha radiación del emisor, es decir, con una R1 = 82 Ω ,
que nos polariza la corriente en el fotodiodo a 45,73 mA, cerca del valor máximo, y los
resultados son los siguientes:
46
Lo que nos revela los resultados anteriores es que el fototransistor se satura con
facilidad con los espacios en blanco, aunque se puedan apreciar los grosores de las barras,
no es una de las mejores opciones. Además, con facilidad se pueden solapar los valores del
ADC entre los distintos grosores, es decir, se pueden confundir con facilidad los diferentes
grosores de barras y espacios en la lectura. Hay demasiada radiación.
Ahora probamos con poca luz, es decir, con R1 = 330 Ω , que hace circular 11,36
mA por el fotodiodo. Los resultados son los siguientes:
En este caso, hay demasiada poca luz, lo que hace que los resultados que da el
conversor A/D sean bajos en el caso de los grosores de barras y grosores de espacios, y
también tiende a solaparse los diferentes grosores de barras y hace difícil la lectura.
47
En este otro caso, probamos un caso intermedio entre lo valores anteriores, es decir,
R1 = 180 Ω , lo que ajusta la corriente que pasa por el fotodiodo a 20,83 mA, un valor
cercano al mostrado en los ejemplos del “datasheet” del CNY70 (apartado 7.3.3 del anexo)
Los resultados son los siguientes:
Ahora hacemos otra comprobación comparando las diferencias entre los valores
medios de los grosores de las barras y espacios. Para ver eso con claridad se ha creado un
gráfico de barras para todos los casos y así comparar cual tiene mejor comportamiento:
48
47k Ω // 100k Ω 47k Ω // 22k Ω
47k Ω // 47k Ω
47k Ω // 56k Ω 47k Ω // 15k Ω
VALOR ADC
VALOR ADC
49
Por lo que se puede comprobar, la barra roja que corresponde a la configuración de
R1=180 Ω , R2 = 47k Ω y R3 = 47k Ω , tiene buena respuesta en las diferencias de barras y
de espacios, aunque en el caso de R1=180 Ω , R2 = 47k Ω y R3 = 100k Ω , tiene buena
diferenciación de barras en cuanto a diferencia de valores medios, pero tienden a solaparse
los valores ADC, por lo que ya no es tan bueno.
1 47 kΩ ⋅ 47 kΩ
R2 || R3 = = = 23,5kΩ (6)
1 1 47 kΩ + 47 kΩ
+
47kΩ 47 kΩ
R1 = 180 Ω
R2 = 47 k Ω
R3 = 47 k Ω
Por último, para elegir un transistor de conmutación había que basarse en el tiempo
de subida y bajada de la conmutación del transistor. Trabajando con un tiempo de muestreo
de 3 ms no en la lectura, hay muchos transistores a elegir. En este caso se ha elegido el
transistor MOSFET NPN 2N7000 (apartado 7.3.3 del anexo) por su bajo coste y su
reducido tiempo de conmutación, que es muy inferior al tiempo de muestreo en la lectura.
50
2.3 REGULACIÓN DE LA LECTURA DE CÓDIGOS DE BARRAS
En este apartado se pretende hallar las características que tienen los códigos de
barras para un cálculo posterior de muestreos, frecuencia de muestreo que deberá realizar
el sensor y la anchura mínima que deberá tener las barras del código de barras para una
buena lectura.
2.3.2 Muestreo
Para conocer el número de muestreos, hemos tenido que saber el número de barras
que hay que leer. Tenemos que como mínimo se deberán de hacer 59 muestreos (30 barras
+ 29 espacios), pero es muy difícil que se haga una lectura del sensor en el punto central de
cada barra, además la velocidad a la que pase el sensor no es constante, sino ligeramente
variable porque las lecturas se realizan con la mano. Entonces se tendrá que hacer más
muestreos para saber que nivel de tensión da en cada momento y a partir de ahí detectar las
barras según las variaciones de tensión.
Por otra parte, la precisión del sensor es un aspecto a considerar. Según las
especificaciones técnicas, el sensor es capaz de detectar líneas negras de un grosor inferior
a 0,5 mm cuando el sensor se encuentra a una distancia inferior de 0,5 mm. Este grado de
precisión es apreciable al tener que detectar barras 0,3 mm de grosor. Entonces, para tener
una buena apreciación de las líneas que se leen, la cantidad de lecturas del conversor A/D
tiene que ser bastante grande, es decir, el numero de muestras que habrá que sacar de la
lectura.
Para hacernos una idea de lo explicado, la figura siguiente muestra el paso del foco
del sensor por una línea negra de un código de barras.
1 2 3
51
4 5 6 7
Figura 2.9. Ejemplo del paso del los infrarrojos del sensor sobre una línea negra
Cuando el foco del sensor detecta solo el color blanco, el nivel de señal reflejada es
máximo, dependiendo de la reflexión del material. Pero en el punto 2, una parte del foco
del sensor se encuentra encima de la línea negra, por lo que la señal total reflejada será
inferior a la señal reflejada del paso 1, y por lo tanto, podemos empezar a percatarnos de
que estamos empezando a detectar una línea. En el punto 4 es cuando obtenemos la
mínima señal reflejada, por lo que nos encontramos justo en el centro de la línea.
Otra cosa a tener en cuenta es que la señal reflejada en un extremo del foco no es la
misma que en el centro del foco aunque este reflejando la misma área. En el centro del
foco es donde la proporción de señal emitida y recibida es máxima, es decir, el 100%. En
cambio, a un ángulo de 50º, la proporción es del 30%.
CNY
70
50º
Figura 2.10. Relación entre la corriente del CNY70 y el ángulo en que la radiación infrarroja es emitida.
Entonces, el número de muestras a realizar deberá ser como mínimo de 5 por cada
barra como mínimo. En total un mínimo de 295 muestras ( 30 barras + 29 espacios por 5
muestras por cada barra hacen 295 muestras en total ) y cuantas más muestras mejor.
52
La distancia “A” de la gráfica corresponde a la distancia del sensor con la
superficie. Por lo tanto, las lecturas se realizarán con el sensor en contacto con la
superficie.
Figura 2.11. Relación entre la corriente del CNY70 y la distancia a la que se encuentra de una superficie.
Un folio normal de 80 g. satinado tiene una reflectancia del 90% (mirar los
porcentajes de reflectancia en el “dataste” del CNY70, apartado 7.3.3 del anexo) , es decir,
refleja la señal infrarroja casi en su totalidad. Y una línea negra sobre este tipo de papel se
refleja de un 4% a un 7%, por lo que la diferenciación entre la señal reflejada en un espacio
en blanco y una barra negra se hace más notoria. Por eso se ha optado por experimentar y
usar el lector en códigos de barras impresos con tinta negra de impresora sobre una hoja de
papel normal, de 80 g. satinado. No se ha encontrado otra posibilidad mejor que esta, ya
que las demás posibilidades hacían que la diferencia entre el blanco y el negro fuera más
pequeña y por lo tanto, el reconocimiento de los diferentes grosores de barras sobre los
diferentes grosores de espacios se hacen más difíciles de reconocer, incluso imposible.
El color también es importante, ya que los diferentes colores reflejan una cantidad
diferente de radiación infrarroja. Se ha optado por las barras negras sobre papel blanco por
53
que son los colores que más difieren en cuanto reflejo de infrarrojos, ya que como teoría, el
color negro es el color que absorbe más energía y el blanco el que menos.
- El foco del sensor es más grande que una línea fina del código de barras.
- El numero de muestras deberá de ser igual o mayor que 295.
- La lectura del código de barras se realizará con el sensor pegado a la superficie.
- Los códigos de barras deberán ser impresos en papel normal y con tinta negra.
- Los códigos de barras serán del máximo tamaño posible, siendo del 200% del
tamaño 100% del estándar.
Tiene suma importancia la corriente que pase por los LED’s que nos indicaran los
estados del dispositivo, ya que una parte del consumo se irá por ellos, y por lo tanto la
autonomia del producto, y además tener en cuenta que el HUB del USB administra un
máximo de 500mA.
Para empezar elegiremos el tipo de LED, que por motivos de espacio y consumo
será el estándar de 3mm de diámetro de encapsulado.
54
Las características de este diodo nos indica que la corriente máxima que debe pasar
por él para un funcionamiento normal es de 10mA, puestos que el microcontrolador esta
alimentado a 5V y el diodo consume 0,7 V aproximadamente, según la ley de Ohm, para
conseguir ese paso de corriente necesitaríamos una resistencia de:
(5V − 0,7V )
10mA = (7)
R
4,3V
R= (8)
10 mA
R = 430 Ω (9)
Puesto a que comercialmente no existe una resistencia de dicho valor, el valor más
próximo sin que sobrepase los 10mA de corriente seria una resistencia de 470 Ω . Entonces
la corriente que pasaría sería de:
4,3V
I= = 9,15 mA (10)
470Ω
Lo que resulta un consumo menor de corriente y una iluminación del LED más que
aceptable. Pero aún podemos ir más lejos, por que utilizando resistencias de 1k Ω también
obtenemos una iluminación aceptable y casi ahorramos el doble de corriente,
aproximadamente el la corriente consumida será la siguiente:
4,3V
I= = 4,3 mA (11)
1000 Ω
4,3mA
I AHORRO (%) = ⋅ 100 = 46,99 % (12)
9,15mA
55
2.5 CALCULO TEORICO EL CONSUMO DE CORRIENTE DEL DISPOSITIVO
Tabla 2.4. Consumo de corriente de los distintos modos de funcionamiento del PIC 18F2550
Los dos valores que se muestran son la diferencia que hay entre una alimentación
de 4,2 V y 5 V. La alimentación de nuestro circuito es la que proporciona el USB, que es
de 5V, pero experimentalmente ese no es exactamente el voltaje que proporciona, sino que
es de 4,84 V, por eso he puesto esos dos valores en la tabla.
VALOR Ud.
LED (3mm) 4,3 mA
FOTODIODO (CNY 70) 20,83 mA
FOTOTRANSISTOR (CNY 70) 0,3 ~ 1,0 mA
BOTON RESET (al pulsarlo) 0,5 mA
56
2.5.2 Consumo de corriente máximo del dispositivo
En el peor de los casos, es decir, el caso en el que hay un máximo consumo de corriente, el
dispositivo tiene 2 LED’s encendidos simultáneamente, el CNY 70 funcionando en el
mayor consumo de corriente y el PIC esta en modo de funcionamiento normal
(considerando el máximo valor de corriente), el consumo máximo de corriente del
prototipo seria de:
Para el cálculo del consumo medio de corriente hay que tener en cuenta una serie de
cosas:
20
I RESET = 0,5 mA ⋅ = 0,1 mA (14)
100
- Los tres LED’s no estarán siempre encendidos a la vez, solo un LED permanecerá
encendido mientras el dispositivo este funcionando, y solo por un corto periodo de
tiempo, van a estar dos LED’s encendidos a la vez. Considero, en un hipotético peor
caso, que el hay dos LED’s encendidos a la vez el 50% del tiempo, aunque no llega a
ser así.
50
I LED 'S = 4,3 mA + 2 ⋅ 4,3 mA ⋅ = 8,6 mA (15)
100
57
- El PIC no estará siempre en modo RUN, variará según este leyendo un código de
barras o no. Entonces oscilará entre el modo normal y el modo espera. Planteándonos
el peor de los casos, que será el de ir leyendo muy seguidamente códigos de barras,
considero que 2/3 del tiempo esta en modo normal y 1/3 está en modo espera, por
que es el tiempo que pasa entre que se lee un código de barras a otro.
2 1
I PIC = ⋅ 25 mA + ⋅ 10,5 mA = 16,67 + 3,5 = 20,16 mA (17)
3 3
Para el proyecto, uno de los objetivos es tener la mayor autonomía posible. La pila
utilizada para alimentar el circuito sin estar conectado por USB es una pila de 9V, cuya
capacidad de corriente es de 560mAh.
Basándonos en el peor de los casos, cuando el dispositivo consume el máximo de
corriente todo el tiempo, es decir, 71,83 mA (véase el apartado 2.2.4), el dispositivo es
capaz de mantenerse operativo el siguiente espacio de tiempo:
560 mAh
TMAX TEÓRICO = = 7,81 horas (20)
71,83 mA
560 mAh
TMEDIO TEÓRICO = = 11,05 horas (21)
50,69 mA
58
Esto nos muestra nos muestra que el dispositivo es capaz de funcionar, con una sola
pila de 9V, durante una jornada laboral de 8 horas de trabajo en el peor de los casos, y 3
horas y media más en el caso de consumo medio.
También existe la posibilidad de mejorar este dato, conectando dos pilas de las
mismas características en paralelo. Lo más importante es que tengan el mismo voltaje (9V
en nuestro caso).
Conectando dos pilas como la anterior en paralelo conseguiremos doblar la
capacidad de corriente total, y eso nos proporciona el doble de tiempo de operatividad del
dispositivo (véase apartado 3.1).
560 mAh
TREPOSO TEÓRICO = = 45,53 horas (22)
12,30 mA
2.5.5 Calculo del número de lecturas que el dispositivo es capaz de realizar con una pila
25200 s + 2880 s + 36 s
N º LECTURAS = = 35145 lecturas (23)
0,8 s
39600 s + 180 s
N º LECTURAS = = 49725 lecturas (24)
0,8 s
59
Como conclusión a esto tenemos que el número de códigos de barras que se pueden
leer con este dispositivo es muy grande. Si contamos que cada producto tiene un código de
barras propio, este lector es capaz de leer un número de productos de almacenes bastante
grandes.
60
3 DESARROLLO DEL SISTEMA FÍSICO
61
En este capítulo se explican los procedimientos realizados para la creación de cada
una de las partes del dispositivo, tanto como los elementos escogidos para dicho montaje y
las razones por las cuales se ha decidido diseñarlo de esta manera y no de otra, como
también la elección de ciertos elementos y no otros.
En el caso de conectar dos pilas en paralelo, se requerirán dos porta pilas de 9V para
cada una de las pilas, y se conectarán en paralelo en la placa PCB. La pila o las pilas irán
colocadas según se especifique en el diseño de la carcasa.
62
3.1.3 Conexión de la doble alimentación
El diodo protege la fuente del puerto USB y el diodo que hay en el transistor BS250
protege a la pila de 9 V.
63
3.2 SENSOR
Una de las partes más importantes del desarrollo de este lector es el sensor que
percibe la variación entre las líneas negras y blancas cuyo funcionamiento se explica en el
apartado 1.7.2.1.
El sensor tiene 4 pines, dos de los cuales se conectan entre si, exactamente los dos
pines que van a la alimentación. Al sensor se sueldan 3 cables que irán a los pads que le
correspondan de la placa PCB. A continuación se muestra una figura que representa dicha
conexión entre el sensor CNY70 a la placa PCB mediante tres cables.
CNY 70
1
2
3
PCB
Figura 3.3. Ejemplo de conexión de los cables del CNY70 con la placa PCB
64
Figura 3.4. Esquema eléctrico de la conexión del CNY con el conector de la placa PCB
Figura 3.5. Foto del conexionado real del CNY70 con un conector
65
3.2.2 Conexión del sensor con las resistencias de polarización y el microcontrolador
El sensor debe conectarse a una de los pines del microcontrolador que se use para la
conversión A/D de la señal sensada. Este pin se le llama entrada analógica y tal y como se
ha diseñado en este proyecto, el pin al que debe conectarse es el pin numero 3, que
corresponde a la entrada analógica 1 (AN1) del PIC 18F2550. La figura siguiente muestra
la conexión mencionada.
66
3.2.3 Motivos de diseño del conexionado con la placa PCB
PCB
9V 18
F
25
50
USB
CNY
70
La intención del diseño sería una carcasa ergonómica lo más pequeña posible y que
el sensor se encuentre en una zona de la carcasa que fuera cómoda para realizar
eficazmente las lecturas.
CNY70
PCB
67
3.2.4 Modo de empleo del sensor en las lecturas
Para realizar las lecturas con el sensor, la manera correcta de hacerlo con un
movimiento lateral de izquierda a derecha de una manera uniforme, con el sensor pegado
al papel y lo más importante es que la posición de las ventanitas del fotodiodo y
fototransistor respecto las líneas del código de barras tienen que quedar en perpendicular
como muestra la siguiente figura:
CORRECTO
(MÁS PRECISO)
POSICIÓN 1
INCORRECTO
(MENOS PRECISO)
POSICIÓN 2
Figura 3.9. Posiciones del lector al realizar una lectura de un código de barras
Antes de explicar el porque es mejor realizar la lectura de una manera que de otra,
hay que explicar un concepto relacionado con las características del sensor. Se trata de la
distancia de conmutación (“Switching distance”). La distancia de conmutación es la
distancia que recorre el sensor desde que la corriente del colector del fototransistor pasa del
90% al 10% o viceversa. En nuestro caso la distancia que recorre desde que pasa del nivel
más alto de negro y llega al nivel más alto de blanco o viceversa. La siguiente figura
explica este fenómeno:
68
Figura 3.10. Distancia de conmutación del CNY70
Figura 3.11. Grafico de la relación que tiene el CNY70 con el Switching distance/Distance A
Como se puede observar, existe una notoria diferencia entre una posición y la otra,
una diferencia importante pensando que al leer códigos de barras nos movemos en valores
que rondan 1 milímetro y menos.
Y la siguiente y última figura muestra la diferencia que existe entre una posición y
otra al pasar por una línea. La primera gráfica muestra el ancho de la línea, la segunda y la
tercera son el comportamiento de la corriente de colector al pasar el sensor por encima de
la línea en una posición o en la otra. Y como resultado, la gráfica que más se ciñe al ancho
de la barra es la de arriba, es decir, cuando el sensor esta e la posición 1.
69
LÍNEA
POSICIÓN 1
POSICIÓN 1
POSICIÓN 2
POSICIÓN 2
Figura 3.12. Distancia de conmutación dependiendo de la posición del sensor respecto a una línea negra
70
Una vez abierto el paquete, me
encontraba con la factura, detalles del
proveedor, en este caso, “MICROCHIPDirect”
y mis PIC’s iban dentro de una bolsa
antiestática y además dentro de un tubo de
plástico antiestático, para más protección
Figura 3.13. Esquema eléctrico de la conexión del cristal de cuarzo con los condensadores y el PIC
71
Para saber que valores deben tener los condensadores, se mira en la hoja de
especificaciones t la relación entre la frecuencia y el valor de capacidad de los
condensadores, tal como muestra la siguiente tabla:
Tabla 3.1. Relación entre la frecuencia del cristal y el valor de los condensadores.
72
3.4 COMUNICACIÓN MICROCONTROLADOR-PC
Figura 3.17. Conectores tipo A (izquierda) y tipo B (derecha) del cable USB
73
Y este es el esquema del cabezal de los dos tipos de conectores USB, del tipo A a la
izquierda y del tipo B a la derecha:
Figura 3.18. Vista alzada y frontal del conector macho USB de los dos tipos
Y por último la vista frontal de los conectores USB macho (a la izquierda) y de los
conectores USB hembra (a la derecha):
Figura 3.19. Vista frontal de los conectores USB macho y hembra de los dos tipos
La implementación del circuito en una placa PCB es la manera óptima para crear un
circuito abarcando el mínimo espacio posible, con la ventaja de poder dar forma a esta
placa.
Antes de proceder al diseño del circuito impreso final, antes se crea un circuito de
prueba sobre una placa de topos, para comprobar que la selección de los componentes y el
diseño del esquema eléctrico son correctos. Una vez probada esta placa que sirve de
prototipo, y viendo que funciona correctamente, procedemos al diseño del PCB.
74
3.5.1 Diseño del circuito impreso
Para empezar, el programa utilizado para crear dicha PCB ha sido el EAGLE 4.15
Layout Editor de la empresa Cadsoft, escogiendo este programa porque creo que es el más
sencillo de usar y me da más posibilidades y rapidez que otros.
Antes que nada, hay que crear el circuito en el editor de esquemáticos del EAGLE.
Se van eligiendo los componentes requeridos en el diseño de una extensa lista de
componentes que tienen las librerías del EAGLE por defecto. A la vez que eliges el
símbolo del componente, a un lado se muestra el diseño en alzado del encapsulado junto a
sus dimensiones para una posterior creación del layout.
Para introducir el PIC 18F2550 en el esquema circuital hay que descargar una
librería de Internet, en la página oficial de EAGLE (http://www.cadsoft.de). La librería en
cuestión se llama “PIC18Fxx5x.lbr” y contiene todos los PIC’s de la familia 18Fxx5x junto
a los diferentes encapsulados de cada uno. El que hay que elegir para este diseño es el
18F2550 en encapsulado ISP.
Una vez realizado las conexiones convenientes entre los componentes, ya esta listo
para que el programa me vuelque los componentes en el “Layout”, es decir, en la pantalla
donde tendré que organizar los componentes sobre la superficie de la placa PCB a la que
daré forma y tamaño. La forma que le he dado ha sido cuadrada, por la sencillez y por
tener menos trabajo a la hora de recortar la placa después.
75
Las dimensiones y características dimensionales del circuito PCB vienen descritas en
la siguiente tabla:
CARACTERÍSTICAS
Dimensiones de la placa 8,64x7,36 mm (3,40x2,9 mils)
Capas de ruteado 2 (top y bottom)
Anchura de las pistas 0,8001 mm (31,5 mils)
Separación entre pistas 0,8001 mm (31,5 mils)
Separación entre las pistas y el cobre del plano de masas 1,016 mm (40 mils)
76
Y la imagen siguiente es sin los componentes:
Figura 3.21. Diseño PCB con solo las pistas en las dos capas
Una vez ruteado y puesto el nombre en nuestra placa, se crea un plano de masa,
para que haya una buena referencia a tierra en todo el circuito. Esto evitará que haya
diferentes caídas de tensión en diferentes puntos del circuito cuando debería haber la
misma tensión. Además, en caso de cortocircuito se derive la corriente a masa sin dañar el
resto del circuito. Mejor sería esta referencia si engancháramos esta placa a una carcasa,
por eso se han puesto unas marcas para poder poner los tornillos y así poder enganchar a
alguna carcasa.
77
Figura 3.22. Diseño PCB con las pistas y el plano de masa
Este fotolito se envía a fabricar. Una vez creada el PCB se procede a una inspección
visual para detectar posibles defectos de fabricación y se comprobarán mediante un
multímetro las conexiones.
78
4 DESARROLLO DEL SISTEMA INFORMÁTICO
79
4.1 ESQUEMA Y DIAGRAMAS DEL SISTEMA
INICIO
GUARDAR EN
MEMORIA DEL PIC
NO PASAR
DATOS AL PC?
SI
ENVIAR DATOS
AL PC
GESTION DE DATOS Y
MOSTRAR POR PANTALLA
80
4.1.2 Flujograma de la adquisición de datos del PIC a través del sensor
El siguiente flujograma explica los pasos que sigue el programa del PIC para obtener
los resultados percibidos por el sensor en forma de datos.
INICIO
( tabla[i]=DATO )
NO
SI
FIN DE LA LECTURA
La tabla es de 400 valores, aunque limitado por la memoria del PIC, son suficientes
valores para poder hacer un buen tratamiento de la señal obtenida. Este valor esta muy por
encima del valor calculado en el apartado 2.3 de la memoria de cálculo. Este número de
muestras implica que el tiempo máximo total de lectura es de 1 segundo como mínimo
aproximadamente, y puede ser más tiempo dependiendo del número de muestras que se
repitan. Sabiendo que cada muestra tarda entorno unos 3 ms.
81
4.1.3 Detección del inicio y final del código de barras
El hecho de detectar el inicio y final del código de barras nos ahorrará mucha faena a
la hora de decodificar la información obtenida para traducirlo en el número EAN final.
Para detectar el inicio del código de barras se comparan los valores obtenidos en el
conversor A/D. Primero hasta que no toca el sensor con la superficie, y luego hasta que el
sensor no pasa por encima de una barra que hará variar el nivel de A/D y por lo tanto
podremos detectar la primera barra. Dicha detección de inicio del código de barras se
explica por pasos en el siguiente flujograma.
INICIO
SI
SI
( tabla[i]=DATO )
INICIO DE LA LECTURA
82
Para la detección del final del código de barras lo que se hace es detectar los
máximos y cuando se hayan contado 30 máximos, es decir, 30 barras, la lectura se dará por
finalizada. Este proceso se hace a la vez que se está leyendo el código de barras. La
detección de máximos y mínimos se explica en el apartado 4.1.4.2.
INICIO DE LA LECTURA
NO
¿Valor máximo?
SI
CUENTA_BARRAS + 1
NO
¿CUENTA_BARRAS = 30 ?
SI
FIN DE LA LECTURA
83
4.1.4 Decodificación de los datos obtenidos para obtener los números EAN
Está es una de las partes más importantes de todo el proyecto, por que es la parte que
se encarga de traducir los valores obtenidos por el sensor en números del estándar EAN, es
decir, el número del código de barras leído.
Para explicar esta parte primero haremos una explicación básica y general de todo el
proceso, que posteriormente se desglosa para explicar con más detalle cada punto de la
decodificación.
INICIO
84
4.1.4.2 Obtención de los máximos y mínimos valores
INICIO
NO
NO
i++
NO ¿Fin de la
tabla de datos
ADC?
SI
85
4.1.4.3 Clasificación de los máximos y mínimos en grupos
GRUPOS 3
LECTURA ADC
Figura 4.1. Ejemplo gráfico de la diferenciación entre distintos grosores de barras
Este gráfico de ejemplo muestra la clasificación de los grupos según el grosor de las
líneas negras, también hay otro tipo de clasificación según las líneas blancas, que se
miraría por los puntos mínimos de la grafica.
86
INICIO
LEER MÁXIMO DE LA
TABLA DE MÁXIMOS
¿Fin de la tabla NO
de máximos?
SI
LEER MÍNIMO DE LA
TABLA DE MÍNIMOS
i++
¿Fin de la tabla NO
de mínimos?
SI
87
Esto sería la teoría básica de la clasificación de los grosores de barras, pero aún es
un algoritmo susceptible de tener algún que otro error a causa de la poca diferencia un
espacio y otro. El problema es que los niveles de los picos máximos y mínimos puede que
entren en el mismo grupo por poca diferencia. Estudiando bien las gráficas que salen como
resultado de las lecturas, se puede apreciar que las barras más anchas tienen puntos más
cercanos al pico que en barras más estrechas.
Tomamos como ejemplo la figura siguiente, donde hay dos picos con distinta
curvatura, cuyo pico máximo es el mismo. Pero si realizamos la media entre el pico
máximo, el valor anterior y el valor posterior, tenemos otro valor de pico. Resulta que el
gráfico de la izquierda tiene los valores anterior y posterior más cercanos del pico máximo
que en el gráfico de la derecha, por lo que la media será más alta, y por lo tanto,
diferenciamos mejor los grosores de las barras.
Valor A/D
Nº de muestra
¼ ½ ¼ ¼ ½ ¼
Figura 4.2. Ejemplo gráfico de la corrección de picos máximos y mínimos con “Window moving”
Para precisar más, podemos considerar un valor más que los otros a la hora de hacer
la media. En el ejemplo anterior, hemos considerado para la media entre los tres que el
pico máximo valía ½ y los valores anterior y posterior ¼, por lo que el valor de la media se
aproxima más al pico máximo que si contasen los 3 valores 1/3. Esto depende de la
necesidad del diseñador. En este proyecto, después de muchas pruebas, se ha llegado a la
conclusión de que estas proporciones deben ser las siguientes:
88
A continuación el flujograma que muestra el procedimiento de obtención de
máximos y mínimos con el método de la ventana móvil:
INICIO
HACER LA MEDIA DE
LOS TRES VALORES (1/3 - 1/3 - 1/3)
¿Fin de la tabla de NO
máximos?
SI
HACER LA MEDIA DE
LOS TRES VALORES (1/6 - 4/6 - 1/6)
¿Fin de la tabla de NO
mínimos?
SI
89
4.1.4.4 Asociación de cada par de números a números del estándar EAN
Ahora nos basaremos en que cada número del código de barras esta compuesto de 2
barras negras y dos barras blancas de diferentes grosores y de diferentes combinaciones.
Con este hecho lo que haremos es asociar cada par de barras a un número del estándar
EAN que en el apartado 1.5.3.5 viene detallado. Entonces recorreremos ambas tablas de
valores máximos y mínimos al mismo tiempo, y recogiendo el valor de las dos barras
negras y el valor la barra blanca que las separa, asignaremos a esta combinación un número
EAN.
A continuación el flujograma que muestra los pasos que sigue el programa de una
forma esquemática y ordenada:
INICIO
índice_valores_máximos + 1
90
índice_valores_máximos + 1
índice_valores_mínimos + 2
¿Fin de la tabla NO
de valores
máximos?
SI
Durante el proceso de obtención del número del código de barras se pueden producir
varios errores a causa de una mala lectura, consecuencia de un incorrecto uso del lector a la
hora de intentar proceder a la lectura de un código de barras. El sistema tiene una serie de
algoritmos y pautas que evitan ciertos errores hasta el punto de corregirlos, en otro caso se
avisa por la señal luminosa del LED que la lectura es incorrecta, y por lo tanto, no es
válida. Según la secuencia del parpadeo del LED nos advertirá de que tipo de error puede
haberse tratado. La asignación de dichas secuencias están descritas en el manual de
usuario, apartado 7.2.2 del anexo.
A continuación describimos todos los posibles errores que pueden producirse en una
lectura:
Ahora las soluciones adoptadas para corregir ciertos errores, o bien, avisar al usuario
de que se ha producido un error. La diferencia entre corregir y avisar radica en que hay
errores que no se pueden corregir por falta de información proporcionada por el sensor, por
ese motivo un indicador luminoso LED nos advierte que la lectura realizada no es correcta
y por lo tanto no será guardada.
91
Por otra parte, hay errores de lectura que si se pueden corregir y otros que se pueden
evitar. Para los que se pueden corregir, se trata de arreglar la gráfica obtenida de los
valores del conversor A/D, donde se pueden haber producido picos que pueden confundir
al algoritmo de obtención de máximos y mínimos. Los casos que se pueden dar son los
siguientes:
Para corregir esto, se vuelve a recorrer la tabla de los valores del ADC y se corrige
cambiando ciertos valores que pueden producir error, como por ejemplo, hacer la media
entre los valores adyacentes al pico que se quiere arreglar, así como resultado el pico
desaparece y se queda alineada con los valores adyacentes. O por ejemplo, en el pico
máximo, se produzcan dos picos máximos pero que en realidad es un solo pico máximo,
entonces, detectando esos dos picos, se cambia el valor del central y se pone por encima de
los anteriores. Así finalmente conseguimos arreglar la gráfica para que luego detecte los
verdaderos máximos y mínimos.
Por ejemplo, si detectamos una barra de grosor máximo (grosor 4) y una barra de
grosor mínimo (grosor 1), podemos intuir, que entre estas barras no puede haber un espacio
de grosor mayor que 1.
92
4.1.5 Transferencia de datos del PIC al PC
INICIO
¿Hay dato en el
NO buffer de entrada
del HOST?
( PIC à PC )
SI
i++
ENVIAR DATO AL
PC DESDE EL PIC
SI
¿Hay otro dato a
recibir?
NO
FIN DE LA TRANSMISIÓN
93
4.2 PROGRAMACIÓN DE LA APLICACIÓN EN EL PIC
En este apartado nos centramos en las librerías utilizadas para la correcta creación
del programa. El código detallado de cada librería se encuentra en los anexos (apartado
7.3.3) de esta memoria.
18F2550.h : Librería con las direcciones de los pines del PIC 18F2550 y la
definición de constantes esenciales para programar este microcontrolador.
usb.c : Otra librería con más funciones generales sobre la comunicación USB, esta
librería además contiene la librería usb.h.
En este apartado se comentan las funciones utilizadas para la creación del código, y
se describe la función que desempeñan en el conjunto del lector.
#device ADC = 10
94
Después hay que configurar el ADC para que funcione de la manera que queramos,
y al compilador hay que decirselo de la siguiente manera:
setup_port_a(ALL_ANALOG | VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(1);
//por último decirle que el canal donde tiene que estar listo para
recibir informacion a convertir
set_tris_A(0b00000010);
//esto último es para configurar el pin 1 RA1 como entrada y los demas
como salida, aunque el resto nos va a dar igual
Una vez configurado el ADC, pasaremos a la lectura, es decir, a obtener los datos y
guardarlos en una tabla para poder ser tratados luego. Para hacer esto echaremos mano de
la siguiente función:
read_adc();
resultado_adc=read_adc();
95
4.2.3 Funciones utilizadas para la comunicación USB
Ahora detallamos las funciones necesarias para la comunicación USB entre el PIC
y el PC. Pero antes de nada, habrá que hacer una breve descripción del funcionamiento de
comunicación del USB para entender el porqué de dichas funciones y los parámetros que le
acompañan.
El flujo de datos del bus USB desde un punto de vista lógico hay que entenderlo
como una serie de puntos finales (endpoints), que se agrupan en conjuntos que dan lugar a
interfaces, las cuales permiten controlar la función del dispositivo. La arquitectura se puede
dividir en tres niveles o capas. En el nivel mas bajo el controlador de host USB se
comunica con la interfaz del bus utilizando el cable USB, mientras que en un nivel superior
el software USB del sistema se comunica con el dispositivo lógico utilizando el canal
(pipe) de control por defecto. En lo que al nivel de función se refiere, el software cliente
establece la comunicación con las interfaces de la función a través de canales asociados a
puntos finales. Cada dispositivo USB está compuesto por unos puntos finales
independientes y una dirección única asignada por el sistema en tiempo de conexión, de
forma dinámica. A su vez, cada punto final dispone de un identificador único dentro del
96
dispositivo (número de endpoint) que viene asignado de fábrica, además de una
determinada orientación del flujo de datos. Cada punto final es por si solo una conexión
simple, que soporta un flujo de datos de entrada o de salida. Un canal USB es una
conexión lógica entre un punto final del periférico y el software del host, que permite
intercambiar datos entre ellos. El canal que esta formado por el punto final 0 se denomina
canal de control por defecto. Este canal está siempre disponible una vez se ha conectado el
dispositivo y ha recibido un reset del bus. El resto de canales aparecen después de que se
configure el dispositivo. El canal de control por defecto es utilizado por el software USB
del sistema para obtener la identificación y para configurar al periférico.
97
La siguiente figura muestra la arquitectura de comunicación entre dos dispositivos
USB y el host mediante los puntos finales (endpoints):
Figura 4.6. Flujo de comunicaciones entre un dispositivo USB y el host a través de los endpoints
#define USB_EP1_TX_SIZE 1
//tamaño de informacion para reservar en el buffer de envio de datos del
endpoint 1(1 byte)
#define USB_EP1_RX_SIZE 3
//tamaño de informacion para reservar en el buffer de recibir datos del
endpoint 1 (3 bytes)
98
Las funciones para la inicialización del dispositivo USB con el PC son las
siguientes:
usb_init();
Inicializa el stack USB, la periferia del USB y conecta la unidad al bus USB. También
habilita las interrupciones, en general, inicializa el USB.
usb_task();
usb_wait_for_enumeration();
usb_enumerated();
usb_kbhit(1);
Devuelve TRUE si la salida (OUT) del endpoint contiene datos del HOST, el 1 significa
que se refiere al endpoint 1 (EP1).
GND
4k7 Ω
99
La figura siguiente ejemplifica y clarifica esta explicación:
“SENSE PIN”
(PIN QUE DETECTA LA
1 28 CONEXIÓN USB)
PIC
18F2550
23
8 1
20 5V
19 D-
D+
GND
16 4
14 15
PIN 8 à VSS
PIN 15 à D–
PIN 16 à D+
PIN 19 à VSS
PIN 20 à VDD
PIN 23 à RB2
Figura 4.8. Conexión de los pines del puerto USB con los pines del PIC 18F2550
Por último quedan las funciones para recibir datos del PC y enviar datos del al PC.
El de recibir datos (usb_get_packet) se usa en este caso para recibir ordenes del PC para
que el PIC realice alguna tarea, como por ejemplo la de que envie los datos contenidos en
el PIC al PC. En el caso de enviar datos al PC (usb_put_packet) es para lo que se ha
mencionado anteriormente, enviar los datos guardados de las conversiones ADC.
100
4.3 PROGRAMACIÓN DE LA APLICACIÓN EN EL PC
Las librerías utilizadas han sido las propias del compilador, aunque para programar
la comunicación USB, se han hecho servir funciones proporcionadas por MICROCHIP©
que vienen en el archivo “mpusbapi.dll”. Las funciones utilizadas en el programa del PC se
pueden ver en el siguiente apartado, y el resto de las funciones y contenido de este archivo
se puede ver en los anexos, apartado 7.3.3.
Para empezar, este codigo corresponde a la parte de programa del proyecto en Visual
C#, es decir, el llamado por defecto “Program.cs”.
Hay proporcionados una serie de numeros para uso personal y para probar
proyectos, pero en un caso real, la propia casa de USB te proporciona unos números únicos
para tu producto, si tu producto ha pasado una serie de pruebas para garantizar el correcto
funcionamiento del dispositivo USB, y así tu producto poder llevar el logo USB que
garantice al consumidor que el producto ha sido probado por “USB-IF Inc” (“USB
Implementers Forum Inc.”). Para conseguirlo has de rellenar una solicitud para que tu
producto pase las pruebas técnicas para que sea merecedor del logo. Además, se ha de
pagar una fianza de 2000$ americanos. Si eres miembro de “USB-IF Inc.”, a parte de los
beneficios que supone, has de pagar una fianza de 4000$ americanos anuales.
101
El periférico que se va a desarrollar no pertenece a ninguna clase genérica, así que
habrá que indicar el driver que se le quiere asignar. El driver que se utilizará será un driver
USB de propósito general para Windows suministrado por Microchip (mchpusb.sys). Así
mismo, Microchip proporciona un identificador de vendedor (0x04D8) que puede ser
utilizado en productos desarrollados con microcontroladores PIC.
http://www.usb.org/developers/logo_license.html
Y a continuación definir el endpoint por el que van a pasar los datos, que en este
caso sera el endpoint 1 (EP1):
Una vez definido la ruta de paso de datos e identificado el producto, habra que
importar las funciones que necesitaremos para el proyecto. Dichas funciones, como ya
hemos comentado anteriormente, se importan del archivo “ mpusbapi.dll”, y se hace
de la siguiente manera:
#endregion
102
Las funciones importadas del “mpusbapi.dll” son las que se usarán luego en el
programa para crear la comunicación USB entre el PC y el microcontrolador. Dichas
funciones, exactamente sirven para abrir o cerrar los canales de entrada o salida, y para
enviar o recibir paquetes de datos.
void* myOutPipe;
void* myInPipe;
DWORD SentDataLength;
OpenPipes();
_MPUSBWrite(myOutPipe, (void*)SendData, SendLength, &SentDataLength,
SendDelay);
ClosePipes();
}
OpenPipes();
_MPUSBRead(myInPipe, (void*)ReceiveData, ExpectedReceiveLength,
ReceiveLength, ReceiveDelay);
ClosePipes();
}
103
Una vez escritas las funciones anteriores, ya podemos hacer uso de ellas para
nuestros objetivos personales. En este proyecto, lo más importante es el envio y recepción
de datos, por lo que muestro dos ejemplos a continuación:
send_buf[0] = 0x01;
send_buf[1] = (byte)dato;
SendPacket(send_buf, 2);
}
int result,result1,result2;
tabla = new int[128];
send_buf[0] = 0x00;
SendPacket(send_buf, 1);
ReceivePacket(receive_buf, &RecvLength);
result1 = receive_buf[0];
result2 = receive_buf[1];
result2 = result2 << 8;
result = result1 + result2;
tabla[index] = result;
return result;
104
4.3.3 Proceso de instalación del programa y drivers necesarios
Cuando el sistema operativo detecta un nuevo periférico USB, intenta determinar que
driver debe utilizar para comunicarse con el dispositivo y una vez determinado, cargar el
driver seleccionado. Esto lo lleva a cabo el Administrador de Dispositivos, que utiliza
instaladores de clase y dispositivo y archivos INF para encontrar el driver adecuado para
cada dispositivo. El Administrador de Dispositivos además de ser el responsable de
instalar, configurar y desinstalar dispositivos, también se encarga de añadir información
sobre cada dispositivo en el registro del sistema, el cual contiene información sobre el
hardware y el software instalados en el sistema.
Los instaladores de clase y dispositivo son DLL’s. Windows tiene una serie de
instaladores por defecto que el Administrador de Dispositivos utiliza para localizar y
cargar los drivers para dispositivos pertenecientes a clases soportadas por el sistema
operativo. El archivo INF es un fichero de texto que contiene información que ayuda a
Windows a identificar el dispositivo. Este archivo indica al sistema operativo que drivers
debe utilizar y que información debe almacenar en el registro.
El dispositivo desarrollado no pertenece a una de las clases USB por defecto que
soporta el sistema operativo así que tanto el instalador de clase como el archivo INF habrá
que crearlos.
• Version: Especifica el sistema operativo para el que está destinado el fichero INF.
En esta sección se indica también el nombre de la clase de los dispositivos
instalados con este fichero así como un identificador de clase que es utilizado por el
registro del sistema para identificar a los dispositivos pertenecientes a esta clase.
105
• Manufacturer: Contiene el identificador de vendedor y producto
(USB\VID_04D8&PID_0011). Cuando el Administrador de Dispositivo encuentra
una coincidencia entre estos valores y los identificadores obtenidos del dispositivo
durante la enumeración, sabe que ha encontrado el archivo INF correcto.
• Strings: Define las cadenas referenciadas en las otras secciones. El fichero INF
creado (picusb.inf) puede verse en el apartado 7.1.2 del anexo.
Figura 4.9. Vista del “Administrador de tareas” con el dispositivo USB reconocido y funcionando
106
4.3.4 Estética del programa
Figura 4.10. Vista del programa que guarda y gestiona los datos recibidos del dispositivo USB
107
5 PRESUPUESTO
5.1 INTRODUCCIÓN
5.2 COSTE DE RECURSOS HARDWARE
5.3 COSTE DE RECURSOS SOFTWARE
5.4 COSTE DE COMPONENTES Y FABRICACIÓN DEL PCB
5.5 COSTE DE RECURSOS HUMANOS
5.6 COSTE TOTAL DEL PROYECTO
5.7 COSTE DEL DISPOSITIVO EN EL MERCADO
108
5.1 Introducción
Para realizar una estimación del coste económico del proyecto, se han dividido los
gastos asociados al desarrollo del mismo en varios grupos:
El coste total es la suma de todos los costes anteriores. Además, se añade al final el coste
del producto una vez puesto en el mercado.
CONCEPTO PRECIO
PC AMD Duron a 902MHz 81,25€ *
Grabador de PIC’s GTP-USB+ 60,00 €
Soldador de precisión 30,00 €
Multímetro digital 15,00 €
TOTAL 186,25 €
Tabla 5.1. Coste de recursos hardware
109
5.3 Coste de recursos software
CONCEPTO PRECIO
Microsoft Windows XP
131,52 €
Profesional
EAGLE Layout Editor 4.15 200,00 €
Compilador CCS v3.227 331,86 €
Visual C# 2005 Express
0,00 €
Edition
Winpic800 v3.60 0,00 €
TOTAL 663,38 €
Tabla 5.2. Coste de recursos software
110
Cristal oscilador de cuarzo Q1 0,87 1 0,87
20MHz
Diodo LED 3mm diámetro D1 0,10 1 0,10
Rojo(10mA)
Diodo LED 3mm diámetro D2 0,10 1 0,10
Amarillo(10mA)
Diodo LED 3mm diámetro D3 0,10 1 0,10
Verde(10mA)
Pulsador CI vert. 6x6 mm CC- BTN1 0,26 1 0,26
PUSH
Pulsador CI vert. 12x12 mm BTN2 0,34 1 0,34
CC-PUSH
Mini-interruptor de BTN3 0,76 1 0,76
alimentación
Transistor MOSFET de canal N T1 0,24 1 0,24
2N7000
Encapsulado TO-92
Transistor MOSFET de canal P T2 0,46 1 0,46
BS250
Encapsulado TO-92
Estabilizador de tensión a 5 V y T3 0,19 1 0,19
100mA 78L05
Encapsulado TO-92
Zocalo 28 pines ZCL1 0,27 1 0,27
USB tipo B hembra para chasis USB1 1,25 1 1,25
Placa fotosensible fibra de PCB1 3,20 1 3,20
vidrio 2 caras 80x120 mm
1,2mm
Microcontrolador PIC 18F2550 CH1 4,62 1 4,62
TOTAL 16,82 €
111
5.5 Coste de recursos humanos
Las tareas realizadas por el ingeniero son el análisis de requisitos, diseño, implementación
y experimentación, mientras que el técnico se encargará únicamente del montaje y testeo
de la placa de prueba y del PCB. A continuación pueden verse las horas dedicadas a cada
tarea así como el coste resultante.
112
5.6 Coste total del proyecto
Aquí se detalla el coste total del proyecto, desglosado en todas las partes en las que
ha consistido. Hay que mencionar que todos los precios antes mencionados son con IVA
incluido.
CONCEPTO COSTE
Coste de recursos hardware 192,25 €
Coste de recursos software 663,38 €
Coste de componentes y fabricación del PCB 16,82 €
Coste de recursos humanos 6478,40 €
TOTAL 7350,85 €
Aquí se hace una estimación del posible precio de venta del lector en el mercado,
para ello hay que estudiar el impacto que puede tener el producto en el mercado y estudiar
la relación entre costes y ingresos según el número de unidades vendidas.
Para calcular el coste de cada unidad vendida hemos de saber los siguientes
parámetros:
- Costes fijos (CF): Son los costes de recursos humanos, los costes de hardware
y los costes de software. Son costes independientes del número de unidades
vendidas.
- Costes variables (CV): Son los costes de producción y material de cada
unidad. Son costes proporcionales al número de unidades.
- Costes totales (CT): Es la suma de los costes fijos y los costes variables.
- Ingresos totales (IT): Son los ingresos obtenidos de haber vendido una cierta
cantidad unidades. Es proporcional al número de unidades producidas y
vendidas.
113
En este caso, los parámetros anteriores son los siguientes:
Una vez conocidos estos parámetros, hay que llegar a un compromiso con el precio
de cada lector de código de barras. Un precio razonable sería de 30 € por unidad, un precio
muy por debajo de los lectores de códigos de barras en el mercado. La estrategia es la de
obtener beneficios pronto, aunque el precio de cada unidad disminuye dependiendo del
número de unidades vendidas.
A continuación una tabla con de ingresos totales según las unidades vendidas.
Según las unidades vendidas, el precio de cada unidad sufre una rebaja para incentivar más
la venta y obtener más beneficios. Vienen todos los parámetros para calcularlo con las
ecuaciones anteriores.
UNIDADES CF CM CV CT PRECIO UD IT
1-9 7334,03 € 16,74 € 16,74 € 7350,77 € 30 € - 7.320,77 €
10-49 7334,03 € 16,74 € 167,4 € 7501,43 € 30 € - 7.201,43 €
50-99 7334,03 € 16,48 € 824 € 8175,03 € 30 € - 6.675,03 €
100-199 7334,03 € 16,21 € 1.621 € 8.955,03 € 29 € - 6.055,03 €
200-499 7334,03 € 16,21 € 3.242 € 10.576,03 € 29 € - 4.776,03 €
500-999 7334,03 € 16,21 € 8.105 € 15.439,03 € 29 € - 939,03 €
1.000-4.999 7334,03 € 16,08 € 16.080 € 23.414,03 € 28 € 4.585,97 €
5.000-9.999 7334,03 € 15,85 € 79.250 € 86.584,03 € 27 € 48.415,97 €
10.000-99.999 7334,03 € 15,34 € 153.400 € 160.734,03 € 25 € 89.265,97 €
100.000- 15,34 €
7334,03 € 1.534.000 € 1.541.334,03 € 25 € 95.8665,97 €
999.999
1.000.000+ 7334,03 € 15,34 € 15.340.000 € 15.347.334,03 € 25 € 9.652.665,97 €
114
y almacenes industriales, etc. España consta de alrededor de 3.000.000 de empresas,
250.000 de estas se ubican en la industria, y 800.000 en el comercio. Suponiendo que
vendemos una unidad del producto al 50 % de estas empresas, el número de lectores
vendidos sería de 550.000, entonces el beneficio obtenido sería el siguiente:
7334 ,03 €
N º UNIDADES = = 573,42 unidades (33)
12,79 € / ud
115
6 CONCLUSIONES Y TRABAJO FUTURO
6.1 CONCLUSIONES
6.2 TRABAJO FUTURO
116
6.1 Conclusiones
Respecto a la aplicación software, se puede decir que lleva a cabo todas las
funciones para las que fue diseñada, presentando un interfaz de usuario intuitivo y fácil de
utilizar.
Se puede concluir que los ordenadores actuales utilizan una gama muy amplia de
componentes. La interconexión de dichos dispositivos cumple un rol trascendental, donde
aquellos más simples en su instalación y versátiles en su operación invaden rápidamente el
mercado. Un mercado marcado por los dispositivos “Plug & Play”, siendo el medio más
utilizado el estándar USB, el cual provee una interfaz única, práctica y fácil de usar para la
gran mayoría de periféricos que puede utilizar el ordenador, además de extender
notoriamente la cantidad de dichos dispositivos que se pueden utilizar de forma
simultánea.
117
Por último, el bajo coste económico del dispositivo, que está muy por debajo del
resto de lectores de códigos de barras que están a la venta en el mercado. Dichos lectores
rondan los 100 € incluso más, mientras que el lector diseñado en este proyecto es de 30 € o
menos, dependiendo del estudio de mercado realizado. Este hecho hace que las
expectativas creadas al principio del proyecto se cumplan con creces.
Aunque se han cumplido los objetivos del proyecto, es posible mejorarlo en ciertos
aspectos y dotarlo de nuevos elementos y características:
• Utilizar una batería recargable de litio en vez de una pila de 9V. Además,
poder recargar dicha batería vía USB automáticamente cuando este se
conecte al puerto USB. Esto dotaría de mayor autonomía al lector, además de
mayor comodidad al no tener que ir cambiando de pila cuando esta se
consuma.
• Hacer la placa PCB con elementos SMD para disminuir el tamaño de la placa
notablemente. Esto disminuiría el volumen del dispositivo, haciéndolo más
portátil y incorporarlo en carcasas mucho más pequeñas. Además abarataría
el coste de material al haber menos cantidad de silicio y otros elementos.
• Crear una base de datos con los resultados obtenidos de las lecturas de
códigos de barras y clasificar los resultados según el prefijo, el número del
elemento y tener la posibilidad de dotar a cada código de barras de una
descripción.
118
7 ANEXOS
119
7.1 CÓDIGO FUENTE
/////////////////////////////////////////////////////////////////////////
//// CODEMATIC.c ////
//// ////
//// Realizado con el compilador CCS PCWH 3.227 ////
/////////////////////////////////////////////////////////////////////////
#include <18F2550.h>
#device ADC=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
/////////////////////////////////////////////////////////////////////////
////
//
// CCS Library dynamic defines. For dynamic configuration of the CCS
//Library
// for your application several defines need to be made. See the
//comments
// at usb.h for more information
//
/////////////////////////////////////////////////////////////////////////
////
#define USB_HID_DEVICE FALSE //deshabilitamos el uso de
las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for
IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for
OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 1 //size to allocate for the
tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 3 //size to allocate for the
rx endpoint 1 buffer
/////////////////////////////////////////////////////////////////////////
////
//
// Include the CCS USB Libraries. See the comments at the top of these
// files for more information
//
/////////////////////////////////////////////////////////////////////////
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for
CCS's PIC USB driver
#include <PakoUSB.h> //Configuración del USB y los descriptores
para este dispositivo
#include <usb.c> //handles usb setup tokens and get
descriptor reports
120
#define LEDV PIN_B7
#define LEDR PIN_B5
#define LEDA PIN_B6
#define LED_ON output_high
#define LED_OFF output_low
int new_button_pressed=0;
int old_button_pressed=0;
int usb_conectado_old=0;
int usb_conectado_new=0;
int funcion=0;
#INT_EXT
void EXT0_isr()
{
#INT_EXT1
void EXT1_isr()
{
usb_conectado_new=1;
}
else if(usb_conectado_old==1) // if button
action and was pressed
{
ext_int_edge(1,L_TO_H); // change so interrupts on press
usb_conectado_new=0;
121
funcion=0; // the button is now up
}
usb_conectado_old=usb_conectado_new;
void main(void)
{
index=0;
funcion=0; //INICIALIZA EL DISPOSITIVO EN MODO ESPERA
setup_port_a(ALL_ANALOG | VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(1);
//CONFIGURACIÓN DE INTERRUPCIONES
ext_int_edge(1,L_TO_H); //HABILITA INTERRUPCIONES DE FLANCO ASCENDENTE
EN EL EXT1
enable_interrupts(INT_EXT1);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
LED_OFF(LEDV);
LED_OFF(LEDA);
LED_OFF(LEDR);
while(TRUE)
{
122
usb_task(); //habilita periferico usb e
interrupciones
LED_OFF(LEDR);
LED_ON(LEDV); //encendemos led verde
if(index==650) index=0;
}
if (modo == 1) // Modo_borrar_datos_PIC
{
for(index=0;index<650;index++) tabla_num_EAN[index]=0;
//incializamos todos los valores de la tabla de numeros EAN
envia[0]=1;
usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos
confirmacion de haber borrado los datos
}
int guardar_valor_min = 0;
123
int valor_min = 0;
int valor_min_window = 0;
int window_parcial1 = 0, window_parcial2 = 0, resto_parcial1
= 0, resto_parcial2 = 0;
int valor_max_window = 0;
/**************************************************/
tabla[0]=1001;
/**********INICIO DE LECTURA************/
tabla[i]=resultado_adc;
if (tabla[i]<120) i--; //EVITA RUIDO DEBIDO A MALOS CONTACTOS
if(tabla[i]==tabla[i-1]) i--;
else if ((tabla[i]==tabla[i-1]-1)||(tabla[i]==tabla[i-1]+1)) i--;
else if ((tabla[i]==tabla[i-1]-2)||(tabla[i]==tabla[i-1]+2)) i--;
124
{
tabla[i-1]=tabla[i-2]-1; //PARA ELIMINAR PICOS BAJOS PROVOCADOS
POR EL RUIDO AMBIENTAL
tabla[i]=tabla[i-1];
i--;
if(tabla[i-1]<=800)
{
cuenta_barras++;
if(cuenta_barras==30)
{
aux=i;
i=400;
}
}
}
delay_ms(1);
}
/*****FIN DE LECTURA******/
125
/****RETOCAR LA GRAFICA****/
for(i=1;i<400;i++)
{
if((tabla[i-1]>tabla[i])&&(tabla[i+1]>tabla[i])) //PICO MAXIMO
{
if((tabla[i-2]<tabla[i-1])&&(tabla[i+2]<tabla[i+1]))
tabla[i]=(tabla[i-1]+tabla[i+1])/2;
if(tabla[i]<1000)
{
if((tabla[i-2]<tabla[i-1]) && (tabla[i+2]>tabla[i+1]))
tabla[i]=(tabla[i-1]+tabla[i+1])/2; //CASO 1
}
if((tabla[i-1]==tabla[i]+1)&&(tabla[i+1]<tabla[i]))
{
tabla[i-1]--;
tabla[i]=(tabla[i-1]+tabla[i+1])/2;
}
if((tabla[i-1]==tabla[i])&&(tabla[i+1]==tabla[i])&&(tabla[i]>=980))
tabla[i]=tabla[i-1]+1;
cuenta_barras=0;
126
/****FIN DE RETOQUE DE LA LECTURA*******/
/******SEGUNDO FILTRO******/
if (valor_filtro != 0)
{
tabla_valores_filtro[index_valores] = valor_filtro;
index_valores++;
if (index_valores == 30)
{
index_valores = 0;
}
}
127
if ((valor_max_anterior != 0) && (valor_max_posterior != 0)
&& (valor_minimo != 0) && (index_valores <= 14) && (index_valores >= 0))
{
if ((valor_max_anterior == 1) && (valor_max_posterior == 1))
{
}
else if ((valor_max_anterior == 1) &&
(valor_max_posterior == 3))
{
}
else if ((valor_max_anterior == 1) &&
(valor_max_posterior == 4))
{
valor_filtro = 1; //este es el algortimo
bueno de antes
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 1))
{
128
else if ((valor_min_window >= 844) &
(valor_min_window <= 1024)) valor_filtro = 3;
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 2))
{
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 3))
{
if (valor_min_window <= 680) valor_filtro =
1;
else if ((valor_min_window >= 681) &
(valor_min_window <= 1024)) valor_filtro = 2;
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 4))
{
valor_filtro = 1;
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 1))
{
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 2))
{
if (valor_min_window <= 680) valor_filtro =
1;
else if ((valor_min_window >= 681) &
(valor_min_window <= 1024)) valor_filtro = 2;
129
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 3))
{
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 4))
{
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 1))
{
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 2))
{
if (valor_min_window <= 680) valor_filtro =
1;
else if ((valor_min_window >= 681) &
(valor_min_window <= 843)) valor_filtro = 2;
else if ((valor_min_window >= 844) &
(valor_min_window <= 920)) valor_filtro = 3;
else if ((valor_min_window >= 920) &
(valor_min_window <= 1024)) valor_filtro = 4;
else valor_filtro = 0;
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 3))
130
{
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 4))
{
}
guardar_valor_min = 1;
valor_max_anterior = valor_max_posterior;
valor_min_anterior = valor_min_posterior;
//valor_max_anterior = 0;
}
else if ((valor_max_anterior != 0) &&
(valor_max_posterior != 0) && (valor_minimo != 0) && (index_valores >=
15) && (index_valores <= 30))
{
if ((valor_max_anterior == 1) &&
(valor_max_posterior == 1))
{
}
else if ((valor_max_anterior == 1) &&
(valor_max_posterior == 2))
{
131
else if ((valor_min_window >= 681) &
(valor_min_window <= 843)) valor_filtro = 2;
else if ((valor_min_window >= 844) &
(valor_min_window <= 1024)) valor_filtro = 3;
}
else if ((valor_max_anterior == 1) &&
(valor_max_posterior == 3))
{
}
else if ((valor_max_anterior == 1) &&
(valor_max_posterior == 4))
{
valor_filtro = 1;
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 1))
{
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 2))
{
132
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 3))
{
}
else if ((valor_max_anterior == 2) &&
(valor_max_posterior == 4))
{
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 1))
{
if (valor_minimo <= 940) valor_filtro = 1;
//este es el algortimo bueno de antes
else if ((valor_minimo >= 941) &
(valor_minimo <= 1024)) valor_filtro = 2;
else valor_filtro = 0;
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 2))
{
if (valor_min_window <= 680) valor_filtro =
1;
else if ((valor_min_window >= 681) &
(valor_min_window <= 843)) valor_filtro = 2;
else if ((valor_min_window >= 844) &
(valor_min_window <= 1024)) valor_filtro = 3;
else valor_filtro = 0;
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 3))
133
{
}
else if ((valor_max_anterior == 3) &&
(valor_max_posterior == 4))
{
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 1))
{
if (valor_min_window <= 680) valor_filtro = 1;
else if ((valor_min_window >= 681) &
(valor_min_window <= 843)) valor_filtro = 2;
else if ((valor_min_window >= 844) &
(valor_min_window <= 920)) valor_filtro = 3;
else if ((valor_min_window >= 920) &
(valor_min_window <= 1024)) valor_filtro = 4;
else valor_filtro = 0;
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 2))
{
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 3))
{
134
else if ((valor_min_window >= 920) &
(valor_min_window <= 1024)) valor_filtro = 4;
}
else if ((valor_max_anterior == 4) &&
(valor_max_posterior == 4))
{
}
guardar_valor_min = 1;
valor_max_anterior = valor_max_posterior;
valor_min_anterior = valor_min_posterior;
tabla_valores_filtro_min[index_valores_min] =
valor_filtro;
index_valores_min++;
guardar_valor_min = 0;
}
else if ((tabla[i] > tabla[i - 1]) && (tabla[i] > tabla[i
+ 1])) //PICOS MINIMOS
{
valor_minimo = tabla[i];
valor_min = tabla[i];
/*******************************/
135
}
}
LED_ON(PIN_B6);delay_ms(100);
LED_OFF(PIN_B6);delay_ms(100);
LED_ON(PIN_B6);delay_ms(100);
LED_OFF(PIN_B6);delay_ms(100);
LED_ON(PIN_B6);delay_ms(100);
LED_OFF(PIN_B6);
index_valores = 0;
}
index_valores_min = 0;
while (index_valores < 30)
{
index_valores++;
//BARRAS ESPACIADORAS
//JUEGO A (IMPAR)
136
if (tabla_valores_filtro_min[index_valores_min]
== 2) num_EAN[index_EAN] = 1;
if (tabla_valores_filtro_min[index_valores_min]
== 3) num_EAN[index_EAN] = 5;
if (tabla_valores_filtro_min[index_valores_min]
== 4) num_EAN[index_EAN] = 5;
if (tabla_valores_filtro_min[index_valores_min]
== 1) num_EAN[index_EAN] = 0;
}
//JUEGO B(PAR)
137
if ((num1 == 1) && (num2 == 3))
{
if (tabla_valores_filtro_min[index_valores_min]
== 1) num_EAN[index_EAN] = 9;
else if
(tabla_valores_filtro_min[index_valores_min] == 2) num_EAN[index_EAN] =
0;
else if
(tabla_valores_filtro_min[index_valores_min] == 3) num_EAN[index_EAN] =
0;
else if
(tabla_valores_filtro_min[index_valores_min] == 4) num_EAN[index_EAN] =
0;
}
index_EAN++;
}
//JUEGO C(PAR)
138
{
if (tabla_valores_filtro_min[index_valores_min]
== 1) num_EAN[index_EAN] = 9;
if (tabla_valores_filtro_min[index_valores_min]
== 2) num_EAN[index_EAN] = 0;
if (tabla_valores_filtro_min[index_valores_min]
== 3) num_EAN[index_EAN] = 0;
if (tabla_valores_filtro_min[index_valores_min]
== 4) num_EAN[index_EAN] = 0;
}
index_EAN++;
}
index_valores++;
index_valores_min++;
index_valores_min++;
}
/*******FIN DE OBTENCION DEL NUMERO EAN*******/
/**********DIGITO DE CONTROL************/
dc_parcial1 = dc_parcial1 * 3;
digito_control = 10 - dc_resto;
/***************************************/
}
}
139
7.1.2 Fichero .INF
Signature="$WINDOWS NT$"
Class=%ClassName%
ClassGuid={4D36E911-E325-11CE-BFC1-08002BE10318}
Provider=%MFGNAME%
DriverVer=03/10/2005,1.0.0.0
CatalogFile=picusb.cat
[DestinationDirs]
DefaultDestDir = 12
PicUSB.ClassCopyFiles = 11
;------------------------------------------------------------------------
; Class installation sections
;------------------------------------------------------------------------
[ClassInstall32]
AddReg=PicUSB.ClassReg
CopyFiles=PicUSB.ClassCopyFiles
[PicUSB.ClassReg]
HKR,,,0,%ClassName%
HKR,,Class,,%ClassDesc%
HKR,,Icon,,11
HKR,,Installer32,,"picusbci.dll,PicUSBClassInstaller"
[PicUSB.ClassCopyFiles]
picusbci.dll
;------------------------------------------------------------------------
; Device Install Section
;------------------------------------------------------------------------
[Manufacturer]
%MFGNAME%=Standard
[Standard]
%DESCRIPTION%=DriverInstall, USB\VID_04D8&PID_0011
[SourceDisksNames]
1 = %INSTDISK%,,,""
[SourceDisksFiles]
mchpusb.sys = 1,,
wdmstub.sys = 1,,
picusbci.dll = 1,,
;------------------------------------------------------------------------
; Windows 2000/XP Sections
;------------------------------------------------------------------------
[DriverInstall.NT]
CopyFiles=DriverCopyFiles
[DriverCopyFiles]
mchpusb.sys
140
[DriverInstall.NT.Services]
AddService = PicUSB, 2, DriverService
[DriverService]
DisplayName = %SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\mchpusb.sys
LoadOrderGroup = Extended Base
;------------------------------------------------------------------------
; Windows 98/Me Sections
;------------------------------------------------------------------------
[DriverInstall]
AddReg=DriverAddReg
CopyFiles=DriverCopyFiles,StubCopyFiles
DriverVer=09/26/2005,1.0.0.0
[DriverAddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,"wdmstub.sys,mchpusb.sys"
[StubCopyFiles]
wdmstub.sys
;------------------------------------------------------------------------
; String Definitions
;------------------------------------------------------------------------
[Strings]
MFGNAME="PakoJones USB"
INSTDISK="PicUSB Device Driver Disc"
DESCRIPTION="PakoUSB"
SVCDESC="PicUSB Device Driver"
ClassName="PIC 18Fxx5x USB Devices"
ClassDesc="PakoUSB Sample Device"
141
7.1.3 Código de la aplicación en el PC
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
Program codematic_api = new Program(); //declara un nombre a
Program.cs para el uso en este código
/**************VARIABLES GLOBALES***************/
int[] tabla;
/***********************************************/
public Form1()
{
InitializeComponent();
}
int fin_transmision = 0;
int index = 0,j=0;
uint dispositivo_conectado = 0;
tabla = new int[650]; //50x13, 50 números EAN
pantalla_num_ean.Text = " ";
pantalla_estado.Text = " ";
pantalla_estado.Text = "Conectando...";
if (dispositivo_conectado == 1)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "Dispositivo conectado";
}
else if (dispositivo_conectado == 0)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "Dispositivo no conectado";
}
/*********************************/
142
pantalla_estado.Text = " ";
pantalla_estado.Text = "Recibiendo datos... ";
while (index<650)
{
if (j <= 13) pantalla_num_ean.Text +=
codematic_api.Recibir_Datos(index).ToString() + " ";
else
{
pantalla_num_ean.Text +=
codematic_api.Recibir_Datos(index).ToString() + "\n";
j = 0;
}
//tabla[index] = codematic_api.Guardar_datos(index);
//guarda los datos en una tabla
index++;
j++;
}
DialogResult respuesta;
respuesta=MessageBox.Show("\t\n¿Esta seguro de querer borrar los
datos del PIC?\t", "Seleccione una opción", MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (respuesta == DialogResult.Yes)
{
else if (dispositivo_conectado == 0)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "Dispositivo no conectado";
}
/*********************************/
143
}
if (datos_borrados == 1)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "Datos borrados con éxito ";
}
else if (datos_borrados == 0)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "ERROR al borrar los datos del
CODEMATIC ";
}
dispositivo_conectado=codematic_api.Conexion();
if (dispositivo_conectado == 1)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "Dispositivo conectado";
}
else if (dispositivo_conectado == 0)
{
pantalla_estado.Text = " ";
pantalla_estado.Text = "Dispositivo no conectado";
}
}
}
144
Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices; // Clase para importar DLL
namespace WindowsApplication1
{
unsafe public class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
#region Definición de los Strings: EndPoint y VID_PID
string vid_pid_norm = "vid_04d8&pid_0011";
void* myOutPipe;
void* myInPipe;
145
public void OpenPipes()
{
DWORD selection = 0;
DWORD SentDataLength;
OpenPipes();
_MPUSBWrite(myOutPipe, (void*)SendData, SendLength,
&SentDataLength, SendDelay);
ClosePipes();
}
OpenPipes();
_MPUSBRead(myInPipe, (void*)ReceiveData, ExpectedReceiveLength,
ReceiveLength, ReceiveDelay);
ClosePipes();
}
/******************************************************/
int result;
tabla = new int[650];
146
tabla[index] = result; //guarda el dato en la tabla
int result;
usb_connection=_MPUSBGetDeviceCount(vid_pid_norm); // comprueba
la conexión del lector al puerto USB
}
}
147
Form1.Designer.cs
namespace WindowsApplication1
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.apartado_control = new System.Windows.Forms.GroupBox();
this.conexion = new System.Windows.Forms.Button();
this.info = new System.Windows.Forms.Button();
this.borrar_datos_pic = new System.Windows.Forms.Button();
this.recibir_datos = new System.Windows.Forms.Button();
this.apartado_num_ean = new System.Windows.Forms.GroupBox();
this.pantalla_num_ean = new System.Windows.Forms.RichTextBox();
this.apartado_estado = new System.Windows.Forms.GroupBox();
this.pantalla_estado = new System.Windows.Forms.TextBox();
this.salir = new System.Windows.Forms.Button();
this.imagen_titulo = new System.Windows.Forms.PictureBox();
this.apartado_control.SuspendLayout();
this.apartado_num_ean.SuspendLayout();
this.apartado_estado.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.imagen_titulo)).BeginIni
t();
this.SuspendLayout();
//
// apartado_control
//
this.apartado_control.Controls.Add(this.conexion);
this.apartado_control.Controls.Add(this.info);
this.apartado_control.Controls.Add(this.borrar_datos_pic);
this.apartado_control.Controls.Add(this.recibir_datos);
this.apartado_control.Location = new System.Drawing.Point(135, 131);
this.apartado_control.Name = "apartado_control";
this.apartado_control.Size = new System.Drawing.Size(174, 178);
148
this.apartado_control.TabIndex = 0;
this.apartado_control.TabStop = false;
this.apartado_control.Text = "CONTROL";
//
// conexion
//
this.conexion.BackColor = System.Drawing.Color.Gold;
this.conexion.Location = new System.Drawing.Point(14, 96);
this.conexion.Name = "conexion";
this.conexion.Size = new System.Drawing.Size(151, 33);
this.conexion.TabIndex = 3;
this.conexion.Text = "CONEXIÓN DEL PIC";
this.conexion.UseVisualStyleBackColor = false;
this.conexion.Click += new System.EventHandler(this.conexion_Click);
//
// info
//
this.info.Location = new System.Drawing.Point(14, 135);
this.info.Name = "info";
this.info.Size = new System.Drawing.Size(151, 33);
this.info.TabIndex = 2;
this.info.Text = "Acerca de...";
this.info.UseVisualStyleBackColor = true;
this.info.Click += new System.EventHandler(this.info_Click);
//
// borrar_datos_pic
//
this.borrar_datos_pic.BackColor = System.Drawing.Color.OrangeRed;
this.borrar_datos_pic.Location = new System.Drawing.Point(14, 58);
this.borrar_datos_pic.Name = "borrar_datos_pic";
this.borrar_datos_pic.Size = new System.Drawing.Size(151, 33);
this.borrar_datos_pic.TabIndex = 1;
this.borrar_datos_pic.Text = "BORRAR DATOS DEL PIC";
this.borrar_datos_pic.UseVisualStyleBackColor = false;
this.borrar_datos_pic.Click += new
System.EventHandler(this.borrar_datos_pic_Click);
//
// recibir_datos
//
this.recibir_datos.BackColor = System.Drawing.SystemColors.Desktop;
this.recibir_datos.Location = new System.Drawing.Point(14, 19);
this.recibir_datos.Name = "recibir_datos";
this.recibir_datos.Size = new System.Drawing.Size(151, 33);
this.recibir_datos.TabIndex = 0;
this.recibir_datos.Text = "RECIBIR DATOS";
this.recibir_datos.UseVisualStyleBackColor = false;
this.recibir_datos.Click += new
System.EventHandler(this.recibir_datos_Click);
//
// apartado_num_ean
//
this.apartado_num_ean.Controls.Add(this.pantalla_num_ean);
this.apartado_num_ean.Location = new System.Drawing.Point(12, 131);
this.apartado_num_ean.Name = "apartado_num_ean";
this.apartado_num_ean.Size = new System.Drawing.Size(117, 177);
this.apartado_num_ean.TabIndex = 1;
this.apartado_num_ean.TabStop = false;
this.apartado_num_ean.Text = "NUMEROS EAN";
149
//
// pantalla_num_ean
//
this.pantalla_num_ean.Location = new System.Drawing.Point(6, 19);
this.pantalla_num_ean.Name = "pantalla_num_ean";
this.pantalla_num_ean.Size = new System.Drawing.Size(105, 149);
this.pantalla_num_ean.TabIndex = 0;
//
// apartado_estado
//
this.apartado_estado.Controls.Add(this.pantalla_estado);
this.apartado_estado.Location = new System.Drawing.Point(12, 315);
this.apartado_estado.Name = "apartado_estado";
this.apartado_estado.Size = new System.Drawing.Size(297, 50);
this.apartado_estado.TabIndex = 2;
this.apartado_estado.TabStop = false;
this.apartado_estado.Text = "ESTADO";
//
// pantalla_estado
//
this.pantalla_estado.BackColor =
System.Drawing.SystemColors.InfoText;
this.pantalla_estado.Font = new System.Drawing.Font("Tahoma", 9.75F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((byte)(0)));
this.pantalla_estado.ForeColor = System.Drawing.Color.LawnGreen;
this.pantalla_estado.Location = new System.Drawing.Point(6, 19);
this.pantalla_estado.Name = "pantalla_estado";
this.pantalla_estado.Size = new System.Drawing.Size(277, 23);
this.pantalla_estado.TabIndex = 0;
//
// salir
//
this.salir.Location = new System.Drawing.Point(12, 371);
this.salir.Name = "salir";
this.salir.Size = new System.Drawing.Size(297, 33);
this.salir.TabIndex = 4;
this.salir.Text = "SALIR";
this.salir.UseVisualStyleBackColor = true;
this.salir.Click += new System.EventHandler(this.salir_Click);
//
// imagen_titulo
//
this.imagen_titulo.Image =
global::WindowsApplication1.Properties.Resources.logo_codematic_titulo;
this.imagen_titulo.Location = new System.Drawing.Point(22, 12);
this.imagen_titulo.Name = "imagen_titulo";
this.imagen_titulo.Size = new System.Drawing.Size(278, 113);
this.imagen_titulo.TabIndex = 5;
this.imagen_titulo.TabStop = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(321, 409);
this.Controls.Add(this.imagen_titulo);
this.Controls.Add(this.salir);
this.Controls.Add(this.apartado_estado);
this.Controls.Add(this.apartado_num_ean);
this.Controls.Add(this.apartado_control);
150
this.Name = "Form1";
this.Text = "CODEMATIC (PFC - Codigos de barras)";
this.apartado_control.ResumeLayout(false);
this.apartado_num_ean.ResumeLayout(false);
this.apartado_estado.ResumeLayout(false);
this.apartado_estado.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.imagen_titulo)).EndInit(
);
this.ResumeLayout(false);
#endregion
}
}
Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
}
}
151
Form2.Designer.cs
namespace WindowsApplication1
{
partial class Form2
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label4 = new System.Windows.Forms.Label();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.cerrar = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(
);
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Futura Md BT", 12F,
((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold |
System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point,
((byte)(0)));
this.label1.Location = new System.Drawing.Point(190, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(155, 19);
this.label1.TabIndex = 0;
this.label1.Text = "CODEMATIC v1.0";
152
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(191, 41);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(182, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Autor: Francisco Pelegrí Santamaría";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(191, 66);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(205, 13);
this.label3.TabIndex = 2;
this.label3.Text = "Fecha de la versión: 9 de Enero del 2007";
//
// pictureBox1
//
this.pictureBox1.Image =
global::WindowsApplication1.Properties.Resources.logo_acercade;
this.pictureBox1.Location = new System.Drawing.Point(13, 9);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(171, 113);
this.pictureBox1.TabIndex = 3;
this.pictureBox1.TabStop = false;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(191, 92);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(35, 13);
this.label4.TabIndex = 4;
this.label4.Text = "WEB:";
//
// linkLabel1
//
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(239, 92);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(106, 13);
this.linkLabel1.TabIndex = 5;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "www.codematic.com";
//
// cerrar
//
this.cerrar.Location = new System.Drawing.Point(340, 124);
this.cerrar.Name = "cerrar";
this.cerrar.Size = new System.Drawing.Size(62, 21);
this.cerrar.TabIndex = 6;
this.cerrar.Text = "CERRAR";
this.cerrar.UseVisualStyleBackColor = true;
this.cerrar.Click += new
System.EventHandler(this.button1_Click);
153
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(412, 153);
this.Controls.Add(this.cerrar);
this.Controls.Add(this.linkLabel1);
this.Controls.Add(this.label4);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "Form2";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Acerca de CODEMATIC";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
#endregion
154
7.2 MANUAL DE USUARIO
Al conectar el lector de códigos de barras por primera vez, aparecerá el asistente para
la instalación de nuevo hardware. Se marca la opción “No” y se hace click sobre
“Siguiente”. En la siguiente pantalla se marca la opción “Instalar desde una lista o
ubicación específica”. Una vez hecho esto, se hace clic sobre “Siguiente” para pasar a la
próxima pantalla, donde se marca la opción de “Buscar el controlador más adecuado en
estas ubicaciones”. Se hace clic sobre “Incluir esta ubicación en la búsqueda” y a
continuación sobre “Examinar”. Entonces se selecciona la carpeta donde se encuentran los
drivers, en este caso, “Codematic_Driver”, y se hace clic a “Aceptar” y luego a
“Siguiente”. En este momento, comenzarán a copiarse los archivos necesarios en el
ordenador. Una vez se termine de copiar, aparecerá una pantalla indicando que la
instalación del driver está terminada. El LED verde se encenderá, lo que indica que está
listo para que se use el lector.
Figura 7.1 Ventana de administrador de dispositivos con el lector Codematic reconocido por el sistema
El resto de veces que se conecte el lector al ordenador, este será reconocido de forma
automática con lo que no será necesario indicar ningún tipo de información.
155
7.2.2 Utilización del dispositivo
El dispositivo contiene tres LED’s indicadores de los distintos estados del dispositivo
y dos botones para poder interactuar con él directamente. Los tres LED’s indican lo
siguiente:
También hay dos botones, uno grande para realizar las lecturas y el otro más pequeño
para resetear el sistema.
Para un uso correcto del dispositivo, hay que conocer una serie de aspectos respecto
a la posición del sensor, velocidad, etc. Estos aspectos vienen descritos a continuación:
- Pulsar el botón de inicio de lectura. Este se puede reconocer por ser el botón
más grande de los dos botones en el dispositivo.
- Colocar el sensor tocando la superficie, justo al lado del código de barras al que
se va a efectuar la lectura. El sensor debe estar en la posición que marca la
figura siguiente:
- Desplazar el sensor por encima del código de barras de una manera recta e
uniforme, manteniendo la posición respecto el código de barras, sin dejar de
estar en contacto con la superficie y a una velocidad constante.
- El proceso de lectura se marca por el encendido del LED amarillo cuando
detecta el principio del código de barras, y el apagado del mismo LED al
detectar el final del código de barras.
- Si ha habido algún error, el LED rojo se parpadeara tres veces, en intervalos de
medio segundo.
- Si no se ha encendido el LED rojo, significa que la lectura se ha realizado
correctamente.
Para que una lectura se realice correctamente, el LED amarillo deberá encenderse al
inicio del código de barras y apagarse al final del código de barras, si se apaga antes o
después no se habrá realizado una lectura correcta, y lo indicará el LED rojo. El tiempo
para que de tiempo a realizar una lectura esta entre 1 segundo y 1,5 segundos
aproximadamente. Todas las lecturas que se encuentren en ese tiempo y el LED amarillo se
encienda y se apague en el inicio y final del código de barras, son validas.
156
En caso de no encenderse el LED amarillo al intentar realizar una lectura, se deben
comprobar las conexiones del sensor con la placa, resetear el dispositivo pulsando el botón
más pequeño que hay en el dispositivo o comprobar que hay alimentación en el sistema
observando que el LED verde esté encendido.
Para visualizar los resultados de las lecturas hay que conectar el dispositivo por el
puerto USB, y se hace uso de la aplicación creada para su fin y que se comenta en los
siguientes apartados.
En caso de que el LED rojo se encienda, hay que conocer a que tipo de error
corresponde cada secuencia de parpadeo.
Para instalar la aplicación hay que ejecutar el programa “Setup.exe”. Una vez
ejecutado nos verificará si tenemos los requisitos necesarios. En el caso de que “.NET
Framework 2.0” no esté instalado, el propio programa lo descargará de la red y lo instalará
automáticamente. Una vez hecho todo esto, se creará un icono en el menú de “INICIO”
donde se podrá ejecutar el programa “CODEMATIC”.
157
Figura 7.2 Ventana principal de la aplicación CODEMATIC
Para interactuar con el dispositivo lector de códigos de barras, hay que usar los
botones del apartado de CONTROL. En este apartado hay cuatro botones:
158
- Borrar datos del PIC: Borra los números EAN que hayan guardados en el
lector. Cuando se pulsa el botón sale una ventana de aviso donde pregunta si se
esta seguro de borrarlos, es una medida de seguridad, por si se pulsa el botón
por equivocación.
- Dispositivo conectado
- Conectando…
- Dispositivo no conectado
- Datos borrados con éxito
- ERROR al borrar datos del CODEMATIC
- Recibiendo datos…
- ERROR al recibir datos del CODEMATIC
- Fin de transmisión con éxito
159
Por último, el botón de “SALIR” que se encuentra en la parte inferior de la ventana
principal del programa. Es usado para cerrar la aplicación. Cuando se pulsa sale otra
ventana preguntando si se desea salir del programa, como medida de precaución, por si se
ha pulsado el botón por equivocación.
7.3 BIBLIOGRAFÍA
7.3.1 Libros
Jan Alexson.
“USB COMPLETE SECOND EDITION”
Ed. Lakeview Research, 2001.
José María Angulo Usategui, Eugenio Martín Cuenca, Ignacio Angulo Martínez.
“MICROCONTROLADORES PIC, LA SOLUCIÓN EN UN CHIP”
Ed. Thomson, 2000.
José María Angulo Usategui, Eugenio Martín Cuenca, Ignacio Angulo Martínez.
“MICROCONTROLADORES PIC, LA CLAVE DEL DISEÑO”
Ed. Thomson, 2003
John Sharp.
“MICROSOFT VISUAL C# 2005, STEP BY STEP”
Ed. Microsoft Press, 2005.
Xavier Fenard.
“EL BUS USB, GUÍA DEL DESARROLLADOR”.
Ed. Thomson, 2001.
160
7.3.2 Páginas web
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2124&pa
ram=en022613&page=wwwFullSpeedUSB Drivers para el PIC18F2550 y la comunicación
USB (Inglés). (Enero 2007)
161
http://www.winpic800.com Web del creador del grabador GTP-USB+ y del programa de
grabación WinPic800. (Enero 2007)
7.3.3 Datasheet’s
Los datasheet’s están contenidos en el CD del PFC. Los datasheet’s son los
siguientes:
1. CNY70
2. 2N7000
3. BS250
4. Un paseo por USB 1.0
5. Un paseo por USB 2.0
6. 1N4148
7. PIC 2455/2550/4455/4550
8. Making sense of the USB Standard
9. USB Instrumentation by Eric Brown (Yale University)
10. USB Mass Storage Device Using a PIC(C) MCU (AN1003)
11. Power Management for PIC18 USB Microcontrollers with nanoWatt Technology
(AN950)
12. Pila eléctrica de 9V CEGASA (6LF22 Super Alcalina)
13. Verificación de códigos de barras para simbologías lineales. Aspectos generales
técnicos detallados para las Organizaciones Miembros de EAN (Julio 2003)
14. Librería 18F2550.h
15. Librería pic18_usb.h
16. Librería PakoUSB.h
17. Librería usb.c
18. Librería usb.h
19. Librería de funciones para Visual C#, picusbci.dll
20. Programa monitor para estudiar los resultados del lector
21. Archivo de instalación y esquemas del GTP-USB+
162