Arquivo de dezembro \19\+00:00 2011

Melhorando a classe de Nicholas K. Schulze

A classe criada por Nicholas K. Schulze para comunicação pela porta serial é uma mão na roda, principalmente por ter a licença GPL, mas ela só tem recursos para enviar dados para a porta serial, graças a esse recursos pude fazer um sistema de impressão no MS Windows de uma Epson T81 tm, o exemplo que mostrei em uma postagem anterior mostra isso, mas esses dias meu sócio chegou para mim e pediu para eu colocar no nosso sistema um recurso para pegar o peso de uma balança Filizola por meio de conexão serial, bom daí surgiu a ideia de colocar o que faltava na classe de Nicholas K. Schulze um recurso de leitura da porta serial.
O que eu fiz foi simples, pesquisei na internet uma apostila ou tutorial sobre programação com a biblioteca windows.h com enfase no MinGW g++ para eu entender melhor o funcionamento da biblioteca e poder adaptar ou adicionar um método de leitura de dados na classe de Nicholas K. Schulze, achei uma apostila boa em inglês escrita por Robertson Bayer em 30/03/2008 chamada de Windows Serial Port Programming. Analisando o conteudo do capitulo quatro “Reading/Writing data” consegui entender o funcionamento da leitura de dados na porta serial, o próximo passo era colocar isso dentro da classe, mas isso foi mais simples do que achei.
Segue abaixo a classe modificada e um exemplo para se comunicar a a balança Filizola.
serial.h
#ifndef SERIAL_H_
#define SERIAL_H_
#include <windows.h>

class ConexaoSerial {
public:
ConexaoSerial(void);
void begin(char comport[], int _baud);
void close(void);
void write(char data);
void send(char data[]);
DWORD read(char data[], int length);
private:
int baud;
int error;
HANDLE SerialPortHandle;
};

#endif /* SERIAL_H_ */
serial.cpp
/*
    SerialPort.cpp
    Created by Nicholas K. Schulze, Febuary 11, 2011.
    Melhorada por Pablo Alexander, 16 Dezembro de 2011.
*/
#include "serial.h"
#include <stdio.h>
#include <stdlib.h>

//CONSTRUTOR
ConexaoSerial::ConexaoSerial(void){
baud = 9600;
error = 0;
}

//INICIA A CONEXAO
void ConexaoSerial::begin(char comport[], int _baud){

//SELECT BAUD RATE
baud = _baud;
DWORD BR;
switch (baud){
case 2400:
BR = CBR_2400;
break;
case 4800:
BR = CBR_4800;
break;
case 9600:
BR = CBR_9600;
break;
case 19200:
BR = CBR_19200;
break;
case 38400:
BR = CBR_38400;
break;
case 57600:
BR = CBR_57600;
break;
case 115200:
BR = CBR_115200;
break;
case 128000:
BR = CBR_128000;
break;
case 256000:
BR = CBR_256000;
break;
default:
BR = CBR_9600;
break;
}

//OPEN COM PORT
SerialPortHandle = CreateFile(comport, GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
/*FILE_ATTRIBUTE_NORMAL*/0,
NULL);

//Throw error if com port does not exist
if(SerialPortHandle == INVALID_HANDLE_VALUE){
if(GetLastError() == ERROR_FILE_NOT_FOUND){
printf("ERROR: SerialPort port does not exist\n");
}else{
printf("ERROR: invalid handle");
}
error = 1;
}

//SET SerialPort PARAMETERS
if(error == 0){
DCB dcbParamaters/*= {0}*/;
//dcbParamaters.DCBlength = sizeof(dcbParamaters);

if(!GetCommState(SerialPortHandle, &dcbParamaters)){
printf("ERROR: error getting state\n");
error = 1;
}

//use chosen baud rate and standart settings, change these if required
dcbParamaters.BaudRate = BR;
dcbParamaters.ByteSize = 8;
dcbParamaters.StopBits = ONESTOPBIT;
dcbParamaters.Parity = NOPARITY;

if(!SetCommState(SerialPortHandle, &dcbParamaters)){
printf("ERROR: error setting state\n");
error = 1;
}
}

//SET TIMEOUTS
if(error ==0){
COMMTIMEOUTS timeout = {0};

timeout.ReadIntervalTimeout = 40;
timeout.ReadTotalTimeoutConstant = 40;
timeout.ReadTotalTimeoutMultiplier = 10;
timeout.WriteTotalTimeoutConstant = 40;
timeout.WriteTotalTimeoutMultiplier = 10;

if(!SetCommTimeouts(SerialPortHandle, &timeout)){
printf("ERROR: timeout error\n");
error = 1;
}
}
}

//FECHA A CONEXÇÃO
void ConexaoSerial::close(void){
CloseHandle(SerialPortHandle);
}

