Marcadores

Reduzindo o tamanho binário na compilação para o Arduino

No IDE do Arduino, você deve editar o arquivo platform.local.txt para sua placa. Ele está dentro da pasta de hardware, junto com suas outras pastas de projeto do Arduino, ou na pasta de instalação do Arduino. 

Conteúdo a ser adicionado no arquivo platform.local.txt:

compiler.c.extra_flags=-fno-tree-scev-cprop -fno-split-wide-types -Wl,--relax -mcall-prologues
compiler.cpp.extra_flags=-fno-tree-scev-cprop -fno-split-wide-types -Wl,--relax -mcall-prologues
compiler.c.elf.extra_flags=-Wl,--relax

referencia: https://thborges.github.io/blog/marlin/2019/01/07/reducing-marlin-binary-size.html

LiquidCrystal I2C para Arduino Due

#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27,16,2); 
 
void setup()
{
  lcd.init(); 

  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Hello world");
  lcd.setCursor(1,1);
  lcd.print("Arduino Due");
}
 
void loop()
{
 
}

Use a lib : LiquidCrystal_I2C-master.zip

Arduino DueLCD1602
GNDGND
3v3VCC
SDA/21SDA
SCL/22SCL
Precisou de um conversor 3.3v <-> 5v

Conversor De Nível Lógico Bidirecional I2c 5v - 3,3v Arduino



Como otimizar o uso de memória no Arduino

Algumas Dicas para otimizar o uso de memória no Arduino :

Retirado do : https://cdn-learn.adafruit.com/downloads/pdf/memories-of-an-arduino.pdf

"A memória é a primeira coisa a desaparecer."
(Eu não me lembro quem me disse isso)

Existem 3 tipos de memória em um Arduino:

Memória Flash
A memória flash é usada para armazenar a imagem do programa e qualquer dado inicializado. Você pode executar o código do programa a partir do flash, mas você não pode modificar os dados na memória flash do seu código de execução. Para modificar os dados, é necessário primeiro copiá-los para SRAM.
A memória flash é a mesma tecnologia usada para pen drives e cartões SD. Como não é volátil, seu programa continuará estar lá quando o sistema estiver desligado.
A memória flash tem uma vida útil finita de cerca de 100.000 ciclos de gravação. Portanto, se você enviar 10 programas por dia, todos os dias para o próximos 27 anos, você pode danifica-la.

SRAM
Memória estática de acesso aleatório, pode ser lida e gravada no seu programa em execução.

Memória SRAM é usado para diversas finalidades por um programa em execução:

  • Dados estáticos - este é um bloco de espaço reservado na SRAM para todas as variáveis ​​globais e estáticas do seu programa. Para variáveis ​​com valores iniciais, o sistema de tempo de execução copia o valor inicial do Flash quando o programa é iniciado.
  • Heap - O heap é para itens de dados alocados dinamicamente. A pilha cresce da parte superior da área de dados estáticos como itens de dados são alocados.
  • Stack (Pilha) - A pilha é para variáveis ​​locais e para manter um registro de interrupções e chamadas de função. A pilha cresce do topo da memória para baixo em direção à pilha. Toda interrupção, chamada de função e / ou variável local alocação faz com que a pilha cresça. Retornar de uma interrupção ou chamada de função recuperará todo o espaço de pilha usado por essa interrupção ou função.

A maioria dos problemas de memória ocorre quando a Heap a Stack colidem. Quando isso acontece, uma ou ambas as memórias áreas serão corrompidas com resultados imprevisíveis. Em alguns casos, isso causará um acidente imediato. Em outros, os efeitos da corrupção pode não ser percebida até muito mais tarde.


EEPROM
É outra forma de memória não volátil que pode ser lida ou gravada no seu programa em execução. Só pode ser lido byte a byte, para que possa ser um pouco complicado de usar. Também é mais lento que o SRAM e tem uma vida útil finita de cerca de
100.000 ciclos de gravação (você pode lê-lo quantas vezes quiser).
Embora não possa substituir a preciosa SRAM, há momentos em que pode ser muito útil!


