Arduino盾牌,SD卡数据日志,为什么我的SD卡会死掉?
我有一个真正的焦虑问题,似乎找不到解决办法 我创建了一个简单的arduino代码,用于在2个模拟管脚上扫描曲线,由DAC单元控制。扫描是实时进行的,每秒一次,并以分为几个小时的文件存储在SD卡上 我的问题是SD卡上的SPI接口在继续使用期间停止响应。 我使用以下arduino巨盾 以及一张用于存储的“Kingston MicroSDHC 4GB安全数字卡,66X” 我运行了以下代码3天,当我回来时,SPI没有响应(我之前做了1小时的测试,没有问题,并且我检查了系统是否正确更改了文件)Arduino盾牌,SD卡数据日志,为什么我的SD卡会死掉?,arduino,sd-card,Arduino,Sd Card,我有一个真正的焦虑问题,似乎找不到解决办法 我创建了一个简单的arduino代码,用于在2个模拟管脚上扫描曲线,由DAC单元控制。扫描是实时进行的,每秒一次,并以分为几个小时的文件存储在SD卡上 我的问题是SD卡上的SPI接口在继续使用期间停止响应。 我使用以下arduino巨盾 以及一张用于存储的“Kingston MicroSDHC 4GB安全数字卡,66X” 我运行了以下代码3天,当我回来时,SPI没有响应(我之前做了1小时的测试,没有问题,并且我检查了系统是否正确更改了文件) #包括“S
#包括“SPI.h”
#包括
#包括“Wire.h”
//静态定义
#定义ADG509_A0_引脚39
#定义ADG509_A1_引脚38
#定义SS_DAC_引脚53
#定义电压\u模拟\u引脚11
#定义当前\u模拟\u引脚12
#定义led 13
#定义DS1307_地址0x68
#定义芯片并选择53
//可调整定义
#定义ADC_至_电压1/213//用于将arduino ADC转换为电压的值
#定义样本数量100//测量数量,应能被4除而不给出小数
#定义每个数据集的时间500//以毫秒为单位的数据集之间的延迟,注意“延迟=系统计算时间+每个数据集的时间”
#定义电流增益比2//引脚上的电压电平和太阳能面板上的电流之间的关系
#定义电压增益比10//引脚上的电压电平与太阳能电池板上的电压电平之间的关系
#定义每个测量的采样数5//用于对每个测量点进行平均的ADC读数数,请注意,该数字会极大地影响扫描时间
#根据测量值1定义延迟
无效集_DAC(浮点值);//获取介于0.0和5.0之间的输入,并将电压设置为该值
无效写入测量值到SD(浮动电流、浮动电压、整数)//如果已初始化,则将数字写入SD卡
无效将_写入_文件()//检查是否应创建一个新的SD卡文件并使其生效。还处理写入文件的数据
void get_time()//获取系统的当前时间,并将其存储在全局变量中
int bcdToDec(字节val)//将字节转换为小数
字符intToChar(int val,int number)//将整数转换为字符,最多只例外2个DICIMAL
字输出\u字\u用于\u DAC=0//用于在使用前将set_DAC的强制转换输入键入word
字节数据=0//DAC需要临时变量,它是通过通信发送的字节
浮动电压//存储临时电压测量值
浮充电流//存储临时电流测量值
浮动电流_电平//存储短路电流电平,用于找到测量点的最佳位置
字符文件名[13]=“f000000.txt”//存储当前活动文件名以在SD卡上写入
文件数据文件//SD卡上数据文件的当前版本
整数年、月、月、日、工作日、小时、分、秒//用于存储上次读数的全局变量
浮动电流_数组[_样本数_]//用于在扫描期间存储所有当前测量点
浮动电压_阵列[_样本数_]//用于存储扫描期间的所有电压测量点
int typecast_int;//用于将浮点数转换为int
int上次测量时间;
int在那里;
无效设置(){
引脚模式(ADG509_A0_引脚,输出);
引脚模式(ADG509_A1_引脚,输出);
引脚模式(SS_DAC_引脚,输出);
引脚模式(led,输出);
数字写入(led,低电平);
数字写入(ADG509_A1_引脚,低电平);
数字写入(ADG509_A0_引脚,低电平);
SPI.begin();//启动SPI总线
SPI.Setbitor(MSBFIRST);
Wire.begin();
//打开串行通信并等待端口打开:
Serial.begin(9600);
而(!Serial){;}
串行打印(“初始化SD卡…”);
如果(!SD.开始(芯片选择)){
Serial.println(“卡故障或不存在”);
是否有SDcard=0;
返回+
}
Serial.println(“卡已初始化”);
是否有SDcard=1;
}
void循环(){
//寻找太阳能电池板的短路电流
获取时间();
最后测量时间=秒;
set_DAC(5);//开路fet
延迟微秒(1000);
电流电平=模拟读取(电流模拟引脚);
用于(浮动计数器2=0;计数器2<10;计数器2++){
电流电平+=模拟读取(电流模拟引脚);
}
电流电平=(电流电平/10)*1.1*模数转换器至电压;
//在开始扫描之前,完全打开fet以确保太阳能面板在最大电压下稳定
set_DAC(0);//接地fet
延迟微秒(10000);
如果(是否存在卡==1){
数字写入(led,高电平);
}
//用25%的测量点扫掠曲线上的前80%电流
//注:此处不应进行计算,因为这会减慢扫描速度
对于(浮点计数器=0;计数器<采样数*0.25;计数器++){
设置_DAC((计数器*当前_电平*0.80)/(_采样数*0.25));
延迟微秒(200);
电流=模拟读数(电流模拟引脚);
电压=模拟读数(电压=模拟针脚);
对于(浮动计数器2=0;计数器2<每个测量的样本数\u-1;计数器2++){
电流+=模拟读取(电流模拟引脚);
电压+=模拟读数(电压模拟引脚);
}
电流=每次测量的电流/样本数;
伏特=伏特/每次测量的样本数;
typecast_int=计数器;
当前数组[typecast\u int]=当前;
电压阵列[typecast\u int]=伏特;
}
//用75%的测量点扫过曲线上最后20%的电流
//注:无校准
#include "SPI.h"
#include <SD.h>
#include "Wire.h"
//Static definitions
#define ADG509_A0_pin 39
#define ADG509_A1_pin 38
#define SS_DAC_pin 53
#define voltage_analog_pin 11
#define current_analog_pin 12
#define led 13
#define DS1307_ADDRESS 0x68
#define chip_select 53
//Adjustable definitions
#define ADC_to_voltage 1/213 // the value for converting the arduino ADC to voltage
#define number_of_samples 100 //number of measurements, should be able to be divided by 4 without giving decimals
#define time_per_data_set 500 //the delay between datasets in milisecondss, note the the "delay = system_computation_time + time_per_data_set"
#define current_gain_ratio 2 //the realtion between the voltage level on the pin and current on from the solar pannel
#define voltage_gain_ratio 10 //the realtion between the voltage level on the pin and the voltage level from the solar panel
#define number_samples_per_measurement 5 //the number of ADC readings used to make an average of each measuring point, note this number greatly effects sweeping time
#define delay_per_measurement 1
void set_DAC(float value); // gets an input between 0.0 and 5.0 and sets the voltage to the value
void write_measurement_to_SD(float current, float voltage, int number); //writes the numbers to the SD card if initialized
void write_to_file(); //check is a new SD card file should be created and makes it ef nessesary. Also handles the data writing to the file
void get_time(); //Get the current time of the system, and store them in global variables
int bcdToDec(byte val); //Converts bytes to decimals numbers
char intToChar(int val, int number); //Converts integers to chars, only exept up to 2 dicimals
word output_word_for_DAC = 0; //used to type cast input of set_DAC to word before usage
byte data = 0; //temp variable need for DAC, it is the byte send over the communication
float volt; //stores a temporary voltage measurement
float current; //stores a temporary current measurement
float current_level; //stores the short curciut current level, it is used to find the optimal placement for measuring points
char filename[13] = "F0000000.txt"; //stores the current active filename for writing on the SD card
File dataFile; //the current version of the datafile on the SD card
int years, months, monthsDay, weekDay, hours, minute, seconds; //global varibles used to store the last time reading
float current_array[number_of_samples]; //used to store all current measurements points during sweep
float voltage_array[number_of_samples]; //used to store all voltage measurements points during sweep
int typecast_int; // used for typecasting float to int
int last_measurement_time;
int is_SDcard_there;
void setup() {
pinMode(ADG509_A0_pin, OUTPUT);
pinMode(ADG509_A1_pin, OUTPUT);
pinMode(SS_DAC_pin, OUTPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
digitalWrite(ADG509_A1_pin, LOW);
digitalWrite(ADG509_A0_pin, LOW);
SPI.begin(); // start up the SPI bus
SPI.setBitOrder(MSBFIRST);
Wire.begin();
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {;}
Serial.print("Initializing SD card...");
if (!SD.begin(chip_select)) {
Serial.println("Card failed, or not present");
is_SDcard_there = 0;
return;+
}
Serial.println("card initialized.");
is_SDcard_there = 1;
}
void loop() {
//finding the shortcurcuit current of the solar panel
get_time();
last_measurement_time = seconds;
set_DAC(5); //open fet
delayMicroseconds(1000);
current_level = analogRead(current_analog_pin);
for(float counter2 = 0; counter2 < 10; counter2++){
current_level += analogRead(current_analog_pin);
}
current_level = (current_level/10)* 1.1 * ADC_to_voltage;
//fully opening the fet to insure that the solar pannel is stable at max voltage before beginning the sweep
set_DAC(0); //ground fet
delayMicroseconds(10000);
if(is_SDcard_there == 1){
digitalWrite(led, HIGH);
}
//sweeping the first 80% current on the curve with 25% of the measuring points
//note no calculations should be put in here, since it slow the sweep down
for(float counter = 0; counter < number_of_samples * 0.25; counter++){
set_DAC((counter*current_level * 0.80) / (number_of_samples * 0.25));
delayMicroseconds(200);
current = analogRead(current_analog_pin);
volt = analogRead(voltage_analog_pin);
for(float counter2 = 0; counter2 < number_samples_per_measurement - 1; counter2++){
current += analogRead(current_analog_pin);
volt += analogRead(voltage_analog_pin);
}
current = current / number_samples_per_measurement;
volt = volt / number_samples_per_measurement;
typecast_int = counter;
current_array[typecast_int] = current;
voltage_array[typecast_int] = volt;
}
//sweeping the last 20% current on the curve with 75% of the measuring points
//note no calculations should be put in here, since it slow the sweep down
for(float counter = 0; counter < number_of_samples * 0.75; counter++){
set_DAC(current_level * 0.80 + (counter*current_level * 0.20) / (number_of_samples * 0.75));
delayMicroseconds(200);
current = analogRead(current_analog_pin);
volt = analogRead(voltage_analog_pin);
for(float counter2 = 0; counter2 < number_samples_per_measurement - 1; counter2++){
current += analogRead(current_analog_pin);
volt += analogRead(voltage_analog_pin);
}
current = current / number_samples_per_measurement;
volt = volt / number_samples_per_measurement;
typecast_int = counter + number_of_samples * 0.25;
current_array[typecast_int] = current;
voltage_array[typecast_int] = volt;
}
set_DAC(5); //sets DAC high to prepare for next short curcuit measurement
digitalWrite(led, LOW);
//converting data to desired values and writing them to the file
String to_write = "";
int check;
char buffer[20];
to_write = "0,0,-2";
to_write += '\r';
to_write += '\n';
to_write += "0,";
to_write += intToChar(minute,0);
to_write += intToChar(minute,1);
to_write += intToChar(seconds,0);
to_write += intToChar(seconds,1);
to_write += ",-1";
to_write += '\r';
to_write += '\n';
for(int counter = 0; counter < number_of_samples-1; counter++){
to_write += dtostrf(current_array[counter] = current_array[counter] * ADC_to_voltage * current_gain_ratio, 0, 2, buffer);
to_write += ",";
to_write += dtostrf(voltage_array[counter] = voltage_array[counter] * ADC_to_voltage * voltage_gain_ratio, 0, 2, buffer);
to_write += ",";
to_write += counter;
to_write += '\r';
to_write += '\n';
}
to_write += dtostrf(current_array[99] = current_array[99] * ADC_to_voltage * current_gain_ratio, 0, 2, buffer);
to_write += ",";
to_write += dtostrf(voltage_array[99] = voltage_array[99] * ADC_to_voltage * voltage_gain_ratio, 0, 2, buffer);
to_write += ",99";
Serial.println(to_write); //should only be used for debugging since it slow down the system to much
compute_filename(); //initialize a new filename if needed
check = 0;
while(check == 0 && is_SDcard_there == 1){
dataFile = SD.open(filename,FILE_WRITE);
check = dataFile.println(to_write);
if (dataFile){
dataFile.close();
}
}
//wait for next seconds
while(last_measurement_time + delay_per_measurement > seconds){
get_time();
if(seconds < last_measurement_time){seconds = seconds + 60;}
}
}
// gets an input between 0.0 and 5.0 and sets the voltage to the value
void set_DAC(float value){
if(value <= 5){
value = value*819;
int conveter = value;
output_word_for_DAC = conveter;
digitalWrite(SS_DAC_pin, LOW);
data = highByte(output_word_for_DAC);
data = 0b00001111 & data;
data = 0b00110000 | data;
SPI.transfer(data);
data = lowByte(output_word_for_DAC);
SPI.transfer(data);
digitalWrite(SS_DAC_pin, HIGH);
}
}
//writes the numbers to the SD card if initialized
void write_measurement_to_SD(float current, float voltage, int number){
dataFile = SD.open(filename,FILE_WRITE);
dataFile.print(current);
dataFile.print(',');
dataFile.print(voltage);
dataFile.print(',');
dataFile.print(number);
dataFile.println(';');
if (dataFile){
dataFile.close();
}
}
//Converts bytes to decimals numbers
int bcdToDec(byte val){
return ( (val/16*10) + (val%16) );
}
//Converts integers to chars, only exept up to 2 dicimals
char intToChar(int val, int number){ // note it only take ints with 2 digits
String tempString = "";
char returnValue[3];
if(val < 10){
tempString += 0;
}
tempString += val;
tempString.toCharArray(returnValue,3);
return returnValue[number];
}
//Get the current time of the system, and store them in global variables
void get_time(){
Wire.beginTransmission(DS1307_ADDRESS);
byte zero = 0x00;
Wire.write(zero);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
seconds = bcdToDec(Wire.read());
minute = bcdToDec(Wire.read());
hours = bcdToDec(Wire.read() & 0b111111); //24 hours time
weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
monthsDay = bcdToDec(Wire.read());
months = bcdToDec(Wire.read());
years = bcdToDec(Wire.read());
}
//check if the system need a new filename
void compute_filename(){
get_time();
filename[1] = intToChar(years,1);
filename[2] = intToChar(months,0);
filename[3] = intToChar(months,1);
filename[4] = intToChar(monthsDay,0);
filename[5] = intToChar(monthsDay,1);
filename[6] = intToChar(hours,0);
filename[7] = intToChar(hours,1);
if (dataFile){
dataFile.close();
}
}