Publicidade:

terça-feira, 29 de dezembro de 2015

Arduino - Programando o Pro mini com o Uno ou com o Mega

Uma das coisas legais dos Arduinos, é que existem várias versões e cada versão com suas vantagens, seja em tamanho, custo, capacidade de processamento, etc. 


Uma das versões que eu gosto é o Pro mini que consegue reunir quase todos os itens mencionados anteriormente, pequeno, barato e poderoso, tudo em uma pequena plaquinha de 3,4 x 1,9 cm, 8 pinos analógicos, 14 pinos digitais, sendo 6 pwm, botão de reset, led no pino 13 e outro led indicador de energizado e opera a velocidade de 16MHz. Quanto a memória, o Pro Mini disponibiliza 16Kb para memória flash, sendo 2Kb utilizados pelo bootloader, 1Kb de SRAM e 512 bytes de EEPROM. Sem dúvida é uma boa candidata para tirar do papel aquele projeto que você já vem querendo implementar há algum tempo.

Um detalhe importante é que os conectores não vêm soldados na placa, ficando a cargo de quem for utilizá-la escolher qual o melhor tipo de conector a ser utilizado, o que lhe dá a vantagem de poder soldar apenas os pinos que serão de fato necessários de acordo com o projeto a ser implementado. Uma dica quando for soldar os conectores, é usar um pouco de pasta de solda nos terminais, o que facilita bastante conseguir uma solda mais uniforme sem que sobre solda.





Na imagem acima pode-se notar que os 4 primeiros conectores ficaram com a solda "grossa". Como não gostei muito do resultado tentei passar um pouco de pasta de solda, e o resultado foi bem melhor como pode ser observado nos pinos mais à direita.

Em geral os conectores a serem soldados são aqueles que permitem conectar a placa na protoboard ou ainda usar jumper, mas caso vc tenha em mente utilizar alguma outro tipo de conector, tenha certeza que você conseguirá fazer o upload do código após a soldagem, pois dependendo do conector escolhido, o processo de upload pode ficar um pouco mais complicado. Se Notar que será complicado fazer o upload depois de conectar os fios, tente fazer o upload do programa antes de soldar os conectores.

Para mais detalhes sobre as funcionalidades da plaquinha, vale a pena uma boa olhada na imagem abaixo:



Quanto a alimentação pode ser feita diretamente pelo pino Vcc com tensão já regulada em 5V ou através do pino RAW em até 12V pois a placa conta com um regulador de tensão.

Ele não é necessariamente o candidato ideal pra prototipagem, já que nesse quesito o Arduino Uno e o Mega ou outros são os mais indicados, por isso na hora de programá-lo, você irá precisar contar com alguns itens adicionais.

Conversor FTDI

Uma das formas de programa-lo é utilizando um conversor FTDI, o qual possui um conector USB. Porém nesse artigo não irei abordar o seu uso (mas talvez futuramente eu inclua aqui explicações de como utilizá-lo).


Arduino Uno com o Atmega Desencaixado

Outra possibilidade é utilizar um Arduino Uno sem o Atmega conectado na placa. Para isso siga as conexões mostradas abaixo mas com o Atmega desconectado.



Montado na protoboard com os pinos já soldados e com o Atmega removido:


Depois de tudo conectado é hora de configurar a IDE do Arduino para enviar o código para o Pro Mini. Para isso selecione a placa, conforme imagem a baixo.



Feito isso, selecione então o ATmega utilizado, no caso, ATMega328 (5V, 16MHz), como na imagem abaixo:



Agora é só enviar o código. No Exemplo que utilizei, liguei um potenciômetro ao pino A1, um led no pino 13 e outro led no pino 5. O led no pino 13 irá ficar piscando enquanto que o led no pino pwm será controlado através da leitura do pino analógico A1.

O Código possui uma classe temporizadora, a qual ainda irei fazer um outro artigo explicando melhor os detalhes de como ela funciona, mas já fiz outro artigo que abordo sobre temporização, que vale a pena dar uma olhada: http://fabianoallex.blogspot.com.br/2015/09/arduino-como-substituir-delay-pelo.html

Mas o código aqui pode ser qualquer outro que esteja programado para o que você deseja executar.

Código Utilizado:



