Ви не увійшли.
Сторінки 1
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
//volatile boolean flag
volatile boolean flag_CW = 0; // переменные тригерра направления.
volatile boolean flag_CWW = 0; // переменные тригерра направления.
boolean enc_A = 2; //переменные входа фазы A.
boolean enc_B = 3; //переменные входа фазы B.
unsigned int update_lcd = 0; //переменная обновления экрана. своеобразное прерывание.
volatile int place_enc; // переменная.
void setup()
{
pinMode(6, INPUT_PULLUP); // настройка пина кнопки на вход, включае поддяжку.
pinMode(enc_A, INPUT);
pinMode(enc_B, INPUT);
attachInterrupt(0, scan_enc, FALLING); //прерывание INT0. 1>0
attachInterrupt(1, flag_reset, RISING); //прерывание INT1. 0>1
lcd.begin(16, 2); //старт lcd.
}
void loop()
{
if (digitalRead(6)==0) //сброс.
{
place_enc = 0;
}
if (update_lcd==0)
{
lcd.setCursor(0,0); //курсор.
lcd.print("Place="); //выводит текст.
lcd.print(place_enc); //выводит значение переменной P.
lcd.print(" "); //выводит выводит пробел.
update_lcd = 2048;
}
update_lcd = update_lcd-1;
}
void scan_enc()
{
if(flag_CW == 1){goto exit;}
if((digitalRead(enc_B)==1))
{
place_enc ++;
flag_CW = 1;
flag_CWW = 0;
}
if(flag_CWW == 1){goto exit;}
if((digitalRead(enc_B)==0))
{
place_enc --;
flag_CWW = 1;
flag_CW = 0;
}
exit:;
}
void flag_reset()
{
if ((digitalRead(enc_A)==1) && (flag_CW = 1))
{
flag_CW = 0;
}
if ((digitalRead(enc_A)==0) && (flag_CWW = 1))
{
flag_CWW = 0;
}
//flag_CW = 0;
}
=========================================================================================
Ардуино приводит меня в ступор, есть код опроса энкодера у меня он на 1250 импульсов на оборот, он взять из программы написанной на СИ и на Tiny2313 работает без проблем он немного не такой там нет флагов flag_CW flag_CWW там просто есть флаг flag который устраняет ложное срабатывание от тряски на одном месте при большом количестве импульсов это актуально. Но ардуино не пропускает этот код:
============================================================
Arduino: 1.6.9 (Windows XP), Плата:"Arduino Nano, ATmega328"
collect2.exe: error: ld returned 5 exit status
exit status 1
Ошибка компиляции для платы Arduino Nano.
============================================================
Gришлась городить вот эти двойные опросы. Но проблема не только в этом, она в том? что энкодер считает только в плюс? я просто в недоумении в чем проблема
Неактивний
goodspeedmen А чем вам это не подошло?
//#1 энкодер
const int reset_pin=6; // кнопка сброса показаний 0 нажата /1 нет
volatile int place_enc; // количество импульсов
const int enc_A_pin = 2;// нога на энкодер фазы A прерывание 0
const int enc_B_pin = 3; // нога на энкоде фазы B.
void scan_enc() { // функция работающая по прерыванию 0 подсчет импульсов
if(digitalRead(enc_B_pin))place_enc++;
else place_enc--;
}
//#2 экран
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
void setup(){
//#1 энкодер
pinMode(reset_pin, INPUT_PULLUP); // настройка кнопки сбоса показаний
pinMode(enc_A_pin, INPUT);
pinMode(enc_B_pin, INPUT);
attachInterrupt(0, scan_enc, FALLING); //прерывание INT0. 1>0
//#2 экран
lcd.begin(16, 2);
}
void loop(){
//#1 энкодер
if (!digitalRead(reset_pin)) place_enc = 0; //сброс счетчика импульсов
//#2 экран обновление раз в 0,5 секунды
static uint32_t future2 = 0 ;
if (millis() >= future2) {
future2 = millis() + 500 ;
lcd.setCursor(0,0) ; //курсор.
lcd.print("Place=") ; //выводит текст.
lcd.print(place_enc) ; //выводит значение переменной P.
lcd.print(" ") ; //выводит выводит пробел.
}
}
Неактивний
У меня не было этого кода, хотя по сути он не чем не отличается, только нет защит от дребезжания на энкодоре. Ради интереса залью сейчас посмотрю что получится Обновление два раза в секунду маловато
Опробовал:
Да как я и сказал нет защиты от вибрации на валу енкодера? стоя на месте от вибрации счет уменьшается или прибавляется.
Не понятно как работает эта функция?
enc_B_pin от куда он берет аргумент из прерывания на 0. То есть если 0 по ++ если нет то --?
значит если нет {} в операторе if то он берет аргумент из главной функции?
void scan_enc() { // функция работающая по прерыванию 0 подсчет импульсов
if(digitalRead(enc_B_pin))place_enc++;
else place_enc--;
}
Остання редакція goodspeedmen (2016-10-03 19:01:18)
Неактивний
разберем это attachInterrupt(0, scan_enc, FALLING);
Консультируемся по этому. http://arduino.ru/Reference/AttachInterrupt
0 это interrupt: номер прерывания то есть на ноге 2
scan_enc это обработчик прерываний.
FALLING прерывание вызывается только при смене значения на порту с HIGH на LOW
Итого по перепаду на выводе 2 с 1 в 0 вызывается программа прерывания scan_enc. А так как у энкодера 2 вывода сдвинутые по фазе . То второй вывод и есть вывод направления в + или в -. И да если идет вибрация может быть ошибки. Программно их не устранить.
Конечно можно написать 2 функцию attachInterrupt(0, scan_enc2, RISING); Но где гарантия что во время одного обработчика прерываний не вызовут другой.
if(digitalRead(enc_B_pin)) аналог этого if(digitalRead(enc_B_pin)==1) . То есть спрашивает состояние на другом выводе от прерывания.
void scan_enc2() { // функция работающая по прерыванию 0 подсчет импульсов
if(digitalRead(enc_B_pin))place_enc--;
else place_enc++;
}
вызывается прерыванием attachInterrupt(0, scan_enc2, RISING);
Остання редакція qwone (2016-10-03 19:37:02)
Неактивний
//#1 энкодер
const int reset_pin=6; // кнопка сброса показаний 0 нажата /1 нет
volatile int place_enc; // количество импульсов
const int enc_A_pin = 2;// нога на энкодер фазы A прерывание 0
const int enc_B_pin = 3; // нога на энкоде фазы B.
void scan_enc1() { // функция работающая по прерыванию 0 подсчет импульсов
if(digitalRead(enc_B_pin))place_enc++;
else place_enc--;
}
void scan_enc2() { // функция работающая по прерыванию 0 подсчет импульсов
if(digitalRead(enc_B_pin))place_enc--;
else place_enc++;
}
//#2 экран
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
void setup(){
//#1 энкодер
pinMode(reset_pin, INPUT_PULLUP); // настройка кнопки сбоса показаний
pinMode(enc_A_pin, INPUT);
pinMode(enc_B_pin, INPUT);
attachInterrupt(0, scan_enc1, FALLING); //прерывание INT0. 1>0
attachInterrupt(0, scan_enc2, RISING); //прерывание INT0. 0>1
//#2 экран
lcd.begin(16, 2);
}
void loop(){
//#1 энкодер
if (!digitalRead(reset_pin)) place_enc = 0; //сброс счетчика импульсов
//#2 экран обновление раз в 1 секунда
static uint32_t future2 = 0 ;
if (millis() >= future2) {
future2 = millis() + 1000 ;
lcd.setCursor(0,0) ; //курсор.
lcd.print("Place=") ; //выводит текст.
lcd.print(place_enc) ; //выводит значение переменной P.
lcd.print(" ") ; //выводит выводит пробел.
}
}
Неактивний
Спасибо за помощь сейчас нет времени заняться но наша эпопея не закончена
Неактивний
Сторінки 1