Arduino + Adobe Flash

alexey_and
Offline
Зарегистрирован: 03.03.2013

кто-нибудь имеет опыт работы с Flash? был бы очень признателен хотя бы минимальному туториалу как нарисовать кнопку во флеше и дергать с ее помощью ноги на ардуине через ethernet

когда-то давно делал флеш-ролики, еще во времена макромедии. сейчас поставил современный флеш и ужаснулся :) пока что там абсолютно всё за гранью моего понимания :) 

Zapek@n
Offline
Зарегистрирован: 16.02.2012

Напрямую наверное никак. Насколько я понимаю флэш не может никаким образом общаться с com портом. Нужно делать промежуточный слой-сервер, который будет принимать команды от флэш и транслировать их через com порт в ардуину.

Zapek@n
Offline
Зарегистрирован: 16.02.2012

Ну или брать какую-нибудь ethernet arduino  и дергать ее через сеть.

alexey_and
Offline
Зарегистрирован: 03.03.2013

Так я и говорю - черeз ethernet

leshak
Offline
Зарегистрирован: 29.09.2011

Ардуине - пофиг кто там на том конце провода. Флеш, javascript или собрали запрос руками в адресной строке браузера. На то он и стандартный протокол HTTP что-бы не зависит от того кто его реализует.  Вам нужно написать на ардуино обработчик GET или POST запроса (и на форуме, и в в гугле - примеры находятся, или хотя-бы в библиотеке ищем пример как ардуино выступает в роли сервера). А кто послал это запрос - вторичное дело.

Это значит что ардуино часть (и вообще освоится) - можно с помощью обычного HTML-ля. Потом javascript, jQuery.ajax() | jQuery API Documentation вам в помощь.

Когда поняли всю эту кухню - просто гуглим ActionScript Get Request  (ActionScript - это язык который внутри флеша используется). Ищем как в нем запросы слать.

Например вот: Adobe ActionScript 3.0 * Работа с внешними данными  . Вообщем изучения URLLoader - ваша цель.

Ну, а как во флеше рисовать кнопки/формы -наверное лучше взять книжечку какую-нибудь. Или, опять-таки, нагуглить уроки флеша. 99% что в этих уроках будет и то как послать куда-то запрос загрузить данные.

С точки зрения флеша - опять, таки. Он не знает кто там на другом конце провода. Ардуино, apach+php или IIS.net.  Он делает GET/POST запрос и получает ответ.

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

P.S. А вообще - зачем вам флеш? Наоборот, сейчас все стараются убегать от него в сторону HTML+javascript. Flash есть далеко не везде (и чем дальше, тем хуже). Особенно глухо (и похоже не предвитися) - на мобильных девайсах. А все больше (и уже довольно ощутимо) использования интернета происходит с телефоном/планшетов. И это уже не экзотика.

alexey_and
Offline
Зарегистрирован: 03.03.2013

со стороны ардуины как раз боле-менее все понятно, по крайней мере есть куча статей как юзать ethernet

а вот как с флеша команды посылать - не совсем ясно. пытаюсь разобраться в этой статье - http://www.mikechambers.com/blog/2010/08/04/getting-started-with-flash-and-arduino/

слишком замудрено, и не понятно куда этот action script пихать

пс. флеш - это пока на мой взгляд самый простой и быстрый способ сделать интерактивную картинку, где нажатие на различные элементы будет сопровождаться анимацией и посылом команд на ардуино. от ардуино требуется только включать-выключать реле. потом "картинка" должна быть залита на андроид в виде air-приложения

просто я совсем не программист. но простейшую анимацию на флеше сделать смогу. по ардуине тоже кое-как понятно. затык с action script. сделать бы хотя бы кнопку-светодиод как в статье, уже можно было бы от этого плясать

leshak
Offline
Зарегистрирован: 29.09.2011

Да зачем в этот темный лес с сокетами лезть (и сомневаюсь я что вы простой пример для него на ардуине найдете)? Даже просто отлажитьвать - и то гиморой.

Сделайте- проще.

На ардуние, пусть она зажигает диод если вызвали урл вида

http://192.168.1.100/blink?state=on

и выключет если вызвали http://192.168.1.100/blink?state=off    (192.168.1.100 - ардесс вашей ардуины).

и пусть отвечает банальным "ok" - типа "я команду выполнила".

Можно еще добавить http://192.168.1.100/blink?state=report - возвращает on или off в зависимости от текущего состояния диода.

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

А далее, просто во флеше, делаете вызовы этих урлов по нажатию трех кнопок. Одна, с помощью чем-то типа URLLoader - вызвает один урл, вторая - другой, третья - третий (и в зависимости от ответа - что-то рисует во флеше).

На этапе отладки флеша - тоже можно отложить в сторону ардуину, и тренироваться дергать из него файлики с компа http://localhost/blink_state_on_response.html и т.п.  Когда отладите - просто поменяете урлы на ардуиновские.

Если "вроде все правильно", но не "не работает". Нажимаете, скажем в chrome F12. И смотрите на вкладке "Networks" какие вызовые делает флеш. Если вместо вот этих урлов выше, вы видите попытку вызвать http://192.168.1.100/crossdomain.xml - а дальше тишина, то значит нужно погуглить почитать про него что это за зверь.

И реализовать в дуине что-бы она отвечала и на запрос такого вида http://192.168.1.100/crossdomain.xml содержимым типа

<?xml version="1.0"?>
<cross-domain-policy>
  <allow-access-from domain="*" />
</cross-domain-policy>

или

<?xml version="1.0"?>
<cross-domain-policy>
  <allow-access-from domain="yourdomain" />
</cross-domain-policy>

где yourdomain - домен с которого вы флеш грузите (на время разработки, это скорее всего будет Localhost).

P.S. Естественно это все в предположении что флеш у вас расположен на какой-то Html странице, а не stanalone приложение. С ними я меньше знаком, но думаю танцев с crossdomain.xml тогда вообще не нужно будет. Правда отлаживать будет сложней, но можно поставить что-то типа Fiddler - The Free Web Debugging Proxy by Telerik и им смотреть какие и куда запросы шлет флеш.

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

пс. флеш - это пока на мой взгляд самый простой и быстрый способ сделать интерактивную картинку

JQuery/html5+canvas с вами не согласен :)

Или javascript+svg

Но, конечно, это уже скорее дело вкуса. "Что лучше" - холиварная тема. "Просто и быстро" - конечно сильно зависит от прошлого опыта того кто делает :)

В самом andoide вызовы ардуины выглядели-бы примерно так:

Помогалка для вызова урлов:

	protected String getUrl(String... url) {
	    Log.v(LOG_TAG, String.format("do:%s", url[0]));
		
		 String output = null;
		 String requestUrl=url[0];

		  HttpGet httpGet = new HttpGet(requestUrl);
		  
		  HttpResponse httpResponse;
		  
			try {
				
				Log.d(LOG_TAG_REQUEST,requestUrl);
				
				httpResponse = httpClient.execute(httpGet);
				
				int statusCode=httpResponse.getStatusLine().getStatusCode();
				
				Log.d(LOG_TAG_RESPONSE,requestUrl);
				Log.d(LOG_TAG_RESPONSE,"StatusCode:"+httpResponse.getStatusLine().getStatusCode());
				
				HttpEntity httpEntity = httpResponse.getEntity();
				String content=EntityUtils.toString(httpEntity);
					if(statusCode==HttpStatus.SC_OK){
						output=content;
					} else {
						Log.v(LOG_TAG_RESPONSE,"Reason:"+httpResponse.getStatusLine().getReasonPhrase());
					}
				
				Log.v(LOG_TAG_RESPONSE,"Content:"+content);
				
				
			} catch (ClientProtocolException e) {
				
				e.printStackTrace();
			} catch (IOException e) {

				e.printStackTrace();
			}
		   
			
			 return output;
		
	}

