Qual é a melhor maneira de definir um pino de E / S?

9

Eu li definições como

const int ledPin = 9;

e também

#define ledPin 9

Eu sei que uma definição como

int ledPin = 9;

é uma prática ruim se você não vai alterá-lo (o que geralmente não muda), embora eu tenha visto isso várias vezes nos programas do Arduino. Qual dos outros dois é o preferido?

Joris Groosman
fonte

Respostas:

6

#define ledPin 9é preferível. Ao fazer int ledPin = 9;isso, você estará alocando uma intmemória cujo valor é usado toda vez que você usa ledPin. #defineé diferente no sentido em que não aloca memória. não há memória chamada ledPin. Antes de compilar, todos os "ledPin" no código (exceto as cadeias) são substituídos por 9. Então, basicamente

digitalWrite(ledPin);

torna-se

digitalWrite(9);

Vantagens de #define: Economiza memória e, como todos ledPinsão substituídos 9 antes da execução , economiza tempo do processador.

Realmente não importa em códigos pequenos ...


fonte
Os compiladores incorporados são realmente tão ruins que não fazem dobragem constante ao usar const int?
Chuu
11
@chuu, tanto quanto eu sei, o Arduino usa o gcc para avr. Portanto, quase definitivamente deve ser otimizado. As respostas aqui não mostram muita compreensão de boas práticas em C ++
chbaker0
3
em C ++, const int ledPin = 9;é preferível a outras 2 opções. Isso NÃO alocará memória para um intexceto se você definir um ponteiro para algum lugar, o que ninguém faria.
Jfpoilpret
Const int aloca memória @jfpoilpret. #define não ocupam qualquer memória porque é apenas um nome simbólico de uma expressão e não o nome de uma memória ...
Confira este link cplusplus.com/forum/beginner/28089 e veja por si mesmo. Caso contrário, faça a verificação com o Arduino IDE: verifique o tamanho dos dados com const e com #define.
Jfpoilpret
4

A rigor, a #defineabordagem utilizará um pouco menos de memória. A diferença é geralmente pequena embora. Se você precisar reduzir o uso de memória, outras otimizações provavelmente seriam muito mais eficazes.

Um argumento a favor do uso const inté o tipo safety . Sempre que você se refere a esse número de PIN por variável, você sabe exatamente que tipo de dados está recebendo. Pode ser promovido / convertido implicitamente ou explicitamente pelo código que o utiliza, mas deve se comportar de maneiras muito claras.

Por outro lado, o valor em a #defineé aberto à interpretação. Na grande maioria das vezes, provavelmente não causará nenhum problema. Você só precisa ter um pouco de cuidado se tiver um código que faça suposições sobre o tipo ou tamanho do valor.

Pessoalmente, quase sempre prefiro a segurança de tipo, a menos que tenha uma necessidade muito séria de economizar memória.

Peter Bloomfield
fonte
Eu estava no campo #define até ler a resposta de Peter. Acho que sei quem irá refatorar o código neste fim de semana. ;)
linhartr22
2

Provavelmente, a melhor maneira seria
const uint8_t LED_PIN = 9; // may require to #include <stdint.h>
ou
const byte LED_PIN = 9; // with no include necessary
const unsigned char LED_PIN = 9; // similarly
O nome está em maiúsculas, conforme a prática geral em C ++ (e outros) para nomear constantes. Isso não deve usar nenhuma RAM por si só e usar cerca de 1 byte de memória do programa por uso.
No entanto, pode haver problemas quando o número é maior que 127 e é estendido por sinal enquanto é promovido para números inteiros maiores assinados (não tenho muita certeza disso), embora seja improvável que isso aconteça com números de pinos.

Rykien
fonte
-1

Não apenas

const int ledPin = 9;

use RAM, mas, nesse caso, usará mais RAM do que o necessário, pois digitalWrite(uint8_t, uint8_t)só precisa de argumentos de um byte, e um int geralmente é de dois bytes (depende do compilador, mas é típico). Observe que você pode atribuir ao literal um tipo explícito no #define:

#define ledPin ((int)9) 

embora em um contexto como um argumento de função em que um tipo específico seja necessário (porque a função tenha sido adequadamente prototipada!), ela seja convertida implicitamente ou receba uma mensagem de erro se os tipos não corresponderem.

JRobert
fonte
@DrivebyDownvoter, você comenta seus motivos?
JRobert # 30/15