Publicidade:

terça-feira, 12 de abril de 2016

Arduino - Memória EEPROM - AT24C256

Essa semana postei um artigo no site sistemas embarcados. O Assunto foi memória EEPROM, interna e externa. No caso da memória externa foi abordado o CI AT24C256. Segue o link para o artigo completo: http://www.sistemasembarcados.org/2016/04/arduino-memoria-eeprom.html

Veja também o vídeo sobre o AT24C256.



Veja também o vídeo que mostra a classe feita para facilitar a gravação e leitura da memória:



Código-fonte:

/*
Baseado nos exemplos abaixo:
http://hobbytronics.co.uk/eeprom-page-write
http://playground.arduino.cc/Code/EEPROMWriteAnything

Fabiano A. Arndt
www.youtube.com/fabianoallex
www.facebook.com/dicasarduino
*/

#include <Wire.h>

/*************************************************************************************************************
*******************************CLASSE EE24CXXX - CI I2C EEPROM AT24C128/256***********************************
**************************************************************************************************************/
class EE24CXXX {
  private:
    byte _device_address;
  public:
    EE24CXXX(byte device_address){ _device_address = device_address; }
    void write(unsigned int eeaddress, unsigned char * data, unsigned int data_len);
    void read (unsigned int eeaddress, unsigned char * data, unsigned int data_len);
    
    template <class T> int write(unsigned int eeaddress, const T& value);
    template <class T> int read(unsigned int eeaddress, T& value);
};

void EE24CXXX::write(unsigned int eeaddress, unsigned char * data, unsigned int data_len) {
  unsigned int  address;
  unsigned int  page_space;
  unsigned int  page=0;
  unsigned int  num_writes;
  unsigned char first_write_size;
  unsigned char last_write_size;  
  unsigned char write_size;  
  
  page_space = int(((eeaddress/64) + 1)*64)-eeaddress;      // Calculate space available in first page

  if (page_space>16) {                                      // Calculate first write size
     first_write_size = page_space-((page_space/16)*16);
     if (first_write_size==0) { first_write_size=16; }
  } else {
    first_write_size = page_space; 
  }
  if (data_len>first_write_size)  { last_write_size = (data_len-first_write_size)%16;   }      // calculate size of last write  
  num_writes = (data_len>first_write_size) ? ((data_len-first_write_size)/16)+2 : 1;           // Calculate how many writes we need
     
  unsigned char i=0, counter=0;
  address = eeaddress;
  for (page=0; page<num_writes; page++)  {
    if (page == 0) { 
      write_size = first_write_size; 
    } else if(page == (num_writes-1)) { 
      write_size = last_write_size;
    } else { 
      write_size = 16;
    }
 
    Wire.beginTransmission(_device_address);
    Wire.write((int)((address) >> 8));   // MSB
    Wire.write((int)((address) & 0xFF)); // LSB
    counter = 0;
    do { 
      Wire.write((byte) data[i++]);
      counter++;
    } while(counter<write_size);
    Wire.endTransmission();
    address += write_size;   // Increment address for next write
     
    delay(5);  // needs 5ms for page write
  }
}

void EE24CXXX::read(unsigned int eeaddress, unsigned char * data, unsigned int data_len){
  unsigned char i = 0;
  unsigned int size = data_len;
  unsigned int j=0;
  while (size > 0){
    Wire.beginTransmission(_device_address);
    eeaddress += j*28;
    
    Wire.write((int)(eeaddress >> 8));   // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    
    if (size >= 28) { 
      Wire.requestFrom(_device_address, (unsigned int) 28);
      size -= 28;
    } else {
      Wire.requestFrom(_device_address, (unsigned int) size);
      size = 0;
    }
    while(Wire.available()) { data[i++] = Wire.read(); }
    j++;
  }
}

template <class T> int EE24CXXX::write(unsigned int eeaddress, const T& value) {
  const byte* p = (const byte*)(const void*)&value;
  unsigned char data[sizeof(value)+1];
  for (int i=0; i<sizeof(value); i++) { data[i] = *p++; }
  data[sizeof(value)] = '\n';
  write(eeaddress, data, sizeof(value));
  return sizeof(value);
}

template <class T> int EE24CXXX::read(unsigned int eeaddress, T& value) {
  byte * p = (byte*)(void*)&value;
  unsigned char c[sizeof(value)];
  read(eeaddress, c, sizeof(value));
  for (int i=0; i<sizeof(value); i++) { *p++ = c[i]; }
  return sizeof(value);
}
/*************************************************************************************************************
*******************************FIM - CLASSE EE24CXXX - CI I2C EEPROM AT24C128/256*****************************
**************************************************************************************************************/

EE24CXXX m(0x50);

struct teste{
  int a;
  int b;
  int c;
};

void setup() {
  Serial.begin(9600);
  Wire.begin();  
  
  char i[] = {"1234567890"};
  char j[10];

  m.write(18522, i);              //grava na memória a quantidade de bytes ocupada pelo tipo de dados passado
  
  int count = m.read(18522, j);   //carrega da memória a quantidade de bytes 
  
  Serial.print("Quant: ");
  Serial.println(count);
  Serial.print("Valor: ");
  Serial.println(j);
}