И в вызывал-бы ее просто

String result=getUrl("htt p://192.168.1.100/blink?state=on"); // включили диод на ардуине

if(result!="ok"){
  что-то непонятное дуина ответила
}

В реальм коде, конечно, эта помоглка еще обернута асинхронным таском (что-бы пока ждем ответа - интерфейс оставался отзывчивым).

Но в ActionScript - ваше URLLoader/URLRequest, кажись уже изначально асинхронен.

Вот если этот URLRequest - Adobe ActionScript® 3 (AS3 ) API Reference семпл переиначить (всего-то урл поменять), то включение диода будет выгляить примерно так


package {
    import flash.display.Sprite;
    import flash.events.*;
    import flash.net.*;

    public class URLRequestExample extends Sprite {
        private var loader:URLLoader;
        
        public function URLRequestExample() {
            loader = new URLLoader();
            configureListeners(loader);

            var request:URLRequest = new URLRequest("htt p://192.168.1.100/blink?state=on");
            try {
                loader.load(request);
            } catch (error:Error) {
                trace("Unable to load requested document.");
            }
        }

        private function configureListeners(dispatcher:IEventDispatcher):void {
            dispatcher.addEventListener(Event.COMPLETE, completeHandler);
            dispatcher.addEventListener(Event.OPEN, openHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

        private function completeHandler(event:Event):void {
            var loader:URLLoader = URLLoader(event.target);
            trace("completeHandler: " + loader.data);

           if(loader.data!="ok"){
               trace("Не смогли включить светик ");
           } else  {
              trace("Да будет свет, сказал монтер");
              // ну а тут - рисуете что вам нам нужно для включенного диода
           }
        }

        private function openHandler(event:Event):void {
            trace("openHandler: " + event);
            trace("вроде подцепились к дуине");
        }

        private function progressHandler(event:ProgressEvent):void {
            trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
        }

        private function securityErrorHandler(event:SecurityErrorEvent):void {
            trace("securityErrorHandler: " + event);
        }

        private function httpStatusHandler(event:HTTPStatusEvent):void {
            trace("httpStatusHandler: " + event);
            trace("Дуина ответила");
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            trace("ioErrorHandler: " + event);
            trace("Дуина молчит");
        }
    }
}

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

спасибо, leshak!

вчера наконец дошли руки, и вот простейшая управлялка:

http://www.youtube.com/watch?v=MVSUA1ghUHQ

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

по управлению диодной лентой не совсем понятно, как ей управлять через вызов урл? если это вообще возможно? я себе представляю в виде ползунка, который будет менять яркость. плюс пара запрограммированных сценариев. а управление ргб - в виде круга с палитрой, как в фотошопе. видел такие примеры на ютюбе, все реально. но никаких подробностей люди не раскрывали

leshak
Offline
Зарегистрирован: 29.09.2011

А чем принципиально отличается управление RGB от управления LED-дом? Да ничем.

Вы просто думаете в неверных терминах.

Смотрите, у вас есть какое-то UI. Междумордие. Пользовательский интерфейс.

Он собирает от пользователя какие-то данные (установки цвета, нажатие кнопок и т.п.) В виде чего он выполнен - кругов, слайдеров, обыкновенных текстовых полей - дело десятое. На чем он сделан на флеше, на процессинге, на javascript - тоже не важно. В конечно итоге у него задача - получить от пользователя три цифры R,G,B

В конечном итоге у вас формируется "комманда" с каким-то наборов параметров. Дальше вам эту команду - нужно отослать ардуине.

Какой канал вы для этого выберите - тоже не важно. Это может быть Serial, блупуп, http или еще что-то. Не важно. Главное "передать какие-то данные".

Если выбрали http, то вы что никогда не видели вызова скрипта с несколькоими параметрами (ну значит опять нужно перечитать описание Http протокола)?  http://someurl/handler?param1=value1&param2=value2&param3=value3

Далее, на стороне арудины, вам нужно (если мы работаем с http) распарсить пришедший запрос. Из этих param1,param2,param3 (естественно в настоящем скетче у них будут какие-то нормальные имена, скажем commandName,r,g,b  - http://arduino/?commandName=setRGB&r=1&g=2&b=3)

Нужно их "распарсить" в какие-то переменные. Ну а дальше, уже исходя их их значений - выполнить какие-то действия.

И, опять-таки, блоку "исполнения" - фиолетово откуда пришли эти значения. Из http, из Serial или были зашиты в скетче.

Вообщем у вас есть "блоки"

1. Пользовательский интерфейс - сбор данных от пользователя
2. Передача данных ардуине
3. Прием и распарсивание данных на ардуине
4. Исполнение какой-то команды 

И эта общая "структура" не меняется в зависимости от того чем вы рулите. Сервой или RGB-лентой.

 

leshak
Offline
Зарегистрирован: 29.09.2011

Кстати, было бы интерестно если бы вы рассказали про то как реализовали механику штор. Что-то готовое купили или соорудили что-то типа  " Видите, Балаганов, что можно сделать из простой швейной машины Зингера? Небольшое приспособление — и получилась прелестная колхозная сноповязалка."?

alexey_and
Offline
Зарегистрирован: 03.03.2013

нет, ну эти-то основы боле-менее понятны, в том числе и что можно слать сразу несколько параметров :) вот как эти параметры формировать - вот вопрос... вот как привязать палитру к числовым значениям ргб? или как сделать бегунок от 0 до 255? 

вот например http://www.youtube.com/watch?v=pZSADQihV_Y

экшн начинается с 2:50. а с урл-запросами будет такая же хорошая скорость реакции?

кстати мне скинули отличные примеры для jquery, думаю покопать в этом направлении. http://habrahabr.ru/post/104618/

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

но единственный минус - подтормаживает на андроиде. хотя щас у меня в пользовании не самый слабый из них - галакси 3

alexey_and
Offline
Зарегистрирован: 03.03.2013

про шторы - это готовая система. просто мне показалось купить готовую дешевле чем изобретать самому :) http://www.youtube.com/watch?v=w6HsFyN0N_Y

https://www.dropbox.com/s/uwn81mdr1cuzmro/IMG_0959.jpg

https://www.dropbox.com/s/uwn81mdr1cuzmro/IMG_0959.jpg

https://www.dropbox.com/s/fsiueqt1g4jvi1s/IMG_7018.jpg

https://www.dropbox.com/s/fsiueqt1g4jvi1s/IMG_7018.jpg

 

а вот блекаут роллы - практически колхозные

http://www.youtube.com/watch?v=I0IAuGwi7mU

взял просто самые дешевые роллы, купил трубчатый мотор, переклеил ткань на подходящую по диаметру трубу и готово. для сравнения цен - готовый электро-ролл мне насчитали порядка 12 тр за одну (а мне надо две), а моя самоделка обошлась в 2400 за ролл и 3000 за мотор с доставкой федексом. если везти обычной почтой, 1000 р еще можно сэкономить

https://www.dropbox.com/s/edj16p0n43ddp6l/2013-05-08%2021.48.38.jpg

https://www.dropbox.com/s/v28hl23yz9bek2j/2013-05-08%2021.48.55.jpg

https://www.dropbox.com/s/z2beyyfeg08h7om/2013-05-11%2013.12.27.jpg

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

нет, ну эти-то основы боле-менее понятны, в том числе и что можно слать сразу несколько параметров :) вот как эти параметры формировать - вот вопрос... вот как привязать палитру к числовым значениям ргб? или как сделать бегунок от 0 до 255? 

