Я не могу открыть/записать в dataFile SD Shield в mySketch, но у меня нет проблем с примером скетча Datalogger из SD-библиотеки...?

Здравствуйте, сообщество Arduino

Я собираю данные и пытаюсь войти в систему Deek Robot SD Shield через Mega.

У меня есть данные в строке данных, которые я могу Serial.print вывести на монитор, но вместо этого я хотел бы записать их на SD-карту. Когда я запускаю скетч примера регистратора данных из библиотеки SD, я вижу данные и получаю доступ к файлу журнала данных с SD-карты (согласно точке примера), но когда я пытаюсь перекрестно опылить пример с помощью mySketch, отладочное сообщение

ошибка при открытии datalog.txt

это все, что у меня есть.

Я загрузил скетч, извиняюсь, он довольно длинный, есть некоторые вспомогательные вещи, вызов для открытия и записи файла данных и т. д. начинается со строки 200 и заканчивается на 212.

Я пробовал размещать функции файла данных в разных местах кода, используя другие библиотеки, читая сообщения на форуме, но ничего не получалось. если бы кто-нибудь мог указать, что я делаю неправильно, я был бы бесконечно благодарен.

Ура, Майкл

//!!!измените это на имя скетча!!!!
#define SKETCH_VERSION "SD for loop array test"

//включаем соответствующие библиотеки
#include <EnableInterrupt.h>
#include <SPI.h>
#include <SD.h>

//глобально определяем пины
#define BUSY 3    //фиолетовый*
#define RD 4      //желтый* RD+CS связаны вместе
#define RESET 5   //серый*
#define CONVST 6  //зеленый* CONVSTA+CONVSTB спаяны вместе на плате
#define RANGE 7   //синий* *не постоянный - перепроверьте!!!*

#define DB0 38
#define DB1 39
#define DB2 40
#define DB3 41
#define DB4 42
#define DB5 43
#define DB6 44
#define DB7 45
#define DB8 46
#define DB9 47
#define DB10 48
#define DB11 49
#define DB12 50
#define DB13 51
#define DB14 52
#define DB15 53

byte statusLed       = 13;
byte sensorPin1       = 10;
byte sensorPin2       = 11;
byte sensorPin3       = 12;

int sensorValue[8];
int rawData[16];

// изменяем размер этих массивов, чтобы он соответствовал количеству каналов, считываемых АЦП
int adcChannel[5];
int adcData[5];
int channelCount=5;

volatile byte pulseCount1;
volatile byte pulseCount2;
volatile byte pulseCount3;

int pulses[3];

// cs pin для sd-shield *NB 53 для Mega
const int chipSelect = 53;

unsigned long oldTime;

void setup() {             // устанавливаем оборудование

  Serial.begin(9600);     
  //SD Card.....
  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для родного порта USB
  }

  Serial.print("Initializing SD card...");

  // смотрим, присутствует ли карта и может ли она быть инициализирована:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // больше ничего не делаем:
    while (1);
  }
  Serial.println("card initialized.");

  enableInterrupt(BUSY, bitBang, FALLING);

  oldTime            = 0;

  pinMode(DB0, INPUT_PULLUP);
  pinMode(DB1, INPUT_PULLUP);
  pinMode(DB2, INPUT_PULLUP);
  pinMode(DB3, INPUT_PULLUP);
  pinMode(DB4, INPUT_PULLUP);
  pinMode(DB5, INPUT_PULLUP);
  pinMode(DB6, INPUT_PULLUP);
  pinMode(DB7, INPUT_PULLUP);
  pinMode(DB8, INPUT_PULLUP);
  pinMode(DB9, INPUT_PULLUP);
  pinMode(DB10, INPUT_PULLUP);
  pinMode(DB11, INPUT_PULLUP);
  pinMode(DB12, INPUT_PULLUP);
  pinMode(DB13, INPUT_PULLUP);
  pinMode(DB14, INPUT_PULLUP);
  pinMode(DB15, INPUT_PULLUP);

  pinMode(RESET, OUTPUT);
  pinMode(CONVST, OUTPUT);
  pinMode(RD, OUTPUT);
  pinMode(RANGE, OUTPUT);
  pinMode(BUSY, INPUT);

  //сбросьте АЦП, чтобы начать преобразование
  digitalWrite(RESET, HIGH);
  delayMicroseconds(10);
  digitalWrite(RESET, LOW);

  digitalWrite(CONVST, LOW);
  digitalWrite(RD, HIGH);
  digitalWrite(RANGE, LOW);
  digitalWrite(BUSY, LOW);

  delayMicroseconds(100);

  // Настраиваем линию светодиодов состояния как выход
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, HIGH);  // У нас подключен светодиод с активным низким уровнем

  pinMode(sensorPin1, INPUT);
  digitalWrite(sensorPin1, HIGH);

  pinMode(sensorPin2, INPUT_PULLUP);
  digitalWrite(sensorPin2, HIGH);

  pinMode(sensorPin3, INPUT_PULLUP);
  digitalWrite(sensorPin3, HIGH);

  pulseCount1        = 0;
  pulseCount2        = 0;
  pulseCount3        = 0;

  oldTime            = 0;

  // датчики Холла настроены на срабатывание при изменении состояния ПАДЕНИЕ
  // (переход из ВЫСОКОГО состояния в НИЗКОЕ состояние)
  enableInterrupt(sensorPin1, pulseCounter1, FALLING);
  enableInterrupt(sensorPin2, pulseCounter2, FALLING);
  enableInterrupt(sensorPin3, pulseCounter3, FALLING);

  //это печатает имя скетча !!!чтение строки 1!!!
  Serial.print("sketch version: ");
  Serial.println(SKETCH_VERSION);

}

