README.md 5.95 KB
Newer Older
Gabriel Krieger's avatar
Gabriel Krieger committed
1
2
3
4
5
# Documentação para uso Shield SD

`Centro de Tecnologia Acadêmica - UFRGS`
http://cta.if.ufrgs.br

6
![Logo](index.png)
Gabriel Krieger's avatar
Gabriel Krieger committed
7
8
9
10
11
12
13

`Licença: GPL v3`

`Autor: Béuren F. Bechlin`

## Shield

14
15
16
A montagem do componente está descrita abaixo, lembrando que está sendo usado um shield de cartão SD e todos tendem a ter o mesmo padrão. Caso tenha alguma diferença leia a placa do seu shield que você irá encontrar os pinos corretos.

![Fritzing](SD_CARD_bb.png)
Gabriel Krieger's avatar
Gabriel Krieger committed
17

18
---
Gabriel Krieger's avatar
Gabriel Krieger committed
19
20
## Programação

21
22
### Definicões e inclusões

Gabriel Krieger's avatar
Gabriel Krieger committed
23
Inicialmente inclua a biblioteca SD.h onde estará as funções e objetos necessários.
24
25
26
27

```c++
#include <SD.h>
```
Gabriel Krieger's avatar
Gabriel Krieger committed
28
29
30
31
32
33
34
35
36

Então iremos definir as configurações do SPI (Serial Peripheral Interface). Por default usaremos:

1. MOSI - pino 11
2. MISO - pino 12
3. CLK - pino 13

E ainda o para CS definiremos o pino 4.

37
38
39
40
41
```c++
#define CS_pin 4
```

### Inicializando comunicação
Gabriel Krieger's avatar
Gabriel Krieger committed
42
43
44
45
46

Ok, após essas definições de hardware poderemos prosseguir com o algoritmo para comunicação.

Para esse exemplo usaremos a comunicação serial com o computador para debug e mensagens.

47
48
49
50
51
52
53
54
```c++
#include <SD.h>

#define CS_pin 4
void setup(){
	// Iniciando comunicação serial
	Serial.begin(9600);
	// Mensagem de que está tentando iniciar a comunicação com cartão SD
55
	Serial.print("Iniciando cartão SD ...");
Gabriel Krieger's avatar
Gabriel Krieger committed
56
			  
57
58
59
60
61
	// Definindo o pino do CS como saída
	// Além disso é necessário definir o pino 10, na maioria das placas Arduino, como saída
	//   ou pode haver problemas com as funções da biblioteca SD
	pinMode(CS_pin, OUTPUT);
	pinMode(10, OUTPUT);
Gabriel Krieger's avatar
Gabriel Krieger committed
62
		
63
64
  if (!SD.begin(CS_pin)) {
  	Serial.println("O cartão falhou ou não está conectado.");
Gabriel Krieger's avatar
Gabriel Krieger committed
65
	
66
67
68
  	return;
  }
  Serial.println("Cartão SD iniciado.");
Gabriel Krieger's avatar
Gabriel Krieger committed
69
	 
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
}
```

### Funções

Então, concluída a inicialização do cartão SD podemos manipulá-lo através das funções da biblioteca.
As funções mais usadas estão a seguir:

* SD.begin(cspin): inicializa a o cartão SD e a biblioteca no pino de comunicação *cspin* (chipselect). Returna TRUE caso sucesso e FALSE caso contrário.
* SD.exists(filename): verifica se o diretório ou arquivo *filename* existe, retornando TRUE caso sim e FALSE
caso contrário
* SD.open(filename, mode): abre o diretório ou arquivo *filename* do cartão SD com o modo identificado no segundo
argumento, podendo ser suprimido e então por default teremos o modo FILE_READ - byte. Em geral é atribuído um objeto 
do tipo File para manipulação dos métodos da biblioteca. Além disso essa função cria o arquivo caso ele não exista.
  1. FILE_READ: abre o arquivo como leitura, começando pelo início do arquivo.
  2. FILE_WRITE: abre o arquivo como escrita, começando pelo fim do arquivo.

As próximas funções se referem a classe File, que é necessário para escrever/ler dados de arquivos.