Ну так это не на ардуино сайтах смотреть нужно, а на посвященных той технологии на который вы делаете UI-шку.

Ну, к пример jQueryUI библиотеку (и еще сотни альтернатив на любой вкус)

Slider | jQuery UI - одинчный ползунок

Slider | jQuery UI - пример трех ползунков для выбора цвета

 

alexey_and пишет:

вот например http://www.youtube.com/watch?v=pZSADQihV_Y

экшн начинается с 2:50. а с урл-запросами будет такая же хорошая скорость реакции?

Вы сметесь? Я даже незнаю на каком чипе у вас айзернет шилд.

На чем jQuery запускается и т.п. Вообщем тут такое количество влияющих параметров, что "только пробовать". 

Но думаю, вполне можно добится и "визуально все быстро". 

alexey_and пишет:

но единственный минус - подтормаживает на андроиде. хотя щас у меня в пользовании не самый слабый из них - галакси 3

Ну, нативнае приложение всегда шустрее будет. С другой стороны - у jquery есть мобильная версия (правда не щупал ее). Да и всяких легковесных библиотек альтернативных - тоже море.

А еще, на andoird все может слега притормаживать, потому что изначально, большинство этих плагинов писались под события мыши. Которые на мобильных - эмулируют из событий тача (отсюда и тормоза). Вообщем-то нужно эти вещи дополнительно "подпиливать" именно под пальцевое управление.

Вообщем это мы уже ушли из ардуино области, в область разработки UI. Да еще не определившись на чем именно UI писатся будет.

Но, в любом случае, думаю с этим лучше разбиратся на профильных ресурсах. Только не пугать людей там "аруиной" :)  Там она будет выступать в роли "просто какой-то мой очень леговесный сервер/обработчик запросов".

leshak
Offline
Зарегистрирован: 29.09.2011

leshak пишет:

Slider | jQuery UI - пример трех ползунков для выбора цвета

Практически готовое вам решение. Нужно только в функции

refreshSwatch() с помощью, скажем, jQuery.ajax() | jQuery API Documentation отправить ардуине вот эти три переменные red,green,blue

Или одну переменную hex (что-бы типа "поменьше передавать"), но тогда со стороны ардуину нужно будет парсить этот hex и разбирать не отдельные байты (вообщем вот это как раз пример, как выбирая формат мы можем "игратся с быстродействием").

leshak
Offline
Зарегистрирован: 29.09.2011

Вот примерно так это будет выглядеть:

.....
function refreshSwatch() {
    var red = $( "#red" ).slider( "value" ),
      green = $( "#green" ).slider( "value" ),
      blue = $( "#blue" ).slider( "value" ),
      hex = hexFromRGB( red, green, blue );
    $( "#swatch" ).css( "background-color", "#" + hex );
    
   // отравляем ардуине
   $.get("h_t_t_p://myarduino", {r:red,g:green,b:blue} ,function(){
      console.log("arduino updated!!!");
   });

  }
.............

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

leshak пишет:

Вы сметесь? Я даже незнаю на каком чипе у вас айзернет шилд.

wiznet 5100

вот так это щас выглядит https://www.dropbox.com/s/nlxv2v22ydj4n1q/2013-06-04%2000.57.06.jpg

 

leshak пишет:

На чем jQuery запускается и т.п. Вообщем тут такое количество влияющих параметров, что "только пробовать". 

а вот тут подробнее :) есть нормальный комп с виндой, есть мак. пока на попробовать мне все равно что и на что ставить, но проще конечно на мак. хотя могу поставить на мак любую ос в виртуалке. в дальнейшем я бы просто купил какой-нибудь компактный комп для серверных целей, ос любая, хоть вин, хоть фри или лин. дружу со всеми :)

leshak пишет:

Ну, нативнае приложение всегда шустрее будет. С другой стороны - у jquery есть мобильная версия (правда не щупал ее). Да и всяких легковесных библиотек альтернативных - тоже море.

А еще, на andoird все может слега притормаживать, потому что изначально, большинство этих плагинов писались под события мыши. Которые на мобильных - эмулируют из событий тача (отсюда и тормоза). Вообщем-то нужно эти вещи дополнительно "подпиливать" именно под пальцевое управление.

Вообщем это мы уже ушли из ардуино области, в область разработки UI. Да еще не определившись на чем именно UI писатся будет.

ну нативное конечно :) вон какие игры 3д щас запиливают :) но мне это точно не грозит :)

тормозит именно анимация. причем в стандартном браузере впринципе терпимо, а в хроме - совсем беда. может мобильная версия решит эти проблемы? на компе-то все шикарно

 

вобщем мне кажется сейчас надо сконцентрироваться на одной из задач - например димм обычного светодиода с помощью ползунка

допустим взять за основу вот это: http://jqueryui.com/slider/#slider-vertical

с чего начать? какой софт ставить на комп?

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

leshak пишет:

Вы сметесь? Я даже незнаю на каком чипе у вас айзернет шилд.

wiznet 5100

Ну это - не плохо. Он меньше грузит ардуину чем enc28j60. Да и 4-ре соединяния одновременно поддерживает. 

 

alexey_and пишет:

leshak пишет:

На чем jQuery запускается и т.п. Вообщем тут такое количество влияющих параметров, что "только пробовать". 

а вот тут подробнее :)

Подробней:

попробовать();
while(тормозит()==true){
     var причина=найти_причину();

   switch(причина):
      case "много данных": уменьшать размер команды
              break;
      case "долго содинения устанавливается":
               пробовать_сокеты_long_пулинк_udp и т.п.();
           break();
    case "долго_ардуина_обрабатывает":
              переписывать_реализацию_или_упрощать_формат_команды();
    default:
             искать_решение_для_причина(причина);
   };
}
console.log("Ура!!! Не Тормозит");

 

Вообщем это проект. Работа. Тут "парой общих фраз" не отделаешься :)

alexey_and пишет:

есть нормальный комп с виндой, есть мак. пока на попробовать мне все равно что и на что ставить, но проще конечно на мак. хотя могу поставить на мак любую ос в виртуалке. в дальнейшем я бы просто купил какой-нибудь компактный комп для серверных целей, ос любая, хоть вин, хоть фри или лин. дружу со всеми :)

Ну так смотря на чем выхотите. Какие вкусы. Ну не будет тут советов. Если анродид - то идите и для него качайте SDK. Они там среду разработке дают (есть на Eclipse, есть на IdeaIDE)

Если на JavaScript решили делать, то даже обычного NotePad хватит. Обычный текстовый редактор.

Но не удобно :

Раньше пользовал, для этих целей Notepad++, сейчас на Sublime2 перешел. Но - это дело вкуса.