/*********************************************************************************************************
************************************CLASSE MYTIMER********************************************************
**********************************************************************************************************/
struct MyTimerSequence{
  unsigned long * times;
  unsigned int size;
  unsigned int repeat;
};
class MyTimer{
  private:
    boolean          _enable;
    unsigned long    _mref;
    unsigned long    _mref_disable;
    unsigned long    _time_disable;
    MyTimerSequence *_sequences;
    long             _lag;
    int              _quantidade;
    int              _index_time;
    int              _last_index_time;
    int              _index_sequence;
    int              _last_index_sequence;
    void             (*_onChanging)( int index_sequence, int index_time ); //ponteiro para funcao do evento onChanging
    void             (*_onEnable)();
    void             (*_onDisable)();
  public:
    MyTimer(MyTimerSequence * sequences, int quantidade, long lag, unsigned long mref){
      _lag = lag;
      _mref = mref;
      _sequences = sequences;
      _quantidade = quantidade;
      _time_disable = 0;
      _enable = false;
      _undetermine();
    }
    
    void _undetermine(){
      _index_time          = -1;
      _last_index_time     = -1;
      _index_sequence      = -1;
      _last_index_sequence = -1;
      update();
    }
    void setSequences(MyTimerSequence * sequences, int quantidade){
      _sequences = sequences;
      _quantidade = quantidade;
      _undetermine();
      update();
    };
    void setMillisRef(unsigned long mref)                  { _mref    = mref;        _undetermine();    }
    void setLag(long lag)                                  { _lag     = lag;         _undetermine();    }
    boolean isChanging()                                   { return (( _index_time != _last_index_time)||( _index_sequence != _last_index_sequence))&&(_enable); }
    boolean isIndexTime(int index_sequence, int index_time){ return ( _index_time == index_time)&&(_index_sequence == index_sequence)&&(_enable);   }
    void setOnChanging( void (*onChanging)(int, int) )     { _onChanging = onChanging;                  }
    void setOnEnable  ( void (*onEnable)() )               { _onEnable   = onEnable;                    }
    void setOnDisable ( void (*onDisable)() )              { _onDisable  = onDisable;                   }
    void update();
    
    void enable()  { _enable = true;  if ( _onEnable )  { (*_onEnable )(  ); }  } 
    void disable() { _enable = false; if ( _onDisable ) { (*_onDisable)(  ); }  } 
    
    void setTimeDisable(unsigned long time){ _time_disable = time; _mref_disable = millis(); } 
};
void MyTimer::update(){
  if ((millis() - _time_disable > _mref_disable) && (_time_disable > 0)) { disable(); }  //verifica se está configurado pra desabilitar por time
  if (!_enable) { return; }
  
  unsigned long s = 0;
  for (int i=0; i<_quantidade;i++){ 
    for (int j=0; j<_sequences[i].repeat; j++){
      for (int k=0; k<_sequences[i].size; k++){
        s += _sequences[i].times[k]; 
      }
    }
  }
  long adjustment      = _mref % s;
  long rest            = (millis() + s - adjustment - _lag) % s;
  _last_index_time     = _index_time;
  _last_index_sequence = _index_sequence;
  
  
  boolean ind_break = false;
  s = 0;
  for (int i=0; i<_quantidade;i++){ 
    for (int j=0; j<_sequences[i].repeat; j++){
      for (int k=0; k<_sequences[i].size; k++) {
        s += _sequences[i].times[k]; 
        if (rest < s) {  
          _index_time = k; 
          _index_sequence = i;
          ind_break = true;
          break; 
        } 
      }
      if (ind_break) { break; }
    }
    if (ind_break) { break; }
  }
  if ( isChanging() && _onChanging ) { (*_onChanging)(  _index_sequence, _index_time  ); }
}
/*********************************************************************************************************
************************************FIM CLASSE MYTIMER****************************************************
**********************************************************************************************************/

unsigned long seq01[] = {750};
unsigned long seq02[] = {60, 60};
unsigned long seq03[] = {200};

MyTimerSequence sequences[] = { 
                                 { seq01, sizeof(seq01)/sizeof(unsigned long), 1},
                                 { seq02, sizeof(seq02)/sizeof(unsigned long), 10},
                                 { seq03, sizeof(seq03)/sizeof(unsigned long), 1},
                                 { seq02, sizeof(seq02)/sizeof(unsigned long), 6},
                                 { seq03, sizeof(seq03)/sizeof(unsigned long), 1},
                                 { seq02, sizeof(seq02)/sizeof(unsigned long), 3}
                              } ;

 
