Перейти к содержанию

Отрицательный Отсчет-Реверсивный Счетчик На Энкодере


ura308

Рекомендуемые сообщения

Подскажите как реализовать? реверсивный счетчик, энкодер крутит в сторону вычитания до нуля и счетчик останавливается-как сделать чтоб неостанавливалось дальше считало от нуля 1,2,3,...реверсивно

void fnBtEnc(void)

{

static uchar cButt;

static uchar cEnc;

//------------------

cButt=fnReadButt();

if(cButt)

{

lCnt=0;

fnCalc(lCnt);

}

//------------------

cEnc=Encoder_Exe();

if(cEnc != NULL_ENC)

{

switch(cEnc)

{

case PLUS_ENC:

lCnt+=1; // энкодер вправо

break;

case MINUS_ENC:

if(lCnt)lCnt-=1; //энкодер влево

break;

}

fnCalc(lCnt);

}

}

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Только начал осваивать "Си" для AVR

Архив с проектом в конце сообщения ( WinAvr 2010,симуляция Proteus 7.на семисегментниках )

Проект с радиокота http://radiokot.ru/f...hp?f=61&t=84965

Вариант с Lcd16х2 не рассматриваю - некомфортно,нечитабельно с расстояния! только на сегментных индикаторах!

Поставил дома на станок в качестве линейки,А он считает реверсивно только в одном направлении - если при резе дошел до "0" то при резе в другом направлении относительно "0" счет не происходит. Толку от него ровным счетом ноль!

У заводского на другой оси все в порядке! у него энкодер имеет выходы A ,B и Z-изменение направления.

У меня стоит обычный оптический 200 импульсов энкодер A и B выходы.

Нужно чтобы при изменении направления вращения энкодера относительно "0" (допустим после первого импульса ) -инверсировался опрос энкодера так, что бы счетчик считал как и считал ранее а минус высвечивался в зависимости он направления счета относительно "0"

Вывод на индикацию через 74HC595 чтобы освободить ножки для вывода "индикации - (Минус)"

Неплохо бы было и делитель добавить чтоб убрать погрешность (количество импульсов на 1мм)

Довести проект "до ума" Таких проектов в интернете просто нет!

Я думаю он многим будет полезен!

сам код опроса энкодера

:


//! Файл	 : button_enc.h
//!**************************************************
#include "button_enc.h"
#include "hard_config.h"
//----------------------------- Константы: -----------------------------------
enum { State0, StateA, StateB, StateAB }; //состояния энкодера
//----------------------------- Переменные: ----------------------------------
static char EncPrev;	 //предыдущее состояние энкодера
static char EncPrevPrev; //пред-предыдущее состояние энкодера
//----------------------- Инициализация энкодера: ----------------------------
void Encoder_Init(void)
{
EncPrev = State0;	 //инициализация предыдущего состояния
EncPrevPrev = State0; //инициализация пред-предыдущего состояния
PORTA=0xFF;
}
//------------------------- Обработка энкодера: ------------------------------
REZ_ENC Encoder_Exe(void)
{
char EncCur = 0;

char cRezEnc=NULL_ENC;

if(!Pin_ENC_F1) {EncCur = StateA;} //опрос фазы 1 энкодера
if(!Pin_ENC_F2) {EncCur |= StateB;} //опрос фазы 2 энкодера
if(EncCur != EncPrev)			 //если состояние изменилось,
{
if(EncPrev == StateAB &&	 //если предыдущее состояние StateAB
 EncCur != EncPrevPrev )	 //и текущее и пред-предыдущее не равны,
{
 if(EncCur == StateB) {cRezEnc= MINUS_ENC;}
 else{ cRezEnc=PLUS_ENC;}
}
//----------------------------------------------------------------------------------------------------------------
вот когда это дописал считает реверсивно!только в другом направлении вращения Но неправильно( начал пропускать импульсы)
а реверсивно в этом направлении вообще почти не считает ( на 200 импульсах в сек) а на 24 считает кое как
( в другом направлении когда считает импульсы не пропускает)
как автоматизировать процесс переключения между ними? в зависимости от направления вращения если на табло "0" или сброс в ноль
с какой переменной брать результат счетчика - или этот ноль?
что подправить чтоб импульсы не пропускал?
------------------------------------------------------------------------------------------------------------------//
else
if(EncPrev == StateAB && //если предыдущее состояние StateAB
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == StateB) {cRezEnc=PLUS_ENC;}
else{ cRezEnc= MINUS_ENC;}
}
//---------------------------------------------------------------------------------------------------------------------
EncPrevPrev = EncPrev;		 //сохранение пред-предыдущего состояния
EncPrev = EncCur;			 //сохранение предыдущего состояния
}
return cRezEnc;
}

главная функция;

//!**************************************************
//! Файл	 : main.c
//! Авторское право (с) :
//! Разработка	 : urry <urry1@rambler.ru>
//! Дата создания	 :
//! Описание
//!
//!**************************************************
#include "hard_config.h"
// определяем массив вывода и флаги
volatile sFlags_ strFlags;
volatile uchar cCalculate[DIGIT];
static unsigned long lCnt;
// определение используемых функций --------------
static void fnInit(void);
void fnBtEnc(void);
void fnLtoA(unsigned long tmp);
void fnCalc(unsigned long l);
//------------------------------------------------
//=========================================
int __attribute__((naked)) main (void)
//=========================================
{
fnInit();
for(;
{
if(strFlags.bTick)
{
strFlags.bTick=false;
fnBtEnc();
if(BITTST0(PINA,1))// пропадание напряжения !
{
fnEepSave(lCnt); // записываемся
off:
asm("wdr");
goto off;// до сброса питания ничего не делаем
}
} //end strFlags.bTick
asm("wdr");
}// end for
}// end main
//=========================================
//-----------------------------------------
static void fnInit(void)
{
DDRD=0;
DDRD|=(1<<R_1)|(1<<R_2)|(1<<R_3)|(1<<R_4)|(1<<R_5);
PORTD=0xFF;
DDRB=0xFF;
// Timer/Counter 0 initialization
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;
// Universal Serial Interface initialization
USICR=0x00;
// Analog Comparator initialization
ACSR=0x80;
asm("wdr");
wdt_enable(WDTO_1S);
lCnt=fnEepRead();
fnCalc(lCnt);
strFlags.bReady=1;
Encoder_Init();
//--------------------------------
sei();
}
//------------------------------------
void fnBtEnc(void)
{
static uchar cButt;
static uchar cEnc;
//------------------
cButt=fnReadButt();
if(cButt)
{
lCnt=0;
fnCalc(lCnt);
}
//------------------
cEnc=Encoder_Exe();
if(cEnc != NULL_ENC)
{
switch(cEnc)
{
case PLUS_ENC:
lCnt+=5;
break;
case MINUS_ENC:
if(lCnt)lCnt-=5;
break;
}
fnCalc(lCnt);
}
}
//------------------------------------
void fnLtoA(unsigned long tmp)
{
const unsigned long step[DIGIT]={10000,1000,100,10,1};
uchar i,atemp;
unsigned long val,temp;
char flag=0;
val=tmp;
for (i=0; i<DIGIT; i++)
{
if(i==3){flag =1;}
temp=step[i];
atemp=0;
while(val >= temp)
{
atemp++;
val-=temp;
}
if((flag) || (atemp))
{
 cCalculate[i]=atemp;
 flag=1;
}
else{cCalculate[i]=10;}
}
}
//------------------------------------
void fnCalc(unsigned long l)
{
if(l >= 99999){l=0;}
fnLtoA(l);
strFlags.bReady=1;
}
//------------------------------------

kot_impuls_metr_05.rar

Изменено пользователем ura308
Ссылка на комментарий
Поделиться на другие сайты

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

  • 1 год спустя...

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

надуманная проблема.

в какой-то точке есть "0" энкодера.

крутим вправо - счетчик увеличивается - получаем положительное число.

крутим влево - счетчик уменьшается. при переходе через ноль после декремента получаем число 0xFFFF. это уже ОТРИЦАТЕЛЬНОЕ  число и равно -1.

ну, и так далее, получаем отрицательные числа.

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

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

для двухбайтового числа имеем максимальное положительное число 32767 и минимальное отрицательное -32768.

думаю, такого диапазона координаты должно хватить.

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

В 27.02.2016 в 13:28, ura308 сказал:

if(EncPrev == StateAB && //если предыдущее состояние StateAB

EncCur != EncPrevPrev ) 

{

...

}

else

if(EncPrev == StateAB && //если предыдущее состояние StateAB

EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,

Это что за чудо??? Типа:

Если условие не выполнилось

(EncPrev == StateAB && EncCur != EncPrevPrev ) 

, проверим еще раз ничего не меняя, вдруг оно со второго раза выполнится???? Рассчитываете на глюк процессора???

Что вы добавили???

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Очень сложное решение простой проблемы.

Ловим, допустим, передний фронт на INTO (один вывод энкодера) и считываем состояние второго вывода энкодера.

Если там 1 - в одну сторону крутится, 0 - гарантированно в другую.

//функция обработчик внешнего прерывания INT0
ISR( INT0_vect )
{
	cw = 0;
	ccw = 0;
	if (PIND & (1 << PIND1))
	{
		cw = 1;
	}
	else
	{
		ccw = 1;
	}
}

int main(void)
{
  while(1)
		if(cw+ccw > 0)
		{
    		//////////////
			cw = 0;
			ccw = 0;
		}
  }
}

 

Ссылка на комментарий
Поделиться на другие сайты

В 28.12.2017 в 21:57, Darth_Vader сказал:

Ловим, допустим, передний фронт на INTO (один вывод энкодера) и считываем состояние второго вывода энкодера.

Если там 1 - в одну сторону крутится, 0 - гарантированно в другую.

А если энкодер разболтан, его случайно коснулись и он дернул ИНТ0? Засчитаете вращение? Это самый неправильный алгоритм.

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

Изменено пользователем Zhuk72
Ссылка на комментарий
Поделиться на другие сайты

  • 4 недели спустя...

Хорошие энкодеры работают годами и дребезг граничного положения как правило можно скомпенсировать как программно так и аппаратно.

Но если энкодер дешёвый, то при неправильно настроенной оптике могут происходить чудеса.

Пока ты жив, надежда есть.

Ссылка на комментарий
Поделиться на другие сайты

  • 2 года спустя...

Всем привет! Не отвечал по теме так как были утеряны файлы проекта.

Возможно кому то и пригодится в своих проектах 

Код был частично изменен и доработан;

1: Переход через ноль. но без индикации "минус" ( не заморачивался с отриц. показаниями).

2:  Была увеличена скорость обработки (энкодер на 400 импульсов).

      Скорость измерения около 1м в секунду-без пропусков шагов.

      С индикацией 1или 2 знака после запятой.

3: Вот само решение переход через "0" .Основные изменения в коде;

   //------------------
    cEnc=Encoder_Exe();
    if(cEnc != NULL_ENC)
    {
        switch(cEnc)    // считаем от нуля в обе сторны реверсивно
        {
        case PLUS_ENC:
            if(lCnt == 0 && (signed long)(lCnt + incStep) < 0)
                incStep *= -1; 
            lCnt+=incStep;   
            break;
        case MINUS_ENC:
            if(lCnt == 0 && (signed long)(lCnt - incStep) < 0)
                incStep *= -1; //на 1имп число на табло 10 десятки мм на табло
            lCnt-=incStep;   
            break;
            
        }
        
        fnCalc(lCnt);
    }
}        
//-----------------------------------