//ENVIA UM CARACTERE
void ConexaoSerial::write(char data){
char buf[1] = {data};
DWORD dwBytesWrite = 0;

if(!WriteFile(SerialPortHandle, buf, 1, &dwBytesWrite, NULL)){
printf("ERROR: write error\n");
}
}

//ENVIA UM STRING
void ConexaoSerial::send(char data[]){
while(*data){
write(*data++);
}
}

//RECEBE UMA STRING
DWORD ConexaoSerial::read(char data[], int length) {
DWORD dwBytes = 0;

if (!ReadFile(SerialPortHandle, data, length, &amp;dwBytes, NULL)) {
return 0;
}

return dwBytes;
}
main.cpp
#include <iostream>
#include "serial.h"

//Define o caractere de busca ENQUIRY
#define CHAR_ENQUIRY 5

using namespace std;

int main(int argc, char **argv) {
ConexaoSerial *com = new ConexaoSerial();
com->begin((char *)"COM3", 2400);

int n = 7;
char buffer[8] = "";

//solicita o peso da balança
com->write(CHAR_ENQUIRY);
//le o valor
com->read(buffer,n);

//exibe na tela
cout << endl << buffer << endl;

com->close();
return 0;
}

Para compilar o exemplo use: g++ main.cpp serial.cpp -o balanca.exe

Deixe um comentário

Contador de Visitas

Pesquisando na internet consegui achar um contador de visitas que vale a pena coloca e seu site ou blog. O 99Counters além de ser gratuito possuí um design muito superior aos outros contadores gratuitos, ele também possuí estatísticas de acesso que podem ser definidas com a visualização pública, assim todos seus visitantes podem ter acesso a isso e saber quantos acessos você tem por dia/mês/ano. Isso pode parecer que não é muito interessante, mas imagine a hipótese de um visitante que acessa seu blog ou site tem uma empresa e vê que você possuí um considerável número de visitas, existe a possibilidade desse visitante querer anunciar o seu produto no seu blog ou site. No final das contas um contador hoje em dia continua sendo útil, ainda mais se você usar um serviço esterno que de crédito as informações mostradas.

Deixe um comentário

Mudando a cor do console

Você que está na faculdade naquela chata aula de C/C++ e não aguenta mais ver aqueles conceitos chatos a linguagem, não tem como eu te ajudar! Mas posso colocar mais cor no seu mudo obscuro, nessa postagem vou mostrar um simples código que mostra como modificar a cor do console usando a biblioteca do MS Windows. Para facilitar o entendimento do código eu redeclarei algumas variáveis da biblioteca do MS Windows e criei um procedimento para alterar a cor quando necessário. Lembrando que testei esse código em um MS Windows XP, possivelmente a cor padrão possa mudar em futuras distribuições.
Posso não ter colocado no código, mas é possível usar intensidade na cor padrão COR_PADRAO | COR_INTENSO, além disso também é possível alterar a cor de fundo, basta verificar as definições que estão na biblioteca wincon.h.

 

/*
 * Exemplo de como mudar a cor do console o MS Windows
 *
 * O Exemplo usa a biblioteca windows.h
 *
 * Exemplo Criado por Pablo Alexander
 * http://www.pabloalexander.net
 * contato@pabloalexander.net
 */
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>

//inclui a biblioteca do MS Windows
#include <windows.h>

//definimos a cor padrão (MS Windows XP)
#define COR_PADRAO 7
//redefine algumas cores padrão
#define COR_VERMELHO FOREGROUND_RED
#define COR_AZUL FOREGROUND_BLUE
#define COR_VERDE FOREGROUND_GREEN
#define COR_INTENSO FOREGROUND_INTENSITY

using namespace std;

//HANDLE para manipular o console
HANDLE hConsole;

//procedimento para mudar a cor
void Cor(WORD bandeiras);

int main(int argc, char **argv) {
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

cout << "Iniciando teste de cores:" << endl << endl;

Cor(COR_VERMELHO);
cout << "Vermelho" << endl;

Cor(COR_VERMELHO | COR_INTENSO);
cout << "Vermelho Intenso" << endl;

Cor(COR_VERDE);
cout << "Verde" << endl;

Cor(COR_VERDE | COR_INTENSO);
cout << "Verde Intenso" << endl;

Cor(COR_AZUL);
cout << "Azul" << endl;

Cor(COR_AZUL | COR_INTENSO);
cout << "Azul Intenso" << endl;

Cor(COR_PADRAO);
cout << endl << "Fim do teste!" << endl;

return 0;
}

void Cor(WORD bandeiras) {
SetConsoleTextAttribute(hConsole, bandeiras);
}

Deixe um comentário