Microcontrolador PIC18F2550 + interfase de usuario en Netbeans

June 1, 2017 | Autor: Carlos Quintana | Categoría: Electronic Engineering, Electronics, Electrical and Computer Engineering (ECE)
Share Embed


Descripción





Diseño e implementación de un sistema de envío de señales a un computador mediante un microcontrolador PIC18F2550 y una interface gráfica utilizando el entorno JAVA-NETBEANS y las librerías Steel series y JFreeChart.

El presente documento resume los pasos para implementar un circuito electrónico y una interfaz de usuario que serán capaces de:

Digitalizar la señal analógica proveniente de dos sensores resistivos.
Mostrar su resultado sobre una pantalla LCD alfanumérica típica.
Enviar el resultado hacia una PC portátil mediante una conexión USB – puerto COMM virtual.
Mostrar los valores de los sensores en un programa desarrollado en lenguaje Java.

Esquema electrónico del circuito de aplicación:



Descripción del funcionamiento del circuito:

El microcontrolador PIC18F2550 procesará las señales provenientes de los potenciómetros 1 y 2 obteniéndose dos valores digitales que varían entre 0 y 1023 de acuerdo a la posición en la que se encuentre la perilla del potenciómetro. A continuación, estos valores son convertidos a cadenas de caracteres para ser enviados al LCD. La actualización del LCD se da cada 0,4 segundos. El programa además constantemente pregunta si ha sido conectado a un puerto USB, de ser así, se encenderá un indicador led ubicado en el terminal 13 (pin RC2). Al ejecutarse la interface de usuario en el ordenador se encenderá otro led indicador conectado en el terminal 18 (pin RX) cada vez que se transmitan datos entre el circuito y el ordenador. Todo esto debe ocurrir sin que sea necesario interrumpir el envío de datos al LCD.


Vale agregar que éste circuito puede ser modificado fácilmente para conectar otras clases de sensores como los de temperatura NTC o PTC simplemente reemplazando los potenciómetros. El programa del microcontrolador además ha sido provisto de un bloque de arranque o Bootloader USB que permite al desarrollador depurar el programa sin tener que retirar el dispositivo del circuito impreso o del protoboard como en este caso. El bootloader se ejecuta siempre primero, antes de la aplicación y pregunta por el estado del terminal 6 (pin RA4), si es 0 lógico, entonces espera a que el programador actualice el programa del microcontrolador. Una vez hecho esto el programador presiona el botón RESET del circuito y el programa de la aplicación será ejecutado.

El programa (firmware) del microcontrolador:

#include
#device adc=10
#fuses HSPLL,NOWDT,MCLR,NOPROTECT,NODEBUG,USBDIV,PLL5,CPUDIV2,VREGEN,NOPBADEN
#use delay(clock=48000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
/*--------------------------------------------------*/

#define USB_CON_SENSE_PIN PIN_A5
#define pin_rs PIN_C0
#define pin_en PIN_C1
#define usb_led PIN_C7
#define rcv_led PIN_C2

#include
#include
#include

/*--------------------------------------------------*/
/* Remapeo de vectores */
/*--------------------------------------------------*/

#build (reset=0x800, interrupt=0x808)
#org 0, 0x7FF {}

/*--------------------------------------------------*/
/* Declaracion de variables */
/*--------------------------------------------------*/

int16 adcLCDch0, adcLCDch1, contador;
short usb_config, usb_conect;

/*--------------------------------------------------*/
/* Programa de aplicacion */
/*--------------------------------------------------*/

