Arduino Due + Ethernet шилд + SD карта: странная проблема.

Vadim111
Offline
Зарегистрирован: 14.01.2015

Раньше работал с UNO, как с веб сервером. Но понадобилось выводить более крупные веб страницы и применять больше скриптовой обработки. Решил купить DUE. Купил китайца. Проверил надписи на чипах, все, вроде ды, соответствует. (Если важно, то это SainSmart.com). Специально для UNO скачал последнюю версию IDE - 1.6.4 (до этого пользовался совсем старой версией еще 1.0...)

Начал с самого элементарного: Залил пример скетча для веб сервера (из примеров) - работает. Залил скетч для работы с SD картой и файлами на ней - работает. Попытался совместить эти два элементарных действия, т.е. в скетче при обращении к серверу выводить файл с карточки. Не работает. Глючит жестко - и пинги пропадают, и карточка совсем не инициализируется.

Но самое непонятное в другом: После заливки своей (пускай глючной) программы я пытаюсь залить заведомо рабочие и проверенные скетчи из примеров. Они тоже перестают работать. Нажатие кнопок Ресет в любых сочетаниях, и на Ардуине, и на шилде, и до заливи, и после не помогает. Хотя плата, вроде бы, адекватно, как положено, реагирует на сброс. Но если я отключу питание с платы, а потом опять включу, то все начинает работать, как с чистого листа, до того момента, пока я не залью свой скетч. После этого опять не работает ничего.

Т.е. получается, что тут какая-то комплексная проблема: во-первых, плата отказывается работать с двумя устройствами сразу (ethernet-ом и карточкой), а во-вторых, она, получается, не перегружается полностью при ресете?

(для информации: с другими, более простыми примерами, как-то мигание диодом и пр. проблем с работой платы не замечал)

Понимаю, что проблема сложная, но может быть кто-нибудь сможет помочь советом? Буду очень признателен.

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Карту правильно инициализируете?

Шилды совместимы с DUE (три вольта)?

Учитываете, что логика трехвольттовая7

Vadim111
Offline
Зарегистрирован: 14.01.2015

Gippopotam пишет:

Карту правильно инициализируете?

Шилды совместимы с DUE (три вольта)?

Учитываете, что логика трехвольттовая7

1. Карту инициализирую программно. Подключаю библитеку и пишу соответствующий код.

2. Питание ethernet 5100 изначально 3,3V. Т.е. что с UNO, что с DUE он работает одинаково.

3. Нет, этого не учел. Точнее: согласно даташиту за связь именно с SD картой отвечает пин 4. Из 5-и вольтовой UNO на 3-х вольтовый шилд в 4 пине подавался именно 5-и вольтовый сигнал (остальные пины SPI не беру во внимание). Раньше об этом не задумывался, хотя это, вроде бы как, несоответствие. Теперь из DUE на тот же 4 пин идет 3 вольтовый сигнал. Может быть 3-х вольт мало? Но ведь ethernet шилд 3-х вольтовый. Как же тогда соединить DUE и ethernet шилд?

4. По-прежнему смущает то, что на примерах из библиотек все работает замечательно, а для полного сброса плат надо отключать питание.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

"угадайка" - это конечно прикольно, но если вы дадите посмотреть на код - будет продуктивней.

Какой размер флешки?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

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

Vadim111
Offline
Зарегистрирован: 14.01.2015

Большое спасибо всем ответившим, но проблема только усугубилась.

Gippopotam пишет:

"угадайка" - это конечно прикольно, но если вы дадите посмотреть на код - будет продуктивней.

Какой размер флешки?

Флешка на 2 Гига. Спереди написано MicroSD, сзади -  производство Тайвань и номера. Возможно, какой-то китайский подвальный цех, но эта флешка успешно отработала с GoPro камерой и отлично работает при выводе Веб страниц с UNO. Других флешек меньше 64 Гиг пока под рукой нет.

Прилагаю код, который состоит из двух стандартных IDE-шных примеров.

В функции Setup есть закомментированная часть кода. Если я заливаю скетч, где эта часть закомментирована, то sd карта даже не инициализируется, веб сервер не пингуется. Если я раскомментирую эту часть, а после заливки скетча произведу сброс путем отключения питания с платы, то плата выводит указанную страницу (на странице всего два тега), т.е. начинает работать.

Подобное поведение платы меня вообще ввело в ступор. Как эта часть кода в setup-е может влиять на работу скетча? К тому же, подобные пляски с бубном после заливки скетча очень смущают.

(Пробовал заливать другие старые личные скетчи, без работы с веб, все работает. Т.е. придраться к работоспособности платы пока не могу.

// Подключение библиотек.
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

// Стандартные параметры для Веб сервера.
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);

// Переменная для работы с файлами.
File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  
  Serial.print("Initializing SD card...");

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

//  if (SD.exists("example.txt")) {
//    Serial.println("example.txt exists.");
//  }
//  else {
//    Serial.println("example.txt doesn't exist.");
//  }
//
//  // open a new file and immediately close it:
//  Serial.println("Creating example.txt...");
//  myFile = SD.open("example.txt", FILE_WRITE);
//  myFile.close();
//
//  // Check to see if the file exists:
//  if (SD.exists("example.txt")) {
//    Serial.println("example.txt exists.");
//  }
//  else {
//    Serial.println("example.txt doesn't exist.");
//  }
//
//  // delete the file:
//  Serial.println("Removing example.txt...");
//  SD.remove("example.txt");
//
//  if (SD.exists("example.txt")) {
//    Serial.println("example.txt exists.");
//  }
//  else {
//    Serial.println("example.txt doesn't exist.");
//  }
  if (SD.exists("index.htm")) {
    Serial.println("index.htm exists.");
  }
  else {
    Serial.println("index.htm doesn't exist.");
  }
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
            //Стандартный заголовок html.
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            client.println();
            // Открываем нужный файл.
            myFile = SD.open("index.htm");
            if (myFile) {
                Serial.println("WebFile open.");
                //Читаем данные из файла.
                while(myFile.available()) {
                    client.write(myFile.read());
                }
                //Закрываем файл.
                myFile.close();
                Serial.println("WebFile close.");
            }
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

 

Vadim111
Offline
Зарегистрирован: 14.01.2015

Puhlyaviy пишет:
Проблема не странная. Уже обсуждали не раз. хотите что бы работало одновременно правильно инициализируйте spi для каждого устройства. а если по очереди, то не забывайте выключать одно перед обращением ко второму.

Простите, но я перерыл все по поиску "ethernet SD card" ничего подобного не нашел. О какой-то особенной инициализации spi раздельно для карты и веб слышу впервые. Все примеры, которые успешно работали с UNO ничего подобного, вроде бы, не требовали.

Не могли бы вы или в общих чертах описать, как это делается, или дать ключевые слова для поиска. В каких темах это обсуждалось? По слову "spi" найти что-то трудно. Буду очень признателен.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Вы вообще в курсе что DUE это ARM , тоесть вообще другая архитектура :) хотя и UNO есть второй SPI, но в ардуино он не реализован.

void setup(){
// initialize the bus for a device on pin 4
SPI.begin(4);
// initialize the bus for a device on pin 10
SPI.begin(10);
}

Vadim111
Offline
Зарегистрирован: 14.01.2015

Puhlyaviy!

Громадное спасибо!

Все заработало. Даже не думал, что две строчки кода могут привести к такому непредсказуемому поведению платы. Заинтересовало другое: с DUE веб страница грузится (по ощущениям) раза в 4 медленнее, чем с UNO. Ожидал противоположное, но это вообще не вопрос, т.к. речь идет о секундах. Главное, что все работает стабильно.

На всякий случай более подробно опишу свой опыт:

Когда я работал с UNO (а также с NANO и PRO mini) то Ethernet шилд не требовал к себе особого внимания. Один и тот же код я мог использовать и для загрузки страницы из скетча и с SD карты. При этом, если карта торчала, но не использовалась, это никак не сказывалось на работе всей схемы.

С DUE надо поступать более аккуратно.

Если надо работать и с Веб, и с картой, то надо принудительно инициализировать шину на 4 пине для карточки и на 10 пине для Веб, что и указано в коде, приведенном Puhlyaviy.

