terça-feira, 22 de maio de 2012

Códigos do Material Adicional da Aula 8 (Ponte H)

Pessoal,

Segue abaixo os códigos do Material Adicional da Aula 8 (Ponte H) publicado no Youtube.

Código do Motor de Passo:

#include

const int stepsPerRevolution = 200;

Stepper myStepper(stepsPerRevolution, 8,9,10,11);           

void setup() {
  myStepper.setSpeed(60);
  Serial.begin(9600);
}

void loop() {
   Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  delay(500);
 
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
  delay(500);
}
 


Código do Blink com dois motores:

void setup() {               
  pinMode(13, OUTPUT); 
  pinMode(12, OUTPUT);
  pinMode(10, OUTPUT); 
  pinMode(11, OUTPUT);
  digitalWrite(13, LOW); 
  digitalWrite(12, LOW);
  digitalWrite(10, LOW); 
  digitalWrite(11, LOW);
}

void loop() {
  digitalWrite(13, HIGH);
  digitalWrite(12, LOW);
  digitalWrite(10, HIGH);
  digitalWrite(11, LOW);
  delay(1000);             
  digitalWrite(13, LOW);   
  digitalWrite(12, HIGH);
  digitalWrite(10, LOW);  
  digitalWrite(11, HIGH);
  delay(1000);             
}

sábado, 5 de maio de 2012

Código Fonte Arduino para Ponte H via PWM

Pessoal,

Segue o código do exemplo de acionamento da Ponte H via PWM, conforme o vídeo abaixo:



int portaH1 = 9;
int portaH2 = 10;
int potpin = 0; 
int val;
int val1;
int val2;
 
void setup()
{
  Serial.begin(9600);
}
 
void loop()
{
  val = analogRead(potpin);           
 
  val1 = map(val, 0, 511, 255, 0);    
  val2 = map(val, 512, 1023, 0, 255);
 
  if (val > 511) val1 = 0;
  else val2 = 0;
 
  Serial.print("Val: ");
  Serial.print(val, DEC);
  Serial.print(" Val1: ");
  Serial.print(val1, DEC);
  Serial.print(" Val2: ");
  Serial.println(val2, DEC);
 
  analogWrite(portaH1, val1);
  analogWrite(portaH2, val2); 
}

segunda-feira, 23 de abril de 2012

Código Fonte RTC+LCD - Curso Arduino Advanced - Aula 7


Pessoal,

Segue abaixo o código fonte utilizado na Aula 7 do Curso Arduino Advanced, sobre o Relógio em Tempo Real com Display LCD 16x2.



#include
#include
#include


RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