O que pode estar ocupando espaço demais no seu projeto ?

Cartões SD
Qualquer uso com uma interface SD ou Micro-SD requer um Buffer SRAM de 512 bytes para se comunicar com o cartão.

Píxels
Cada pixel requer apenas 3 bytes de SRAM para armazenar a cor. Mas esses bytes começam a somar quando você tem muitos metros de tira ou uma grande variedade.

Remover código morto
Se o seu projeto é um mash-up de código de várias fontes, é provável que existam partes que não estejam sendo usadas e pode ser eliminado para economizar espaço.

  • Bibliotecas não utilizadas - Todas as bibliotecas #include são realmente usadas?
  • Funções não utilizadas - Todas as funções estão sendo chamadas?
  • Variáveis não utilizadas - Todas as variáveis estão realmente sendo usadas?
  • Código inacessível - Existem expressões condicionais que nunca serão verdadeiras?
  • Dica - Se você não tem certeza sobre um #include, uma função ou uma variável. Comente. Se o programa ainda compilar, esse código não está sendo usado.
  • Consolidar código repetido
  • Se você tiver a mesma sequência de instruções de código em dois ou mais lugares, considere criar uma função com elas.
  • Remover variáveis ​​não utilizadas Se você não tiver certeza se uma variável está sendo usada ou não, comente-a. Se o esboço ainda compilar, livre-se dele!


F () para strings!
Strings literais são ofensores repetidos à memória. Primeiro, eles ocupam espaço na imagem do programa no Flash, depois são copiado para SRAM na inicialização como variáveis ​​estáticas. É um desperdício horrível de SRAM, pois nunca iremos escrever para eles.
Paul Stoffregen, do Teensyduino, desenvolveu a macro F () como uma solução super simples para esse problema.
A macro F () diz ao compilador para manter suas seqüências de caracteres em PROGMEM. Tudo o que você precisa fazer é colocar a string literal em uma macro F ().

Mova dados constantes para PROGMEM.
Os itens de dados declarados como PROGMEM não são copiados para SRAM na inicialização. Eles são um pouco menos convenientes de se trabalhar, mas eles podem economizar quantidades significativas de SRAM. A referência básica do Arduino para o PROGMEM é https://www.arduino.cc/reference/pt/language/variables/utilities/progmem/

Reduzir tamanhos de buffer
Alocações de buffer e matriz:
Se você alocar um buffer, verifique se ele não é maior do que o necessário.
Buffers em bibliotecas:
Lembre-se também de que algumas bibliotecas alocam buffers nos bastidores que também podem ser candidatos a cortes.

Buffers do sistema:
Outro buffer escondido profundamente no sistema é o buffer de recebimento serial de 64 bytes. Se o seu esboço não estiver recebendo muito
dados seriais de alta velocidade, você provavelmente pode reduzir esse tamanho do buffer pela metade - ou talvez até menos.
O tamanho do buffer serial é definido em HardwareSerial.cpp. #define SERIAL_BUFFER_SIZE 64

Variáveis ​​globais e estáticas
São as primeiras coisas carregadas na SRAM. Eles empurram o início da pilha para cima em direção ao STACK e ocuparão esse espaço por toda a eternidade.


Alocações Dinâmicas
Objetos e dados alocados dinamicamente fazem com que o Heap cresça em direção ao Stack(pilha). Ao contrário das variáveis ​​globais e estáticas, essas variáveis ​​podem ser desalocadas para liberar espaço. Mas isso não necessariamente faz com que o Heap encolha! Se houver outros dados dinâmicos acima dele, a parte superior do Heap não será movida. Quando o Heap estiver cheio de buracos como um queijo suíço chamamos de "Heap fragmentado".

Variáveis ​​locais
Toda chamada de função cria um quadro de STACK(pilha) que faz com que a pilha cresça em direção ao Heap. Cada quadro de pilha conterá:

  • Todos os parâmetros passados ​​para a função
  • Todas as variáveis ​​locais declaradas na função.

