параллельные процессы_выдача частоты 6кГц, опрос НХ711, выдача Serial

vasus
Offline
Зарегистрирован: 18.05.2017

Задача такая, необходимо выдавать на ногу сигнал частотой до 6кГц (управление шаговиком), опросить датчик веса и дать информацию по ком порту.

пробовал это осуществить на плате НАНО. Но вывод числа порядка десятков тыщ, по серийнику у меня занимал около 600мкс, что ни как не получаестя до нужной частоты, а тут ещё и опрос датчика... 

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

или для этого нужна другая плата, например МЕГА2560, потомучто там как то удается управлять с такой скоростью шаговиками, опршивать АЦП и выводить все на экран и в ком порт? 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Возможно. Мега НЕ БЫСТРЕЕ ! У нее просто больше мозгов, памяти и переферии. Используйте прерывания. Сигнал на шаговик генерите апаратными ногами таймера.

vasus
Offline
Зарегистрирован: 18.05.2017

вот этого я пока не знаю, как толком работать с таймерами... я правильно понимаю, что я могу задать таймеру задачу по генерации импульсов и параллельно выполнять loop()

b707
Offline
Зарегистрирован: 26.05.2017

vasus пишет:

вот этого я пока не знаю, как толком работать с таймерами... я правильно понимаю, что я могу задать таймеру задачу по генерации импульсов и параллельно выполнять loop()

да, правильно.

Кстати, библиотеку HX711 в вашем случае тоже лучше доработать, так как она вешает контроллер на время измерения - примерно по 70мс на каждый отсчет.

b707
Offline
Зарегистрирован: 26.05.2017

про "нюансы" библиотеки HX711.h - см тут

vasus
Offline
Зарегистрирован: 18.05.2017

спасибо про "нюансы", значт надо как-то избавиться от wile:)

тогда дальше, можно ли , чтобы таймер перестал тикать через заданное мной колличество "тиков" ,

и подскажите, пожалуйста, как им пользоваться, а то вот здесь почитал 

http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-bl...

но пока не совсем понятно, можно ли его вызывать отдельно, какой нить командой из loop(), будут ли читать ся переменные ( если я буду менять делитель и прочее)

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

 

b707
Offline
Зарегистрирован: 26.05.2017

по таймерам еще вот эту ветку советую http://arduino.ru/forum/programmirovanie/preryvaniya-po-taimeru

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

vasus пишет:

...вывод числа порядка десятков тыщ, по серийнику у меня занимал около 600мкс, что ни как не получаестя до нужной частоты, а тут ещё и опрос датчика... 

Эти цифры можно существенно улучшить, нужжно только знать, что именно Вы выводите, как и с какой целью.

vasus пишет:

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

Видите ли, Ардуино - это концепция, которая подразумевает унифицированный доступ к аппаратным средствам различных контроллеров. Такой подход приводит к тому, что:

1. Используются далеко не все возможности каждого конкретного контроллера.

2. Те возможности, что используются, используются, как правило, неэффективно.

Для многих задач этого хватает. Но в тех случаях, когда - нет, приходится переходить от концепции Ардуино к работе с конкретным контроллером. Т.е. как раз к тому, для чего предназначены дэйташиты.

vasus
Offline
Зарегистрирован: 18.05.2017

andriano пишет:

Эти цифры можно существенно улучшить, нужжно только знать, что именно Вы выводите, как и с какой целью.

Ну так да, напрмер поделить на 1000, но планируется посылать всё на серийник в комп. а там уж , чтобы студенты сами у меня калибровали в качестве образования, чтобы учились... а не провели испытания, записали результаты и до свидания.

andriano пишет:

Видите ли, Ардуино - это концепция, которая подразумевает унифицированный доступ к аппаратным средствам различных контроллеров. Такой подход приводит к тому, что: 1. Используются далеко не все возможности каждого конкретного контроллера. 2. Те возможности, что используются, используются, как правило, неэффективно. Для многих задач этого хватает. Но в тех случаях, когда - нет, приходится переходить от концепции Ардуино к работе с конкретным контроллером. Т.е. как раз к тому, для чего предназначены дэйташиты.

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

 

vasus
Offline
Зарегистрирован: 18.05.2017

Спасибо, кажется стал понемногу понимать работу таймеров.

Но, при просмотре Этюда http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-blink-i-bez-delay-i-bez-millis возникли вопросы

TCCR1A = 0x40. Это запись в регистр, устанавливает как рабоать выводу 9, записывает биты 010000000

TCCR1B = 0x08 | prescaler. Здесь записывает 1000, а потом добавляет 0101 в итоге 1101. Если со второй частью понятно, то вот первая записывает 3-й бит регистра, что по данному источнику http://samou4ka.net/page/tajmer-schetchik-mikrokontrollerov-avr включает ШИМ... об этом не говорил и хотелось знать зачем.

TCCR1A &= ~0xC0; зачем инвертирровать, нельзяли сразу 3F... или же вообще записать в регистр то, что нужно без оператора обнуления

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

Можно , конечно , в ЛУП() прикинуть время и через миллис его остановить. но при выдаче в серийник может возникнуть задержка.

 

 

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

vasus пишет:

andriano пишет:

Эти цифры можно существенно улучшить, нужжно только знать, что именно Вы выводите, как и с какой целью.

Ну так да, напрмер поделить на 1000...

Вот как раз этого - не надо. Деление - очень медленная операция, на AVR выполняется 680 тактов. Если хочется поделить, делите на степени двойки, например, на 1024, - компилятор соптимизирует до сдвига, и будет во много раз быстрее.

Но Вы не ответили ни на один вопрос: что? как? с какой целью? Поэтому что-то порекомендовать весьма затруднительно.

Цитата:

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

Тут, скорее, несколько другое: сам котроллер формально обладает такими же возможностями, как и любой другой компьютер (с полной системой команд). На ПК мы привыкли, что ВСЕ задачи решаются программно, а здесь - для многих задач более оптимально аппаратное решение. А аппаратные средства, в отличие от ЦПУ, в разных контроллерах довольно разнообразны.

vasus
Offline
Зарегистрирован: 18.05.2017

andriano пишет:

Но Вы не ответили ни на один вопрос: что? как? с какой целью? Поэтому что-то порекомендовать весьма затруднительно.

Прошу прощение, вроде в начале вкраце обрисовал....

В общем задача такая, по команде с сом-порта запустить вращение шаговика с заданной скоростью и на определенное количество оборотов. Параллельно опрашивать НХ711 и выдавать в сом-порт, плюс время опроса. Можно, думаю, каждые 100мс. Ожидаемое количество подаваемых импульсов около 110000, частота 10кГц. Поэтому будет первое переполнение точно.

вот набросал скеч, отрабатывал, смотрел что как в протеусе (дабы не мучать контроллер:) )

и вот мне не понятно... почему задержка перет первым запуском таймера порядка 4с... а потом он включается/выключается на раз

 

#include <Q2HX711.h>

enum Prescalers {
  PRESCALER_1 = 1, PRESCALER_8 = 2, PRESCALER_64 = 3, PRESCALER_256 = 4, PRESCALER_1024 = 5
};
uint8_t prescaler = PRESCALER_1024;
  uint16_t topValue = 0;
  const byte hx711_data_pin = A2;
const byte hx711_clock_pin = A3;
int T = 0;
int z=0;
int F=0;

Q2HX711 hx711(hx711_data_pin, hx711_clock_pin);
  
void setup() {
  
  pinMode(9, OUTPUT);
  pinMode(7, INPUT);
  digitalWrite(7, LOW);
   TCCR1A &= 0x3F;
  TCCR1B = 0x08 | prescaler;  // Установить СТС режим и делитель частоты
  OCR1A = topValue;       //  установить TOP равным topValue
  Serial.begin(115200);
 T = millis();
}

void loop() {
 z = millis();
  if (digitalRead(7)==HIGH){ TCCR1A = 0x40;}
   else {    TCCR1A &= 0x3F;   }
  if (z-T>=10) {
  F = Serial.read(); Serial.print(hx711.read()/100.0); T=z; }
  
  }
 
void timer(){
  TCCR1A = 0x40;          //  Инвертирование пина 9 по сравнению
 }
vasus
Offline
Зарегистрирован: 18.05.2017

vasus пишет:

Ожидаемое количество подаваемых импульсов около 110000, частота 10кГц. Поэтому будет первое переполнение точно.

упс, кажись тупанул.... ведь таймер переполняется и переключает пин... поэтому мне нужно порядка 110 000 переполнений или даже 220 000.... ну это детали... во время отладки выясню... главне суть уловить

vasus
Offline
Зарегистрирован: 18.05.2017

Вот набросал код

enum Prescalers {
  PRESCALER_1 = 1, PRESCALER_8 = 2, PRESCALER_64 = 3, PRESCALER_256 = 4, PRESCALER_1024 = 5
};
uint8_t prescaler = PRESCALER_1024;
  uint16_t topValue = 0;

int T = 0;
int z=0;
int F=0;
long n=1;

  
void setup() {
  
  pinMode(9, OUTPUT);
  pinMode(7, INPUT);
  digitalWrite(7, LOW);
   TCCR1A = 0x40;
  TCCR1B = 0x08 | prescaler;  // Установить СТС режим и делитель частоты
  OCR1A = topValue;       //  установить TOP равным topValue
  TIMSK1 = 0x01;
  Serial.begin(115200);
 T = millis();
}


void loop() {
 z = millis();
  if (z-T>=100) {
  F = Serial.read(); Serial.print("x"); Serial.print(n); T=z; }
   }
 
ISR(TIMER1_OVF_vect){
n++;
if (n>=100) {TCCR1A &= 0x3F;}
}

но почему-то счет переменной n происходит один раз, какбудто вызывается один раз

 

sadman41
Offline
Зарегистрирован: 19.10.2016

n - не volatile, вне обработчика прерывания работаете с ней не атомарно. Не знаю, сказывается ли это на поведении кода в данном случае, но делать так не стоит: http://arduino.ru/forum/apparatnye-voprosy/takhometr-daewoo-matiz-08#com...

vasus
Offline
Зарегистрирован: 18.05.2017

Добавил volatile в начале. ничего не поменялось.... :(

вызывается просто один раз в самом начале, прибавляет 1 и все

vasus
Offline
Зарегистрирован: 18.05.2017

АААААА, НАШЕЛ! у мея таймер по сравнению и вектор тоже нужен по сравнению... все заработало:)

ssss
Offline
Зарегистрирован: 01.07.2016

vasus пишет:

В общем задача такая, по команде с сом-порта запустить вращение шаговика с заданной скоростью и на определенное количество оборотов. Параллельно опрашивать НХ711 и выдавать в сом-порт, плюс время опроса. Можно, думаю, каждые 100мс. Ожидаемое количество подаваемых импульсов около 110000, частота 10кГц.

В общем... такое на МК сделать можно...

Возьмём идеальную модель и самый тяжёлый случай... когда всё происходит одновременно...

1. Для генератора импульсов нужны два таймера... Один генерит меандр нужной частоты... другой (типа ворота) блокирует первый по достижению нужного количества импульсов...

2. ЮАРТ на приём и передачу хардварно...

3. Опрашивать НХ711 тоже желательно хардварно...

В принципе... даже копеечный СТМ32Ф030 с этим легко справится... но без либ и ардуино... Пункт 1 обеспечивается хардварно... и никаких ресурсов ЦП вообще не требует... Пункт 2 тоже никаких трудностей не вызывает... особенно если подвязать ДМА... Пункт 3 реализуется на таймере и ДМА... практически хардварно... Остаётся всё это только связать между собой... для передачи полученных данных и обработки... что уже не требует  особой срочности...

На меге это всё сделать... будет очень тяжело... быстрее даже невозможно...

 

vasus
Offline
Зарегистрирован: 18.05.2017

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

2. как хардварно ЮЗАРТ пользовать не вкурсе. Пользуюсь стандартно Serial.....

3. тоже беру библиотеку Q1HX711(кажется так)

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