Протокол обмена данными и удаленный вызов функций (RPC)
- Войдите на сайт для отправки комментариев
Здравствуйте!
Приспичило мне подружить дуину и процессинг, чтобы слали друг-другу данные.
Дуина должна посылать на комп все события происходящие, т.е. данные сенсоров, изменения положения реле и т.п. в формате: время+ событие.
Комп эти данные должен получать и обрабатывать - строить графики, вести статистику.
И в свою очередь может изменять настройки и запускать занания на дуине (максимальная температура, минимальная температура, включить свет\выключить свет и т.п.)
Чтобы данные не терялись на Srial порте, как это часто бывает - нужна пакетная передача, т.е. добавлять маркеры в начало и конец. + проверять целостность пакета. А в идеале еще и шифровать его.
т.е. получаем структуру: START+DATA+CHECKSUM+END
думаю что он маркера конца можно отказаться, для краткости.
По этой теме нашел вот такую классную статью:
http://robocraft.ru/blog/1090.html
Сделал все как там, но код каботает не так как хотелось бы и столкнулся со сложностью парсинга строки: т.е. необходимо расписывать полотно Switch\Case ... чего очень делать нехочется... Да и еще пришел к выводу, что нужно присылать подтверждения об успешной передаче пакета или ошибке, чтобы выслать повторно..
Так пришел к библиотеке Firmata
Но напрямую управлять пинами ардуины мне не нужно - она должна быть по максимуму автономной...
Так наткнулся на библиотеку TinyRPC http://roboforum.ru/forum2/topic8627.html
Суть в том, что можно получить доступ над любой функцией в коде ардуино..
Но вот засада: эта библиотека не устанавливается! т.е. для установки, там требуется заменить файлы в папке lib (чтобы добавить кнопку в интерфейс Arduino IDE) -но после этого Arduino IDE - отказывается запускаться... Я так понимаю что это из-за того, что библиотека сделана для ARduino IDE alpha..
В любом случае - вопрос такой: как можно сделать тоже самое в ручную??
Или может быть есть рабочая библиотека для этих целей?
на всякий случай привожу код примера из tinyRPC:
Сам скетч:
// Include TinyRpc library #include <tinyrpc.h> #define LED 13 int num, c; char str[100]; void TurnLed(int state); void setup() { pinMode(LED, OUTPUT); Serial.begin(57600); } void loop() { // Read string from uart num = 0; while(Serial.available() == 0) delay(100); while((c = Serial.read()) != '\n') { if(c != -1) { str[num] = c; num++; } } // Run TinyRpc library routines json_node* root = json_parse(str); char* rep = json_execute(root); // Send back response Serial.println(rep); free(rep); json_free(root); } void TurnLed(int state) { if (state) digitalWrite(LED, HIGH); else digitalWrite(LED, LOW); }
Код класса на С#, который должен создаваться при клике на кнопке:
using System; using System.Collections.Generic; using System.Linq; using System.IO.Ports; using System.Text; namespace TinyRpc { public class RemoteObject { private SerialPort sport; public RemoteObject(string port, int BaudRate) { sport = new SerialPort(port); sport.BaudRate = BaudRate; sport.Open(); } public void TurnLed(int state) { string command = "{\"method\": 0, \"params\": {" +"\"state\":" + state.ToString(); command += "}}"; sport.Write(command + "\n"); } } }
В результате на стороне компа можно вызывать функции таким же образом как в Фирмате, например:
int t=Arduino.GetTemp(1);
Вопрос - как починить либу.. или как это сделать руками или какая рабочая либа может делать тоже самое?
У меня тоже была такая проблема. В смысле - проблема протокола для обмена данными. Сидел, сочинял, что-то получалось, что-то новое всплывало. И когда мне надоело топтаться на месте, я, заметив что "события" в системе происходят не так уж часто, просто заставил комп постоянно переспрашивать дуню "что нового?" на скорости 9600. Ну она ему и отвечает что произошло за последние милисекунды.
Над размером пакета в этом случае можно не заморачиваться, т.к. придёт ровно столько сколько заложено на тот или иной ответ.