Локальный сервер поднимать - ну гугланите. Смотря на каком языке вы будете серверную часть писать (если будете).

php - можно апачь поставить (правда я последний раз делал это лет 8-мь назад, возможно счас в моде другие серваки)

C# - ну тут конечно IIS на винде (идет в поставке с ней), есть и IIS Express (если хорошо дружите с linux - можете и на линухе с помощью mono попытатся запустить)

питон, рельсы,NodeJs (и серверную часть на javascript писать)  и т.п. - ну это лучше у них смотреть на что популярно у них.

Ели серверную логику не думаете мутить - ну тогда вообщем-то любой веб-сервер умеет статичный .html/.js отдавать. Какой поставить - и ладно.

 

alexey_and пишет:

тормозит именно анимация. причем в стандартном браузере впринципе терпимо, а в хроме - совсем беда. может мобильная версия решит эти проблемы? на компе-то все шикарно

Может. А может "ну его нафиг все эти свисто-пердлеки? Еще и батарею жрут. К тому же - в каждом отдельном случае нужно разбиратся "что именно тормозит". Может вы смотрите пример как раз из серии "как почесать пяткой левое ухо". Какую-то крутотень демонстрирующую как в браузере можно "выжать все" из топовой видео-карты.

alexey_and пишет:

вобщем мне кажется сейчас надо сконцентрироваться на одной из задач - например димм обычного светодиода с помощью ползунка

Не возражаю. Сконцентрируйтесь :)  Возмите мой пример для трех ползунков и упростите до одного :)

alexey_and пишет:

с чего начать? какой софт ставить на комп?

Jacascirpt?   Текстовый редактор и браузер. Или Chrome или FF+FireBug(плагин девелоперский).

Ну и, кажись уже упоминал Fiddler - The Free Web Debugging Proxy by Telerik пригодится.

 

leshak
Offline
Зарегистрирован: 29.09.2011

Но вообще, мое мнение: если хочется крос-платформенности - это JavaScript. Расплата - медленее, тестировать под всеми браузерами. Поменьше всяких "пасхальных яиц" (сложные css-ки, всякие шейдеры и т.п. - разные браузеры могут по разному отрабатывать). Вообщем - обычная плата за универсальность.

Если цель Android - то засучивать рукава и погружатся в андроид. Сделать все "как хочется" и иметь минимум ограничений - только нативное приложение. Постепенно все к этому пришли. Что "javascript-универсальность" не дает нужного качества. И под каждую платформу, все-таки нужно пилить отдельное приложение.

alexey_and
Offline
Зарегистрирован: 03.03.2013

что подразумевается под серверной логикой? я думал просто веб сервер, набираешь адрес и видишь страницу. в osx есть встроенный апач, работает :) щас пытаюсь чтоб хотя бы пример ползунка запустился http://jqueryui.com/slider/#slider-vertical

leshak пишет:

А может "ну его нафиг все эти свисто-пердлеки? Еще и батарею жрут.

на батарею пофиг, пульт управления будет приделан к стене, со скрытой проводкой 

сейчас у меня нет цели сделать только на андроид, или только javascript. есть цель просто сделать, пока все равно как и на чем, главное - проще... очень тяжело мне все эти вещи понимать. хотя б с чего-нибудь начать, чтоб хоть как-то работало, а потом уже можно допиливать

alexey_and
Offline
Зарегистрирован: 03.03.2013

упд: ползунок таки запустился :) ура!

вечером попробую скрестить с ардуиной

Samodelkin
Offline
Зарегистрирован: 07.06.2012

alexey_and пишет:

про шторы - это готовая система. просто мне показалось купить готовую дешевле чем изобретать самому :) http://www.youtube.com/watch?v=w6HsFyN0N_Y

Подскажите, а где покупали готовую конструкцию и во сколько это обошлось.

alexey_and
Offline
Зарегистрирован: 03.03.2013

http://www.elektrokarniz.ru
Но в следующий раз буду делать сам. Из заводских комплектующих конечно же
Обошлось почти в 30 тыщ

alexey_and
Offline
Зарегистрирован: 03.03.2013

leshak, у меня пока нету ргб ленты, хочу поэксперементировать с простым диодом

никак не могу сообразить, в http://jqueryui.com/slider/#slider-vertical куда дописывать функцию посыла значения ардуине?

кстати, в колор пикере функция работает, исправно шлет строчки вида /?r=130&g=140&b=60

конечно потом будет закономерный вопрос как разобрать такую строку :)

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

leshak, у меня пока нету ргб ленты, хочу поэксперементировать с простым диодом

Ну и что? Возмите три диода. Вот вам и RGB. Для тестов и одинакового цвета покатят.

alexey_and пишет:

никак не могу сообразить, в http://jqueryui.com/slider/#slider-vertical куда дописывать функцию посыла значения ардуине?

Ну дык не только в код примера, но в доку на компонент смотреть нужно:

Slider Widget | jQuery UI API Documentation

Так как мы хооим ловить событие прокрутки, то логично искать в разаделе "Events". ТАм мы видим два примерно подходящих по смыслу: change и slide

Смотрим в ваш пример, ищем функцию повешенную на slide.Видим  анонимную функция повешенную на slide

 slide: function( event, ui ) {
        $( "#amount" ).val( ui.value );
      }

А в теле функции - устанавливается input поле  (можно и с обратного конца идти. Раз у нас меняется "циферка", то искать где же она меняется).

alexey_and пишет:

кстати, в колор пикере функция работает, исправно шлет строчки вида /?r=130&g=140&b=60

Ну дык ;)

Кстати, вот еще как раз для ваших задачь, сего на хабре выкатили js-библиотеку

PhoneJS — Новый HTML5-фреймворк для мобильных приложений / Блог компании DevExpress / Хабрахабр

Правда не знаю, насколько легко будет с ней разобратся без опыта jQuery и Knockout

Ну да UI симпатичное делать, в любом случае сейчас порог входа повыше чем в 90-тые :)

А сдругой стороны - все трудно пока не разобрался. А потом просто. Все же как-то разбираеются :) Другое дело что "за вечер" может и не выйти :)  Но выйдет - обязательно.

alexey_and
Offline
Зарегистрирован: 03.03.2013

leshak пишет:

Ну и что? Возмите три диода. Вот вам и RGB. Для тестов и одинакового цвета покатят.

ргб это ргб, а мне нужно будет еще и обычными рулить. поэтому хотелось бы и с одиночным слайдером разобраться

 

leshak пишет:

Смотрим в ваш пример, ищем функцию повешенную на slide.Видим  анонимную функция повешенную на slide

ну да, а как из нее вынуть значение? 

leshak пишет:

Кстати, вот еще как раз для ваших задачь, сего на хабре выкатили js-библиотеку

это уже такие дебри, до которых мне как до китая раком

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

ну да, а как из нее вынуть значение? 

 

Ну так доку же читаем:

Slider Widget | jQuery UI API Documentation

Описание параметров этого эвента. Второй параметр ui. Имеет своство "value" - The value that the handle will move to if the event is not canceled.

То есть "то что нам нужно".

ui.value - значение слайдера. И никуда его "вынимать" не нужно. Оно уже сюда передалось.

Вот же строчка устанавливающая значение текст-бокса

   $( "#amount" ).val( ui.value );

В какое значение устанавливает? В ui.value