void setup(){
// initialize the bus for a device on pin 4
SPI.begin(4);
// initialize the bus for a device on pin 10
SPI.begin(10);
}

Т.е. надо добавить эти 2 строчки кода, а весь остальной скетч можно не трогать.

Более подробно об этом нашел здесь:

http://www.arduino.cc/en/Reference/SPI

и здесь:

http://www.arduino.cc/en/Reference/DueExtendedSPI

 

Если в Е-шилде торчит карточка, но не используется, то в Setup обязательно надо прописывать:

void setup(){

pinMode(4, OUTPUT);

digitalWrite(4, HIGH);
}

 

И еще нашел (в этом до конца не уверен), если в Ардуине торчит Ethernet шилд, но тоже не используется (отключен от сети), то лучше прописать:

void setup(){

pinMode(10, OUTPUT);

digitalWrite(10, HIGH);
}

Еще раз: всем большое спасибо!

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Всё. Лету в этом году пиндец! Отменяется лето... уже второе спасибо за месяц... раньше вот уходили тихо в туман и с погодой было все хорошо, а как только спасибо так сразу и снег в мае по колено.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Gippopotam пишет:

Карту правильно инициализируете?

...

Vadim111 пишет:

1. Карту инициализирую программно. Подключаю библитеку и пишу соответствующий код.

Vadim111 пишет:

Все заработало. Даже не думал, что две строчки кода могут привести к такому непредсказуемому поведению платы.

удручает...

 

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Gippopotam пишет:

Gippopotam пишет:

Карту правильно инициализируете?

...

Vadim111 пишет:

1. Карту инициализирую программно. Подключаю библитеку и пишу соответствующий код.

Vadim111 пишет:

Все заработало. Даже не думал, что две строчки кода могут привести к такому непредсказуемому поведению платы.

удручает...

 

 


вот не лень было собирать, привыкнешь :) он же ушел и так и не понял что код у него кривой, а это просто костыль.

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

 

Гыгы а я карту инициализирую аппаратно- достаю из слота и вызывают духа-инициализатора)ксатит, у меня остался ещё один инициатива томский бубен. Могу отдать. Лицензионный.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Yarik.Yar пишет:

 

Гыгы а я карту инициализирую аппаратно- достаю из слота и вызывают духа-инициализатора)ксатит, у меня остался ещё один инициатива томский бубен. Могу отдать. Лицензионный.


Я бубны только у индейских шаманов беру. Дорого. Но красивые и главное 100% гарантия результата.

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Слющай, да. ти фирму не аскарбляй! Индусския бубны! Сам Аллах заклинал!

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Yarik.Yar пишет:

Слющай, да. ти фирму не аскарбляй! Индусския бубны! Сам Аллах заклинал!


Слышал про шамана Штопаный Мануал? Вот он лично эти бубны подписывает!

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

А я мануала как накурюсь, так всё подписать могу! Что мне твой шаманишко!

У меня есть помощник - Дряхлый Даташит, он со мной курит!

Vadim111
Offline
Зарегистрирован: 14.01.2015

Puhlyaviy пишет:

он же ушел и так и не понял что код у него кривой, а это просто костыль.

Простите, это адресовано мне?

У меня, конечно, есть небольшой опыт по написанию программ, типа, Hellow world, но Била Гейтса я из себя никогда не изображал. :-)

Код, который я выложил - это полная копия библиотечных примеров Arduino IDE. Посмотрите, если не верите. Еще, при изучении работы с шилдом, руководствовался статьей:

http://startingelectronics.com/tutorials/arduino/ethernet-shield-web-server-tutorial/basic-web-server/

Других ресурсов, разжевывающих все так подробно, просто нет, а написать что-то более совершенное, чем IDE-шные примеры - это уж слишком круто для 90% энтузиастов, работающих с Ардуино.

Если в коде действительно есть ошибка, просьба указать, где именно и какой вариант более правильный. Уверен, для многих подобное замечание будет очень полезным.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Примеры написаны для одной железки. Никто не гарантирует что при подключении вязанки, Примеры будут работать.
Тем более когда железо висит на одной шине, аля куча абонентов на одном телефоном проводе. Изучайте матчасть. Скучно по 57 разу обьяснять.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Vadim, как ваши опыты с due ?