Управление питанием при помощи Arduino . Часть вторая.
Появилось немного фоточек процесса :), в продолжение предыдущего поста
P.S. «Реализация в железе» — не моя.
[Not a valid template]Жизнь замечательных грибов
В этой рубрике собраны статьи с тегом «arduino». Разработка, тестирование, макетирование. Описание железок и способа работы с ними
Появилось немного фоточек процесса :), в продолжение предыдущего поста
P.S. «Реализация в железе» — не моя.
[Not a valid template]Для решения задачи управления розетками было принято решение разработать сиё на основе Arduino. Самый простой способ = самый надежный. Будем управлять по протоколу http. Для этого на ардулине придется «поднять» мини web сервер, который единственно на что способен : 1) принимать запрос и выполнять его 2) Отправлять в json формате информацию о статусе реле. Дополнительно в скетче использовалась библиотека TextFinder, для выделения параметров запроса GET.
Скетч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
#include <SPI.h> #include <Ethernet.h> #include <TextFinder.h> //назначаем МАС и IP byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192,168,1,177); EthernetServer server(80); //на каких ногах переключатели int pinscount=8; int pins[]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; int pins_status[]={LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW}; int command = 0; int setpin=0; int setpinstatus=0; void setup() { Serial.begin(9600); // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); for (int i=0; i < pinscount; i++){ pinMode(pins[i], OUTPUT); }; } void loop(){ EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { TextFinder response(client); if(response.find("GET /")) { if (response.find("command=")) { command = response.getValue(); Serial.println(command); } }; if (command==1) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.print("<!DOCTYPE HTML>"); //Выводим информацию об устройстве client.print("{\"ip\":\""); client.print(Ethernet.localIP()); client.print("\",\"pins\":["); for (int i=0; i < pinscount; i++){ client.print(pins[i]); if (i<pinscount-1){client.print(",");}; }; client.print("],\"pinsstatus\":["); for (int i=0; i < pinscount; i++){ client.print(pins_status[i]); if (i<pinscount-1){client.print(",");}; }; client.print("]}\n"); }; if (command==99){ client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.print("<!DOCTYPE HTML>"); if (response.find("setpin=")) { setpin = response.getValue(); Serial.println(setpin); } if (response.find("setpinstatus=")) { setpinstatus = response.getValue(); Serial.println(setpinstatus); } digitalWrite(pins[setpin], setpinstatus); pins_status[setpin]=setpinstatus; client.print("{\"status\":\"ok\"}\n"); }; client.stop(); } } delay(1); client.stop(); Serial.println("client disonnected"); } } |
Пример запроса на получение статуса розеток:
http://192.168.1.177/?command=1
Пример запроса на переключение реле:
http://192.168.1.177/?command=99&setpin=3&setpinstatus=1
Таким образом, т.к. на выходе JSOIN, легко нарисовать «Веб морду».
Увы.. Работа Arduino Mega с сетевой картой оказалась не очень стабильной. Время от времени карта «зависает» и спасает только ресет всего устройства. Для того чтобы сделать «reset» есть два пути: 1) Подать на pin reset напряжение 2) Воспользоваться библиотекой /avr/wdt.h
Мы пойдем вторым путем..
#include <avr/wdt.h>
1 2 3 4 5 6 7 8 |
void loop() { //если давно не было подключения к интернету, думаем что контроллер завис и ресетим.. if (millis() > fail_timer) { ConsPrint("RESTART ARDUINO..."); wdt_enable(WDTO_15MS); delay(1500); }; ... |
Значения могут быть следующие:
WDTO_15MS
WDTO_30MS
WDTO_60MS
WDTO_120MS
WDTO_250MS
WDTO_500MS
WDTO_1S
WDTO_2S
WDTO_4S
WDTO_8S
,т.е. «назначаем рестарт через столько то времени». Но! Есть еще и возможность успеть сбросить таймер перезапуска : wdt_reset(); или вовсе отменить: wdt_disable();
Используя этот функционал мы например можем сделать следующую логику приложения:
запускаем таймер «ресет через 5 секунд»
запускаем «опасный для зависания код»
если код выполнился — сбрасываем таймер, перезагрузки не будет
если код не выполнился — произойдет автоматическая перезагрузка arduino
Продолжаю героически пилить «Умный дом». На текущий момент сделано: вывод времени, даты, дня недели, погоды на сегодня и завтра, текущей температуры, включение/выключение дисплея по датчику движения.
Не удалось: подружить плату точного времени ds3231 работающую по шине i2C и Ethernet плату ENC28J60 работающую по шине SPI, Пошел какой-то конфликт между платами, разобраться как разрулить не смог. Пришлось время тоже брать с интернета.
Ниже приведен скетч на текущий момент. » Читать далее
Теоретически шина SPI на Arduino позволяет подключать к ней одновременно несколько устройств. Причем активным устройством на текущий момент, для работы скетча будет считаться то устройство, у которого низкий уровень сигнала на пине Cabel Select.
Например, подключаем два устройства к ардуине : SD картридер и сетевой интерфейс на микросхеме enc28j60, по следующей схеме:
Arduino Mega | enc28j60 | SD |
49 (SS, nCS, CS, CSB, CSN, nSS, STE) | CS | |
50 (SCLK, SCK, CLK) | SO | SPI_CLK |
51 (MOSI, SDI, DI, SI) | SI | SPI_MOSI |
52 (MISO, SDO, DO, SO) | SCK | SPI_MISO |
53 (SS, nCS, CS, CSB, CSN, nSS, STE) | SD_CS | |
GND | GND | GND |
5V | VCC | 5V |
Или может быть понятнее рисунок:
Т.е. как мы видим, часть пинов используется совместно, но пины 49 и 53 выделены для управления, для того чтобы скетч и «железка» знали, какое именно устройство в данный момент может передавать данные по общим пинам. Если на управляющем пине низкий уровень напряжения, то скетч и железка считает, что может передавать данные именно та железка, которая подведена к данному пину. Например по моей схеме: если на 49 пине низкий уровень, а на 53 высокий, то работает сетевая карта. И наоборот.
На деле как оказалось конечному пользователю не нужно заморачиватся выставлением уровней на управляющих пинах…если конечно драйвера железок написаны правильно…
Например мой скетч по работе одновременно и с SD и с сетевой картой заработал с полпинка..
Пример скетча: » Читать далее