То есть даже не глядя в доку можно догазатся ui.value это и есть - то что нам нужно отослать с помощью $.get()

Цитата:

leshak пишет:

Кстати, вот еще как раз для ваших задачь, сего на хабре выкатили js-библиотеку

это уже такие дебри, до которых мне как до китая раком

Ну это как раз тот случай когда "страшно то чего не знаем". Главное небоятся и потихоньку пилить :)

Но конечно, на разбирательство с основами прийдется потратить время. Полистайте какой-нибудь учебничек-введение в jQuery . Что-бы конструкции вида $("#amount").val(КАКОЕ_ТО_ЗНАЧЕНИЕ) были интуитивно понятны. Хотя бы "бегло проглядите".

Пригодится. Так как в html-краях, jQuery Это уже "стандарт дефакто". Почти ни один сайт без нее обходится. Даже тот который мог бы обойтись :)

alexey_and
Offline
Зарегистрирован: 03.03.2013

спасибо за терпение :)

вобщем кучу вариантов перепробовал, куда деть $.get, никак не работает. даже слайдер не появляется :(

 

<!doctype html>
 
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>jQuery UI Slider - Vertical slider</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
  <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
  <link rel="stylesheet" href="/resources/demos/style.css" />
  <script>
  
  $(function() {
    $( "#slider-vertical" ).slider({
      orientation: "vertical",
      range: "min",
      min: 0,
      max: 255,
      value: 60,
      slide: function( event, ui ) {
        $( "#amount" ).val( ui.value );
                      // отравляем ардуине
   $.get("http://192.168.1.177", {ui.value} ,function(){
      console.log("arduino updated!!!");
   } 
   
      });
 
      
    });
    $( "#amount" ).val( $( "#slider-vertical" ).slider( "value" ) );
    
  });
  
  
  </script>
</head>
<body>
 
<p>
  <label for="amount">Volume:</label>
  <input type="text" id="amount" style="border: 0; color: #f6931f; font-weight: bold;" />
</p>
 
<div id="slider-vertical" style="height: 200px;"></div>
 
 
</body>
</html>

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

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

хотелось бы побороть этот глюк...

MaksMS
Offline
Зарегистрирован: 11.03.2013

Это езернет шилд не стартует ,надо между reset и землей подключить ёмкость на 1 мкф ,только её надо будет убирать при программировании ардуинки

Один шилд  w5100 у меня тоже так же только стартует,а другой,заказанный ранее из того же магазина таким косяком не страдает..

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

вобщем кучу вариантов перепробовал, куда деть $.get, никак не работает. даже слайдер не появляется :(

Что говорит о том, что у вас какая-то ошибка в javascript. Он не выполняется. Поэтому не важно куда вы ее поместили. Открывайте javascript консоль и смотрите там на что браузер ругается. Не всегда ошибки там "говорящие" (проблема в одном месте, а ругается в другом причем совершенно левой ошибкой), но... это лучше чем ничего. Тогда уже тупо по кускам комментить код. Методом "перелет/недолет" искать место вызывающие проблемы. В chrome консоль открывается кнопкой F12 и переходом на вкладку Console (кстати там же вы можете видеть и вывод отладочной инфы console.log("Some message"); А на вкладке Networks - можно видеть какие вызовы идут. Зачастую этого хватает, и не обязательно подключать "тежолую артилерию" типа Fiddler2

Откройте учебничек по javascript. Порешайте какие-то задачки что-бы с синтаксисом освоится. И вообще подход "тупо брать пример" - плохой. Если берете себе пример, то нужно разобрать его по косточкам, понять каждую букву "зачем она тут".
 
В вашем случае - найдите принципиальное отличие (название параметров и количество - не важно), между
 
$.get("....", {r:red,g:green,b:blue} ,function(){

И

$.get("....", {ui.value} , function(){

Или, логически по рассуждайте с другого конца: в конечно итоге $.get должен дернуть какой-то URL. И в QueryString этого урла - ножно передать какие-то параметры (или параметр). Каждый параметр имеет имя и значение. Значит, что-бы собрать такой запрос - $.get должен получить эту информацию. Вы должны ему ее как-то предоставить.  Я это сделал, а вы?

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

спасибо, теперь до меня дошло!

я не ставил имя

вот так теперь работает :)

  $(function() {
    $( "#slider-vertical" ).slider({
      orientation: "vertical",
      range: "min",
      min: 0,
      max: 100,
      value: 60,
      slide: function( event, ui ) {
        $( "#amount" ).val( ui.value );
        $.get("h_t_t_p://192.168.1.177", {led1:ui.value} ,function(){
      console.log("MK updated!!!");
   });
      }
    });
    $( "#amount" ).val( $( "#slider-vertical" ).slider( "value" ) );
  });

у меня большая проблема в том, что нет фундаментальных знаний. поэтому когда я начинаю читать даже книги типа "javascript с нуля" или "jquery для начинающих" - я все равно ничего не понимаю :(

но желание сделать задуманное - непреодолимо, поэтому бьюсь как могу

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

пока наметил для себя такой план: сделать управлялку как у меня на видео (просто кнопки), только уже целиком с использованием jquery. потом дополнить слайдерами для света и ргб

и только потом уже кастомизировать до интерактивной картинки

alexey_and
Offline
Зарегистрирован: 03.03.2013

MaksMS пишет:

Это езернет шилд не стартует ,надо между reset и землей подключить ёмкость на 1 мкф ,только её надо будет убирать при программировании ардуинки

Один шилд  w5100 у меня тоже так же только стартует,а другой,заказанный ранее из того же магазина таким косяком не страдает..

СПС за подсказку, как доберусь до радиомагаза, куплю кондер и попробую

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

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

Если теоретически - это меньшая наглось, чем разбирательство с javascript/jquery :) Ближе к теме сайта.

Погуглить - это полезно. А еще, на сайте есть встроенных поиск, задачи разбора строк и конвертации их в числа - обсуждались.

Например

Разбор тестовой строки | Аппаратная платформа Arduino

Парсинг строки адреса Arduino в режиме веб-сервера | Аппаратная платформа Arduino

leshak
Offline
Зарегистрирован: 29.09.2011

А еще, небыло времени, но было-бы интерестно, организовать общение ардуины/javascript в формате JSON/JSONP

Теоретически - более перспективно с точки зрения совместимостей с чем угодно. Да и "ответы ардуины" на стороне javascript легче парсить.

Вот только не знаю как это будет с точки зрения производительности/памяти. Все-таки за "универсальность" - нужно платить.

Можно не с нуля, гугл говорит что есть для ардуины JSON библиотеки. Можно попытатся что-то подобрать готовое и подпилить под себя.

alexey_and
Offline
Зарегистрирован: 03.03.2013

еще вчера нашел эти темы. кстати в гугле и на офф сайте ничего толкового не нашлось

пока ничего не получается

отдельно вот этот код работает шикарно

// структра описывающие наш параметр

struct port_param_t{String name; int value;};

#define MAX_PARAMS 20 // сколько параметров максимально мы умеем парсить

port_param_t params[MAX_PARAMS]; // в этот массис будем сохранять наши парсенные параметры

byte parsedParams=0; // сколько параметров нам удалось напарсить

void setup(){

  Serial.begin(9600);
  char* inputString="http://192.168.3.5/?slider=200"; // наши тестовые данные
  // выводим что собираемся парсить

  Serial.print("input '");Serial.print(inputString);  Serial.println("'");
  // парсим
  parseParams(inputString);
  // выводим что получилось
  printParams();
}

// парсид входящую строку в массив params[] и устанавливает parsedParam в количество прочитанных элементов

void parseParams(char* inputString){
  
  parsedParams=0; // пока ничего не напарсили
 char* buffer=strtok(inputString,"?"); // лучше так проверять/пропускать вопросилово
 
  if(buffer!=NULL){
    for(buffer=strtok(NULL,"&"); buffer!=NULL;     buffer=strtok(NULL,"&") ) 
    {
  String buffer1= String(buffer);
    params[parsedParams].name= buffer1.substring(0,buffer1.indexOf('='));   
    params[parsedParams].value=strtoint(buffer1.substring(buffer1.indexOf('=')+1)); 
  
    parsedParams++; // отмечаем сколько удалось распарсить
     }
         if(parsedParams>MAX_PARAMS-1)return; // больше нет места куда сохранять парсенное.
     } 
  
}
// Выводит в Serial массив parsedParams[]
void printParams(){
  for(byte i=0;i<parsedParams;i++){
      // TODO: всю эту кучу принтов можно заменить одним sprintf
      
      Serial.print(params[i].name);
      Serial.print(" -> ");
      Serial.println(params[i].value);
    //  Serial.print("=");
    //  Serial.println(params[i].value,DEC);
  }
}

int strtoint(String str) // Процедура переобразования строки в число
{
  int tempInt;
  char rez[str.length()+1];
  str.toCharArray(rez, sizeof(rez));
  tempInt = atoi(rez);
  return tempInt;
}

void loop(){
}

 

 

но вот как сюда  

  char* inputString="ttp://192.168.3.5/?slider=200";

скормить то, что прилетает по ethernet-y - вопрос :)

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

Ну, пример, по моему мнению вы выбрали неудачный (хотя и рабочий).  Как я уже говорил в тех ветках лично я противник объекта String

Куча лишних конвертаций и расхода памяти (так как с ним не работает ни одна стандартная сишная фунция).

Вот тут у нас, вместо того что-бы тупо вызвать atoi(), нам нужно вначале "предварительно подготовить". Вначале созадем еще одну копию всего буффера (лишний расход памяти), потом из нее делаем еще одну копию подстроки (лишний расход памяти, при вызове substring()), потом с этого выделанного - снимаем еще одну копию в массив rez. И ура, наконец-то мы опять вернулись к обычной сишной строке и может вызвать нужную нам функцию atoi().

И ради чего это (плюс расход на создание классов String)? Ради того что-бы не тратить время на изучение Cи-шный строк и стандартных функций. И, в итоге, все равно к ним пришли :)

>скормить то, что прилетает по ethernet-y - вопрос :)

Значит, отложите пока леды, jquery, парсинг и т.п.

Научитесь выводить все что "прилетает по ethernet-ту в Serial". Со всеми заголовками и т.п.

Потом научитесь "то что прилетает" - сохранять в какой-то буфер. И выводить его одним Serial.println(buff);

Ну а после этого - повросов "как сюда скормить" - уже не будет.

alexey_and
Offline
Зарегистрирован: 03.03.2013

ну там есть и пример вашего авторства, тоже рабочий.

Цитата:

Научитесь выводить все что "прилетает по ethernet-ту в Serial".

как раз это получается без заморочек:

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (readString.length() < 100) {
          readString += c;
        }

        if (c == '\n') { 
          Serial.println(readString); 

вижу в сериале следущее:

GET /?OPEN HTTP/1.1

GET /favicon.ico HTTP/1.1

GET /?CLOSE HTTP/1.1

GET /apple-touch-icon-precomposed.png HTTP/1.1

GET /favicon.ico HTTP/1.1

GET /apple-touch-icon-precomposed.png HTTP/1.1

GET /?STOP HTTP/1.1

GET /apple-touch-icon.png HTTP/1.1

GET /favicon.ico HTTP/1.1

GET /apple-touch-icon-precomposed.png HTTP/1.1

GET /apple-touch-icon.png HTTP/1.1

 

Цитата:

Потом научитесь "то что прилетает" - сохранять в какой-то буфер. И выводить его одним Serial.println(buff);

то есть скормить парсеру прилетевшее из эзернета можно только через буфер? пойду разбираться...

 

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

ну там есть и пример вашего авторства, тоже рабочий.

А знаю. И много объяснений :)

 

alexey_and пишет:

Цитата:

Потом научитесь "то что прилетает" - сохранять в какой-то буфер. И выводить его одним Serial.println(buff);

то есть скормить парсеру прилетевшее из эзернета можно только через буфер? пойду разбираться...

Как раз это не тот случай когда "есть с чем разбиратся" :) Нужно просто не пугатся слова буфер.

"Буффер" в данном это "место в памяти" (переменная, указатаельно область памяти) куда мы накапливаем-складываем принятые данные для последующей обработки.

В вашем случае это переменная readString. Это уже и есть буффер :) Вы накапливаете в него символы, а когда видите конец строки (\n)- выводите ее Serial.

И вот эта строка "GET /apple-touch-icon.png HTTP/1.1" - это и есть запрос который поступил к ардуине.

Вот его и нужно парсить.

Только "формат" немного не подходит. Те примеры парсинга которые вы смотрели, у себя на входе, ожилают обычную C-шную строку  string  (char[] или char* с нулем в конце). А вы сделали буффер на базе объекта стринг String

Значит у вас есть такие пути:

1.либо сделать еще один буффер "нужного вида" и скопировать данные в него (и уже его отправить на парсинг)
2. либо переписывать сам парсинг на использование .substring, .indexOf и т.п.  вместо strok и т.п.
3. Изначально принимать данные в какой-нибудь char[]  (только не забыть в него потом \0 дописать).

 

Как реализовать первый вариант можно подсмотреть в функции strtoint() примера который вы взяли (там это делаете для отправки строки функции atoi())

Но, как я уже говорил - лично мне это не нравится. У нас выходит преобразование String->string->String->string  . Вообщем гоняем байты туда сюда фигову тучу раз без какого-либо толка.

Вообщем у вас, к ардйине будет приходить вот такая строка вида

"GET /?led1=255 HTTP/1.0"

Я бы, рекомендовал добавить еще в урл запроса, какое-то слово, что-бы отличать "правильные запросы", он "неправильных".

Скажем что-то типа

"GET /ledControl?led1=255 HTTP/1.0"

Ну и, соотвественно, все строки которые начинаются не с ""GET /ledControl?" - тупо игонорить. Это либо заголовки, либо "левый запросы" (фавикон браузер запросил, заголовки и тп..)

А которые "начинаются" - отдавать парсеру (только желательно, перед этим - откусить оконковку " HTTP/1.0"

 

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

Вообщем я бы делал примерно вот так (w500 у меня нет, поэтому я сделал на Serial, но принципиальной разницы - нет).

 

 

#define BUFF_LENGH 100 // задаем размер буфера, это максимальная длина строки которую мы можем обработать
char buff[BUFF_LENGH+1]; //  сам, буфер. +1 потому, что нам еще символ конца нужно дописывать

#define VALID_GET "GET /ledControl?"  // начала запроса с этой строки означает "правильный запрос"

unsigned int index; // текущий символ в буффере

void setup(){
  Serial.begin(57600);
}

void loop(){
  if(Serial.available()){
    char ch=Serial.read();
    
    switch(ch){
      case '\r': 
           break; // игнорируем
      case '\n': // конце строки
            buff[index-9]=0; // отмечаем конец строки, причем смешаем его на -9, что-бы отрезалася " HTTP/1."
            
            if(strstr(buff,VALID_GET)==(char*)&buff){  // запрос правильный
              handle_get_request(buff);
            } else {
              Serial.print("Ingnored:"); Serial.println(buff);
            }
            
            index=0; // и опять будем писать в буфер с начала
            
            break;
       default: // все осталные символы - просто сохраняем в буффер
          buff[index++]=ch;

          if(index==BUFF_LENGH) index=0; // если в буфере больше нет места - опять будем писать в начало
          
           
    }
    
  }
}

void handle_get_request(char* request){
  
  Serial.print("Processed:");
  Serial.println(request); // ну вот тут мы будем парсить, принимать решения и т.п.
  
}

Если этому скетчу послать строки

GET /ledControl?led1=255 HTTP/1.0
GET /ledControl?led1=255&led2=128 HTTP/1.0
GET /favicon.ico HTTP/1.1

То он выдаст

Processed:GET /ledControl?led1=255
Processed:GET /ledControl?led1=255&led2=128
Ingnored:GET /favicon.ico

Первый два запроса - принзнал кошерными, третий - забраковал.

alexey_and
Offline
Зарегистрирован: 03.03.2013

хм, что-то сходу не заработало. вообще ничего не выдает

leshak
Offline
Зарегистрирован: 29.09.2011

alexey_and пишет:

хм, что-то сходу не заработало. вообще ничего не выдает

Что не заработало? Что не выдает? Что шлете? Скорость в Serial монитор-е правильную выставили? Line-endging включили? 

P.S. Вообщем-то то что в концы "выдает такое" - это я копировал копи-пастом из сериал-монитора. То что моя ардуина "выдала".

alexey_and
Offline
Зарегистрирован: 03.03.2013

line ending не был включен, виноват. теперь все работает :)

alexey_and
Offline
Зарегистрирован: 03.03.2013

добавил в код ethernet части, вот что получилось:


#include <SPI.h>
#include <Ethernet.h>
 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 177 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router 
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port


#define BUFF_LENGH 100 // задаем размер буфера, это максимальная длина строки которую мы можем обработать
char buff[BUFF_LENGH+1]; //  сам, буфер. +1 потому, что нам еще символ конца нужно дописывать

#define VALID_GET "GET /ledControl?"  // начала запроса с этой строки означает "правильный запрос"

unsigned int index; // текущий символ в буффере

void setup(){
  Serial.begin(9600);
    //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
}

void loop(){
//  if(Serial.available()){

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char ch = client.read();

//  char ch=Serial.read();
    
    switch(ch){
      case '\r': 
           break; // игнорируем
      case '\n': // конце строки
      
      
      
///      
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();
 
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
          client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
          client.println("<link rel='stylesheet' type='text/css' href='http://homeautocss.net84.net/a.css' />");
          client.println("<TITLE>Home Automation</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<H1>Mega Control</H1>");
          client.println("<hr />");
          client.println("<br />");
         
          client.println("<a href=\"/ledControl?led13=1\"\">LED13 ON</a>");
          client.println("<a href=\"/ledControl?led13=0\"\">LED13 OFF</a>");        
 
//           client.println("<a href=\"/?STOP\"\">STOP</a><br />"); 
 
          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();
///      
      
      
            buff[index-9]=0; // отмечаем конец строки, причем смешаем его на -9, что-бы отрезалася " HTTP/1."
            
            if(strstr(buff,VALID_GET)==(char*)&buff){  // запрос правильный
              handle_get_request(buff);
            } else {
              Serial.print("Ingnored:"); Serial.println(buff);
            }
            
            index=0; // и опять будем писать в буфер с начала
            
            break;
       default: // все осталные символы - просто сохраняем в буффер
          buff[index++]=ch;

          if(index==BUFF_LENGH) index=0; // если в буфере больше нет места - опять будем писать в начало
          
           
    }
    
  }
}
  }}
  