MyTimer t1(sequences, sizeof(sequences)/sizeof(MyTimerSequence), 0, 0);  //tem um atraso de 100 milissegundos em relação a referencia 0
   
void setup() {
  Serial.begin(9600);
  
  pinMode(13, OUTPUT);
  pinMode(5, OUTPUT);
  
  t1.setOnChanging( onChanging_t1 );
  t1.enable();
}
 
void loop() {  
  t1.update();
  
  analogWrite(5, analogRead(A1)/4);
}
 
void onChanging_t1(int sequence, int index ) {
  digitalWrite(13, LOW); 
  if (index == 0 && (sequence == 1 || sequence == 3 || sequence == 5)){ digitalWrite(13, HIGH);  }
  
}


Via ISP (Arduino Uno e Mega)

Pra quem pretende utilizar o Arduino Pro Mini com uma certa frequencia, ter que retirar o ATMega do conector do Arduino Uno é um trabalho que pode se tornar um pouco chato, além de ter algum dos Arduinos Uno que não tem como desconectar o ATmega. Nesses casos, o mais recomendado é utilizar o a gravação através de ISP. Pra isso é necessário seguir alguns passos. Vou listá-los e mais abaixo demonstro como realizar cada um dos passos:

Obs.: Esses mesmos passos podem ser seguidos utilizando um Arduino Mega.

  - 1º Passo: Fazer o upload do Sketch "ArduinoISP" para o Arduino Uno (ou Mega).
  - 2º Passo: Conectar os Cabos entre o Arduino Uno (ou Mega) e o Pro Mini.
  - 3º Passo: Mudar a Placa para Arduino Pro ou Pro mini.
  - 4º Passo: Mudar o Programador para "Arduino as ISP".
  - 5º Passo: Fazer Uploado via Programador (Ctrl+Shift+U).
  - 6º Passo: Voltar as configurações iniciais. (Esse passo é só para não ter problemas ao voltar a programar o arduino UNO posteriormente).

1º Passo: Fazer o upload do Sketch "ArduinoISP" para o Arduino Uno (ou Mega).

A Sketch ArduinoISP está na própria IDE do Arduino, bastando entrar no menu Arquivo, Exemplos e Abrir "ArduinoISP", conforme imagem abaixo:


Com o Arquivo aberto, faça o upload do arquivo para o Arduino Uno (ou Mega).


2º Passo: Conectar os Cabos entre o Arduino Uno (ou Mega) e o Pro Mini.

Esquema Com o Arduino Uno:

       Pro mini | Arduino Uno
13 | 13
12 | 12
11 | 11
RST | 10   
Vcc |  5V
  Gnd |  Gnd 

Ligar um capacitor de 10uF no Reset do arduino Uno e no Gnd.







Esquema Com o Arduino Mega:

         Pro mini | Arduino Mega
13 | 52
12 | 50
11 | 51
RST | 53   
Vcc |  5V
  Gnd |  Gnd 

Ligar um capacitor de 10uF no Reset do arduino Uno e no Gnd.




3º Passo: Mudar a Placa para Arduino Pro ou Pro Mini.

Menu Ferramentas --> Placa --> Arduino Pro ou Pro Mini


Escolher o processador:

Menu Ferramentas --> Processador --> ATMega328 (5V, 16MHz)



4º Passo: Mudar o Programador para "Arduino as ISP"

Menu Ferrramentas --> Programador --> Arduino as ISP



5º Passo: Fazer Upload via Programador (Ctrl+Shift+U)

Nesse ponto aqui, por falta de atenção tive alguns problemas, pois tentei fazer o upload via comando tradicional, clicando no botão. Até que percebi que o Correto é enviar através de uma outra função, que fica no Menu Arquivo:

Com o Sketch que se deseja upar aberto
vá até o Menu Arquivo --> Carregar Usando Programador



Feito Isso, o Programa deve ser enviado para o Pro Mini.

6º Passo: Voltar as configurações iniciais.

Como esse procedimento exige muitas mudanças de configurações da IDE do Arduino, é recomendável que as configurações oginais sejam restauradas, para evitar da próxima vez que a IDE seja usada, não cause outros problemas, principalmente se for um computador utilizado por outros programadores. Deixe sempre do jeito que estava quando iniciou.




Nenhum comentário:

Postar um comentário