Счетчик импульсов + SoftwareSerial + дисплей

svorog
Offline
Зарегистрирован: 27.04.2017

Всем доброго времени суток! Прошу помоч: через "уно" опрашиваю энекодер на прерываниях, через монитор порта он выводит данные, все прекрасно, но когда захотел вывести информацию на дисплей "nextion" там используются программная шина UART, то столкнулся с ошибкой компиляциипри подключении  SoftwareSerial.h и я так понимаю получается конфликт т.к. SoftwareSerial тоже использует прерывания.

кто может подсказать:

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

2. можно ли с "уны" опрашивающий энкодер на прерываниях каким то образом передавать значение переменной на "Мегу 2650" а с уже с  "Меги" выводить переменную на экран через SoftwareSerial.h ?

3. Может есть другой способ оправать энкодер с высокой частотой не используя прерывания?

пытался использовать вот этот код:

[code]

#include <SoftwareSerial.h>

const uint8_t  pinRX   = 4;   // Опр. номер вывода Arduino RX программного UART, подключается к выводу TX дисплея
const uint8_t  pinTX   = 5;

SoftwareSerial softSerial(pinRX,pinTX);

volatile char ABprev = 0;
const int increment[16] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};
float chetchic = 0.000;

ISR (PCINT0_vect) { //
  char AB = PINB & 3;
  chetchic += increment[AB+ABprev*4];
  ABprev = AB;
}

void setup() {
  pinMode(8, INPUT);  // A
  pinMode(9, INPUT);  // B
  PCICR |= (1 << PCIE0);  //
  PCMSK0 |= 3;
  ABprev = PINB & 3;
   Serial.begin(115200);
}

void loop() {
 if(millis()%50<=2){delay(2);                                                              // Следующее действие выполням каждые 50мс
    softSerial.print((String)"t3.txt=\""+chetchic/1000+"\""+char(255)+char(255)+char(255)); // Отправляем команду дисплею: «t3.txt="текст"» заканчивая её тремя байтами 0xFF. Эта команда устанавливает значение для текстового поля t3
    }     
[/code]

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

svorog пишет:

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

Как Вы сами думаете, можно ли ответить на этот вопрос, не зная, что именно Вы подразумеваете под "высокой частотой"?

Например, "ежегодно" - это высокая частота или нет?

Цитата:

2. можно ли с "уны" опрашивающий энкодер на прерываниях каким то образом передавать значение переменной на "Мегу 2650" а с уже с  "Меги" выводить переменную на экран через SoftwareSerial.h ?

А зачем СофтСериал, если есть Мега?

svorog
Offline
Зарегистрирован: 27.04.2017

1. По скорости изменения импульсов у меня на энкодере планируется до 8000 имп/с.

2. А по поводу СофтСериал и Мега, то не знаю как ещё вывести информацию на  дисплей "nextion" без него, т.к. в описании библиотеки описан способ именно через CофтСериал, если есть другой способ буду благодарен если подскажете.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

А можно огласить весь список пожалуйста? То есть что за задучу надо решить? Почему именно 8000 имп/с и сошелся ли свет клином на Некситоне?

svorog
Offline
Зарегистрирован: 27.04.2017

Энкодер 1000 имп на оборот, ожидается скорость вращения до 8 об/с, соответственно 8000 имп/с. Некстион  в наличи, хотелось бы все таки использовать его (если конечно это возможно).

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Скорость вращения чего? И что именно надо  выводить на дисплей?

 

svorog
Offline
Зарегистрирован: 27.04.2017

8 об/с у ШД который вращает ШВП,  на дисплей хочу выводить количество импульсов, в дальнейшем планирую откалибровать и перевести в относительные координаты.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

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

svorog
Offline
Зарегистрирован: 27.04.2017

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

svorog пишет:

1. По скорости изменения импульсов у меня на энкодере планируется до 8000 имп/с.

когда я только начинал поделки на ардуине, купил нано 328р

и одна из функций моей первой поделки была измерение оборотов двигателя по датчику холла

тогда у меня еще был говнокод по полной со всеми его тормозами

так вот обычный "дигиталрид" и вывод на дисплей через СПИ на 7219 (7ми сигментный 8 разрядов) сводобно считал 15000 оборотов! (тестировал на дремеле с 15к скоростью вращения).....

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

svorog пишет:

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

не людите мозги - поставьте датчик хола и считайте его (как нажатия обычной кнопки...) арда без напрягов посчитает вам и 8 000 и 80 000 и даже 800 000 оборотов/мин

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

nik182
Offline
Зарегистрирован: 04.05.2015

ELITE пишет:

...к тому же датчик хола не имеет "дребезга"...

Очень спорное утверждение, особенно в случае вращающихся поблизости магнитомягких масс. Даже в кнопочках на датчиках хола при медленном нажимании отлично виден дребезг от микромоторики пальца. Надо брать со встроенным гистерезисом, что бы дребезга не было. Во всяком случае из самых доступных - из вентиляторов компьютера- дребезг виден замечательно.

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

конденсатор паралельно кнопке/датчика на несколько нф решает проблему (100нф примерно = 7мс)

для 8000 обм/м хватит на 3-5нф

svorog
Offline
Зарегистрирован: 27.04.2017

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

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

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

и да, зачем софтваресериал? у меги 4 аппаратных сериала!!!

svorog
Offline
Зарегистрирован: 27.04.2017
#include <Wire.h>
volatile char ABprev = 0;
const int increment[16] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};
float chetchic = 0.000;

