Arduino uno + ethernet shield W5100 + 74HC595N в каскаде из 3х
- Войдите на сайт для отправки комментариев
Вс, 31/07/2016 - 18:48
Добрый день.
Недавно начал изучать Arduino.
Построил каскад из 3х 74HC595N - без ethernet shield W5100 работают как надо по коду:
//Пин подключен к ST_CP входу 74HC595 const int latchPin = 8; //Пин подключен к SH_CP входу 74HC595 const int clockPin = 12; //Пин подключен к DS входу 74HC595 const int dataPin = 11; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); } void registerWrite(int whichPin, int whichState) { // для хранения 32 битов используем unsigned int unsigned int bitsToSend[3] = {0,0,0}; // выключаем светодиоды на время передачи битов digitalWrite(latchPin, LOW); // устанавливаем HIGH в соответствующий бит bitWrite(bitsToSend[whichPin/8], whichPin%8, whichState); for(int i = 0; i < 3; i++) shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend[i]); // "защелкиваем" регистр, чтобы биты появились на выходах регистра digitalWrite(latchPin, HIGH); } void loop() { registerWrite(13, HIGH); }
При попытке написать скетч для управления светодиодами через ethernet shield W5100 управление не работает\
#include <SPI.h> #include <Ethernet.h> byte mac[] = {0xDE, 0x24, 0xF7, 0xDD, 0x23, 0x7B}; byte ip[] = {172,17,7,112}; EthernetServer server(80); EthernetClient client; int WAIT = 300; #define bufferMax 128 int bufferSize; char buffer[bufferMax]; String readString = String(128); char post; //Пин подключен к ST_CP входу 74HC595 const int latchPin = 8; //Пин подключен к SH_CP входу 74HC595 const int clockPin = 6; //Пин подключен к DS входу 74HC595 const int dataPin = 7; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); Serial.begin(9600); Serial.println("device is run"); Ethernet.begin(mac, ip); server.begin(); } void registerWrite(int whichPin, int whichState) { // для хранения 16 битов используем unsigned int unsigned int bitsToSend[3] = {0,0,0}; // выключаем светодиоды на время передачи битов digitalWrite(latchPin, LOW); // устанавливаем HIGH в соответствующий бит bitWrite(bitsToSend[whichPin/8], whichPin%8, whichState); for(int i = 0; i < 3; i++) shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend[i]); // "защелкиваем" регистр, чтобы биты появились на выходах регистра digitalWrite(latchPin, HIGH); } void loop() { registerWrite(2, HIGH); EthernetClient client = server.available(); if (client) { // Проверяем подключен ли клиент к серверу while (client.connected()) { char c = client.read(); if (readString.length() < 30) { readString += c; } if (c == '\n') { if(readString.indexOf("p=1") > 0) { Serial.println("device is on"); registerWrite(1, HIGH); registerWrite(5, HIGH); } if(readString.indexOf("p=0") > 0) { Serial.println("device is off"); registerWrite(1, HIGH); registerWrite(2, HIGH); } client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); client.println("<!DOCTYPE html>"); client.println("<html lang=\"ru\">"); client.println("<head>"); client.println("<meta charset=\"UTF-8\">"); client.println("<title>Home</title>"); client.println("</head>"); client.println("<body>"); client.println("Устройство:"); client.println("<br>"); client.println("<a href=\"?p=0\">Выкл</a>"); client.println(" <a href=\"?p=1\">Вкл</a>"); client.println("</body>"); client.println("</html>"); readString=""; client.stop(); } } } }
Помогите разобраться с этим. В какую сторону копать?
Скетч неполный, так Вы сами себе злобный буратино - не нужна помощь, как хотите.
Рискну предположить, что у Вас оба девайса и W5100, и 74HC595N сидят на SPI и подрались между собой либо за пины, либо за master/slave, либо ещё за что-нибудь. Вот туда и копайте.
Евгений, скетч второй поправлю, он с ошибками,
А, вам, спасибо за подсказку. Видимо там конфликт в SPI master\SLAVE
Код у меня сейчас такой:
Так как W5100 и 74HC595N работают по SPI, то правильно я понимаю? что на 74HC595N мне надо передавать в режиме slave?
Они оба слейвы на SPI. Чтобы не разбираться, где они конфликтуют, выносите 74HC595N на свободные пины и делайте софтовый SPI, благо протокол простейший -- подняли ногу SCK -> выставили значение очередного бита на ногу MOSI -> опустили ногу SCK -- передача бита состоялась.
Думаю ваш вариант не подойдет.
У меня основная задача - иметь платформу по подключению большого числа светодиодов, который каждый в отдельности может управляться через POST.
Вообще в идеале нужно открывать файл на удаленном сервере, писать его на SD-карту, а потом уже парся строку из файла подавать биты на различные ножки.
Я понимаю, что задача не тревиальная, но реализовать ее же можно.
Можно узнать, почему?
Софтовый SPI конечно медленнее аппаратного, но зато с выносом туда регистров, можно будет использовать оба интерфейса одновременно. Если же один аппаратный SPI будет использоваться и для связи с шилдом и для передачи данных регистрам, то оба устройства будут получать доступ к интерфейсу по очереди.
Карта тоже по SPI обычно подлкючается. Тогда всем трем устройствам придется ждать друг друга.
Да не сказал бы я, что такая уж нетривиальная.
Бред какой-то...
М/К и так один поток только обрабатывает, тут в любом случае одновременно работать езернет и 74HC595N НЕ БУДУТ В ПРИНЦИПЕ. Разделять устройства на разные пины не нужно. Это может только критично, если одно устройство может вызыватся внутри прерывания в момент, когда идет обращение к другому устройству - только в этом случае может быть коллизия. В данном случае в данной задаче этого нет.
Нужно просто правильно выбирать через CS нужное устройство при обращении к нему.
Что-то я совсем запутался.
Для работы через аппаратный SPI нужно подключать библиотеку и передавать данные через SPI.transfer()
А для программного SPI, что нужно?
Для чего client описан глобально в строке 6 (блин, вставляйте код правильно - как без номеров обсуждать?), а потом в функции loop он же описан локально. Вы понимаете. что он не глобален? и в loop каждый раз новый создаётся?
На сдвиговый регистр Вы всегда передаёте только в режиме master, т.к. именно Вы иницируете передачу. а не сдвиговый регистр - ему-то это зачем?
Я код перепишу и выложу нормальном виде.
А вот по вашему высказыванию
"На сдвиговый регистр Вы всегда передаёте только в режиме master, т.к. именно Вы иницируете передачу. а не сдвиговый регистр - ему-то это зачем?"
можете дать более подробное объяснение?
Переписал код основываясь на исходнике из интернета.
"На сдвиговый регистр Вы всегда передаёте только в режиме master, т.к. именно Вы иницируете передачу. а не сдвиговый регистр - ему-то это зачем?"
можете дать более подробное объяснение?
Ну, если просто ... представьте - двое общаются. Один начинает общение когда ему удобно. А другой - просто ждёт пока к нему обратятся и может ждать бесконечно. Мастер - это тот, кто начинает общение и заканчивает его, а слейв - делает что ему скажут - принимает оосбщения от мастера, выдаёт свои и т.п.
Перед началом общения слейв просто сидит и ждёт пока мастер к нему обратится. Мастер же как раз обращается - начинает беседу.
С этой точки зрения любой сервер - слейв, а клиент - мастер.
В случае с регистром, кто начинает общение, микропроцессор или регистр? КОнечно, микропроцессор - значит он в режиме мастер.