Преобразование сигнала с энкодера delta инкрементного оптического в напряжение

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013

Здравствуйте, требуется объяснить суть, так как не могу понять самого принципа. Есть два поворотных инкрементых оптических энкодера, полученные с них сигнала надо записать а затем преобразовать  в управляющее напряжение для поворота на такой же угол, код для обработки сигналов с датчиков составил, но дальше не могу понять, с чего начать.Направьте слабого программиста в нужное русло.

maksim
Offline
Зарегистрирован: 12.02.2012

Чо?

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

попробуйте ф-ей map

пусть ваш датчик  имеет 3600 отсчетов на поворот, управляете с помощью ЦАП(?): например он 10 разрядный(0-1023)

x = <значение енкодера>;
x = map(x,0,3599,0,1023); //приводим значение угла к диапазону значений для ЦАП

дальше пихаем в ЦАП, ето самый простоц вариант :)

 

 

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013

Michal пишет:

попробуйте ф-ей map

пусть ваш датчик  имеет 3600 отсчетов на поворот, управляете с помощью ЦАП(?): например он 10 разрядный(0-1023)



x = <значение енкодера>;
x = map(x,0,3599,0,1023); //приводим значение угла к диапазону значений для ЦАП

дальше пихаем в ЦАП, ето самый простоц вариант :)

 

 

спасибо, буду пробовать))

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013

maksim пишет:

Чо?

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

maksim
Offline
Зарегистрирован: 12.02.2012

Какого двигателя?

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013

Двигатель постоянного тока

maksim
Offline
Зарегистрирован: 12.02.2012

Угол поворота двигателя постоянного тока не зависит от напряжения питания. Чтобы повернуть вал DC-двигателя на определенный угол нужен энкодер. А вот чтобы не "проскакить" заданный угол нужна возможность управления током DC-двигателя, для этого можно воспользоваться ШИМом.

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

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

короче какой вопрост, такой ответ :)

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013

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

maksim
Offline
Зарегистрирован: 12.02.2012

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

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013

Максим, примерный код с запуском и считыванием вот такой (прошу не ругать, может что не так) Энкодер с фазами A B Z

