Como inicializar Serial do Arduino por meio de uma biblioteca

Olá a todos,

Estou aprendendo a fazer bibliotecas para Arduino e desenvolvi um exemplo simples para verificação se uma porta foi corretamente inicializada.

Minha dúvida é: tem como inicializar a Serial do Arduino pelo arquivo .cpp quando for detectado que a serial não está inicializada? Tentei colocar o seguinte código:

if (!Serial) {  Serial.begin(9600);  Serial.print("Serial iniciada");}

Mais a Serial não inicializa. Só inicializa se eu colocar diretamente na função setup do Arduino o seguinte código:

Serial.begin(9600);

 

Acesse aqui repositório.

Exibições: 297

Responder esta

Respostas a este tópico

Boa noite,

Recomendo que leia essa referência :

Writing a Library for Arduino

https://www.arduino.cc/en/Hacking/LibraryTutorial

Conhece o GitHub do Arduino?

Sugiro que pesquise nesse GitHub 

https://github.com/arduino/Arduino/search?q=Serial.begin

Recomendo que leia essa referência :

Writing a Library for Arduino

https://www.arduino.cc/en/Hacking/LibraryTutorial

Antes de fazer a bibloteca eu já tinha lido este artigo do site da Arduino.cc.


Conhece o GitHub do Arduino?

Sugiro que pesquise nesse GitHub

https://github.com/arduino/Arduino/search?q=Serial.begin

Ainda não conhecia, mais não achei nada que pudesse me ajudar.


Descobri em parte o problema. Ao fazer a seguinte condição:

if (!Serial) {}


sempre retornava 0(ou seja, false), mesmo que eu não iniciasse a Serial em nenhum momento.
Isto implicava em o código de dentro do if:
{  Serial.begin(9600);  Serial.print("Serial iniciada");}

Nunca ser executado, causando assim, o não iniciamento da Serial.

Então mudei o código do arquivo .cpp para:

#include "testePorta.h"testePorta::testePorta(int pin){
pinMode(pin, OUTPUT);
_pin = pin;
i = 0;
retorno = false;
}

bool testePorta::iniciaPortaSaida() {
while (controleWhile) {
pinMode(_pin, OUTPUT);
delay(5000);
digitalWrite(_pin, HIGH);

if (digitalRead(_pin) != HIGH) {
delay(500);
i++;
} else {
controleWhile = false;
digitalWrite(_pin, LOW);
retorno = true;
}
if (i > 3) {
controleWhile = false;
retorno = false;
}
}
return retorno;
}

Agora o usuário deve, obrigatoriamente, iniciar a Serial. E a função iniciaPortaSaida somente retorna true
para o caso de a porta estar iniciada corretamente ou
false no caso de a porta não ser iniciada corretamente.

Olá MicSG,

Serial é uma variável que é  uma instância de uma classe C++ definida dentro das entranhas do "firmware" do Arduino, o que é, nesse caso, chamado de objeto.

Serial normalmente terá valor diferente de zero (ou NULL), que é justamente o endereço do objeto na memória.

Portanto if (Serial), como você já verificou, sempre será TRUE, uma vez que o valor retornado pela expressão dada pela variável Serial é diferente de 0 (FALSE). Esse teste, no caso do UNO, nunca vai retorna falso,pois a porta serial é inicializada antes mesmo de ser executado o setup() do sketch, portanto a variável Serial já será um objeto instanciado.

Serial.begin(velocidade) apenas indica para o objeto controlador da porta serial que a partir desse ponto se deseja usar a velocidade em bits por segundo e que os pinos TX e RX devem estar prontos no modo USART, assim como ativar Timers ou IRQs associadas ao funcionamento do periférico de comunicação serial do microcontrolador. Mas, no caso do UNO, a variável Serial já estava "ativa" via firmware do Arduino antes mesmo de executar esse comando.

Serial.end() não destrói o objeto Serial, mas apenas desconecta os pinos RX e TX da função USART, permitindo que sejam usados para, por exemplo, acender um LED ou testar uma entrada digital, como em uma porta comum. Em alguns casos (depende da sua placa), também desativa Timers ou IRQs (interrupções) associadas ao periférico USART.

O que quero dizer com tudo isso é que há muito mais acontecendo "em baixo do capô" quando usamos os métodos do objeto Serial, do que possa parecer.

Espero que essa explicação ajude em algo no seu objetivo.

Compreendi que existe bastante "embaixo dos panos". Obrigado pela explicação

Outro ponto importante, se você quer saber qual é o modo que uma porta está (OUTPUT, INPUT), a forma correta é através da leitura dos registradores do periférico dessa porta, e não via ativando (HIGH) a porta e lendo em seguida.

Use a função abaixo para o UNO:

#define UNKNOWN_PIN 0xFF  // equivalente a -1 em int8

uint8_t getPinMode(uint8_t pin) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);

// teste para checar se os parametros estao corretos
// na chamada da funcao
if ((NOT_A_PIN == port) || (0 == bit)
|| (bit & bit - 1)) return UNKNOWN_PIN;

volatile uint8_t *reg, *out;
reg = portModeRegister(port);
out = portOutputRegister(port);

// testa os REGISTRDORES da porta enviada como parametro
// No caso do 328p (UNO) o REGISTER é o
// Data Direction Register (DDRB, DDRC, DDRD)
if (*reg & bit) return OUTPUT;
else if (*out & bit) return INPUT_PULLUP;
else return INPUT;
}

Obrigado vai me ajudar bastante

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço