quinta-feira, agosto 28, 2014

Lunar Lander Mark III - Software

No post anterior vimos o circuito e a montagem do Lunar Lander. Veremos agora alguns detalhes do software.


O primeiro passo para o software são as rotinas para tratamento dos displays. Para o display de 4 dígitos eu já tinha encontrado uma biblioteca adequada (TM1637). Daí que eu resolvi fazer uma biblioteca equivalente para o display de 8 dígitos. O resultado está aqui.

O display de 8 dígitos utiliza um MAX7219, que é bastante simples de utilizar. A única rotina complicada é a escrita de números decimais. Como na rotina equivalente na biblioteca TM1637, ela suporta escrever um número qualquer de dígitos a partir de qualquer posição, com supressão ou não dos zeros à esquerda. Além disso, eu coloquei o tratamento de números negativos (necessário para a velocidade). Eu me atrapalhei um pouco no mapeamento dos dígitos nos registradores, mas após um  par de horas cheguei à rotina abaixo:

  1. void MAX7219Display::showNumberDec(long num, bool leading_zero,   
  2.     uint8_t length, uint8_t pos)  
  3. {  
  4.     uint8_t prim;  
  5.     uint8_t aux[8];  
  6.  bool showZero = leading_zero;  
  7.     uint8_t i;  
  8.   
  9.     // Valida parâmetros  
  10.     if (pos >= m_nDig)  
  11.         pos = m_nDig-1;  
  12.     if ((pos+length) > m_nDig)  
  13.         length = m_nDig - pos;  
  14.       
  15.     // Trata números negativos  
  16.     prim = MAX7219_DIG7 - pos;  
  17.     if (num < 0)  
  18.     {  
  19.         num = -num;  
  20.         write7219 (prim, SEG_G);  
  21.         prim--;  
  22.         length--;  
  23.     }  
  24.   
  25.     // Gera os dígitos  
  26.     for (i = 0; i < length; i++)  
  27.     {  
  28.         aux[i] = (uint8_t)(num % 10L);  
  29.         num = num / 10L;  
  30.     }          
  31.       
  32.     // Escreve os dígitos  
  33.     for(i = 0; i < length; i++)   
  34.     {  
  35.         uint8_t dig = aux[length - i - 1];  
  36.         if (!showZero && (dig == 0) && (i != (length-1)))  
  37.         {  
  38.             write7219 (prim - i, 0);  
  39.         }  
  40.         else  
  41.         {  
  42.             if (dig != 0)  
  43.                 showZero = true;  
  44.             write7219 (prim - i, digitToSegment[dig]);  
  45.         }  
  46.  }  
  47. }  

Uma vez tendo as rotinas de escrita nos displays, foi só adaptar o código que eu tinha feito para a segunda versão do Lunar Lander. O código final também pode ser baixado do github (aqui).

Ok, chega de conversa. O vídeo abaixo mostra o projeto em funcionamento, com um pouso sendo "habilmente" concluído.



Nenhum comentário: