К меге подключены две RGB ленты, коммандная строка передается с планшета вида liv,255,255,255. Ардуина принимает и парсит строку и через analogWrite включает нужные цвета в нужной комнате. Если ползуно медлено двигать цвет меняется плавно и без рывков, но если более бытро двигать ползнок смены цвета начинаются рывки, и хаотическая смена цвета, походу планшет наотправлял строк и ардуина не успевает их обрабатывать, так ли это и можно ли как то оптимизировать работу? И еще одна проблема, ардуина обрабатывает только перпоследнюю поступившую строку, то есть последння не доходит хотя была отправлена. Скетч следующий: Код (C++): void loop() { EthernetClient client = server.available(); if (client.available()) { char c = client.read(); indata += c; if (indata.indexOf("livlig") >= 0) { Serial.println("Light is on"); indata = ""; } else if (indata.indexOf("livcol") >= 0) { parseColor(indata, 3, 5, 6); } else if (indata.indexOf("get") >= 0) { getTemp(); } } } void parseColor(String input, int pin1, int pin2, int pin3) { int boundLow; int boundHigh; boundLow = input.indexOf(delimiter); boundHigh = input.indexOf(delimiter, boundLow+1); int r = input.substring(boundLow+1, boundHigh).toInt(); boundLow = input.indexOf(delimiter, boundHigh+1); int g = input.substring(boundHigh+1, boundLow).toInt(); int b = input.substring(boundLow+1).toInt(); analogWrite(pin1, r); analogWrite(pin2, g); analogWrite(pin3, b); indata = ""; // очистить строку }
Расскажу, как бы сам пытался решить подобную задачу. 1. Отправка с планшета, только если данные изменились. Ни каких лишних пакетов. 2. Сделал бы пакет минимальным. Простой вариант строка ?255,255,255! В отличии от Вашего пакета используется 13 байт. Ваш пакет 16 байт. Более сложный, отправлял бы бинарные данные, тем самым пакет ?255,255,255! выглядел бы ?255255255!, а это уже 5 байт. 3. В начале получаем байты, а потом парсим. Ваш код Код (C++): if (client.available()) { char c = client.read(); indata += c; if (indata.indexOf("livlig") >= 0) { Serial.println("Light is on"); indata = ""; } else if (indata.indexOf("livcol") >= 0) { parseColor(indata, 3, 5, 6); } else if (indata.indexOf("get") >= 0) { getTemp(); } } Добавляем 1 символ и проверяем, зачем, кода можно получить весь пакет не задерживаясь, а потом парсить данные. Тем более у Вас есть начало пакета и конец, к примеру символ ? - начало, ! - символ конца. 4. Учитывая, что мы перешли на более простой пакет, можно отказаться от String использовать массива char для пакета в варианте строка или массива byte для пакета бинарных данных. 5. Разбор данных в цикле for. Как для варианта строки, так для варианта бинарных данных, с ними еще быстрее. Дальше в зависимости от результатов. Можно и SPI библиотеку сделать на прерываниях и сделать буфер, для хранения нескольких пакетов и т.д. Переход на Due даст свои плюсы, Вы получите более быстрый SPI и возможность использовать библиотеки с DMA к примеру для W5200. Подробнее тут - http://forum.arduino.cc/index.php?topic=139147.0. Но если Вы будете бесконечно слать данные, то и ее может не хватить.
Когда вы отправляете три числа r,g,b, контроллер ничего не знает о том, с какой скоростью нужно их выводить. Поэтому, имеет смысл отправить четыре числа t,r,g,b, где t - время в миллисекундах, чтобы он мог рассчитать интервалы между изменением r,g,b по своим "часам". Небольшая задержка в выполнении команд с правильными интервалами времени будет несколько лучше хаотичного поведения.