```c++
90
File dataFile = SD.open("teste/log.txt", FILE_WRITE);
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
```

* file.available(): checa se existe bytes (caracteres) para serem lidos do arquivo. Retorna o número de bytes disponíveis, int.
* file.write(data): escreve a *data* no arquivo, podendo ser byte, char, int ou string (char *). Retorna o número de bytes que 
foram escritos.
* file.read(): lê um **único** byte do arquivo. Retorna o próximo byte (ou caracter) ou -1 se não haver mais caracteres a serem lidos.
Lembrando que para leitura de números é necessário um algoritmo para converter-los, já que a leitura é somente byte-a-byte. 
* file.close(): fecha o arquivo e garante que todos os dados gravados anteriormente estão fisicamente salvos no cartão.
* file.size(): pega o tamanho do arquivo. Retorna o tamanho do arquivo em bytes.
* file.flush(): garante que todos os bytes escritos no arquivo serão salvos. Isso é feito automáticamente com *file.close()* mas 
essa função não fecha a comunicação.
* file.position(): retorna a posição em que se encontra a leitura/escrita, análogo ao cursor, dentro do arquivo.
* file.seek(): determina a nova posição de leitura/escrita no arquivo. Deve estar entre 0 e o tamanho do arquivo(inclusive).

### Exemplos

107
#### Escrita e leitura
108
```c++
109
110
111
112
113
114
115
116
117
118
119
120
/*
  Exemplo é adaptado do tutorial disponivel no site do Arduino.
	http://www.arduino.cc/en/Tutorial/ReadWrite  

  created   Nov 2010
  by David A. Mellis
  modified 9 Apr 2012
  by Tom Igoe
 
 This example code is in the public domain.
*/

121
122
#include <SD.h>

123

124
125
#define CS_pin 4
void setup(){
126
127
128
  // Iniciando comunicação serial
  Serial.begin(9600);
  // Mensagem de que está tentando iniciar a comunicação com cartão SD
129
  Serial.print("Iniciando cartão SD ...");
130
			  
131
132
133
134
135
136
137
138
  // Definindo o pino do CS como saída
  // Além disso é necessário definir o pino 10, na maioria das placas Arduino, como saída
  //   ou pode haver problemas com as funções da biblioteca SD
  pinMode(CS_pin, OUTPUT);
  pinMode(10, OUTPUT);

  // Verificando se é possível estabelecer comunicação	
  if (!SD.begin(CS_pin)) {
139
  	Serial.println("O cartão falhou ou não está conectado.");
140
	
141
142
  	return;
  }
143
  Serial.println("Cartão SD iniciado.");
144
145
146
 
  // Abrindo um arquivo para escrita, note que somente um arquivo pode ser aberto por
  //   vez entao necessario fechar com o metodo close() antes de abrir outro.
147
  File dataFile = SD.open("teste.txt", FILE_WRITE);
148
149
150
 
  // Testando se o arquivo esta pronto para ser escrito:
  if (dataFile) {
151
152
    Serial.print("Escrevendo no arquivo teste.txt...");
    dataFile.println("Testando 1, 2, 3.");
153
    // Fechando o arquivo:
154
    dataFile.close();
155
    Serial.println("Terminado.");
156
157
  } else {
    // Caso o arquivo tenha algum problema retorna um erro:
158
    Serial.println("Erro em abrir o arquivo teste.txt.");
159
160
  }
 
161
  // Re-abre o arquivo para leitura
162
  dataFile = SD.open("teste.txt");
163
  if (dataFile) {
164
    Serial.println("teste.txt:");
165
166
167
168
169
170
171
172
173
   
    // Lendo ate nao ter mais nada nele
    while (dataFile.available()) {
        Serial.write(dataFile.read());
    }
     // Fechando o arquivo:
    dataFile.close();
  } else {
    // Caso o arquivo tenha algum problema retorna um erro:
174
    Serial.println("Erro em abrir o arquivo teste.txt.");
175
  }
176
}
Gabriel Krieger's avatar
Gabriel Krieger committed
177

178
179
180
void loop()
{
  //Nao faz nada
181
182
}

183
```