Проблема с кодом не работают вместе OneWire и самодельный SD shield

Тема в разделе "Arduino & Shields", создана пользователем KarDen, 8 июл 2014.

  1. KarDen

    KarDen Нуб

    Приветствую, уважаемые! Примите в свои ряды начинающего любителя Arduino. Я не электротехник, хотя немного разбираюсь, и не программист, хотя пытаюсь разобраться. С Arduino дружу уже пол года. Недавно задумал проект - стенд измерений и регистрации. Снимаю данные с системы (до 10 штук) датчиков по шине OneWire и пишу все это на SD карту. OneWire датчики пока 3 штуки DS18B20 температурные, потом будут и другие. SD шилд самодельный, порядок изготовления есть на Хабре. Проблема в том, что по отдельности все работает. Схема с датчиками опрашивается, датчики определяются и выводятся в консоль. Схема с SD шилдом также работает, на карте появляется файлик, в него пишутся данные. Но при попытке одновременной работы и с тем и с другим, происходят не понятные мне вещи. Для большей наглядности дам коды и результаты их отработки.


    Код OneWire:



    //использую буржуйскую библиотеку OneWire для работы с датчиками температур
    #include <OneWire.h>

    //линия OneWire у меня висит на пине 9 Ардуинки

    OneWire ds(9);

    //мне понадобятся следующие глобальные переменные и массивы

    byte i=0,devicenum=0,k=0,tempdata[12],address[8],addressmap[10][8];
    String devicetype[10];


    //функция настройки при запуске

    void setup(void)
    {
    Serial.begin(9600);

    /*пока поиск адресов дает true, ищу адреса и записываю в матрицу из 10 строк,
    таким образом в своем стенде использую до 10 датчиков*/
    while (ds.search(address)){
    for ( i = 0; i < 8; i++) addressmap[k]=address;
    k=k+1;
    }
    //запоминаю количество найденных устройств на шине 1-Wire
    devicenum = k-1;

    /*для каждого устройства расшифровываю байт, означающий тип и
    пишу в отдельную матрицу из десяти элементов типа string*/
    for (k=0; k<=devicenum; k++) {
    switch (addressmap[k][0]) {
    case 16: devicetype[k]="digital thermometer ds1820 (ds1920) series"; break;
    case 32: devicetype[k]="4-channel 16 bit analog->digital converter"; break;
    case 34: devicetype[k]="digital thermometer ds1822"; break;
    case 40: devicetype[k]="digital thermometer ds18b20, up to 12 bit resolution"; break;
    default: devicetype[k]="unknoun 1-Wire device"; break;
    }
    }
    //адреса и типы всех найденных устройств вывожу на печать
    for( k = 0; k <= devicenum; k=k+1) {
    Serial.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
    for( i = 0; i < 8; i=i+1) {
    Serial.print(addressmap[k], HEX);
    Serial.print(" ");
    }
    Serial.print(']'); Serial.print(" type of device is "); Serial.println(devicetype[k]);
    }
    Serial.println("That's all list of online devices");

    }
    void loop(void)
    { }





    Отработка:


    Device #0 address is [ 28 8C A1 5A 5 0 0 81 ] type of device is digital thermometer ds18b20, up to 12 bit resolution
    Device #1 address is [ 28 BA F2 5A 5 0 0 5 ] type of device is digital thermometer ds18b20, up to 12 bit resolution
    Device #2 address is [ 28 A3 98 5A 5 0 0 64 ] type of device is digital thermometer ds18b20, up to 12 bit resolution
    That's all list of online devices




    Код SD card shield (взят там же на Хабре):



    #include <SD.h>

    File myFile;

    void setup()
    {
    Serial.begin(9600);
    Serial.print("Initializing SD card...");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    // Note that even if it's not used as the CS pin, the hardware SS pin
    // (10 on most Arduino boards, 53 on the Mega) must be left as an output
    // or the SD library functions will not work.
    pinMode(10, OUTPUT);

    if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
    }
    Serial.println("initialization done.");

    // открываем файл. заметте, что только один файл может быть открыт за раз,
    // поэтому вы должны закрыть этот, чтобы открыть другой.
    myFile = SD.open("test.txt", FILE_WRITE);

    // если файл нормально открылся, запишем в него:
    if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // закрываем файл:
    myFile.close();
    Serial.println("done.");
    } else {
    // а если он не открылся, то печатаем сообщение об ошибке:
    Serial.println("error opening test.txt");
    }

    // откроем файл снова, для чтения:
    myFile = SD.open("test.txt");
    if (myFile) {
    Serial.println("test.txt:");

    // читаем из файла, пока не достигнем конца файла:
    while (myFile.available()) {
    Serial.write(myFile.read());
    }
    // закрываем файл:
    myFile.close();
    } else {
    // а если не открылся, то пишем об ошибке:
    Serial.println("error opening test.txt");
    }
    }

    void loop()
    {
    // больше делать нечего, но тут мог бы быть ваш код
    }




    Отработка:



    Initializing SD card...initialization done.
    Writing to test.txt...done.
    test.txt:
    testing 1, 2, 3.




    Мой код:



    //использую буржуйскую библиотеку OneWire для работы с датчиками температур
    #include <OneWire.h>
    #include <SD.h>

    //линия OneWire у меня висит на пине 9 Ардуинки

    OneWire ds(9);

    //мне понадобятся следующие глобальные переменные и массивы
    int HighByte, LowByte, TReading, Tc_100;
    byte i=0,devicenum=0,k=0,j=0,s=0,tempdata[12],address[8],addressmap[10][8];
    String devicetype[10];
    File myFile;


    //функция настройки при запуске

    void setup(void)
    {
    Serial.begin(9600);

    /*пока поиск адресов дает true, ищу адреса и записываю в матрицу из 10 строк,
    таким образом в своем стенде использую до 10 датчиков*/
    while (ds.search(address)){
    for ( i = 0; i < 8; i++) addressmap[k]=address;
    k=k+1;
    }
    //запоминаю количество найденных устройств на шине 1-Wire
    devicenum = k-1;

    /*для каждого устройства расшифровываю байт, означающий тип и
    пишу в отдельную матрицу из десяти элементов типа string*/
    for (k=0; k<=devicenum; k++) {
    switch (addressmap[k][0]) {
    case 16: devicetype[k]="digital thermometer ds1820 (ds1920) series"; break;
    case 32: devicetype[k]="4-channel 16 bit analog->digital converter"; break;
    case 34: devicetype[k]="digital thermometer ds1822"; break;
    case 40: devicetype[k]="digital thermometer ds18b20, up to 12 bit resolution"; break;
    default: devicetype[k]="unknoun 1-Wire device"; break;
    }
    }
    //адреса и типы всех найденных устройств вывожу на печать
    for( k = 0; k <= devicenum; k=k+1) {
    Serial.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
    for( i = 0; i < 8; i=i+1) {
    Serial.print(addressmap[k], HEX);
    Serial.print(" ");
    }
    Serial.print(']'); Serial.print(" type of device is "); Serial.println(devicetype[k]);
    }
    Serial.println("That's all list of online devices");



    Serial.print("Initializing SD card...");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    // Note that even if it's not used as the CS pin, the hardware SS pin
    // (10 on most Arduino boards, 53 on the Mega) must be left as an output
    // or the SD library functions will not work
    pinMode(10, OUTPUT);

    if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
    }
    Serial.println("initialization done.");
    // открываем файл. заметте, что только один файл может быть открыт за раз,
    // поэтому вы должны закрыть этот, чтобы открыть другой

    myFile = SD.open("test.txt", FILE_WRITE);

    // если файл нормально открылся, запишем в него:
    if (myFile) {
    // Вывожу в консоль сообщение о записи всех найденных датчиков в файл
    Serial.print("Запись массива датчиков в файл test.txt");

    for( k = 0; k <= devicenum; k=k+1) {
    myFile.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
    for( i = 0; i < 8; i=i+1) {
    myFile.print(addressmap[k], HEX);
    myFile.print(" ");
    }
    myFile.print(']'); myFile.print(" type of device is "); myFile.println(devicetype[k]);
    }
    myFile.println("That's all list of online devices");

    // Вывожу в консоль сообщение о записи данных с датчиков в файл
    Serial.print("Запись данных с датчиков в файл test.txt");
    // Серия из 12 измерений
    for( s = 0; s < 12; s=s++) {
    for( k = 0; k <= devicenum; k=k+1) {
    for(i=0;i<8;i++) address=addressmap[k];
    ds.reset();
    ds.select(address);
    ds.write(0x44,1); // запускаем конвертацию

    delay(1000); // скорее всего достаточно 750ms
    // we might do a ds.depower() here, but the reset will take care of it.
    ds.select(address);
    ds.write(0xBE); // считываем ОЗУ датчика
    for ( j = 0; j < 9; j++) { // обрабатываем 9 байт
    tempdata = ds.read();
    // высчитываем температуру :)
    LowByte = tempdata[0];
    HighByte = tempdata[1];
    TReading = (HighByte << 8) + LowByte;
    Tc_100 = TReading/16;
    }
    myFile.print(" T = ");myFile.print(Tc_100);myFile.println(" C");
    }
    delay (5000);
    Serial.println("Жду 5 секунд до следующей серии измерений");
    }
    myFile.close();
    Serial.println("Готово");
    }
    // если он не открылся, то печатаем сообщение об ошибке:
    else Serial.println("error opening test.txt");
    }
    void loop(void)
    { }



    Отработка:



    Device #0 address is [ 28 8C A1 5A 5 0 0 81 ] type of device is digital thermometer ds18b20, up to 12 bit resolution
    Device #1 address is [ 28 BA F2 5A 5 0 0 5 ] type of device is digital thermometer ds18b20, up to 12 bit resolution
    Device #2 address is [ 28 A3 98 5A 5 0 0 64 ] type of device is
    That's all list of online devices
    Initializing SD card...initialization done.
    error opening test.txt

    Обратите внимание, не дописался тип третьего датчика, не открыт файл ну и соответственно в него не записаны измерения.
    Буду рад вашей помощи!
     
  2. ALev

    ALev Гик

    При попытке собрать Ваш пример компилятор ругается на эту строчку:
    Код (Text):
    for ( i = 0; i < 8; i++) addressmap[k]=address;
    И правильно делает, т.к. присваивать один массив другому в Си++ нельзя.
    Какую версию Arduino IDE вы используете?
     
  3. KarDen

    KarDen Нуб

    Ух, виноват, не проверил пост на ошибки. Ctrl+C и Ctrl+V поменяли программу до неузнаваемости.
    У меня Arduino IDE 1.0.5-r2
     
  4. KarDen

    KarDen Нуб

    Код (Text):
    for ( i = 0; i < 8; i++) addressmap[k][i]=address[i];
    Все понятно, поле код не ставил. Сейчас выложу свой скетч
     
  5. KarDen

    KarDen Нуб

    Код (Text):
    //использую буржуйскую библиотеку OneWire для работы с датчиками температур
    #include <OneWire.h>
    #include <SD.h>

    //линия OneWire у меня висит на пине 9 Ардуинки

    OneWire ds(9);

    //мне понадобятся следующие глобальные переменные и массивы
    int HighByte, LowByte, TReading, Tc_100;
    byte i=0,devicenum=0,k=0,j=0,s=0,tempdata[12],address[8],addressmap[10][8];
    String devicetype[10];
    File myFile;


    //функция настройки при запуске

    void setup(void)
    {
      Serial.begin(9600);
     
    /*пока поиск адресов дает true, ищу адреса и записываю в матрицу из 10 строк,
    таким образом в своем стенде использую до 10 датчиков*/
    while (ds.search(address)){
    for ( i = 0; i < 8; i++) addressmap[k][i]=address[i];
    k=k+1;
    }
    //запоминаю количество найденных устройств на шине 1-Wire
    devicenum = k-1;

    /*для каждого устройства расшифровываю байт, означающий тип и
    пишу в отдельную матрицу из десяти элементов типа string*/
    for (k=0; k<=devicenum; k++) {
      switch (addressmap[k][0]) {
      case 16: devicetype[k]="digital thermometer ds1820 (ds1920) series"; break;
      case 32: devicetype[k]="4-channel 16 bit analog->digital converter"; break;
      case 34: devicetype[k]="digital thermometer ds1822"; break;
      case 40: devicetype[k]="digital thermometer ds18b20, up to 12 bit resolution"; break;
      default: devicetype[k]="unknoun 1-Wire device"; break;
                                }
                                }
    //адреса и типы всех найденных устройств вывожу на печать
    for( k = 0; k <= devicenum; k=k+1) {
    Serial.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
      for( i = 0; i < 8; i=i+1) {
        Serial.print(addressmap[k][i], HEX);
        Serial.print(" ");
                                }
        Serial.print(']'); Serial.print(" type of device is "); Serial.println(devicetype[k]);
                                      }
        Serial.println("That's all list of online devices");


     
    Serial.print("Initializing SD card...");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    //  Note that even if it's not used as the CS pin, the hardware SS pin
    //  (10 on most Arduino boards, 53 on the Mega) must be left as an output
    //  or the SD library functions will not work
    pinMode(10, OUTPUT);

      if (!SD.begin(10)) {
        Serial.println("initialization failed!");
        return;
      }
      Serial.println("initialization done.");
    // открываем файл. заметте, что только один файл может быть открыт за раз,
    //  поэтому вы должны закрыть этот, чтобы открыть другой
       
      myFile = SD.open("test.txt", FILE_WRITE);
     
      // если файл нормально открылся, запишем в него:
      if (myFile) {
      // Вывожу в консоль сообщение о записи всех найденных датчиков в файл
      Serial.print("Запись массива датчиков в файл test.txt");
     
    for( k = 0; k <= devicenum; k=k+1) {
    myFile.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
      for( i = 0; i < 8; i=i+1) {
      myFile.print(addressmap[k][i], HEX);
      myFile.print(" ");
                                }
        myFile.print(']'); myFile.print(" type of device is "); myFile.println(devicetype[k]);
                                      }
        myFile.println("That's all list of online devices");
       
    // Вывожу в консоль сообщение о записи данных с датчиков в файл
      Serial.print("Запись данных с датчиков в файл test.txt");
    // Серия из 12 измерений
    for( s = 0; s < 12; s=s++) {
        for( k = 0; k <= devicenum; k=k+1) {
          for(i=0;i<8;i++) address[i]=addressmap[k][i];
      ds.reset();
      ds.select(address);
      ds.write(0x44,1);        // запускаем конвертацию
     
      delay(1000);    // скорее всего достаточно 750ms
      // we might do a ds.depower() here, but the reset will take care of it.
        ds.select(address);  
      ds.write(0xBE);        // считываем ОЗУ датчика
      for ( j = 0; j < 9; j++)  { // обрабатываем 9 байт
        tempdata[i] = ds.read();
        // высчитываем температуру :)
      LowByte = tempdata[0];
      HighByte = tempdata[1];
      TReading = (HighByte << 8) + LowByte;
      Tc_100 = TReading/16;
                                  }
      myFile.print(" T = ");myFile.print(Tc_100);myFile.println(" C");
                                            }
      delay (5000);
      Serial.println("Жду 5 секунд до следующей серии измерений");
                                }
        myFile.close();
        Serial.println("Готово");
                  }
      // если он не открылся, то печатаем сообщение об ошибке:
      else Serial.println("error opening test.txt");
    }
    void loop(void)
    {

    }