void loop() { }


sexta-feira, 8 de abril de 2016

Arduino - Série de vídeos sobre montagens de CIs

Comecei há alguns dias uma série de vídeos rápidos sobre montagens de CIs. Conforme foram sendo feitos, essa lista aqui vai sendo atualizada. Inscreva-se no Canal para acompanhar todos os vídeos.


















Arduino - Instalação de driver para Nano V3 (CH340G) no win7

Faz um tempo já que comprei alguns Arduinos Nano, mas acabaram ficando um bom tempo guardado. Hoje resolvi utilizá-los (tentar) e tive algumas dificuldades para tentar instalar os drivers corretos no windows 7. Vários artigos explicam como fazer, mas não obtive sucesso com nenhum.

Depois de muito tentar, resolvi procurar os drivers do próprio CI (CH340G, da foto abaixo) que veio com o Arduino Nano que comprei, e encontrei um vídeo, que através do qual consegui resolver o problema. E como dor de barriga não dá uma vez só, resolve criar esse pequeno artigo, pra caso eu venha precisar novamente, eu ter os passos necessários, e claro, para também compartilhar com quem encontrou o mesmo problema.


Vídeo que explica o procedimento:


o arquivo citado no vídeo, encontra-se nesse link: http://www.mediafire.com/download/c9pyi2u7g93iqt6/CH341SER.ZIP

ou se preferirem, aqui no blog mesmo:

https://drive.google.com/file/d/0B9ZzXhiNwNSrMW1KNEUxajZYUjg/view?usp=sharing

de resto, só seguir os passos mostrado no vídeo, apesar de não ser português nem inglês, tem como acompanhar.


sábado, 5 de março de 2016

Eletronica - Divisor de Tensão

Divisor de tensão

Basicamente um divisor de tensão é algo parecido com o circuito abaixo:


          R1           R2
Vin-----/\/\/\---+---/\/\/\-----GND
                 |
                 |
               Vout


A tensão obtida em Vout será dada pela seguinte fórmula:

Vout = R2 / (R1+R2) * Vin

É comum precisarmos utilizar divisões de tensão pra reduzir a tensão de 5V para 3.3V. Isso significa que precisamos ter um Vout de 2/3 de Vin. Há várias combinações de resistores comerciais que se aproximam desses valores, como por exemplo, um resitor de 10 Kohms para R1 e um de 20 Kohms para R2, ou um resistor de 330 ohms para R1 e 680 ohms para R2. Ou ainda diversos outros resistores que tem uma mesma relação aproximada de 2/3 entre eles.

Mas caso você não tenha em mãos os resistores com os valores corretos para ter essa redução, uma solução bem simples, é utilizar 3 resistores de mesmo valor (o valor não importa, o importante é que os 3 sejam exatamente o mesmo valor).

Tendo os 3 resistores iguais, basta combiná-los na forma de um dos dois circuitos abaixo, que a tensão de saída obtida será sempre dada pela fórmula abaixo:

Vout = 2/3 Vin.

como exemplo, imaginemos uma entrada de 5V

 2/3 * 5V ==> 3.33V


(1)
          R            R         R
Vin-----/\/\/\---+---/\/\/\----/\/\/\-----GND
                 |
                 |
               Vout

OU

(2)
          R
     +--/\/\/\--+   
     |    R     |         R
Vin--+--/\/\/\--+---+---/\/\/\-----GND
                    |
                    |
                  Vout


Pra ficar um pouco mais claro, matematicamente falando, vamos analisar a fórmula inicial do cálculo do divisor de tensão, que é:


Vout = R2 / (R1+R2) * Vin

Considerando, 3 Resistores de valores R, teríamos o seguinte para o circuito (1):

Como temos dois resistores em Série no lugar de R2, devemos somar os dois resistores, que será 2R.


Vout = R2 / (R1+R2) * Vin
Vout = 2R / (2R + R) * Vin
Vout = 2R / 3R * Vin

como R/R é igual a 1, podemos cortar os dois R
e como resultados teremos:

Vout = 2/3 * Vin
ou
Vout = 0.66666 * Vin

Ou seja, nossa fórmula não irá depender do valor de R, bastando apenas que ele seja diferente de zero.


no circuito (2) temos no lugar de R1, dois resistores de valor R em paralelo. Como sabemos, quando dois resistores de mesmo valor estão em séries, sua resistencia equivalente, é o valor de R divido por 2. ou seja, a metade do valor. nesse caso, a fórmula ficara da seguinte maneira:

Vout = R2 / (R1+R2) * Vin
Vout = R  / (R + R/2)  * Vin
Vout = R / (R + 0.5 R) * Vin
Vout = R / 1.5 R * Vin

como R/R é igual a 1, podemos cortar os dois R
e como resultados teremos:

Vout = 1/1.5 * Vin
Vout = 0.6666 * Vin

Como vemos, temos o mesmo resultado que o circuito (1)