Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arduino盾牌,SD卡数据日志,为什么我的SD卡会死掉?_Arduino_Sd Card - Fatal编程技术网

Arduino盾牌,SD卡数据日志,为什么我的SD卡会死掉?

Arduino盾牌,SD卡数据日志,为什么我的SD卡会死掉?,arduino,sd-card,Arduino,Sd Card,我有一个真正的焦虑问题,似乎找不到解决办法 我创建了一个简单的arduino代码,用于在2个模拟管脚上扫描曲线,由DAC单元控制。扫描是实时进行的,每秒一次,并以分为几个小时的文件存储在SD卡上 我的问题是SD卡上的SPI接口在继续使用期间停止响应。 我使用以下arduino巨盾 以及一张用于存储的“Kingston MicroSDHC 4GB安全数字卡,66X” 我运行了以下代码3天,当我回来时,SPI没有响应(我之前做了1小时的测试,没有问题,并且我检查了系统是否正确更改了文件) #包括“S

我有一个真正的焦虑问题,似乎找不到解决办法

我创建了一个简单的arduino代码,用于在2个模拟管脚上扫描曲线,由DAC单元控制。扫描是实时进行的,每秒一次,并以分为几个小时的文件存储在SD卡上

我的问题是SD卡上的SPI接口在继续使用期间停止响应。 我使用以下arduino巨盾 以及一张用于存储的“Kingston MicroSDHC 4GB安全数字卡,66X”

我运行了以下代码3天,当我回来时,SPI没有响应(我之前做了1小时的测试,没有问题,并且我检查了系统是否正确更改了文件)

#包括“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();
  }  
}