void loop() {
  //Serial.print("привет");
  // изменяем это значение на предпочтительную частоту дискретизации
  if ((millis() - oldTime) == 1000) {

    oldTime = millis();

    //Serial.print(millis());
    //Серийный.print("\t");

    // сообщаем АЦП начать чтение (преобразование аналогового ввода в цифровой вывод)
    delayMicroseconds(10);
    digitalWrite(CONVST, LOW);
    delayMicroseconds(10);
    digitalWrite(CONVST, HIGH);
    // когда чтение-преобразование завершено, АЦП посылает на вывод BUSY низкий уровень, запуская BitBang ISR

    //выводим данные АЦП из массива внутри ISR bitBang в строку
    String adcString = "";
    for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
      adcString += String(adcData[thisChannel]);
      adcString += ",";
    }

    //отключаем прерывание для доступа к текущему счетчику импульсов
    disableInterrupt(sensorPin1);
    disableInterrupt(sensorPin2);
    disableInterrupt(sensorPin3);
    // получаем текущее количество импульсов и сохраняем в переменной
    pulses[0] = pulseCount1;
    pulses[1] = pulseCount2;
    pulses[2] = pulseCount3;
    //сбросить счетчик импульсов
    pulseCount1 = 0;
    pulseCount2 = 0;
    pulseCount3 = 0;
    //включаем прерывание и снова начинаем увеличивать счетчик импульсов
    enableInterrupt(sensorPin1, pulseCounter1, FALLING);
    enableInterrupt(sensorPin2, pulseCounter2, FALLING);
    enableInterrupt(sensorPin3, pulseCounter3, FALLING);

    String pulseString = "";
    for(int i=0; i<3; i++){
      pulseString += String(pulses[i]);
      if (i<2) {
        pulseString += ",";
      }
    }

    String dataString = String(adcString + pulseString);
  // открываем файл. обратите внимание, что одновременно может быть открыт только один файл,
  // так что вы должны закрыть это, прежде чем открывать другое.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // если файл доступен, пишем в него:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // также печатать в последовательный порт:
    Serial.println(dataString);
  }  
  // если файл не открыт, выскакивает ошибка:
  else {
    Serial.println("error opening datalog.txt");
  } 

 //Serial.println(dataString);

  }  
//начнем снова
}

// захват данных АЦП ISR (для n канала)
void bitBang ()  {
  //цикл for для битбанга значений аналоговых (АЦП) каналов (максимум 8) с последовательным сохранением их в массиве переменных (равном каналам АЦП)
  for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
  // отправляем низкий уровень вывода считывания АЦП для битового удара по первому каналу
  digitalWrite(RD, LOW);
  //читаем состояние 16 контактов и сохраняем в переменной
  rawData[0] = digitalRead(DB15);
  rawData[1] = digitalRead(DB14);
  rawData[2] = digitalRead(DB13);
  rawData[3] = digitalRead(DB12);
  rawData[4] = digitalRead(DB11);
  rawData[5] = digitalRead(DB10);
  rawData[6] = digitalRead(DB9);
  rawData[7] = digitalRead(DB8);
  rawData[8] = digitalRead(DB7);
  rawData[9] = digitalRead(DB6);
  rawData[10] = digitalRead(DB5);
  rawData[11] = digitalRead(DB4);
  rawData[12] = digitalRead(DB3);
  rawData[13] = digitalRead(DB2);
  rawData[14] = digitalRead(DB1);
  rawData[15] = digitalRead(DB0);
  // преобразовать в 16-битный 2-секундный комплимент и сохранить в массиве переменных
  adcData[thisChannel] = rawData[0] | (rawData[1] << 1) | (rawData[2] << 2) | (rawData[3] << 3) | (rawData[4] << 4) | (rawData[5] << 5) | (rawData[6] << 6) | (rawData[7] << 7) |  (rawData[8] << 8) | (rawData[9] << 9) | (rawData[10] << 10) | (rawData[11] << 11) | (rawData[12] << 12) | (rawData[13] << 13) | (rawData[14] << 14) | (rawData[15] << 15);
  // отправляем высокий уровень на выводе АЦП, чтобы сказать, что мы прочитали первый канал
  digitalWrite(RD, HIGH);
  //повторить для n каналов
  }
}

// подсчет импульсов ISR
void pulseCounter1(){
  // Увеличиваем счетчик импульсов
  pulseCount1++;
}
void pulseCounter2(){
  // Увеличиваем счетчик импульсов
  pulseCount2++;
}
void pulseCounter3(){
  // Увеличиваем счетчик импульсов
  pulseCount3++;
}

, 👍0

Обсуждение

Я думаю, что щит не использует 53 в качестве CS. обычно контакт 10 или 4 используется для экранов, совместимых с Uno. но контакт 53 должен использоваться как ВЫХОД, если Mega является мастером SPI., @Juraj


1 ответ


Лучший ответ:

0

SD-карта использует SPI для обмена данными. Похоже, вы используете эти контакты для какой-то другой цели. Если вы хотите использовать SD-карту, вам нужно выбрать другие контакты и оставить на SD-карте 50, 51, 52 и 53.

,

Спасибо Delta G, вы G! Я использовал старую версию своего эскиза, какой идиот! У меня были все провода, подключенные к правильным контактам, но я не проверил это дважды на эскизе - ошибка школьника 101. Еще раз спасибо и, как я уже сказал, я бесконечно благодарен. Позвони мне, если когда-нибудь будешь в Блайти - я должен тебе как минимум выпить. Привет, Майкл, @Microk