void main(void){

/* Configuracion inicial */

set_tris_a(0x33);
set_tris_b(0);
set_tris_c(0);
output_a(0);
output_b(0);
output_c(0);
adcLCDch0 = 0;
adcLCDch1 = 0;
delay_ms(100);

/* Inicializacion del LCD */

LCD2x16_Init();
delay_ms(100);

/* Configuracion del módulo ADC */


setup_adc_ports(AN0_TO_AN1 " VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);

while(1){

if (input(USB_CON_SENSE_PIN)){
if (!usb_config){
usb_task();
if (usb_enumerated()){
output_high(usb_led);
usb_conect = FALSE;
if(usb_cdc_kbhit()){
if(usb_cdc_getc()=='A'){
printf(usb_cdc_putc,"%04lu%04lu",adcLCDch0,adcLCDch1);
output_high(rcv_led);
delay_ms(20);
output_low(rcv_led);
}
}
}
}
else {
delay_ms(50);
usb_init();
usb_config = TRUE;
}
}
else {
if (usb_config){
delay_ms(50);
usb_conect = TRUE;
output_low(usb_led);
}
}

if (usb_conect){
set_adc_channel(0);
delay_us(20);
adcLCDch0 = read_adc();
LCD2x16_Goto(1,1);
printf(LCD2x16_Caracter,"Canal0 = %4lu ",adcLCDch0);
set_adc_channel(1);
delay_us(20);
adcLCDch1 = read_adc();
LCD2x16_Goto(2,1);
printf(LCD2x16_Caracter,"Canal1 = %4lu ",adcLCDch1);
delay_ms(400);
}
}
}

El programa ha sido desarrollado en lenguaje C utilizando el compilador PIC C de la marca CCS versión 4.14
Como entorno de programación se utilizó el programa MPLAB 8.91 de microchip.



El programa del ordenador ha sido escrito en lenguaje JAVA dentro del entorno NETBEANS en su versión 7.2





Las librerías utilizadas para desarrollar la aplicación son SteelSeries: http://www.java2s.com/Code/Jar/s/DownloadSteelSeries395sourcesjar.htm
Y JFreeChart: https://sourceforge.net/projects/jfreechart/files/
Programa de la aplicación de usuario:
package TestGauge2;
import eu.hansolo.steelseries.tools.BackgroundColor;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortEvent;
import com.fazecast.jSerialComm.SerialPortPacketListener;
import eu.hansolo.steelseries.tools.ColorDef;
import eu.hansolo.steelseries.tools.FrameDesign;
import eu.hansolo.steelseries.tools.LcdColor;
import java.awt.event.*;
import java.util.Scanner;
import javax.swing.JOptionPane;
import javax.swing.Timer;

/**
*
* @author sandro
*/
public class frmGauge2 extends javax.swing.JFrame {

SerialPort chosenPort;
int x = 0;
byte[] out = new byte[1];
XYSeries serieA = new XYSeries("CANAL 0");
XYSeries serieB = new XYSeries("CANAL 1");
Timer timer1, timer2;
boolean marca1 = false;
/**
* Creates new form frmGauge2
*/
public frmGauge2() {
initComponents();

Radial.setTitle("ADC CANAL 0");
Linear.setTitle("ADC CANAL 1");
Radial.setUnitString("Units");
Linear.setUnitString("Units");
Radial.setMinValue(0);
Linear.setMinValue(0);
Radial.setMaxValue(1100);
Linear.setMaxValue(1100);
Radial.setLcdDecimals(0);
Linear.setLcdDecimals(0);
Radial.setLcdUnitString("Units");
Linear.setLcdUnitString("Units");
Radial.setLcdUnitStringVisible(true);
Linear.setLcdUnitStringVisible(true);
Radial.setFrameDesign(FrameDesign.GOLD);
Linear.setFrameDesign(FrameDesign.GOLD);
Radial.setBackgroundColor(BackgroundColor.RED);
Linear.setBackgroundColor(BackgroundColor.RED);

XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(serieA);
dataset.addSeries(serieB);
JFreeChart chart = ChartFactory.createXYLineChart("Lectura vs. tiempo", "Time (seconds)", "ADC Reading", dataset);
ChartPanel panel = new ChartPanel(chart);
jPanel2.setLayout(new java.awt.BorderLayout());
jPanel2.add(panel);
jPanel2.validate();

ActionListener taskPerformer2 = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if(!marca1){
if(cbPuertos.getSelectedIndex() == -1){
SerialPort[] portNames = SerialPort.getCommPorts();
for(int i = 0; i < portNames.length; i++){
cbPuertos.addItem(portNames[i].getSystemPortName());
}
}
else {
marca1 = true;
// cbPuertos.removeAllItems();
}
}
else {
SerialPort[] portNames = SerialPort.getCommPorts();
int i = portNames.length;
if(i == 0){
cbPuertos.removeAllItems();
timer1.stop();
chosenPort.removeDataListener();
chosenPort.closePort();
while(chosenPort.isOpen()){
}
Radial.setValueAnimated(0);
Linear.setValueAnimated(0);
serieA.clear();
serieB.clear();
x = 0;
marca1 = false;
cbPuertos.setEnabled(true);
btnConectar.setText("CONECTAR");
}
}
}
};
timer2 = new Timer(500, taskPerformer2);
timer2.start();

out[0] = 'A';
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
//
private void initComponents() {

Linear = new eu.hansolo.steelseries.gauges.LinearBargraph();
Radial = new eu.hansolo.steelseries.gauges.Radial();
jPanel1 = new javax.swing.JPanel();
cbPuertos = new javax.swing.JComboBox();
cbColores = new javax.swing.JComboBox();
btnConectar = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(null);

javax.swing.GroupLayout LinearLayout = new javax.swing.GroupLayout(Linear);
Linear.setLayout(LinearLayout);
LinearLayout.setHorizontalGroup(
LinearLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 138, Short.MAX_VALUE)
);
LinearLayout.setVerticalGroup(
LinearLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 448, Short.MAX_VALUE)
);

