Arduinoで遊ぼう - SDメモリカードを読み書きする(廃止)
Posted by arms22 on 2010年01月23日 23 02013/2/20
この記事の内容は古く廃止予定です。最新のArduinoに対応した記事を公開しています。
下記リンクから参照してください。
ArduinoでSDメモリカードを読み書きする
次のプロジェクトで大容量の記憶領域が必要になったのでSDメモリカードの読み書きに挑戦しました。写真は超薄型基板で作ったシールドにヒロセのSDメモリカードスロット「DM1A」を載せた自作のSDメモリカードシールドです。カードスロットのピンピッチは2.54mmより狭いけど、少しづつずらしてやるとうまく半田付けできました。
接続する
※2010/1/25 追記
SDメモリカードの端子は斜めになった角から9,1,2,3,4,5,6,7,8となっています。
※2010/1/26 追記
回路図が間違っていたのを修正しました。
ArduinoとSDメモリカードは次のように接続します。
10番 --> CS(1)SDメモリカードの動作電圧は2.7~3.6Vです。5V動作のArduinoで使用する場合、電圧を下げる必要があります。10 -> CS、11 -> DI、13 -> SCKの間に分圧用の抵抗を挿入します。抵抗値は1.5KΩと3.3KΩぐらい。VDDとVSSの間には0.1uFの積セラを挿入します。
11番 --> DI(2)
12番 <-- DO(7)
13番 --> SCLK(5)
※トップの写真では3.3V動作のArduino Proを使用しているため、分圧用の抵抗を省略しています。
※Ethernet Shieldと併用する場合、10番端子はEthernet Shieldが使用しているため、CSを別の端子に接続する必要があります。
ライブラリをインストールする
Arduino用のSDメモリカードライブラリを検索すると、Wave Shield用のライブラリやSparkFunのマイクロSDメモリカードシールド用のライブラリが見つかった。これらはRoland RiegelさんのMMC/SD/SDHCカードライブラリをベースに作られているようす。そのまま使ってもいいけど、機能が限定されていたり、使いづらそうだったのオリジナルのRoland RiegelさんのライブラリにArduinoっぽいラッパークラスを作ってそれを使うことにした。
FatFs library for Arduino based roland riegel's MMC/SD/SDHC card library
http://code.google.com/p/arms22/downloads/detail?name=FatFs-003.zip
追記2010/1/26
データを書き込んだSDメモリカードがPCで読めない不具合を修正しました。
ダウンロードして解凍したフォルダを~/Documents/Arduino/librariesフォルダにコピーしてください。librariesフォルダがない場合は新規作成してください。
※FatFsライブラリはルート直下のファイルの読み書きと、同時に1ファイルの読み書きにのみ対応しています。これらの制限を解除したい場合、fat_config.hを変更して下さい。
※ライトプロテクト、カード検出には対応していません。これらの制限を解除したい場合、sd_raw_config.hを変更して下さい。
※FAT12でフォーマットしたカードは認識しません。
サンプルスケッチ
まずは書き込み。FatFs.initialize()でライブラリを初期化、カードをマウントします。FatFs.createFile()で新しいファイル「analog.txt」をルートディレクトリに作成します。すでにファイルがある場合は作成しません。
ファイルの読み書きはFileクラスを通して行います。open()でファイルを開きます。1秒毎にアナログ端子0番の値をファイルに書き込みます。FileクラスはPrintインターフェースを実装しているのでprint()、println()が使えます。
#include <FatFs.h>
const char file_name[] = "analog.txt";
File file;
void setup()
{
delay(1000);
if(FatFs.initialize()){
FatFs.createFile(file_name);
}
else{
while(1);
}
}
void loop()
{
if(file.open(file_name)){
file.seekToEnd();
file.println(analogRead(0));
file.close();
}
delay(1000);
}
#if FAT_DATETIME_SUPPORT
void get_datetime(uint16_t* year, uint8_t* month, uint8_t* day, uint8_t* hour, uint8_t* min, uint8_t* sec)
{
*year = 2010;
*month = 1;
*day = 23;
*hour = 9;
*min = 0;
*sec = 0;
}
#endif
ファイルの更新日時を書き込みたい場合は、fat_config.hを次のように変更し、get_datetime()を実装します。
#define FAT_DATETIME_SUPPORT 1
次は読み込み。FatFs.initialize()で初期化、SDメモリカードをマウントし「analog.txt」を開きます。read()で32バイトづつ読み出し、Serial.print()でパソコンに送信します。
#include <FatFs.h>
File file;
void setup()
{
Serial.begin(9600);
delay(1000);
if(FatFs.initialize()){
if(file.open("analog.txt")){
char buf[32];
int sz;
while((sz = file.read((uint8_t*)buf, sizeof(buf))) > 0){
for(int i=0; i<sz; i++){
Serial.print(buf[i]);
}
}
file.close();
}else{
Serial.println("can not open.");
}
}
else{
Serial.println("can not initialize.");
while(1);
}
}
void loop()
{
}
※ATmega168を搭載したArduinoを使う場合、書き込みの機能はオフにします。ATmega168はRAMが1Kしかないため、SerialライブラリとFatFsライブラリを同時に使うには書き込みの機能をオフにする必要があります。sd_raw_config.hを次のように変更してください。
#define SD_RAW_WRITE_SUPPORT 0
MMC/SD/SDHC card library
http://ladyada.net/make/waveshield/download.html
厚さ0.4mmの超薄型ユニバーサル基板
http://arms22.blog91.fc2.com/blog-entry-292.html
ELM - MMCの使いかた
http://elm-chan.org/docs/mmc/mmc.html
ELM - FATファイルシステム・モジュール
http://elm-chan.org/fsw/ff/00index_j.html
Kingston 2GB microSDカード SDC/2GB 永久保証
posted with amazlet at 11.02.02
キングストンテクノロジー (2008-07-01)
売り上げランキング: 202
売り上げランキング: 202
Ads by Google
23 Comments
このコメントは管理人のみ閲覧できます
このコメントは管理人のみ閲覧できます
このコメントは管理人のみ閲覧できます
回路図を修正しました。
このコメントは管理人のみ閲覧できます
> ArduinoとSDメモリカードの接続は12番 <-- DO(7)[直接]
> となるのでしょうか。
はい。直接繋ぎます。
SDカードは3.3Vで駆動しているので、
SDカードからの出力は3.3V(Hi)になります。
5V動作のArduinoに直接つないでも問題ないはずです。
Arduinoの入力ポートのHiの閾値はVcc * 0.7=3.5Vで
ぎりぎり無理っぽい気しますが、
海外のサイトではこれで動いている見たいです。
> となるのでしょうか。
はい。直接繋ぎます。
SDカードは3.3Vで駆動しているので、
SDカードからの出力は3.3V(Hi)になります。
5V動作のArduinoに直接つないでも問題ないはずです。
Arduinoの入力ポートのHiの閾値はVcc * 0.7=3.5Vで
ぎりぎり無理っぽい気しますが、
海外のサイトではこれで動いている見たいです。
FatFS、ありがたく使わせて頂いてます。ちょっと改造してEthernet Shieldと同時使用ができました。
Ethernet Shieldの出力と衝突しないように制御する改造が必要にはなりますが、うまくいっているようです。
Ethernet Shieldの出力と衝突しないように制御する改造が必要にはなりますが、うまくいっているようです。
Arduinoは単一機能が動けばOK的なところがあるので、
こうして組み合わせると不具合がいろいろでてきますねー。
SPI周りはもう少し整理してもらいところです。
こうして組み合わせると不具合がいろいろでてきますねー。
SPI周りはもう少し整理してもらいところです。
Arduino初心者です。
この回路では、SDのCSがArduinoの10番ピンに繋がっています。
他のSPI機器と併用したいので、これを他のピンに移動したい場合、ライブラリのどのファイルの、どの部分を、どのように変更すれば良いのでしょうか?
ライブラリを見ていたのですが、まるで見当がつかないので、ご教示願います。
この回路では、SDのCSがArduinoの10番ピンに繋がっています。
他のSPI機器と併用したいので、これを他のピンに移動したい場合、ライブラリのどのファイルの、どの部分を、どのように変更すれば良いのでしょうか?
ライブラリを見ていたのですが、まるで見当がつかないので、ご教示願います。
sd_raw_config.hの83行目から90行目がポートの設定です。
この辺をいい感じに変更して下さい。
ポートの入出力設定
#define configure_pin_ss() DDRB |= (1 << DDB2)
CSポートの制御
#define select_card() PORTB &= ~(1 << PORTB2)
#define unselect_card() PORTB |= (1 << PORTB2)
この辺をいい感じに変更して下さい。
ポートの入出力設定
#define configure_pin_ss() DDRB |= (1 << DDB2)
CSポートの制御
#define select_card() PORTB &= ~(1 << PORTB2)
#define unselect_card() PORTB |= (1 << PORTB2)
arms22 さん
C言語自体よくわかっておらず、演算子もよく理解していないのですが、ご指摘の通り変更したら、どうにか動きました。
どうもありがとうございました。
C言語自体よくわかっておらず、演算子もよく理解していないのですが、ご指摘の通り変更したら、どうにか動きました。
どうもありがとうございました。
すみません、動いているようでしたが、動いておりませんでした。
センサー(気圧センサのSCP1000)をLOW、SDカードをHIGHにしても、センサーは起動しておらず、無意味な数値、あるいは「0」が来ているだけでした。
SDカードと他のSPI機器を接続する場合の注意、というのを見付けたのですが、
http://elm-chan.org/docs/mmc/mmc.html
こいつのせいでしょうか?
理由が解っても、どこをどういじってよいのか。。。
センサー(気圧センサのSCP1000)をLOW、SDカードをHIGHにしても、センサーは起動しておらず、無意味な数値、あるいは「0」が来ているだけでした。
SDカードと他のSPI機器を接続する場合の注意、というのを見付けたのですが、
http://elm-chan.org/docs/mmc/mmc.html
こいつのせいでしょうか?
理由が解っても、どこをどういじってよいのか。。。
CSをHIGHした後にクロックを出すだけなら、
unselect_card()の後にsd_raw_send_byte()を呼べばいいと思いますよ。
unselect_card()の後にsd_raw_send_byte()を呼べばいいと思いますよ。
このコメントは管理人のみ閲覧できます
このコメントは管理人のみ閲覧できます
管理人様
始めまして。
デバッグデータの保存用にSDカードを使いたくて、
こちらのライブラリとサンプルスケッチを
Arduino 1.0でコンパイルしましたが、
何故かwrite関数でエラーが出ます。
unit8_t型がダメなようです。
始めまして。
デバッグデータの保存用にSDカードを使いたくて、
こちらのライブラリとサンプルスケッチを
Arduino 1.0でコンパイルしましたが、
何故かwrite関数でエラーが出ます。
unit8_t型がダメなようです。
はじめまして。建築関係のマイコン初心者です。いろいろ探してスケッチ作りましたが、ようやく温度表示が出来たのみで、SDカードへの書き込み、時間の表示が出来ません。申し訳有りませんが、どこがおかしいのかご教授ください。
知り合いでarduinoわかる人がいないので、よろしくお願いします。
温度計はダラスのDS18B20,adfruitのSDカードシールドを使っています。
#include <Wire.h>
#include <SD.h>
#include <OneWire.h>
int DS1307_ADDRESS=0x68;
byte command;
const int chipSelect = 4; int interval=10;
OneWire ds(7); // on pin 7
File datafile;
int cnt=10;
int hour,minute,sec;
int year,month,day;
void setTime(){
byte hour=(Serial.read()-0x30)*0x10;
hour=hour+(Serial.read()-0x30);
byte minute=(Serial.read()-0x30)*0x10;
minute=minute+(Serial.read()-0x30);
byte sec=(Serial.read()-0x30)*0x10;
sec=sec+(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,3);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.write((r_sec & 0x00)|sec);
Wire.write(minute);
Wire.write((r_hour & 0x00)|hour);
Wire.endTransmission();
}
void setDay(){
byte year=(Serial.read()-0x30)*0x10;
year=year+(Serial.read()-0x30);
byte month=(Serial.read()-0x30)*0x10;
month=month+(Serial.read()-0x30);
byte date=(Serial.read()-0x30)*0x10;
date=date+(Serial.read()-0x30);
byte day_of_week=(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x03);
Wire.write(day_of_week);
Wire.write(date);
Wire.write(month);
Wire.write(year);
Wire.endTransmission();
}
void printDofW(byte day_of_week){
switch(day_of_week){
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.print("Monday");
break;
case 3:
Serial.print("Tuseday");
break;
case 4:
Serial.print("Wednesday");
break;
case 5:
Serial.print("Thursday");
break;
case 6:
Serial.print("Friday");
break;
case 7:
Serial.print("Saturday");
break;
default:
Serial.print("error");
}
}
void printTime(){
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,7);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
byte r_day_of_week=Wire.read();
byte r_date=Wire.read();
byte r_month=Wire.read();
byte r_year=Wire.read();
Serial.print(r_year,HEX);
Serial.print("/");
Serial.print(r_month,HEX);
Serial.print("/");
Serial.print(r_date,HEX);
Serial.print(" ");
Serial.print(r_hour,HEX);
Serial.print(":");
Serial.print(r_minute,HEX);
Serial.print(":");
Serial.print(r_sec,HEX);
Serial.print(" smtwtfs= ");
printDofW(r_day_of_week);
Serial.println();
//Serial.println(r_day_of_week,HEX);
}
void setup()
{
Serial.begin(9600);
while (!Serial){
;
}
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(SS, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not preset");
// don't do anything more:
return;
}
Serial.println("card initialized.");
// Open up the file we're going to log to!
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (! dataFile) {
Serial.println("error opening datalog.txt");
// Wait forever since we cant write data
while (1) ;
}
}
void loop(){
if ((millis() % (1000*interval))==0){
String dataString = "";
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(5000);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(5000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present,HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(" Temperature = ");
dataFile.print(celsius);
dataFile.println(" Celsius, ");
dataFile.close();
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
}
else {
Serial.println("error opening datalog.txt");
}
delay(10000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
}
}
知り合いでarduinoわかる人がいないので、よろしくお願いします。
温度計はダラスのDS18B20,adfruitのSDカードシールドを使っています。
#include <Wire.h>
#include <SD.h>
#include <OneWire.h>
int DS1307_ADDRESS=0x68;
byte command;
const int chipSelect = 4; int interval=10;
OneWire ds(7); // on pin 7
File datafile;
int cnt=10;
int hour,minute,sec;
int year,month,day;
void setTime(){
byte hour=(Serial.read()-0x30)*0x10;
hour=hour+(Serial.read()-0x30);
byte minute=(Serial.read()-0x30)*0x10;
minute=minute+(Serial.read()-0x30);
byte sec=(Serial.read()-0x30)*0x10;
sec=sec+(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,3);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.write((r_sec & 0x00)|sec);
Wire.write(minute);
Wire.write((r_hour & 0x00)|hour);
Wire.endTransmission();
}
void setDay(){
byte year=(Serial.read()-0x30)*0x10;
year=year+(Serial.read()-0x30);
byte month=(Serial.read()-0x30)*0x10;
month=month+(Serial.read()-0x30);
byte date=(Serial.read()-0x30)*0x10;
date=date+(Serial.read()-0x30);
byte day_of_week=(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x03);
Wire.write(day_of_week);
Wire.write(date);
Wire.write(month);
Wire.write(year);
Wire.endTransmission();
}
void printDofW(byte day_of_week){
switch(day_of_week){
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.print("Monday");
break;
case 3:
Serial.print("Tuseday");
break;
case 4:
Serial.print("Wednesday");
break;
case 5:
Serial.print("Thursday");
break;
case 6:
Serial.print("Friday");
break;
case 7:
Serial.print("Saturday");
break;
default:
Serial.print("error");
}
}
void printTime(){
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,7);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
byte r_day_of_week=Wire.read();
byte r_date=Wire.read();
byte r_month=Wire.read();
byte r_year=Wire.read();
Serial.print(r_year,HEX);
Serial.print("/");
Serial.print(r_month,HEX);
Serial.print("/");
Serial.print(r_date,HEX);
Serial.print(" ");
Serial.print(r_hour,HEX);
Serial.print(":");
Serial.print(r_minute,HEX);
Serial.print(":");
Serial.print(r_sec,HEX);
Serial.print(" smtwtfs= ");
printDofW(r_day_of_week);
Serial.println();
//Serial.println(r_day_of_week,HEX);
}
void setup()
{
Serial.begin(9600);
while (!Serial){
;
}
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(SS, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not preset");
// don't do anything more:
return;
}
Serial.println("card initialized.");
// Open up the file we're going to log to!
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (! dataFile) {
Serial.println("error opening datalog.txt");
// Wait forever since we cant write data
while (1) ;
}
}
void loop(){
if ((millis() % (1000*interval))==0){
String dataString = "";
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(5000);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(5000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present,HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(" Temperature = ");
dataFile.print(celsius);
dataFile.println(" Celsius, ");
dataFile.close();
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
}
else {
Serial.println("error opening datalog.txt");
}
delay(10000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
}
}
とりあえず
・SDカードへの書き込み
・時間の表示
をそれぞれ確実に動くことを確認してから、合体させたほうがよいと思いますよ。
・SDカードへの書き込み
・時間の表示
をそれぞれ確実に動くことを確認してから、合体させたほうがよいと思いますよ。
スケッチの件ですが個別にスケッチ検討してようやく動くようになりました。初めはadafruitのSDシールドを使用していました。説明を良く読めばわかった事ですが、(このシールドは7番ピンを使うのでchipselect= 7にしないとSDカードを認識しません。イーサネットや、XBeeのマイクロSDカードは4で認識します)英語なので、適当に読んでいました。いまはグーグルのクローム使って同時通訳で英文は読むようにしました。完成した物(イーサネット及びXBeeシールドのマイクロSDカード向けです。時間はDS1307をイーサネットシールドに重ねて計測しました。設定は10分おきにしています。)を下記に記入します、ご助言有り難うございました。
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Wire.h>
#include <SD.h>
#include <OneWire.h>
int DS1307_ADDRESS=0x68;
byte command;
byte sec,minute,hour,day,week,month,year,ctrlb;
const int chipSelect = 4;
int cnt=10;
int adr0=0;
int interval=10;
OneWire ds(7); // on pin 7
LiquidCrystal lcd(2,3,8,5,6,9);
File datafile;
int sno=0;
void getTime(){
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(adr0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,3);
byte r_sec=Wire.read();
sec=(r_sec/16)*10+(r_sec % 16);
byte r_minute=Wire.read();
minute=(r_minute/16)*10+(r_minute % 16);
byte r_hour=Wire.read();
hour=(r_hour/16)*10+(r_hour%16);
}
void setTime(){
byte hour=(Serial.read()-0x30)*0x10;
hour=hour+(Serial.read()-0x30);
byte minute=(Serial.read()-0x30)*0x10;
minute=minute+(Serial.read()-0x30);
byte sec=(Serial.read()-0x30)*0x10;
sec=sec+(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(adr0=0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,3);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.write((r_sec & 0x00)|sec);
Wire.write(minute);
Wire.write((r_hour & 0x00)|hour);
Wire.endTransmission();
}
void setDay(){
byte year=(Serial.read()-0x30)*0x10;
year=year+(Serial.read()-0x30);
byte month=(Serial.read()-0x30)*0x10;
month=month+(Serial.read()-0x30);
byte date=(Serial.read()-0x30)*0x10;
date=date+(Serial.read()-0x30);
byte day_of_week=(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x03);
Wire.write(day_of_week);
Wire.write(date);
Wire.write(month);
Wire.write(year);
Wire.endTransmission();
}
void printDofW(byte day_of_week){
switch(day_of_week){
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.print("Monday");
break;
case 3:
Serial.print("Tuseday");
break;
case 4:
Serial.print("Wednesday");
break;
case 5:
Serial.print("Thursday");
break;
case 6:
Serial.print("Friday");
break;
case 7:
Serial.print("Saturday");
break;
default:
Serial.print("error");
}
}
void printTime(){
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(adr0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,8);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
byte r_day_of_week=Wire.read();
byte r_date=Wire.read();
byte r_month=Wire.read();
byte r_year=Wire.read();
Serial.print(r_year,HEX);
Serial.print("/");
Serial.print(r_month,HEX);
Serial.print("/");
Serial.print(r_date,HEX);
Serial.print(" ");
Serial.print(r_hour,HEX);
Serial.print(":");
Serial.print(r_minute,HEX);
Serial.print(":");
Serial.print(r_sec,HEX);
Serial.print(" smtwtfs= ");
printDofW(r_day_of_week);
Serial.println();
//Serial.println(r_day_of_week,HEX);
}
void setup() {
Serial.begin(9600);
// set up the LCD's number of columns and rows:
Wire.begin();
lcd.begin(16, 2);
lcd.clear();
while (!Serial){
;
}
Serial.print("Initializing SD card...");
pinMode(SS, OUTPUT);
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not preset");
return;
}
else{
lcd.print("Card ON");
Serial.println("card initialized.");
}
sno=0;
}
void loop()
{
if(Serial.available()){
command=Serial.read();
if (command==0x74){ // "t"=0x74
setTime();
}
if (command==0x64){ // "d"=0x64
setDay();
}
}
if ((millis() % (1000*interval))==0){
String dataString = "";
sno++;
getTime();
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(5000);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
switch (addr[0]) {
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present,HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,8);
sec=Wire.read();
minute=Wire.read();
hour=Wire.read();
week=Wire.read();
day=Wire.read();
month=Wire.read();
year=Wire.read();
ctrlb=Wire.read();
Serial.print(month,HEX);
Serial.print("/");
Serial.print(day,HEX);
Serial.print(" ");
Serial.print(hour,HEX);
Serial.print(":");
Serial.print(minute,HEX);
Serial.print(":");
Serial.print(sec,HEX);
Serial.print(" ");
Serial.print("no=");
Serial.print(sno);
Serial.print(" t = ");
Serial.print(celsius);
Serial.print(" C ");
lcd.clear();
lcd.setCursor(0,0);
lcd.print(month,HEX);
lcd.print("/");
lcd.print(day,HEX);
lcd.print(" ");
lcd.print(hour,HEX);
lcd.print(":");
lcd.print(minute,HEX);
lcd.print(":");
lcd.print(sec,HEX);
lcd.print(" , ");
lcd.print("R=");
for( i = 0; i < 8; i++)
lcd.print(' , ');
lcd.print(addr[i], HEX);
lcd.setCursor(0,1);
lcd.print("no=");
lcd.print(sno);
lcd.print(" t= ");
lcd.print(celsius);
lcd.print(" C ");
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.print("no=");
dataFile.print(sno);
dataFile.print(",");
dataFile.print("R=");
for( i = 0; i < 8; i++)
dataFile.print(' , ');
dataFile.print(addr[i], HEX);
dataFile.print(" , ");
dataFile.print(month,HEX);
dataFile.print("/");
dataFile.print(day,HEX);
dataFile.print(", ");
dataFile.print(hour,HEX);
dataFile.print(":");
dataFile.print(minute,HEX);
dataFile.print(":");
dataFile.print(sec,HEX);
dataFile.print(" , ");
dataFile.print(" , t =, ");
dataFile.print(celsius);
dataFile.println(". C ");
dataFile.close();
}
else {
Serial.println("error opening datalog.txt");
}
delay(600000); // maybe 750ms is enough, maybe not
}
}
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Wire.h>
#include <SD.h>
#include <OneWire.h>
int DS1307_ADDRESS=0x68;
byte command;
byte sec,minute,hour,day,week,month,year,ctrlb;
const int chipSelect = 4;
int cnt=10;
int adr0=0;
int interval=10;
OneWire ds(7); // on pin 7
LiquidCrystal lcd(2,3,8,5,6,9);
File datafile;
int sno=0;
void getTime(){
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(adr0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,3);
byte r_sec=Wire.read();
sec=(r_sec/16)*10+(r_sec % 16);
byte r_minute=Wire.read();
minute=(r_minute/16)*10+(r_minute % 16);
byte r_hour=Wire.read();
hour=(r_hour/16)*10+(r_hour%16);
}
void setTime(){
byte hour=(Serial.read()-0x30)*0x10;
hour=hour+(Serial.read()-0x30);
byte minute=(Serial.read()-0x30)*0x10;
minute=minute+(Serial.read()-0x30);
byte sec=(Serial.read()-0x30)*0x10;
sec=sec+(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(adr0=0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,3);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.write((r_sec & 0x00)|sec);
Wire.write(minute);
Wire.write((r_hour & 0x00)|hour);
Wire.endTransmission();
}
void setDay(){
byte year=(Serial.read()-0x30)*0x10;
year=year+(Serial.read()-0x30);
byte month=(Serial.read()-0x30)*0x10;
month=month+(Serial.read()-0x30);
byte date=(Serial.read()-0x30)*0x10;
date=date+(Serial.read()-0x30);
byte day_of_week=(Serial.read()-0x30);
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x03);
Wire.write(day_of_week);
Wire.write(date);
Wire.write(month);
Wire.write(year);
Wire.endTransmission();
}
void printDofW(byte day_of_week){
switch(day_of_week){
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.print("Monday");
break;
case 3:
Serial.print("Tuseday");
break;
case 4:
Serial.print("Wednesday");
break;
case 5:
Serial.print("Thursday");
break;
case 6:
Serial.print("Friday");
break;
case 7:
Serial.print("Saturday");
break;
default:
Serial.print("error");
}
}
void printTime(){
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(adr0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,8);
byte r_sec=Wire.read();
byte r_minute=Wire.read();
byte r_hour=Wire.read();
byte r_day_of_week=Wire.read();
byte r_date=Wire.read();
byte r_month=Wire.read();
byte r_year=Wire.read();
Serial.print(r_year,HEX);
Serial.print("/");
Serial.print(r_month,HEX);
Serial.print("/");
Serial.print(r_date,HEX);
Serial.print(" ");
Serial.print(r_hour,HEX);
Serial.print(":");
Serial.print(r_minute,HEX);
Serial.print(":");
Serial.print(r_sec,HEX);
Serial.print(" smtwtfs= ");
printDofW(r_day_of_week);
Serial.println();
//Serial.println(r_day_of_week,HEX);
}
void setup() {
Serial.begin(9600);
// set up the LCD's number of columns and rows:
Wire.begin();
lcd.begin(16, 2);
lcd.clear();
while (!Serial){
;
}
Serial.print("Initializing SD card...");
pinMode(SS, OUTPUT);
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not preset");
return;
}
else{
lcd.print("Card ON");
Serial.println("card initialized.");
}
sno=0;
}
void loop()
{
if(Serial.available()){
command=Serial.read();
if (command==0x74){ // "t"=0x74
setTime();
}
if (command==0x64){ // "d"=0x64
setDay();
}
}
if ((millis() % (1000*interval))==0){
String dataString = "";
sno++;
getTime();
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(5000);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
switch (addr[0]) {
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present,HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS,8);
sec=Wire.read();
minute=Wire.read();
hour=Wire.read();
week=Wire.read();
day=Wire.read();
month=Wire.read();
year=Wire.read();
ctrlb=Wire.read();
Serial.print(month,HEX);
Serial.print("/");
Serial.print(day,HEX);
Serial.print(" ");
Serial.print(hour,HEX);
Serial.print(":");
Serial.print(minute,HEX);
Serial.print(":");
Serial.print(sec,HEX);
Serial.print(" ");
Serial.print("no=");
Serial.print(sno);
Serial.print(" t = ");
Serial.print(celsius);
Serial.print(" C ");
lcd.clear();
lcd.setCursor(0,0);
lcd.print(month,HEX);
lcd.print("/");
lcd.print(day,HEX);
lcd.print(" ");
lcd.print(hour,HEX);
lcd.print(":");
lcd.print(minute,HEX);
lcd.print(":");
lcd.print(sec,HEX);
lcd.print(" , ");
lcd.print("R=");
for( i = 0; i < 8; i++)
lcd.print(' , ');
lcd.print(addr[i], HEX);
lcd.setCursor(0,1);
lcd.print("no=");
lcd.print(sno);
lcd.print(" t= ");
lcd.print(celsius);
lcd.print(" C ");
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.print("no=");
dataFile.print(sno);
dataFile.print(",");
dataFile.print("R=");
for( i = 0; i < 8; i++)
dataFile.print(' , ');
dataFile.print(addr[i], HEX);
dataFile.print(" , ");
dataFile.print(month,HEX);
dataFile.print("/");
dataFile.print(day,HEX);
dataFile.print(", ");
dataFile.print(hour,HEX);
dataFile.print(":");
dataFile.print(minute,HEX);
dataFile.print(":");
dataFile.print(sec,HEX);
dataFile.print(" , ");
dataFile.print(" , t =, ");
dataFile.print(celsius);
dataFile.println(". C ");
dataFile.close();
}
else {
Serial.println("error opening datalog.txt");
}
delay(600000); // maybe 750ms is enough, maybe not
}
}
はじめまして。aruduino+XBeeSDシールド+LCDの構成で使っています。
子機XBeeスイッチ入力を親機XBeeでカウントしています。
Timer2の割り込み(1分)動作後親機XBeeの受信ができなくなります。
SDに書き込まれてはいるのですがフリーズしてしまいます。
LiquidCrystal lcd(3, 5, 6, 7, 8, 9);
#include <SD.h>
#include <MsTimer2.h>
#define PIN_SDCS 4
原因がわかりません。
どなたかご教授お願い致します。
子機XBeeスイッチ入力を親機XBeeでカウントしています。
Timer2の割り込み(1分)動作後親機XBeeの受信ができなくなります。
SDに書き込まれてはいるのですがフリーズしてしまいます。
LiquidCrystal lcd(3, 5, 6, 7, 8, 9);
#include <SD.h>
#include <MsTimer2.h>
#define PIN_SDCS 4
原因がわかりません。
どなたかご教授お願い致します。
もしTimer2止めてフリーズしないならTimer2の処理が悪さしているってことだから、原因をある程度絞り込めたね。
Leave a reply
該当の記事は見つかりませんでした。