void handle_get_request(char* request){
  
  Serial.print("Processed:");
  Serial.println(request); // ну вот тут мы будем парсить, принимать решения и т.п.
  
}

 

в сериал мониторе при нажатии на кнопки на странице:

Ingnored:GET /
Ingnored:GET /favicon.ico
Ingnored:GET /apple-touch-icon-precomposed.png
Ingnored:GET /apple-touch-icon.png
Processed:GET /ledControl?led13=1
Ingnored:GET /favicon.ico
Ingnored:GET /apple-touch-icon-precomposed.png
Ingnored:GET /apple-touch-icon.png
Processed:GET /ledControl?led13=0
Ingnored:GET /favicon.ico
Ingnored:GET /apple-touch-icon-precomposed.png
Ingnored:GET /apple-touch-icon.png

 

думаю для полного счастья осталось придумать концепцию именования функций (типа ledControl), переменных (типа led13) и их значений. и как вообще сбрасывать это в переменные. т.е. как из "Processed:GET /ledControl?led13=0" сделать value "0" у "int led13 = 13"

leshak
Offline
Зарегистрирован: 29.09.2011

Во первых ну зачем же было во так "винигретить". Почему бы вот эту отсылку страницы не вынести в какую отдельную функцию и назвать ее скажем responsePage_MegaControl(); и просто вызывать ее? Тогда логика "приема в буффер" - оснатеся чистой, а не винигретом где мы сразу и принимаем, и отвечаем и еще 10-ть вещей делаем.