Даташит.rar Прошивка.rar схема.rar Счетчик исходник WinAVR-2010.rar

Изменено пользователем Falconist
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • @donec  должна, но в disk_initialize нет ретурнов... и у ТСа нет понимания работы файловой системы, вопрос, для чего он взялся за этот проект ?
    • Заинтересовали. Положение с 1 поста не открывается. Скорее всего пытаются сделать что то типа "цифровой подстанции" для экономии меди.
    • Удивительно, но нет. Вот подсказка, для чего именно нужен форум: https://www.google.com/search?client=opera&q=для+чего+нужен+форум&sourceid=opera&ie=UTF-8&oe=UTF-8 А вам, @John33-11 , нужна халявная техподдержка. Чуете разницу?
    • так бы сразу и сказал, что сознательно занимаешься издевательством. если тайм-аут закончился, то МК уже перешел на записанную прошивку и бессмысленно пытаться установить соединение. а если записан только загрузчик и остальная флешь чистая, то после окончания тайм-аута процессор быстренько пробежит с нулевого адреса до загрузчика, и опять начнется время ожидания. то есть, с "пустой" флешью можно делать соединение через любое время после подачи питания или сброса МК.
    • У тебя с чтением или пониманием плохо? перечитай предыдущий пост и приведи пример тиристора/симистора с указанными параметрами. ссылки на 800А тиристоры меня не интересуют. и да класс тиристора не определяется буквами.
    • С чего вы взяли что это бессмысленная  тема ???? . Ведь для чего нужен форум разве не для помощи ???? . Написал же выше что ошибка 56 без буквы . При включении в сеть беговой дорожки начинается загрузка и виснет она на надписи APP (приложение ).  Если вытащить ключ безопасность она на него реагирует как положено, но когда его ставишь обратно пишет ошибка 56.   Я создал эту тему для того может быть кого нибудь был опыт с ремонтом беговых дорожек . На плате управления стоит МК NUVOTON NUC126S4AE. Может быть у кого есть прошивка этого чуда. Part Number A1848C3.  До этого дорожка работала на ней побегали и выключили .
    • ""без соединения пытаться делать запись - некорректно и неразумно."" - это для разумных хомосапиенс, а для мартышек ...?! Конечно я не АВТОР, но если-бы меня спросили, я бы заблокировал нажатие кнопок "выбор файла", "запрограммировать" до нужного состояния соединения с МК (догадайся САМ какого...) А соединение не устанавливается, потому что я мухлюю, я жду больше положенного времени и жму кнопку соединиться, чтобы выявить нештатные ситуации. Я много писал для сторонних пользователей, и если инструкцию написать на лбу и поставить зеркало, все равно сделают неправильно, нужны коридоры действий, ... шаг влево, шаг вправо ... А по поводу смены скоростей, это просто особенность, не на что не влияющая, - не заморачивайся.  
×
×
  • Создать...