void setup()
{
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  lcd.begin(16, 2);
  if (!RTC.isrunning())
  {
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}


void loop()
{
  DateTime agora = RTC.now();
  String relogio_data = "DT: ";
  String relogio_hora = "HR: ";
  
  int dia = agora.day();
  int mes = agora.month();
  int ano = agora.year();
  
  relogio_data += ArrumaZero(dia);
  relogio_data += "/";
  relogio_data += ArrumaZero(mes);
  relogio_data += "/";
  relogio_data += ano;
  
  int hora = agora.hour();
  int minuto = agora.minute();
  int segundo = agora.second();
  
  relogio_hora += ArrumaZero(hora);
  relogio_hora += ":";
  relogio_hora += ArrumaZero(minuto);
  relogio_hora += ":";
  relogio_hora += ArrumaZero(segundo);
  
  lcd.setCursor(0, 0);
  lcd.print(relogio_data);
  lcd.setCursor(0, 1);
  lcd.print(relogio_hora);
  
  delay(500);
}


String ArrumaZero(int i)
{
  String ret;
  if (i < 10) ret += "0";
  ret += i;
  return ret;
}


Abraços,
Renato

sábado, 7 de abril de 2012

Matrizes Multi-Dimensionais no Arduino

Em uma aula do Curso Arduino aprendemos sobre matrizes de 1 dimensão, ou seja, matrizes com um indíce. Não existe nada que diga que matrizes são limitadas a uma única dimensão de vetores. Na verdade, você pode ter um número arbitrário de dimensões em uma matriz. As matrizes de 2 dimensões são muito comuns, especialmente para guardar coisas como coordenadas de uma tela, ou linhas e colunas de uma planilha. Dimensões maiores são usadas quando temos mais aspectos que especificam mais itens únicos (coordenadas 3D, por exemplo).
Uma coisa importante a se entender sobre matrizes é que tecnicamente, não existe tal coisa como matriz multi-dimensional. Todas camadas são vetores (ou matrizes de uma dimensão), mas algumas delas contém matrizes de matrizes de matrizes. Isso significa que quando você encontra algo como isso:
int multiarray[4][2]


Você provavelmente está pensando em uma grade de inteiros como isso:
   0       1
0 [0][0]  [0][1]
1 [1][0]  [1][1]
2 [2][0]  [2][1]
3 [3][0]  [3][1]


Na realidade, o Arduino não pode guardar a “grade”, pois a memória é uma longa linha de endereços. A linguagem C trata cada linha como uma matriz de 2 elementos, a qual é um único elemento de 4 matrizes de elementos. Em outras palavras, cada elemento é uma matriz, que contém 2 elementos. Então a variável multiarray[0] é uma matriz de 2 elementos, multiarray[1] é outra matriz de 2 elementos, assim por diante. Isso também significa que multiarray[0] é um ponteiro! O tipo da variável multiarray[0] é int*. Assim, como a variável multiarray é um ponteiro para multiarray[0], isso significa que o tipo dela é int(*)[2]!!!
Se você pensa que está ficando confuso, você está certo! Se você acha que existe muita probabilidade de um código baseado em matrizes não funcionar, acertou de novo! Vamos adicionar mais um pouco de confusão aqui. Eu disse que a matriz não pode ser armazenada como uma grade, vamos dar uma olhada como ela é guardada.

A variável multiarray tem 4 elementos, então deve se parecer com isso:
|  conteúdo em 0 || conteúdo em 1 || conteúdo em 2 || conteúdo em 3 |
   multiarray[0]    multiarray[1]   multiarray[2]     multiarray[3]

Como cada elemento de multiarray é uma matriz de 2 inteiros, que significa que “conteúdo em” são 2 inteiros consecutivos, assim:
memória:    |[int0] [int1]||[int0] [int1]||[int0] [int1]||[int0] [int1]|
multiarray:       [0]            [1]            [2]            [3]
multiarray:  [0][0] [0][1]  [1][0] [1][1]  [2][0] [2][1]  [3][0] [3][1] 

Isso significa que você pode lidar de duas formas, como 4 matrizes de 2 elementos, ou uma matriz simples de 8 elementos.

Vamos ver como utilizar as duas formas de acessar matrizes, utilizando funções.
void setup()
{
   Serial.begin(9600);
}
void setarray(int ma[][2],int size)
{
  for (int i=0;i<size;i++)
    for (int j=0;j<2;j++)
      ma[i][j] = 10*i+j;
}
void printarray(int* ma,int dim1, int dim2)
{
  for (int i=0;i<dim1;i++)
  {
    for (int j=0;j<dim2;j++) {
      Serial.print(*(ma+(i*dim2+j)));
 Serial.print(" ");
     }
    Serial.println(" ");
  }
}
void loop()
{
  int multiarray[4][2];
  setarray(multiarray,4);
  printarray(&multiarray[0][0],4,2);
   while(true); // fica parado
}


Na função setarray(), o tamanho da sub-matriz é fixa, ficando mais fácil de utilizar. O problema é que não é flexivel. Em contrapartida, printarray() é muito mais complicado de implementar, mas muito mais flexível também. Repare que printarray simplesmente pega o endereço do primeiro elemento e o explora de forma linear, da mesma forma que é armazenado na memória. Ao utilizar o código acima, temos o seguinte resultado:
0 1 
10 11 
20 21 
30 31 

Não é necessário dizer que matrizes de 3, 4 ou mais dimensões aumentam muito a complexidade quando utilizadas em parâmetros de funções. 

domingo, 1 de abril de 2012

Manifesto do Raduino

Pessoal,

Recebi um email do Marcelo Rodrigues, fundador do Laboratório de Garagem, me ameaçando de processo judicial por difamação.

Abaixo trechos do email enviado por Marcelo Rodrigues para Renato Aloi:

"...Você tem 24 horas para retirar do ar o tópico "Manifesto Raduino" do seu blog..."

e também:

"...onde você calunia e difama o meu nome e o da nossa instituição, ou vou entrar com uma ação contra você na justiça..."

Decidi então retirar o manifesto do ar, dentro do prazo que ele me deu de 24 horas.

Queria agradecer a todos que me apoiaram, mas eu sou um desenvolvedor independente de tecnologia e não tenho condições de ir adiante com o Manifesto e arcar com os custos gerados por processos judiciais.

Obrigado de coração a todos que acompanham meu trabalho... Por isso vou recuar nessa questão e continuar trabalhando, para que aqueles que acompanham meu trabalho não sejam prejudicados.

Abraços,
Renato Aloi

terça-feira, 13 de março de 2012

Portas Analógicas do Arduino

Uma descrição das portas analógicas de um chip Arduino (Atmega8, Atmega168, Atmega328, or Atmega1280).

Conversor A/D

Os microcontroladores Atmega usados para o Arduino contém embarcados 6 canais de conversão analógica-digital (A/D). O conversor do Arduino tem uma resolução de 10 bits, retornando inteiros entre 0 e 1023. Enquanto a função principal das portas analógicas para a maioria dos usuários do Arduino é ler sensores, as portas analógicas também tem a funcionalidade de entrada/saída de propósito geral (GPIO) (da mesma forma que as portas digitais 0~13).
Consequentemente, se o usuário precisar mais entradas/saídas de propósito geral, e todas as portas analógicas não estiverem em uso, estas podem ser usadas para GPIO.

Mapeamento de Portas

As portas analógicas podem ser usadas da mesma forma que portas digitais, utilizando apelidos A0 (para a porta analógica 0), A1 etc. Por exemplo, o código deverá parecer com o abaixo, configurando a porta analógica como saída (OUTPUT) e atribuindo o valor alto (HIGH):
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH);