getContentPane().add(Linear);
Linear.setBounds(331, 11, 138, 448);

javax.swing.GroupLayout RadialLayout = new javax.swing.GroupLayout(Radial);
Radial.setLayout(RadialLayout);
RadialLayout.setHorizontalGroup(
RadialLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 284, Short.MAX_VALUE)
);
RadialLayout.setVerticalGroup(
RadialLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 284, Short.MAX_VALUE)
);

getContentPane().add(Radial);
Radial.setBounds(10, 11, 284, 284);

cbPuertos.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
cbPuertos.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Puerto", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 12))); // NOI18N

cbColores.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
cbColores.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "ROJO", "NEGRO", "AZUL", "VERDE", "METAL", "COCOS", "SATIN", "BLANCO" }));
cbColores.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Color", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 12))); // NOI18N
cbColores.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbColoresActionPerformed(evt);
}
});

btnConectar.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
btnConectar.setText("CONECTAR");
btnConectar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnConectarActionPerformed(evt);
}
});

javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(cbPuertos, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cbColores, javax.swing.GroupLayout.PREFERRED_SIZE, 164, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(81, 81, 81)
.addComponent(btnConectar, javax.swing.GroupLayout.PREFERRED_SIZE, 146, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(84, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(cbPuertos, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE)
.addComponent(cbColores))
.addGap(18, 18, 18)
.addComponent(btnConectar, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

getContentPane().add(jPanel1);
jPanel1.setBounds(10, 313, 311, 132);

javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 656, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 448, Short.MAX_VALUE)
);

getContentPane().add(jPanel2);
jPanel2.setBounds(487, 11, 656, 448);

java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-1169)/2, (screenSize.height-524)/2, 1169, 524);
}//

private void btnConectarActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if(cbPuertos.getSelectedIndex() != -1){
if(btnConectar.getText().equals("CONECTAR")) {
// attempt to connect to the serial port
chosenPort = SerialPort.getCommPort(cbPuertos.getSelectedItem().toString());
chosenPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
while(!chosenPort.openPort()){
}
if(chosenPort.isOpen()){
btnConectar.setText("DESCONECTAR");
cbPuertos.setEnabled(false);
}
PacketListener listener = new PacketListener();
chosenPort.addDataListener(listener);
try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); }
// create a new thread that listens for incoming text and populates the gauge
/* Thread thread = new Thread(){
@Override public void run() {
Scanner scanner = new Scanner(chosenPort.getInputStream());
while(scanner.hasNextLine()) {
try {
String line = scanner.nextLine();
String subA = line.substring(0,4);
String subB = line.substring(4,8);
int numberA = Integer.parseInt(subA);
int numberB = Integer.parseInt(subB);
serieA.add(x++,numberA);
serieB.add(x++,numberB);
Radial.setValueAnimated(Double.parseDouble(subA));
Linear.setValueAnimated(Double.parseDouble(subB));
} catch(Exception e) {}
}
scanner.close();
}
};
thread.start();*/
/* Se configura el evento timer1 */
ActionListener taskPerformer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
int y = chosenPort.writeBytes(out, 1);
}
};
timer1 = new Timer(1500, taskPerformer);
timer1.start();
}
else {
// disconnect from the serial port
timer1.stop();
chosenPort.removeDataListener();
chosenPort.closePort();
while(chosenPort.isOpen()){
}
Radial.setValueAnimated(0);
Linear.setValueAnimated(0);
serieA.clear();
serieB.clear();
x = 0;
marca1 = false;
cbPuertos.setEnabled(true);
btnConectar.setText("CONECTAR");
}
}
else {
JOptionPane.showMessageDialog(null, "Conecte un dispositivo", "Error de conexión", JOptionPane.ERROR_MESSAGE);
}
}