Во вторых - во вторых, по нормальному на страницы которые мы не можем обратать, нужно отвечать не HTTP OK (200), а HTTP Page not found (404) или какой-нибудь Http Bad Request

В третьих - на "нормальный запрос" - а зачем вам вообще отвечать так многословно? А у вас же с той стороны ответ читает ajax вызов. К тому же - ничего с этим ответом не делает. Игнорирует его. Обращает внимание только на Http статус (ждет Http200). Следовательно весь текст - ему не нужен.

В четвертых - строки, лучше переместить в Progmem - для экономии оперативки

>. т.е. как из "Processed:GET /ledControl?led13=0"

Не из "Processed:GET /ledControl?led13=0", а из "GET /ledControl?led13=0". Посмотрите в код. Слова "Processed" и "Ignored" - это просто отладочная информация в Serail. Что-бы легче было понять какое решение мы приняли по этой строке. Но в самой строке - этих слов нет.

>сделать value "0" у "int led13 = 13"

Разбор тестовой строки | Аппаратная платформа Arduino

Парсинг строки адреса Arduino в режиме веб-сервера | Аппаратная платформа Arduino

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

ну в реале страница будет лежать на отдельном веб-сервере, и отсылка страницы из программы уйдет

с остальным попробую разобраться...

alexey_and
Offline
Зарегистрирован: 03.03.2013

кое-что получилось. конечно там винегрет полный, что делаю - в лучшем случае понимаю половину. но тем не менее есть некоторый успех :)

только вот засада - почему такая слабая отзывчивость? меги мало для этих задач или можно оптимизировать прогу?

вот видео, показан слайдер, что прилетает в сериал, и собственно светодиод 