Resistores de Elevação

As portas analógicas também tem resistores de elevação (pull-up), que funcionam exatamente da mesma forma que nas portas digitais. Eles são ativados por comandos como:
digitalWrite(A0, HIGH);  // set pullup on analog pin 0 
enquanto a porta for de entrada (INPUT).
Tome cuidado, entretanto, que ligar um resistor de elevação em uma porta analógica afetará os valores lidos pela função analogRead().

Detalhes e Avisos

O comando analogRead não funcionará direito se a porta não for corretamente configurada para saída (OUTPUT), então se esse é o caso, configure de volta a porta para entrada (INPUT) para usar a função analogRead. De forma similar, se a porta for configurada como HIGH e como saída, o resistor de elevação ficará ativado, mesmo voltando a porta para entrada.
O datasheet do Atmega também avisa sobre modular portas analógicas em uma proximidade temporal ao fazer leituras A/D (analogRead) em outras portas analógicas. Isso pode causar ruído elétrico e introduzir jiter no sistema analógico. Pode ser desejável, depois de manipular as portas analógicas (em modo digital), adicionar um atraso antes de começar a usar a função analogRead() para ler outras portas analógicas.

Traduzido do Original:

Para pt-BR por Renato Aloi


Arduino PWM

O Exemplo “Fading” (File>Example>Basics>Fade) demonstra o uso da saída analógica (PWM) para esvanecer um LED. Este exemplo está disponível no menu do Arduino: File->Sketchbook->Examples->Analog.

Modulação por Largura de Pulso, ou PWM (do inglês Pulse Width Modulation), é uma técnica de amostrar o sinal analógico em termos digitais. Controle digital é usado para criar uma onda quadrada, um sinal alternando entre ligado e desligado. Este padrão ligado/desligado pode simular voltagens entre totalmente ligado (5 Volts) e desligado (0 Volts), alternando a porção de tempo que o sinal gasta ligado contra o tempo que o sinal gasta desligado. A porção de tempo “ligada” é chamada de largura de pulso. Para variar valores analógicos, você muda, ou modula a largura de pulso. Se você repetir esse padrão ligado/desligado rápido suficiente com um LED, por exemplo, o resultado é como se o sinal fosse uma voltagem estável entre 0~5V, controlando o brilho do LED.
No gráfico abaixo, as linhas verdes representam um período regular de tempo. Esta duração, ou período, é o inverso da frequência do PWM. Em outras palavras, com a frequência do PWM do Arduino por volta de 500Hz, as linhas verdes devem medir 2 milissegundos, cada. Uma chamada na função analogWrite() está na escala de 0~255, tanto que analogWrite(255) aciona um ciclo de trabalho (duty cycle) de 100%, e analogWrite(127) é um duty cycle de 50% (na metade do tempo), por exemplo.

Uma vez que você executar esse exemplo, sacuda seu Arduino para frente e para trás. O que você está fazendo é essencialmente mapeando o tempo através do espaço. Para seus olhos, o movimento desfoca o piscar do LED em uma linha. No esvanecer do LED, ligando e desligando, essas linhas vão brilhar e encolher em comprimento. Agora você está vendo a largura de pulso.

Written by Timothy Hirzel

Traduzido para pt-BR por Renato Aloi