MEXATPOHuK
Offline
Зарегистрирован: 25.03.2013
  /*
  Управляем системой позиционирования.
  */
  // задаем константы
  const int buttonPin1 = 13;
  const int buttonPin = 2;     // номер входа, подключенный к кнопке
  const int dpt1 = 3;          // номер входа, управляющего двигателем 1
  const int dpt2 = 6;          // номер входа, управляющего двигателем 1
  const int dpt3 = 9;          // номер входа, управляющего двигателем 2
  const int dpt4 = 11;         // номер входа, управляющего двигателем 2
  const int encoder0pinA = 4;  // номер входа, фаза А энкодера 0
  const int encoder0pinB = 5;  // номер входа, фаза B энкодера 0
  const int encoder0pinZ = 7;  // номер входа, фаза Z энкодера 0
  const int encoder1pinA = 8;  // номер входа, фаза А энкодера 1
  const int encoder1pinB = 10;  // номер входа, фаза B энкодера 1
  const int encoder1pinZ = 12;  // номер входа, фаза Z энкодера 1
  volatile long encoder0Pos = 0.0;        //  переменная в обработчике прерываний по подсчету импульсов
  volatile long encoder0Rotations = 0.0;  // переменная по подсчету оборотов.
  volatile long encoder1Pos = 0.0;        //  переменная в обработчике прерываний по подсчету импульсов
  volatile long encoder1Rotations = 0.0;  // перем
  // переменные
  int val;
  int buttonState = 0; 
  int buttonState1 = 0;
  // переменная для хранения состояния кнопки
  void setup() {
  pinMode(3, OUTPUT);         // уствановка 3 пина в состояние выхода
  pinMode(6, OUTPUT);        // установка 6 пина в состояние выхода
  pinMode(9, OUTPUT);        // установка 9 пина в состояние выхода
  pinMode(11, OUTPUT);      // установка 11 пина в состояние выхода
  pinMode (encoder0pinA,INPUT);
  pinMode (encoder0pinB,INPUT);
  pinMode (encoder0pinZ,INPUT);
  pinMode (encoder1pinA,INPUT);
  pinMode (encoder1pinB,INPUT);
  pinMode (encoder1pinZ,INPUT);
  pinMode(buttonPin, INPUT); // инициализируем пин, подключенный к кнопке, как вход
  pinMode(buttonPin1, INPUT);
  attachInterrupt(0, doEncoderA, RISING);          //функция обработки внешнего прерывания INT0
  attachInterrupt(1, doEncoderZ, RISING);        //функция обработки внешнего прерывания INT1
  Serial.begin (9600); 
  Serial.println("START READING");
  }
  void loop(){
  // считываем значения с входа кнопки
  buttonState = digitalRead(buttonPin);
  buttonState1 = digitalRead(buttonPin1);
  // проверяем нажата ли кнопка
  // если нажата, то buttonState будет HIGH:
  if ((buttonState == HIGH) && (buttonState1 == HIGH)) {    
  // включаем светодиод    
  digitalWrite(3, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(11, LOW);
  }
  else {     // Здесь будет автоматический режим
  // выключаем светодиод
  digitalWrite(3, LOW);
  digitalWrite(6, LOW);
  digitalWrite(9, LOW);
  digitalWrite(11, LOW);
  }// здесь будет автоматический режим
  void doEncoderA(){                                    // функция действие вызываемое прерыванием1
	  // look for a low-to-high on channel A
	  if (digitalRead(encoder0PinA) == HIGH) { 
	    // check channel B to see which way encoder is turning
	    if (digitalRead(encoder0PinB) == LOW) {  
	      encoder0Pos = encoder0Pos + 1;         // по Ч.С.
	    } 
	    else {
	      encoder0Pos = encoder0Pos - 1;         // против Ч.С.
	    }
	  }
	  else   // must be a high-to-low edge on channel A                                       
	  { 
	    // check channel B to see which way encoder is turning  
	    if (digitalRead(encoder0PinB) == HIGH) {   
	      encoder0Pos = encoder0Pos + 1;          // по Ч.С.
	    } 
	    else {
	      encoder0Pos = encoder0Pos - 1;          // против Ч.С
	    }
	  }
	}   
	void doEncoderZ()
	  {
	    if(digitalRead(encoder0PinZ) == HIGH)
	      {
	      encoder0Pos = 0;
	      encoder0Rotations = encoder0Rotations +1;
	   //   delay(50);
	      }
	   }
	void doEncoderA(){                                    // функция действие вызываемое прерыванием1
	  // look for a low-to-high on channel A
	  if (digitalRead(encoder1PinA) == HIGH) { 
	    // check channel B to see which way encoder is turning
	    if (digitalRead(encoder1PinB) == LOW) {  
	      encoder1Pos = encoder1Pos + 1;         // по Ч.С.
	    } 
	    else {
	      encoder1Pos = encoder1Pos - 1;         // против Ч.С.
	    }
	  }
	  else   // must be a high-to-low edge on channel A                                       
	  { 
	    // check channel B to see which way encoder is turning  
	    if (digitalRead(encoder1PinB) == HIGH) {   
	      encoder1Pos = encoder1Pos + 1;          // по Ч.С.
	    } 
	    else {
	      encoder1Pos = encoder1Pos - 1;          // против Ч.С
	    }
	  }
	}   
	void doEncoderZ()
	  {
	    if(digitalRead(encoder1PinZ) == HIGH)
	      {
	      encoder1Pos = 0;
	      encoder1Rotations = encoder0Rotations +1;
	   //   delay(50);
	      }
	   }
void loop ()
	{
	Serial.print("  ");
	Serial.print(encoder0Pos);
	Serial.print("  ");
	Serial.print(encoder0Rotations);
	Serial.print(" \n ");
	delay(10);
        Serial.print("  ");
	Serial.print(encoder1Pos);
	Serial.print("  ");
	Serial.print(encoder1Rotations);
	Serial.print(" \n ");
	delay(10);
	}
asem7167155
asem7167155 аватар
Offline
Зарегистрирован: 17.05.2015

Прошу помощи в разработке механизма (на базе асинхронного МОТОР-РЕДУКТОРА) для решения задачи ПОЗИЦИОНИРОВАНИЯ. Делаю станки для деревопереработке, ранее решал данный вопрос посредством винта и ручки - механически. Заранее благодарен. Александр. тел. (901) 3167155,  www.7167155.ru.

maksim
Offline
Зарегистрирован: 12.02.2012

Александр,  в данной сфере телефон не самый лучший способ начинать общение. Отписал вам на почту.

aleksandr_lal
Offline
Зарегистрирован: 28.10.2015

С инкрементными энкодерами легче так работать:

  attachInterrupt(0, blink1, CHANGE);
  attachInterrupt(1, blink2, CHANGE);

boolean A, B; //датчики
float P;      //счетчик срабатываний


void blink1() { //прерывание первого
A = digitalRead(2);
B = digitalRead(3);
if (B == A) P = P + 1;
else P = P - 1;
}

void blink2() { //прерывание второго
A = digitalRead(2);
B = digitalRead(3);
if (B != A) P = P + 1;
else P = P - 1;
}

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

 

Вопрос к гуру: Как к такому алгоритму привязать серву? если точнее, то не просто серву, а изуродованную: потенциометр выпаян, запаяны резисторы по 4,99кОм-1% (даже с 1% есть температурный дрейф точки останова в позициях 79-82 градуса поворота), выход сервы не на двигатель, а на опторазвязку и Н-мост, а уже с моста - двигатель постоянного тока с энкодером от принтера. Вопрос как отсчитать заданное количество шагов энкодера и остановить двигатель (провернуть псевдосерву до точки останова), если шагов 20-100 тысяч примерно, чтобы отмерять длинну? Неделю ломаю голову, а полезных мыслей ноль.

asem7167155
asem7167155 аватар
Offline
Зарегистрирован: 17.05.2015

Кто может вывести из  штанген циркуля информацию в контроллер для его переработки, прошупомощи. Хочу измерять линейный размер (диаметр бревна) и рассчитывать его объем в зависимости от длины. Заранее благодарен УМЕЛЬЦАМ. www.7167155.ru asem@mail.ru

 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Ну вы задали вопрос. Какой штангельциркуль? Модель, документация на него.

asem7167155
asem7167155 аватар
Offline
Зарегистрирован: 17.05.2015

Цифровой (электронный) штанген циркуль. Там имеется выход на USB. Также имеется аналогичная цифровая линейка, имеется видеоролик в YouTube подающий идею  и направление. Мне нужен конкретный СКЭТЧ и техническое решение. Заранее благодарен.

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Если не трудно, то дайте ссылку на видеоролик и модель вашего штангельциркуля. Посмотрю.

asem7167155
asem7167155 аватар
Offline
Зарегистрирован: 17.05.2015
asem7167155
asem7167155 аватар
Offline
Зарегистрирован: 17.05.2015

Исходный текст программы можно взять здесь: https://app.box.com/s/88rwv28cmgd1thz

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

qwone пишет:

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

да, ладно - всё уже выточено:

 

f5d135cs-960.jpg

ecd135cs-960.jpg

 

 

 

 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

asem7167155 пишет:
https://youtu.be/7CsvxNz6K50

Так здесь уже есть схема. Я бы конечно сделал понадежней, а не просто на двух транзисторах.

AlexeySh
Offline
Зарегистрирован: 16.01.2017

asem7167155 пишет:
Исходный текст программы можно взять здесь: https://app.box.com/s/88rwv28cmgd1thz

Ссылка не работает.

asem7167155
asem7167155 аватар
Offline
Зарегистрирован: 17.05.2015

Я предполагаю сделать проще. Делюсь ЗАМЫСЛОМ: Диапазон поступающих бревен планируется от 120мм до 260мм (тонкомер), причем, измерять планируется ШТАНГЕН-ЦИРКУДЕМ в 150мм  (начиная от 120мм до 270мм), а уже далее (программно в контроллере) прибавлять КОНСТАНТУ в 100-120мм. Также планируется приспособа в виде КОЛЕСА и ШТАНГИ. Бревно подается в станок продольно, давит на КОЛЕСО, оно поднимается в зависимости от ДИАМЕТРА, а Ш-Ц в это время меряет НЕОБХОДИМОЕ и вся эта информация поступает в контроллер для вычислений. Механикой - просьба НЕ заморачивайться. Требуется програмно-электронная ЧАСТЬ. ВСЕМ удачи и хорошего творческого настроения. Изготавливаемые станки на сайте www.7167155.ru Хочу ИХ оснастить "интеллектом". Толковых умельцев прошу подключиться.

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Программно-электронную часть сделать могу. Особых проблем не вижу. Для обсуждения пишите в скайп alexey_shokarev

AlexeySh
Offline
Зарегистрирован: 16.01.2017

А вообще использовать штангельциркуль для измерений бревен не лучший вариант. Могу предложить более подходящее для станка решение.