segunda-feira, 4 de junho de 2012

Código Fonte Aula 11 do Curso Arduino Advanced

Pessoal,

Segue o código fonte da Aula 11 do Curso Arduino Advanced, sobre EEPROM e SD Card.

#include
#include

File arquivo;
byte inicio_ok;

void setup()
{
  inicio_ok = 1;
  Serial.begin(9600);
  if(!SD.begin(4))
  {
    Serial.println("Erro ao iniciar cartao SD!");
    inicio_ok = 0;
    return;
  }
  Serial.println("Iniciacao Ok!");
}

void loop()
{
  if (inicio_ok)
  {
    int opcao = Serial.read();
    if (opcao == 'c')
    {
      Serial.println("Opcao Configuracao Selecionada!");
      opcao = Serial.read();
      while(opcao == -1)
      {
        opcao = Serial.read();
      }
      int valorConfig = opcao - 48;
      EEPROM.write(0, valorConfig);
      Serial.print("Valor gravado com sucesso: ");
      Serial.println(valorConfig);
    }
    else if (opcao == 'w')
    {
      while(opcao != 'x')
      {
        int leituraSensor = analogRead(0);
        arquivo = SD.open("sensor.txt", FILE_WRITE);
        if(arquivo)
        {
          arquivo.print("Valor do sensor em ");
          arquivo.print(millis());
          arquivo.print(" ms: ");
          arquivo.println(leituraSensor);
          arquivo.close();
          delay(1000 * EEPROM.read(0));
          Serial.print("Feita leitura do sensor em ");
          Serial.print(EEPROM.read(0), DEC);
          Serial.println(" segs.");
        }
        else
        {
          Serial.println("Erro ao abrir o arquivo para escrita!");
        }
        opcao = Serial.read();
      }
      Serial.println("Terminando leitura do sensor!");
    }
    else if (opcao == 'r')
    {
      arquivo = SD.open("sensor.txt");
      if (arquivo)
      {
        while(arquivo.available())
        {
          Serial.write(arquivo.read());
        }
        arquivo.close();
        Serial.println("Termino do arquivo");
      }
      else
      {
        Serial.println("Erro ao abrir arquivo para leitura!");
      }
    }
    else if (opcao == 'e')
    {
      SD.remove("sensor.txt");
      if (!SD.exists("sensor.txt"))
      {
        Serial.println("Arquivo apagado com sucesso!");
      }
      else
      {
        Serial.println("Erro ao apagar arquivo!");
      }
    }
  }
}

sábado, 26 de maio de 2012

Códigos Fontes da Aula 10 (Expansor de Porta) do Curso Arduino

Pessoal,

Segue os códigos fontes utilizados na Aula 10 do Curso Arduino Advanced. E conforme prometido segue o código também do contador regressivo.


Código #1

#include

#define expansor1 0x38

void setup()
{
  Wire.begin();
  Wire.beginTransmission(expansor1);
  Wire.send(0xFF);
  Wire.endTransmission();
}

void loop()
{
  Wire.beginTransmission(expansor1);
  Wire.send(B10000001);
  Wire.endTransmission();
  delay(1000);
  Wire.beginTransmission(expansor1);
  Wire.send(B01111101);
  Wire.endTransmission();
  delay(1000);
}
 
Código #2
 
#include

#define expansor1 0x38
#define expansor2 0x39

void setup()
{
  Wire.begin();
  comunica(expansor1, 0xFF);
  comunica(expansor2, 0xFF);
}

void loop()
{
  comunica(expansor1, B10000001);
  comunica(expansor2, B01111101);
  delay(1000);
  comunica(expansor2, B10000001);
  comunica(expansor1, B01111101);
  delay(1000);
}

void comunica(byte endereco, byte digito)
{
  Wire.beginTransmission(endereco);
  Wire.send(digito);
  Wire.endTransmission();
}
 
Código Extra do Contador Regressivo
 
 #include

#define expansor1 0x38
#define expansor2 0x39

void setup()
{
  Wire.begin();
  EscreveDigito(expansor1, 0xFF);
  EscreveDigito(expansor2, 0xFE);
}

void loop()
{
  for(int i = 99; i >= 0; i--)
  {
    byte a = i / 10;
    byte b = i - (a * 10);
    if (i < 10) a = 0;
    EscreveDigito(expansor2, ConverteDigito(a));
    EscreveDigito(expansor1, ConverteDigito(b));
    delay(1000);
  }
}

byte ConverteDigito(byte decimal)
{
  switch(decimal)
  {
    case 0:
      return B00010001;
    case 1:
      return B01111101;
    case 2:
      return B00100011;
    case 3:
      return B00101001;
    case 4:
      return B01001101;
    case 5:
      return B10001001;
    case 6:
      return B10000001;
    case 7:
      return B00111101;
    case 8:
      return B00000001;
    case 9:
      return B00001001;
    default:
      return B11101111;
  }
}

void EscreveDigito(byte endereco, byte digito)
{
  Wire.beginTransmission(endereco);
  Wire.send(digito);
  Wire.endTransmission();
}
 
Abraços,
Renato Aloi
 

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