private void cbColoresActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
switch(cbColores.getSelectedIndex()){
case 0:
Radial.setBackgroundColor(BackgroundColor.RED);
Radial.setPointerColor(ColorDef.RED);
Radial.setLcdColor(LcdColor.RED_LCD);
Linear.setBackgroundColor(BackgroundColor.RED);
Linear.setBarGraphColor(ColorDef.RED);
Linear.setLcdColor(LcdColor.RED_LCD);
break;
case 1:
Radial.setBackgroundColor(BackgroundColor.BLACK);
Radial.setPointerColor(ColorDef.YELLOW);
Radial.setLcdColor(LcdColor.BLACK_LCD);
Linear.setBackgroundColor(BackgroundColor.BLACK);
Linear.setBarGraphColor(ColorDef.YELLOW);
Linear.setLcdColor(LcdColor.BLACK_LCD);
break;
case 2:
Radial.setBackgroundColor(BackgroundColor.BLUE);
Radial.setPointerColor(ColorDef.BLUE);
Radial.setLcdColor(LcdColor.BLUE_LCD);
Linear.setBackgroundColor(BackgroundColor.BLUE);
Linear.setBarGraphColor(ColorDef.BLUE);
Linear.setLcdColor(LcdColor.BLUE_LCD);
break;
case 3:
Radial.setBackgroundColor(BackgroundColor.GREEN);
Radial.setPointerColor(ColorDef.GREEN);
Radial.setLcdColor(LcdColor.GREEN_LCD);
Linear.setBackgroundColor(BackgroundColor.GREEN);
Linear.setBarGraphColor(ColorDef.GREEN);
Linear.setLcdColor(LcdColor.GREEN_LCD);
break;
case 4:
Radial.setBackgroundColor(BackgroundColor.BRUSHED_METAL);
Radial.setPointerColor(ColorDef.CYAN);
Radial.setLcdColor(LcdColor.GRAY_LCD);
Linear.setBackgroundColor(BackgroundColor.BRUSHED_METAL);
Linear.setBarGraphColor(ColorDef.CYAN);
Linear.setLcdColor(LcdColor.GRAY_LCD);
break;
case 5:
Radial.setBackgroundColor(BackgroundColor.PUNCHED_SHEET);
Radial.setPointerColor(ColorDef.RAITH);
Radial.setLcdColor(LcdColor.REDDARKRED_LCD);
Linear.setBackgroundColor(BackgroundColor.PUNCHED_SHEET);
Linear.setBarGraphColor(ColorDef.RAITH);
Linear.setLcdColor(LcdColor.REDDARKRED_LCD);
break;
case 6:
Radial.setBackgroundColor(BackgroundColor.SATIN_GRAY);
Radial.setPointerColor(ColorDef.MAGENTA);
Radial.setLcdColor(LcdColor.GRAY_LCD);
Linear.setBackgroundColor(BackgroundColor.SATIN_GRAY);
Linear.setBarGraphColor(ColorDef.ORANGE);
Linear.setLcdColor(LcdColor.GRAY_LCD);
break;
default:
Radial.setBackgroundColor(BackgroundColor.WHITE);
Radial.setPointerColor(ColorDef.JUG_GREEN);
Radial.setLcdColor(LcdColor.WHITE_LCD);
Linear.setBackgroundColor(BackgroundColor.WHITE);
Linear.setBarGraphColor(ColorDef.JUG_GREEN);
Linear.setLcdColor(LcdColor.WHITE_LCD);
}
}
private final class PacketListener implements SerialPortPacketListener {
@Override
public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_RECEIVED; }

@Override
public int getPacketSize() { return 8; }

@Override
public void serialEvent(SerialPortEvent event) {
byte[] newData = event.getReceivedData();
int M1 = ((int)newData[0] - 48)*1000;
int C1 = ((int)newData[1] - 48)*100;
int D1 = ((int)newData[2] - 48)*10;
int U1 = (int)newData[3] - 48;
int M2 = ((int)newData[4] - 48)*1000;
int C2 = ((int)newData[5] - 48)*100;
int D2 = ((int)newData[6] - 48)*10;
int U2 = (int)newData[7] - 48;
int numberA = M1 + C1 + D1 + U1;
int numberB = M2 + C2 + D2 + U2;
serieA.add(x++,numberA);
serieB.add(x++,numberB);
Radial.setValueAnimated((double)numberA);
Linear.setValueAnimated((double)numberB);
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(frmGauge2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(frmGauge2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(frmGauge2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(frmGauge2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frmGauge2().setVisible(true);
}
});
}
// Variables declaration - do not modify
private eu.hansolo.steelseries.gauges.LinearBargraph Linear;
private eu.hansolo.steelseries.gauges.Radial Radial;
private javax.swing.JButton btnConectar;
private javax.swing.JComboBox cbColores;
private javax.swing.JComboBox cbPuertos;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
// End of variables declaration
}

Capturas del proyecto en funcionamiento:


Capturas hechas muestran un valor entre 144 a 189.



Capturas muestran un valor entre 494 a 510.
Consultas sobre el proyecto a traves de este medio o al correo [email protected]


Lihat lebih banyak...

Comentarios

Copyright © 2017 DATOSPDF Inc.