Архив рубрики: arduino

Управление реле Arduino из 1с

В продолжение вот этого. Если у arduino есть ethernet шиелд, то ей вполне можно управлять даже из 1С. Например Реле питания.

&НаКлиенте
Функция ФункцияВосстановления(Свойство, Значение, ДополнительныеПараметры) Экспорт
   Если Свойство = "ДатаJSON"Тогда
      Возврат ПрочитатьДатуJSON(Значение, ФорматДатыJSON.ISO);
   КонецЕсли;
   Если Свойство = "СтрокаJSON" Тогда
      Возврат СокрЛП(Значение);
   КонецЕсли;
   Если Свойство = "uidJSON" Тогда
      Возврат Новый УникальныйИдентификатор(Значение);
   КонецЕсли;
КонецФункции

&НаКлиенте
Процедура СчитатьСтатус(Команда)
		файл=новый чтениетекста("http://"+этаформа.Объект.ИП+"/");
		фф=файл.Прочитать();
		файл.Закрыть();
		фф=стрзаменить(фф,"<!DOCTYPE HTML>","");
		тЧтение=Новый ЧтениеJson;
		тЧтение.УстановитьСтроку(фф);
		тДанные = ПрочитатьJSON(тЧтение, Ложь, , , "ФункцияВосстановления", ЭтотОбъект);
		пинсстат=тДанные.pinsstatus;			
		к=0;
		для каждого стат из пинсстат цикл			
			к=к+1;
			если к=1 и стат=1 тогда этаформа.Объект.Реле1=Истина иначе этаформа.Объект.Реле1=ложь;конецесли;
			если к=2 и стат=1 тогда этаформа.Объект.Реле2=Истина иначе этаформа.Объект.Реле3=ложь;конецесли;
			если к=3 и стат=1 тогда этаформа.Объект.Реле3=Истина иначе этаформа.Объект.Реле4=ложь;конецесли;
			если к=4 и стат=1 тогда этаформа.Объект.Реле4=Истина иначе этаформа.Объект.Реле4=ложь;конецесли;
		конеццикла;		
   		тЧтение.Закрыть(); 		
		этаформа.Объект.жсон=фф;

КонецПроцедуры

&НаКлиенте
Процедура СчитатьСтатус(Команда)
		файл=новый чтениетекста("http://"+этаформа.Объект.ИП+"/");
		фф=файл.Прочитать();
		файл.Закрыть();
		фф=стрзаменить(фф,"<!DOCTYPE HTML>","");
		тЧтение=Новый ЧтениеJson;
		тЧтение.УстановитьСтроку(фф);
		тДанные = ПрочитатьJSON(тЧтение, Ложь, , , "ФункцияВосстановления", ЭтотОбъект);
		пинсстат=тДанные.pinsstatus;			
		к=0;
		для каждого стат из пинсстат цикл			
			к=к+1;
			если к=1 и стат=1 тогда этаформа.Объект.Реле1=Истина иначе этаформа.Объект.Реле1=ложь;конецесли;
			если к=2 и стат=1 тогда этаформа.Объект.Реле2=Истина иначе этаформа.Объект.Реле3=ложь;конецесли;
			если к=3 и стат=1 тогда этаформа.Объект.Реле3=Истина иначе этаформа.Объект.Реле4=ложь;конецесли;
			если к=4 и стат=1 тогда этаформа.Объект.Реле4=Истина иначе этаформа.Объект.Реле4=ложь;конецесли;
		конеццикла;		
   		тЧтение.Закрыть(); 		
		этаформа.Объект.жсон=фф;

КонецПроцедуры

Управление питанием при помощи Arduino. Часть третья.

В продолжение части 1 и части 2. выкладываю электрическую схему по подключению. Любезно предоставлено Фёдоровым Александром, далее текст и схемы — его.

Для осуществления развязки по питанию блока релле и основной платы Arduino, а также возможности прошивки через USB без включения внешнего питания рекомендуется подача рабочего питания +5V во внутреннюю линию 5V после преобразователя IC1 через внешний диод (чтобы при питании от USB питание не попадало на блок релле и внешний блок питания). Блок релле также желательно подключать через диод для предотвращения проникновения обратных бросков с блока релле в цепь питания Arduino, при этом перемычка питания блока релле должны быть снята. Небольшое занижение питания за счет диодного перехода до 4.5V не влияет на работу блоков Arduino т.к. сам CPU этих плат запитывается через преобразователь «3.3V» (IC6) имеющий низки параметр минимального падения напряжения около 0.28V, что позволяет запитывать плату даже от 3.7 V

 

 

 

 

Запитка обмоток блока релле непосредственно с контактов питания Arduino не рекомендуется, т.к. встроенные преобразователи напряжения слаботочные (ток не более 1А) и их с натяжкой хватает для запитки самих плат Arduino! Также в цепи штатного разъема под внешнее питание присутствует слаботочный защитный диод D1, который также не расчитан на большие токи!

Arduino+EthernetShield+реле управления питанием

Для решения задачи управления розетками было принято решение разработать сиё на основе Arduino.  Самый простой способ = самый надежный. Будем управлять по протоколу http. Для этого на ардулине придется «поднять» мини web сервер, который единственно на что способен : 1) принимать запрос и выполнять его 2) Отправлять в json формате информацию о статусе реле. Дополнительно в скетче использовалась библиотека TextFinder, для выделения параметров запроса GET.

Скетч:

#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, легко нарисовать «Веб морду».

 

Программный reset для Arduino Mega

Увы.. Работа Arduino Mega с сетевой картой оказалась не очень стабильной. Время от времени карта «зависает» и спасает только ресет всего устройства. Для того чтобы сделать «reset» есть два пути: 1) Подать на pin reset напряжение 2) Воспользоваться библиотекой /avr/wdt.h
Мы пойдем вторым путем..

#include <avr/wdt.h>

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