ISR (PCINT0_vect) { //
  char AB = PINB & 3;
  chetchic += increment[AB+ABprev*4];
  ABprev = AB;
}

void setup() {
  pinMode(8, INPUT);  // A
  pinMode(9, INPUT);  // B
  PCICR |= (1 << PCIE0);  //
  PCMSK0 |= 3;
  ABprev = PINB & 3;
   Serial.begin(115200);
}

void loop() {
                                                    // Следующее действие выполням каждые 50мс
    SendData("t3.txt", "chetchic/1000");
}
void SendData(String div, String data)
{
Serial3.print(div);
Serial3.print("=\"");
Serial3.print(data);
Serial3.print("\"");
Serial3.write(0xff);
Serial3.write(0xff);
Serial3.write(0xff);
    }

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Сварог, ты в ВУЗе когда-нибудь учился? Что такое "инженерное исследование" изучал?

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

1. выводим показания энкодера в стандартный сериал, тот который виден в "мониторе порта".

2. Подключаем к Меге, к сериал3, USB-UART и проверяем, получается ли печатать в третий сериал.

3. проверяем работу Некстиона на Сериал3, без энкодера.

4. и вот теперь проверям все вместе.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Строка 23: что, по вашему мнению, должно отправляться на Nextion? Как по мне - то точно не значение счётчика, а текст для поля t3.txt, со значением "chetchic/1000"

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

ELITE пишет:

тогда у меня еще был говнокод по полной 

А сейчас у тебя что, можно поинтересоваться? Говнокод на 20-ти языках?

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

нет, теперь у меня полуговнокод на 21 языке

GarryC
Offline
Зарегистрирован: 08.08.2016

Первое - как Вы защищены от дребезга, я не увидел, или у Вас энкодер очень хороший?

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

Далее - Вы действительно хотите вывести на экран строку "chetcik/1000" или все таки значение переменной, деленное на 1000.

Ну и в заключение - Вы уверены, что Seril3 доступен, настроен и подключен к Вашему порту? И что означает выдача трех кодов 0xFF в конце сообщения?

 

svorog
Offline
Зарегистрирован: 27.04.2017

Энкодер хороший, с защитой от дребезга.

Про chetcik/1000 уже понял, поменяю, просто думал раз в через монитор порта это срабатывает то и на экран сможет вывести. ну это не вопрос сделаю доп переменную.

Про сериал 3 не уверен что настроен и подключен так как и простейший пример не смог через него работать. не подскажете как его можно настроить?

Про три 0xFF, то это по описанию библиотеки для nextion так закончивается отправка команды на дисплей - тремя байтами 0xFF.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

svorog пишет:

Про сериал 3 не уверен что настроен и подключен так как и простейший пример не смог через него работать. не подскажете как его можно настроить?

Я бы для начала попытался Serial3.begin(9600);.