Esses dados são utilizáveis ​​dentro da função, mas o espaço é 100% recuperado quando a função sai!
Então você deve preferir alocação local do que a global - as variáveis ​​de pilha existem apenas enquanto estão sendo usadas. Se você tiver variáveis ​​que são usados ​​apenas em uma pequena seção do seu código, considere transformar esse código em uma função e declarar as variáveis locais para a função.


Multiplicando as saídas do arduino

Usando somente 3 pinos do Arduino você consegue ter muitas saídas, usando o 74HC595 que é relativamente barato , eu paguei R$ 2,60.

Ele seria um conversor de serial para paralelo , ou seja , você entra com dados serialmente e ele joga para suas saídas de 8 pinos e salva elas até você querer mudar seus valores.



74hc595 pins - pinout of the chip
Pin nameFunctions
QA-QHOutputs Q0 (QA) to Q7 (QH).
QH'Serial data output.
SERSerial data input.
SRCLKSerial data input clock.
RCLKOutput register (Latch) clock.
SRCLRActive low, Asynchronous Shift register Clear.
OEActive low, Output Enable.
VCCPositive Power Supply.
GNDNegative Power supply (Ground - 0V).

Se quiser ter 16 saídas , basta ligar 2 deles , usando o pino QH' no pino DS , como mostrado aqui nessa figura :

16 bit shift register with the 74hc595
Precisa de mais saídas usando só 3 pinos do arduíno ?
Vai ligando em série, sempre ligar o QH' no pino DS do próximo.



O Código do arduíno é bem simples (usando 2 para 16 saídas) :

int RCLKPin = 3;   // pin 12 on the 74hc595 latch - nSS
int SRCLKPin = 6;  // pin 11 on the 74hc595 shift register clock - SCK
int SERPin = 4;    // pin 14 on the 74hc595 data - MOSI
unsigned int d;    // Data to be sent to the shift reg.
int dir =0;        // Direction of walking 1.

void setup() {
  Serial.begin(9600);          // start serial port (debug).

  pinMode(RCLKPin, OUTPUT);    // Set 595 control PIN sto output.
  pinMode(SRCLKPin, OUTPUT);
  pinMode(SERPin, OUTPUT);

  Serial.println("74HC595 Demo 2xchips for 16 bit register.");

  d=1;
}

void loop() {

    delay(100);
    digitalWrite(RCLKPin, LOW);
    //shiftOut(SERPin, SRCLKPin, (0xff00 & d)>>24); // Se usar 4
    //shiftOut(SERPin, SRCLKPin, (0x00ff & d)>>16);
shiftOut(SERPin, SRCLKPin, (0xff00 & d)>>8); //SEMPRE o MSB primeiro shiftOut(SERPin, SRCLKPin, 0x00ff & d); digitalWrite(RCLKPin, HIGH); if (!dir) d<<=1; else d>>=1; // Shift if (d&0x8000) dir=1; // Set direction. if (d&0x0001) dir=0; }

// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut�
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that 000001 or "1" will go through such
  //that it will be pin Q0 that lights. 
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else { 
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}
Se for usar as saídas para ligar leds , use um resistor para cada saída de 470 ohms.
Referencias :
https://www.best-microcontroller-projects.com/74hc595.html
https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial/
https://www.arduino.cc/en/tutorial/ShiftOut


Usar a trava eletrica de carro no arduino


Pra quem quer construir um Pinball caseiro, deve conhecer a trava elétrica de automóveis, no meu usei somente uma para fazer o desvio da bola na rampa.

Pela razão de ser bem mais barato comparado a um kit de bobina de um Pinball.

Para usar com o Arduino , segundo pesquisei , cada trava deve usar uma Centralina:
(Esquema com reles de 5V chavendo com uma fonte de 12V para travar e destravar)



Ou então um shield Ponte H (conforme esse link: http://www.mecatronizando.com.br/2016/10/display-touch-tft-24.html



Fontes: http://pinballwitharduino.blogspot.com/2016/08/flippers.html
https://loggs2.wordpress.com/category/homemade-pinball