Запуск функции при помощи энкодера
- Войдите на сайт для отправки комментариев
Вс, 06/11/2016 - 12:47
Приветстую Вас гуру! Алчу помощи, ибо заблукал в "трёх соснах". ТЗ таково: есть в наличии энкодер, при вращении которого должна два раза запускаться функция, в начале, строго после первого импульса от энкодера и в конце, назавём её - "запрос значения частоты" Задача, вроде бы, тривиальная, но...
P.S. ниже привожу весь код скетча.
Заранее спасибо за помощь:)
-
#include <ArduinoJson.h>
-
#include "Arduino.h"
-
#include <Encoder.h>
-
-
// Initialise the encoder and freq.button
-
Encoder encoder(3, 2);
-
const int pinButton = 8;
-
long oldPos = -999;
-
-
// Initial frequency
-
long frequency = 451000000;
-
-
// Timeouts
-
unsigned long reqTime = 0;
-
const long reqInterval = 10;
-
unsigned long respTime = 0;
-
const long respInterval = 500;
-
boolean gotAnswer = true;
-
-
void setup() {
-
Serial.begin(115200);
-
pinMode(pinButton, INPUT);
-
}
-
-
void loop()
-
{
-
int stateButton = digitalRead(pinButton);
-
if(stateButton == 1 && gotAnswer && (abs(millis() - reqTime) > reqInterval)) {
-
reqTime = millis();
-
respTime = millis();
-
gotAnswer = false;
-
//send to sdrsharp get comm.
-
Serial.println("{\"Command\": \"Get\", \"Method\": \"Frequency\"}");
-
//Json get frequency
-
String inData = Serial.readStringUntil('\n');
-
StaticJsonBuffer<200> jsonBuffer;
-
JsonObject& root = jsonBuffer.parseObject(inData);
-
-
if (!root.success()) {
-
Serial.println("cant_get_frequency");
-
delay(1000);
-
return;
-
}
-
-
frequency = root["Value"];
-
inData = "";
-
//Clear encoder counter
-
encoder.write(0);
-
-
if(Serial.available() > 0) {
-
gotAnswer = true;
-
String inData = Serial.readStringUntil('\n');
-
inData = "";
-
}
-
-
if ((abs(millis() - respTime) > respInterval) && !gotAnswer) {
-
respTime = millis();
-
gotAnswer = true;
-
}
-
}
-
//Get the encoder position
-
long newPos = encoder.read();
-
if (newPos != oldPos && gotAnswer && (abs(millis() - reqTime) > reqInterval) ) {
-
reqTime = millis();
-
respTime = millis();
-
gotAnswer = false;
-
oldPos = newPos;
-
//Set feq.
-
long newFrequency = frequency + (newPos * 3125);
-
Serial.println("{\"Command\": \"Set\", \"Method\": \"Frequency\", \"Value\": "+String(newFrequency)+"}");
-
-
}
-
if(Serial.available() > 0) {
-
gotAnswer = true;
-
String inData = Serial.readStringUntil('\n');
-
inData = "";
-
}
-
-
if ((abs(millis() - respTime) > respInterval) && !gotAnswer) {
-
respTime = millis();
-
gotAnswer = true;
-
}
-
}
Раз уж повесили энкодер на контакты прерываний, используйте их
А это еще что? Зачем кавычки?
должна два раза запускаться функция, в начале, строго после первого импульса от энкодера и в конце, назавём её - "запрос значения частоты" Задача, вроде бы, тривиальная
В таком виде задача не то, что не тривиальна, а попросту неразрешима.
Определитесь сначала с алгоритмом. а потом приступайте к программированию.
Что означает выражение "и в конце"? Когда перестанут вращать энкодер? А откуда Ваша программа узнает. что его перестали вращать? Телепатически? Или по некоторой временной паузе от последнего импульса? Или, может "в конце" означает, "когда на энкодере кнопку нажмут"? Или ещё что-то произойдёт?
Определитесь сначала с задачей чётко и однозначно, а потом уже приступайте к программе.
Скетч сотворён по образу и подобию примеров к библиотеке ArduinoJson. Пример кода с "кавычками" приведён ниже. Скетч из первого моего сообщения прекрасно работает... но хотелось бы избавиться от кнопки переключающей режимы SET/GET. Т.е. мне нужно что бы при первом же импульсе с энкодера однократно выполнялась функция GET, запрашивающая значения частоты, ну, и после крайнего импульса с энкодера (хотя, сие и необязательно, можно обойтись запросом в начеле вращения энкодера). В процессе вращения энкодера запросов частоты быть не должно. Вот такая задачка:)
P.S. Пример кода с "кавычками".
Я уже давно опредилился, даже слепил некого "франкенштейна" из кусков чужого и своего кода, который даже работает:) Осталась одна задача, решить которую мне тяму не хватает. Как заставить энкодер однократно вызывать функцию GET т.е. крутишь энкодер (перестраиваешь частоту) - функция GET одноразово вызвалась, следующий раз функция GET вызывается при новом врещении энкодера, т.е. при следующей перестройке частоты.
P.S. Сейчас немного "причешу" "франкенштейна" и выложу "код" в тему. Прошу не кидаться помидорами, Arduino IDE изучаю только вторую неделю:)
Ву-аля! Вот и мой эпичесий "говнокод":) Которы даже работает, вот бы ещё однократно вызываемую энкодером функцию GET прикрутить, радости моей не было бы предела!
P.S. Пока решил вызывать функцию GET с помощью millis(); что дико меня не устраивает, нужнен вызов функции именно энкодером. Почему именно энкодером, обьясню позже.
Я уже давно опредилился,
Да, ни фига Вы не определились. У Вас в каждом посте хотелки разные.
А на вопрос
Что означает выражение "и в конце"?
ответа так и нет. И не будет? Ну, ладно, как хотите.
"Вконце" - это "одноразовый" вызов функции сразу после остановки вращения энкодера, подумав, считаю что сия функция будет излишней, вполне хватит запроса в начале вращения энкодера.
P.S. В чём заключается моя "неопределённость"? В том, что я хочу реализовать в коде свою "хотелку" в плане одноразового вызова функции GET при помощи энкодера? Куда уж определённее:)
Vasya73, Вы, похоже даже вопроса понять не можете. Вот Вы пишете
"Вконце" - это "одноразовый" вызов функции сразу после остановки вращения энкодера
Так я же Вас и спрашивал как именно Вы собираетесь определять момент "сразу после остановки вращения энкодера"? Ждать некий таймаут и если в течение этого таймаута новых импульсов нет, то значит вращать закончили? Но это не сразу. Как Вы сразу определать собирались?
P.S. В чём заключается моя "неопределённость"?
В том, что в первом посте Вы пишете
должна два раза запускаться функция
А в четвёртом посте Вы же пишете
заставить энкодер однократно вызывать функцию GET
Вы не видите здесь противоречия?
Куда уж определённее:)
Вот и я про то же.
Хорошо, вношу так сказать, ясность:) Как реализовать в коде одноразовый вызов функции GET. Т.е. крутим ручку энкодера, при первом же импульсе от энкодера вызывается функция GET (запрос актуальной частоты), далее, при дальнейшем вращении энкодера функция GET вызываться не должна. Остановились, перестали крутить энкодер функция GET не вызывается. Посидели покурили, решили перестроиться по частоте, снова крутим энкодер вызывая при этом одноразово функцию GET. На данный момент, вроде бы всё доходчиво объяснил. Черновик скетча выкладывал выше.
P.S. Данный скетч разрабатываю для работы с программой SDR#, "посредником" между ПК и Arduino является плагин SDRSharp-Net-Remote. SDR# - это программа управления SDR приёмником. В принципе, управление полосовыми фильтрами я ужо реализовал, переключаются идеально:) А вот работу с энкодером никак не поборю:) Вот и попросил помощи у гуру, мож кто и подскажит как решить сию "проблему" с запросом GET посредством вращения энкодера. В общем, как то так.
Мдаа ... гуманитарий???
На данный момент, вроде бы всё доходчиво объяснил ...
Для гуманитария, может быть, но программировать по такому объяснению невозможно.
Я целый день спрашиваю у Вас одно и то же, но Вы даже вопроса не понимаете.
1) при дальнейшем вращении энкодера функция GET вызываться не должна
2) Посидели покурили, этом одноразово функцию GET
Ну нет в языках программирования понятия "покурили" - НЕТУ!
Вы скажете наконец долбанную длительность перекура? Просто, на случай, если Вы плохо понимаете по-русски: "Would you tell me the fucking smoke break duration!"
Если энкодер не выдаёт щелчков 50мс это уже "покурили" или ещё нет? А если сто мс? Секунда? Минута?
СКОЛЬКО времени нужно курить, чтобы таки вызвать функцию (а при более коротких перекурах не вызывать)?
Вы вопрос понимаете? Вот я медленно вращаю энкодер - 2 щелчка в секунду - вызываем - нет? А если два щелчка в минуту? А если два щелчка в час?
Я целый день пытаюсь от вас добиться каким должен быть интервал между щелчками, чтобы стало нужно вызывать функцию.
Отвечаю. Первый импульс с энкодера - вызов функции GET. Все последующие импульсы игнорируются. Остановились, хоть на минуту, хоть на час, крутанули энкодер - однократно вызвали функцию GET, все последующие импульсы игнорируются. Т.е. сигналы с энкодера будут иметь следующий вид - GET, SET, SET... n-SET и так до остановки вращения энкодера. Через некоторое время, снова крутим энкодер, опять тот же алгоритм - GET, SET, SET, SET... n-SET. SET - это команда установки частоты отправляемая в порт ПК. GET - запрос частоты. Почему нужен именно такой алгоритм? Потому что, перестраивать частоту можно и из окна программы SDR#, для того чтобы "синхронизировать" Arduino с "шарпом" нужно запросить актуальное на данный момент времени значение частоты, что бы Arduino начало перестраивать частоту отталкиваясь от частоты установленной в "шарпе". Например: в SDR# установленна частота 3690000 Гц для того чтобы Arduino начало перестраивать частоту начиная с 3690000 Гц ей нужно запросить значение частоты от которой и будет "плясать":) Такой алгоритм первоначально уже риализован, т.е. переключение с помощью кнопки, т.е. нажал на кнопку SET/GET перед настройкой частоты с помощью энкодера, считал частоту из "шарпа", переключился в режим SET и начинаешь перестраивать частоту от той что считало Arduino. Но такой метод настройки частоты крайне неудобен, поэтому, временно, реализовал сие используя millis(); Теперь о нюансах. Дело в том, что когда происходит запрос частоты из SDR#, то последний "заикаеться":) И используя запрос по таймеру очень уж некомфортно слушать "заикания". Вот я и решил сделать одноразовый запрос частоты в начале вращения энкодера, одно "заикание" SDR# не столь напрягает, как постоянное:)
Тяжело...
Vasya73, что значит "остановились"?
Сама ручка энкодера-то может вращаться непрерывно, но импульсы то от него поступают время от времени. Поэому:
1. "Сразу" в данном случае принципиально невозможно. Возможно только подождать некоторое время и, если мы решим, что ждали уже достаточно долго, а очередного импульса нет, сделать вывод, что экнодер остановился.
2. Необходимо количественно определить это время (называется оно таймаут).
Тэээксс..:) Оставим пока в покое "мой" скетч. Берём гипотетический энкодер и начинаем его крутить. При появлении первого импульса с энкодера, вызываем функцию GET, которая запрашивает значение частоты установленное в SDR#-е. Основываясь на значении считанной из SDR# частоты, Arduino начинает перестройку, т.е. в SDR# установлена частота 7100000 Гц считав сие значение Arduino "синхронизируется" с SDR# и начинает перестройку именно с 7100000 Гц. Я уже не знаю, как ещё объяснять:) Еще один пример: гипотетический энкодер управляет включением лампочки, так вот, при вращении энкодера, получив первый импульс, лампочка включается, получив второй и последующие импульсы лампочка гаснет и так до конца вращения энкодера. Останавливаем вращение энкодера, лампочка находиться в выключенном состоянии. Снова начинаем вращать энкодер, получив первый импульс энкодера, лампочка снова загорается и гаснет получив второй и последущие импульсы. Теперь возвращаемся к работе скетча. Вращаем энкодер, однократно вызвали функцию GET, которая запросила значение частоты от которой и будет перестраиваться Arduino. Т.е. "запросила -> получила" ответ и больше не вызывается, в силу вступает функция SET которая будет работать до конца вращения энкодера. Как то так:) Я уже и алгоритм расписал и скетч черновой выложил, как ещё то объяснить?:)
станавливаем вращение энкодера,
Блин, Вы можете наконец сказать что такое "останавливаем".
Я уже и алгоритм расписал
Ничерта Вы не расписадли, Вы не хнаете что такое алгоритм
как ещё то объяснить?:)
Очено просто. Скажите так: "останавливаем, это когда от энкродера не поступает импульсов в тчение N секунд". Просто скажите, чему равно N.
Без этого, всё Ваши "останавливаем" и "покурили" - это болтовня не имеющая к понятию алгоритма никакого отношения.
Всем участвующим в сим весьма познавательном диалоге большой респект:) Путь к решению вышеуказанной задачи нашел самомтаятельно. Так что, тему можно смело закрывать. Как говориться, если хочешь что-то сделать качественно и что бы понравилось, в первую очередь, самому себе, сделай сам!:) Всем удачи! 73!
P.S. А вот нервничать не рекомендую, берегите себя:)