http://www.youtube.com/watch?v=PW0twn9wTAY&feature=youtu.be

 

на всякий случай код винегрета 


#include <SPI.h>
#include <Ethernet.h>
 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 177 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router 
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port


#define BUFF_LENGH 100 // задаем размер буфера, это максимальная длина строки которую мы можем обработать
char buff[BUFF_LENGH+1]; //  сам, буфер. +1 потому, что нам еще символ конца нужно дописывать

#define VALID_GET "GET /ledControl?"  // начала запроса с этой строки означает "правильный запрос"

unsigned int index; // текущий символ в буффере


/////
#define PARAM_DELIMETER "&" // чем разделены у нас параметры
#define NAME_VALUE_DELIMETER "=" // чем разделены у нас имя параметра и значение

// структра описывающие наш параметр
struct port_param_t{
    byte port;
    byte value;
};

#define MAX_PARAMS 20 // сколько параметров максимально мы умеем парсить
port_param_t params[MAX_PARAMS]; // в этот массис будем сохранять наши парсенные параметры
byte parsedParams=0; // сколько параметров нам удалось напарсить
/////


void setup(){
  Serial.begin(9600);
    //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
    pinMode(13, OUTPUT);
}

void loop(){
//  if(Serial.available()){

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char ch = client.read();

//  char ch=Serial.read();
    
    switch(ch){
      case '\r': 
           break; // игнорируем
      case '\n': // конце строки
      
      
      
///      
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();
 
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
          client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
          client.println("<link rel='stylesheet' type='text/css' href='http://homeautocss.net84.net/a.css' />");
          client.println("<TITLE>Home Automation</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<H1>Mega Control</H1>");
          client.println("<hr />");
          client.println("<br />");
         
          client.println("<a href=\"/ledControl?led13=1\"\">LED13 ON</a>");
          client.println("<a href=\"/ledControl?led13=0\"\">LED13 OFF</a>");        
 
//           client.println("<a href=\"/?STOP\"\">STOP</a><br />"); 
 
          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();
///      
      
      
            buff[index-9]=0; // отмечаем конец строки, причем смешаем его на -9, что-бы отрезалася " HTTP/1."
            
            if(strstr(buff,VALID_GET)==(char*)&buff){  // запрос правильный
              handle_get_request(buff);
            } else {
              Serial.print("Ingnored:"); Serial.println(buff);
            }
            
            index=0; // и опять будем писать в буфер с начала
            
            break;
       default: // все осталные символы - просто сохраняем в буффер
          buff[index++]=ch;

          if(index==BUFF_LENGH) index=0; // если в буфере больше нет места - опять будем писать в начало
          
           
    }
    
  }
}
  }}
  
void handle_get_request(char* request){
  
  Serial.print("Processed:");
  Serial.println(request); // ну вот тут мы будем парсить, принимать решения и т.п.


///////
  char* inputString=request; // наши тестовые данные
  
  // выводим что собираемся парсить
  Serial.print("input '");Serial.print(inputString);  Serial.println("'");
  
  // парсим
  parseParams(inputString);
  
  // выводим что получилось
  printParams();
////////
  
}



///////
void parseParams(char* inputString){
  parsedParams=0; // пока ничего не напарсили
  
  char* buffer=strtok(inputString,"?"); // лучше так проверять/пропускать вопросилово
  
  if(buffer!=NULL){ 
    for(buffer=strtok(NULL, NAME_VALUE_DELIMETER); buffer!=NULL;     buffer=strtok(NULL, NAME_VALUE_DELIMETER) )   {
         // парсим порт
         params[parsedParams].port=parseByte(buffer); // вам же навернео еще и сразу в int захочется конвертнуть, раз это цифры
         
        // парсим значение
         if( (buffer=strtok(NULL,PARAM_DELIMETER)) !=NULL)   params[parsedParams].value=parseByte(buffer);
         else return ; // фигня какая-то, порт есть, а значения нет, прекращаем парсинг
         
         parsedParams++; // отмечаем сколько удалось распарсить
         if(parsedParams>MAX_PARAMS-1)return; // больше нет места куда сохранять парсенное.

     }  
  
  }
  
}


// Выводит в Serial массив parsedParams[]
void printParams(){
  for(byte i=0;i<parsedParams;i++){
      // TODO: всю эту кучу принтов можно заменить одним sprintf
      Serial.print("Port");Serial.print(params[i].port,DEC);
      Serial.print("=");
      Serial.println(params[i].value,DEC);
      analogWrite(13, params[i].value);
      
  }
}

byte parseByte(char* inputStr){
  byte val=0;
  while( (*inputStr)>='0' && (*inputStr)<='9'){ // идем по строке пока у нас цифры попадаются
     val=val*10+((*inputStr++)-'0'); // дописываем ноль к текущем val (десятичный сдвиг влево) 
                                     //и прибавляем новую цифру, и сдвигаемся к следующему символу

  }
  return val;
}
//////////

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

тем временем намутил страницу целиком на jquery mobile с $get запросами, работает куда интереснее и быстрей чем просто html c url-ами :) 

сделал табы - Scenario и Control

http://www.youtube.com/watch?v=AerxKCOP3I8&feature=youtu.be

теперь бы полноценно разобраться с разбором строки и тормозами (если это можно победить впринципе)

alexey_and
Offline
Зарегистрирован: 03.03.2013

наткнулся на прикольную вещь: http://www.sencha.com/products/animator/

генерит в хтмл, на телефоне демки идут так же гладко как на компе

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

пс. подключил к существующей проге на jquery рулонки, получилось супер :) теперь хочу сделать сценарии типа "Night (закрыть всё, выключить свет)", "Relax (шторы закрыты, роллы открыты)" и тому подобные. для этого нужно по уму разбить прогу на ардуино на функции (как говорил leshak) и вызывать их по отдельности когда надо. пока не осилил как это делается

если кому интересно, заведу тему в проектах, кину фотки железа и тп. да и проект уже начинает обретать какой-никакой законченный вид

alexey_and
Offline
Зарегистрирован: 03.03.2013

leshak,

тут возник вопрос, get запросы заканчиваются фейлом. скрин: https://dl.dropboxusercontent.com/u/28876156/Screen%20Shot%202013-07-14%20at%2010.18.43%20PM.png

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

на всякий случай кусок кода страницы:


      $("#curtain_stop").click(function(){
         $.get("h_ttp://192.168.1.177/?curtainSTOP",function(){
            console.log("MK updated!!!");
         });
      });

и 

        <input id="curtain_stop" type="submit" data-icon="delete" data-iconpos="left"
        value="Stop">

 

leshak
Offline
Зарегистрирован: 29.09.2011

У меня есть "два подозрения".

Что-бы выяснить на какой стороне проблемы, попробуйте, сами руками, в строку бразера вбить этот урл

h_ttp://192.168.1.177/?curtainSTOP

И там-же, по F12 посмотреть нормально ли отрабаывается запрос.

Если нормально, то.... присмотритесь как  выглядит  как первая колонка. Так как же на скришноте выше или там другой адресс виден? Как я не присматривался, но.... адреса 192.168.1.117 я в ней не увидел :)  Так что, похоже... вы шелете запрос совсем не ардуине, но... вы говорите "этом ардуина отрабатывает команду". Вообщем явно что-то "осталось за кадром". Возможно вы и ардуине и самому скрипту шлете.