Официальный сайт компании Arduino по адресу arduino.cc
Ethernet shield c sd картой. Не пишет на карту.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Arduino UNO + Ethernet shield c sd картой (W5100). Подключен датчик температуры DS18b20, программа ведет себя не корректно, не пишет на карту и веб сервер отказывается работать. Если из кода убрать все что связанно с работой sd карты, то все нормально, температура вычисляется и веб сервер ее отображает. Помогите найти ошибку в скече, в части работы с картой.
Скеч компилится но в COM порт выводит следующее:
10.250.23.91
R=28 F2 A0 D7 2 0 0 F9 Device is a DS18B20 family device.
P=1 B2 1 4B 46 7F FF E 10 8C CRC=8C
TemperatureDS: 27.12 C
Maximum 27.12 *C
error opening index.txt
client disonnected
×R=28 F2 A0 D7 2 0 0 F9 Device is a DS18B20 family device.
P=1 B2 1 4B 46 7F FF E 10 8C CRC=8C
TemperatureDS: 27.12 C
error opening index.txt
client disonnected
×R=28 F2 A0 D7 2 0 0 F9 Device is a DS18B20 family device.
P=1 B3 1 4B 46 7F FF D 10 9A CRC=9A
TemperatureDS: 27.18 C
.18 *C
error opening index.txt
client disonnected
×R=28 F2 A0 D7 2 0 0 F9 Device is a DS18B20 family device.
P=1 B3 1 4B 46 7F FF D 10 9A CRC=9A
TemperatureDS: 27.18 C
error opening index.txt
client disonnected
/* Web Server A simple web server that shows the value of the analog input pins. using an Arduino Wiznet Ethernet shield. Circuit: * Ethernet shield attached to pins 10, 11, 12, 13 * Analog inputs attached to pins A0 through A5 (optional) created 18 Dec 2009 by David A. Mellis modified 9 Apr 2012 by Tom Igoe */ #include <SPI.h> #include <Ethernet.h> #include <OneWire.h> #include <SD.h> #define DS18S20_ID 0x10 #define DS18B20_ID 0x28 File myFile; // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(10,250,23,91); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); OneWire ds(14); // датчик ds18b20 pin на 8 входе Ардуино byte i; byte present = 0; byte data[12]; byte addr[8]; //константы // On the Ethernet Shield, CS is pin 4. Note that even if it's not // used as the CS pin, the hardware CS pin (10 on most Arduino boards, // 53 on the Mega) must be left as an output or the SD library // functions will not work. const int chipSelect = 4; int timer =0; // Задаём начальное время (точку отсчёта) int val = 0; // переменная для хранения значения датчика жидкости int HighByte, LowByte, Whole, SignBit, Fract, TReading, Tc_100, HighTemp, Fast; int Max, MFract; //переменная для хранения значения максимальной температуры void setup() { Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } 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(4)) { Serial.println("initialization failed!"); // return; } Serial.println("initialization done."); if (SD.exists("index.txt")) { Serial.println("index.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."); //} //****************конец открытия и тестирования файла //} { // start the Ethernet connection and the server: Ethernet.begin(mac, ip); // инициализация Ethernet-модуля server.begin(); // запускаем сервер Serial.print("server is at "); Serial.println(Ethernet.localIP()); } } //} //проверить кол во скобок в строке проверки существования файла void loop() { //******************************************* if ( !ds.search(addr)) { Serial.print("No more addresses.\n"); ds.reset_search(); //сброс датчика температуры return; } Serial.print("R="); for( i = 0; i < 8; i++) { Serial.print(addr[i], HEX); Serial.print(" "); } if ( OneWire::crc8( addr, 7) != addr[7]) { Serial.print("CRC is not valid!\n"); return; //сброс датчика температуры } if ( addr[0] == 0x10) { Serial.print("Device is a DS18S20 family device.\n"); } else if ( addr[0] == 0x28) { Serial.print("Device is a DS18B20 family device.\n"); } else { Serial.print("Device family is not recognized: 0x"); Serial.println(addr[0],HEX); return; } ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad Serial.print("P="); Serial.print(present,HEX); Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print( OneWire::crc8( data, 8), HEX); Serial.println(); LowByte = data[0]; HighByte = data[1]; HighTemp = data[2]; TReading = (HighByte << 8) + LowByte; SignBit = TReading & 0x8000; // test most sig bit if (SignBit) // negative { TReading = (TReading ^ 0xffff) + 1; // 2's comp } Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 Whole = Tc_100 / 100; // separate off the whole and fractional portions Fract = Tc_100 % 100; Serial.print("TemperatureDS: "); if (SignBit) // If its negative { Serial.print("-"); } Serial.print(Whole); Serial.print("."); if (Fract < 10) { Serial.print("0"); } Serial.print(Fract); Serial.print(" C"); Serial.print("\n"); //delay(1000);//не знаю нужно ли //*****вычисление максимального значения температуры***** if (Max < Whole) { Max=Whole; Serial.print("Maximum "); Serial.print(Max); } if (MFract < Fract) { MFract=Fract; Serial.print("."); Serial.print(Fract); Serial.println(" *C"); } //****конец вычисления Мах t************* //Коряво отправляет значение t в COM порт //******************************************* //***********начало записи данных на карту*************** timer = timer + 1; myFile = SD.open("index.txt", FILE_WRITE); // если файл нормально открылся, запишем в него: if (myFile) { Serial.print("Writing to index.txt..."); myFile.print(timer); myFile.print("; "); //myFile.println("Temperature: "); myFile.println(Whole); //myFile.println(" *C"); // закрываем файл: myFile.close(); Serial.println("done."); } else { // а если он не открылся, то печатаем сообщение об ошибке: Serial.println("error opening index.txt"); } // delay(1000); //************конец записи данных на карту*************** // 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 you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connnection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); // add a meta refresh tag, so the browser pulls again every 5 seconds: client.println("<meta http-equiv=\"refresh\" content=\"10\">");//Время обновления страницы client.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />"); client.println("</head>"); client.println("<body>"); client.println("<h1> ИСМ-1</h1> <hr /> <br /> <p></p>"); client.println("<h3>Текущая температура : "); client.println(Whole); client.print("."); if (Fract < 10) { client.print("0"); } client.print(Fract); client.println(" C </h3><br />"); client.println("<h3>Максимальная температура: "); client.println(Max); client.print("."); client.print(MFract); client.println(" C</h3><br />"); client.print("<h3>Статус : "); if (Whole > 28) { client.print("Авария! Внимание высокая температура!"); Serial.println("An accident! Account the heat temperature!"); };// Serial.println все это сделать при расчете тепмературы а не здесь!!! if (Whole < 25) {client.print("Авария! Внимание низкая температура!"); Serial.println("An accident! Account the low temperature");}; if ((Whole > 25) && (Whole < 28)) {client.print("Норма"); Serial.println("Normal temperature");}; client.print("</h3><br />"); client.println("</html>"); break; } 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 disonnected"); }
Встроеные примеры работы с картой работают на ура, т.ч. карта и шилд с уно нормальные. При написании своего говно кода))) пользовался следующими примерами
http://arduino.ru/forum/programmirovanie/zapis-dannykh-s-datchika-dht11-...
http://arduino.ru/forum/programmirovanie/ne-smog-naiti-opisaniemanual-po...
Добавьте в 71 строку
Добавил, но не помогло, вывод в ком порт такой же. Странно. но почету то как бы не отрабатывает вот эта часть кода
http://www.arduino.cc/en/Main/ArduinoEthernetShield
Note that because the W5100 and SD card share the SPI bus, only one can be active at a time. If you are using both peripherals in your program, this should be taken care of by the corresponding libraries. If you're not using one of the peripherals in your program, however, you'll need to explicitly deselect it. To do this with the SD card, set pin 4 as an output and write a high to it. For the W5100, set digital pin 10 as a high output.
Я так понял, что одновременно нельзя использовать и веб сервер и слот карты? Я прав? Может кто нибудь пояснить смысл вышенаписанного на нашем родном могучем?
Нельзя одновременно работать и с изернет и с сд, то есть нельзя например подключиться к серверу client.connected() и не отключившись client.stop() работать с SD. Выбор устройств изернет или СД осуществляется низким уровнем CS, у СД это 4 вывод, а у изернет это 10 вывод. Поробуйте добавить еще
digitalWrite(10, HIGH);
в 213 строку.Попытался разобраться как реализовано тут http://www.ladyada.net/learn/arduino/ethfiles.html
Неудачно. Видимо не так уж просто организовать веб сервер и писать данные с датчиков на sd карту.
не работает даже если просто пронициализировать езернет клиент. что делать в таких случаях? прописывать конект в отдель ной функции и вызывать только в нужных случаях и сразу разьеденяться?
В таки случаях как у вас нужно внимательнее читать сообщения выше.
И зачем вообще вот это pinMode(53, OUTPUT); ?
В таки случаях как у вас нужно внимательнее читать сообщения выше.
И зачем вообще вот это pinMode(53, OUTPUT); ?
Подозреваю что приблудилось из какого-то примера для меги. У нее это SS, пин. В нашем случае, по все видимости это должен быть 10-тый пин, ну и digitalWrite(10,LOW) для надежности. И контрльный в голову - pinMode(4,OUTPUT); digitalWrite(4,HIGH) (не помню выставля SD либа его сама или нет. Наверное да, но...).
Ага, только SS инвертирован, наоборот digitalWrite(10, HIGH) и digitalWrite(4, LOW)
http://www.arduino.cc/en/Main/ArduinoEthernetShield
Note that because the W5100 and SD card share the SPI bus, only one can be active at a time. If you are using both peripherals in your program, this should be taken care of by the corresponding libraries. If you're not using one of the peripherals in your program, however, you'll need to explicitly deselect it. To do this with the SD card, set pin 4 as an output and write a high to it. For the W5100, set digital pin 10 as a high output.
Я так понял, что одновременно нельзя использовать и веб сервер и слот карты? Я прав? Может кто нибудь пояснить смысл вышенаписанного на нашем родном могучем?
Прав. Возможно собака именно в этом. Ну так а гугл-транслейт (или лучше словариком по одному слову)?
Вольно: обломитесь с одновременно работой W5100 и SD. Нужно их по очереди включать/выключать. Для W5100 выключает HIGH на 10-том пине, а SD- на 4-том.
То есть
Можно себе сделать помогалки дефайноми, что-бы не путатся кого включили, кого выключили
P.S. А вообще искать решение проблемы в документации - это у вас верная и полезная привычка :)
UPDATE: выключение происходит с помощью установки HIGH уровня, на соотвествующем пине (10- шилда, 4 - SD).
Ага, только SS инвертирован, наоборот digitalWrite(10, HIGH) и digitalWrite(4, LOW)
Ваша правда. Упустил словово " you'll need to explicitly deselect it". Щас поправля свой пост с помогалками.
"дрыганье ногами" не помогает. алгоритм такой: поработал с Ethernet - потом client.stop. переключаю нужные мне пины - результат - "failed" :(
Так покажите как "дрыгаете"...
"дрыганье ногами" не помогает. алгоритм такой: поработал с Ethernet - потом client.stop. переключаю нужные мне пины - результат - "failed" :(
"Не повезло вам". Что еще можно на это ответить?
Вот если вы покажете свой код (как вы дрыгаете), то возможно кто-то и углядит "собаку". Не факт, но шансы появятся.
А еще уточните у вас оригинальный шилд или какой-то китайский клон (есть у них тяга к "креативу" в мелочах, банально могут быть другие пины).
А еще попробуйте все это при питании от внешного блока, а не через USB. Возможно питание "просаживается".
А еще попробуте, после переключения воткнуть какой-нибудь delay(3000); Возможно ему нужно время на то что-бы "заткнутся" (если поможет то потом опытно можно подобрать более "не ощутимые" значения).
так никаких сверхсложных махинация не делалось...вот всё что нужно
delay пробовал после каждого переключения. результат ноль.
PS. подсткажите как код в спойлер прятать
Есть еще у меня такое предположение, что у СД и изэрнет разные режимы SPI.
ЧЁРТ! китайцы падлы! на оригинальном шилде написало "done" сразу, без всяких.
интересно, какие же пины на этом шилде задействованы...?
так никаких сверхсложных махинация не делалось...вот всё что нужно
pinMode(53, OUTPUT); - это какой-то шаманский ритуал от которого никак не избавится прогрессивное человечество ;) ?
Во вторых выставте, все-таки, в setup(), 4 и 10-ть на Output. Должны бибилы и сами это делать, но лишним не будет.
PS. подсткажите как код в спойлер прятать
Зайдите в форум "программирование". Первая прекрепленная ветка "Вставка програмного кода.... " - то что вам нужно.
ЧЁРТ! китайцы падлы! на оригинальном шилде написало "done" сразу, без всяких.
интересно, какие же пины на этом шилде задействованы...?
Может что и "те же". Ищете даташит на него "там где покупали". Если там нет - ищите в других магазинах ЭТОТ же китайский шилд, может там будет. На краняк брать лупу и смотреть/звонит дорожки что куда идет.
А чисто "пример с SD" который у вас работал, на каком пине пробовали? А если поменять на другой перестает работать?
pinMode(53, OUTPUT); - это какой-то шаманский ритуал от которого никак не избавится прогрессивное человечество ;) ?
Поменяйте 53 на 10 и вставте это ПЕРЕД SWITCH_TO_SD, чем черт не шутит, может он на disconnect еще и режим SS на INPUT переключает.
ЧЁРТ! китайцы падлы! на оригинальном шилде написало "done" сразу, без всяких.
Попробуйте с внешним блоком питания (любят китайцы на качестве питания экономить). Попробуйте другую карту
спасибо огромное.
инициализацию перенес в setup теперь всё работает.
спасибо огромное.
инициализацию перенес в setup теперь всё работает.
Аллилуя.
Ну и пиханите итоговый код сюда. Авось кто-то после вас будет с этим же вопросом бится :)
Да Да. Код если не жалко в студию!))) Ибо у меня что-то пока что не клеиться.(
так на самом деле ничего особенного. все было описано выше. главное инициализацию выполнить в setup'e поочередно
По преведенному коду:
SWITCH_TO_ имеет смысл делать ПОСЛЕ pinMode, а не до. Иначе вы уровень пина выставляете, а внутрений подтягивающий резистор включаете/отключаете. Вообщем-то его тоже может хватить, но это зависит от погоды на плюке.
Ну а
pinMode(53, OUTPUT);
это уже анекдот.
Далее ALL_OFF - тут вообще как-бы не нужен. Я привел его для "полноты картины" (мало-ли может вы еще какое-то девайс подцепите на SPI). Это же типа "задизейплитьи SD, и Ethernet".
И если у вас дальше действительно работает readPage(), то возникает сомнение "а нужны ли вообще SWITHC_TO". Вы то дальше, нигде переключений не делаете. ПОльзуетесь в Loop и шилдом и картой. Возможно это уже поправили на уровне самих либ.
Просто хочу скозать спасибо. Не мог справиться с шилдом. При запуске Web-сервера не работал накопитель, я сервер работал нестабильно искажая данные.
С вашей помощью всё поправил. Работает!
А у меня ещё круче: SD карта отсутствует - ethernet работает нормально, вставляю карту - зависает через некоторое время, причём так зависает что ресет не помагает!! приходится отключать питание, после чего опять запускается! И при всём этом в коде sd карту не инициализирую вообще! Кто-нибудь с таким сталкивался ??
А у меня ещё круче: SD карта отсутствует - ethernet работает нормально, вставляю карту - зависает через некоторое время, причём так зависает что ресет не помагает!! приходится отключать питание, после чего опять запускается! И при всём этом в коде sd карту не инициализирую вообще! Кто-нибудь с таким сталкивался ??
а карте пофигу, инциализируете вы ее или нет... она получила питание и начала в шину песни петь... а изернет от такого народного пения просто виснет в шоке..
достаточно образно обьяснил?
понятно....
mega 2560 - SD работает в двух вариантах:
1: pinmode(53, OUTPUT); В этом случае SD работает, Ethernet тоже но не долго - в скором времени все виснет!
2: pinmode(10, OUTPUT); digitalWrite(10, HIGH); Странно - но заработало! пока полёт нормальный
при всем этом все монипуляции с 4 пином не как не влияют на чтение sd и работу ethernet(этот вообще в любом случаее работает даже без всего выше перечисленного)
загадка...
Попробую постучаться сюда же, чтобы темы не плодить.
Есть система управления домом, которая использует карточку постоянно (запись данных, идущих с исполнительных механизмов), а интернет для удаленного управления только когда есть электричество. Когда его нет, система питается от резервной батареи. Чтобы продлить ее жизнь, надо сильно снижать потребление шилда, или попытаться использовать карточку на выключенном шилде. Есть такая возможность?
Джентльмены, добрый день. У меня была проблема, что читало карту через раз, отказывалась писать, и портило содержимое. Мое подозрение оправдалось - не хватало питания. Я на ногу 3.3v модуля Sd карты положил 5вольт. после этого все заработало. Может на пользу будет )
у меня инициализация mega2560+W5100 производится так.
зернет и карточка вместе нормально работают
ТА же самая беда...
mega+w5100. пробовал и родные примеры. и с внешним питанием и с питанием от usb. и у флешек менял ФС. не помогает)
в строке 32 пин 53 - это что? случаем туда не SS от SD карточки подключен?
в строке 32 пин 53 - это что? случаем туда не SS от SD карточки подключен?
53 - тут в каждом примере)
пробовал без него.
оставив только
вы ерунду не пишите... Методом тыка программировать не надо.
Вы разве не знаете, к какому пину что у вас подключено? К каким пинам подключены контакты SS Эзернет модуля и СДкарты? С какой целью в скетче пин 53 описан как выход?
repon - и вообще, прочитайте всю ветку от начала до конца - там все подробно разобрано, в том числе и ошибки в вашем коде
repon - и вообще, прочитайте всю ветку от начала до конца - там все подробно разобрано, в том числе и ошибки в вашем коде
спасибо) с программированием проблем обычно не имею) с железом не работаю)
поэтому ард код пишу по примерам)
тему читал: пины 4 и 10 для вывода описал, залочил 4, 10 включил в setup.
тему читал: пины 4 и 10 для вывода описал, залочил 4, 10 включил в setup.
пины 4 и 10 - это для Уно. А что там на Меге - нужно разобраться. может быть как раз 53
В разных релизах Ethermet.h CS определён по-своему.
Однако не совсем понятно, зачем вручную дергать CS, если библиотека сама с этим неплохо справляется.
стандартный SS пин (53 на меге) ничего не включает, его трогать нельзя и надо объявить как OUTPUT
т.е. так наодо?:
я закоментил строку, чтоб не описывать метод.
тут проблема в том, что не проходит
до лоопа можно не доходить
кто-нибудь видим пути решения ?)
Конечно кто-то видит.
Пишете нормальный код, а не вот этот с самопальным дрыганьем CS когда нужно и ненужно. Разбираетесь с тем, что происходит в Ethernet.h , переконфигурируете, если требуется, соединяете всё проводами, кидаете в коробу, трясёте полчаса, перекладываете в миксер. Обрабатываете пять минут на средней скорости и смываете в унитаз. Впрочем, можете только половину инструкции соблюсти.
кто-нибудь видим пути решения ?)
ну например - создать тему в "Ищу испольнителя", нанять программиста, отправить или оплатить ему покупку такого шилда - и я уверен, что решение будет найдено за пару дней
А в форуме пытаться удаленно разобраться. что вы сделали не так - дело дохлое