Ви не увійшли.
if(если нажата кнопка)
{ какой то код выполняется
analogRead(Ax); и тд и тп
}
if(если нажата кнопка)
{ какой то код выполняется
analogRead(Ax); и тд и тп
}
if(если нажата кнопка)
{ какой то код выполняется
analogRead(Ax); и тд и тп
}
if(если нажата кнопка)
{ какой то код выполняется
analogRead(Ax); и тд и тп
}
if(если нажата кнопка)
{ какой то код выполняется
analogRead(Ax); и тд и тп
}
........................
если будет нажата 1 кнопка то время подсчета будет одно а если 5 кнопок то оно увеличивается.
if (time == 0x4000)
{
какой то код
time = 0;
}
time++;
goodspeedmen пише:К чему это всё? Таймер wochdog, его назначение это сбросить микроконтроллер если он вдруг зашёл в бесконечный цикл. Когда происходит прерывание по переполнению этого таймера в векторе прерывания указан адрес reset микроконтроллера. Как его можно использовать в том о чём я писал?
Вообще не для этого. https://geektimes.ru/post/255800/
Вы даёте ссылку на статью в которой пишется именно о том что я писал. Вы простите хорошо себя чувствуете?
Похоже тема напомнила мне это место.
А ты что больше всего любишь делать?
— Это всё я тоже люблю,— сказал Кристофер Робин,— но что больше всего я люблю делать — это...
— Ну, ну?
— Ничего.
— А как ты это делаешь? — спросил Пух после очень продолжительного размышления.
— Ну, вот, спросят, например, тебя, как раз когда ты собираешься это делать: “Что ты собираешься делать, Кристофер Робин?”, а ты говоришь: “Да ничего”, а потом идёшь и делаешь.
— А, понятно! — сказал Пух.
К чему это всё? Таймер wochdog, его назначение это сбросить микроконтроллер если он вдруг зашёл в бесконечный цикл. Когда происходит прерывание по переполнению этого таймера в векторе прерывания указан адрес reset микроконтроллера. Как его можно использовать в том о чём я писал?
попробуйте ватчдог
На сколько я помню и понимаю это совсем не для этого, хоть это и 8 битный таймер.
Генерация пауз возможно путем функции delay (20); (остановка программы, не всегда приемлемо). Или программным счетчиком, проблема в том, что чем больше операций выполняет микроконтроллер между подсчетом счётчика тем эта "пауза" увеличивается. Кто как решает эту проблему?
Потому что синтаксисом предусмотрено.
http://arduino.ua/ru/prog/Goto
Вынесите за пределы операторов.
читал я эту страницу и там нет ни какой ";" в конце перехода, но компилятор просил: expect " } " что-то трали вали...
Мне кажется что приведенный фрагмент кода, демонстрационный. Но если посмотреть с другой стороны то все if с табуляцией (то есть вложенные), поэтому пусть ТС разберется еще со скобками, все ли операторы закрыты. О точке с запятой в конце операторов не понял. Я ни когда после фигурной скобки ее не ставлю. Хотя придерживаюсь правила что даже если в операторе есть одна команда, я ее беру в ф. скобки, но встречаю что очень многие этого не делают
.
Пишу обычно типа:
if (a<b){
a=b+c;
}
Многие пишут:
if (a<b) a=b+c;
А вообще то зачем в процедурном языке применять метки? Так ли они нужны?
Да я не указал что первый if является основным всё остальные вложенными, как мне кажется если произошло действие которое должно то зачем проверять остальные условия?
Колдовал я колдовал и наколдовал вот такое самое интересное что в Proteus работает в реальности считает только в минус, но судя по снятой диаграмме должно работать и в чем причина не понятно...
int counter = 0;
void setup()
{
Serial.begin(57600);
Serial.println("Encoder - Interrupt");
DDRD = B00000000; //
PORTD = B11111111; //
DDRB = B111111; //
PORTB = B000000; //
//INT0 PD2. Mode: Falling Edge. INT1 PD2. Mode: off
EICRA=(0<<ISC11) | (0<<ISC10) | (1<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (1<<INT0);
EIFR=(0<<INTF1) | (1<<INTF0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
}
void loop()
{
if((digitalRead(2) == 1) && (digitalRead(3) == 1)){EIMSK |= (1<<INT0);}
}
ISR(INT0_vect) //INT0 PD2. Mode: Falling Edge. \
{
if((digitalRead(2) == 0) && (digitalRead(3) == 0)) {counter++; Serial.println(counter);}
if((digitalRead(2) == 0) && (digitalRead(3) == 1)) {counter--; Serial.println(counter);}
EIMSK &=~ (0<<INT0);
}
Вообще не понятно, что вы хотите и что это за устройство такое и как оно работает. Микроконтроллеры не предназначены угадывать желания, они работают по определенному алгоритму, который описывает программист в коде.
void loop()
{
if()
{
if(){}
if(){goto there_A;}
if(){}
if(){}
}
there_A:
}
Так выдаёт ошибку, когда я перенес метку в начало программы всё компилировалось
void loop()
{
there_A:
if()
{
if(){}
if(){goto there_A;}
if(){}
if(){}
}
//there_A:
}
Есть ли какие то ограничения этой команды?
Я переписал ваш код более понятными мне названиями, инкремент происходит в начале шага и в конце, если крутить медленно то это можно увидеть. Какой код вы хотите увидеть? Я написал ту часть которая относится к энкодеру (инкремент, декремент точно такой же), зачем вам мои светодиоды и прочие?
я вроде не где не ошибся но почему инкремент 20 за шаг? смотрел стандартные примеры там вообще 4
boolean A_inc, B_inc, cw_T, cww_T;
=======================================
A_inc = (digitalRead(2));
B_inc = (digitalRead(3));
if(A_inc == B_inc)
{
cw_T = A_inc;
cww_T = B_inc;
}
if(cw_T != A_inc)
{
cw_T = A_inc;
if(Selection_flag == 0)
{
if(setTemp <= 450)
{
setTemp+=10;
}
}
if(Selection_flag == 1)
{
if(set_Temp <= 450)
{
set_Temp+=10;
}
}
if(Selection_flag == 2)
{
if(set_Cooler <= 225)
{
set_Cooler+=30;
}
}
}
я написал ваш код так и у меня считает по 20 хотя инкремент как можете видеть по 10 единиц. Если я кручу энкодер оооочень медленно по шагу то действительно инкремент происходит по 10 единиц. два инкремента за шаг
Считываем значение с ножек к которым подключен енкодер, затем если энкодер находиться в исходном состоянии (на обоих выводах енкодера низкий уровень) записываем значение в переменные (сравнения или как там их назвать). При повороте энкодера на одном из выводов появляется высокий уровень, это значение сравнивается с временной (прошлого состояния) и в неё записывается тоже высокий уровень что по идеи не должно подавить дребезг.
Вы бы не могли объяснить логику последнего кода?
А если это объявленный массив char? Получается логика, что я спрашиваю у элемента массива является ли он сам собой
и тут я понял, что не знаю как это сделать???
TCNT1H = 0x85EE >> 8;
TCNT1L = 0x85EE & 0xff;
Хотелось понять принцип работы подобных конструкций. Первая операция это логический сдвиг в право в регистр TCNT1H он 8 битный, но TCNT1 регистр имеет разрядность 16 бит и физически состоит из двух 8 битных регистра, TCNT1H (старшая часть 8 - 15 бит) и TCNT1L (младшая часть 0 - 7). Что получается при такой операции? Поскольку регистр 8 разрядный то в него только 0x85 или 0xEE по логике загрузится 0xEE и сдвинутся в права, что приведет к загрузке 0x85 в регистр TCNT1H.
Далее побитовое И между числом 0x85EE и 0xff старшая часть числа в расчет браться не будет, она не помещается, значит будет производиться операция между числами 0xEE и 0xff и результатом операции будит истина, то есть в регистре TCNT1L будет 0xEE. Правильны ли мои рассуждения?
Все технологии автоматизации требуют наличия потока производства. Я так понимаю, что это проект ради проекта.
boolean compare, triger, inc_cw, nc_cww;
byte division,division_CW,division_CWW, backlash_CW, backlash_CWW, backlash;
int counter_lcd , calibre_lcd;
// настройка вннешнего прерывания INT0 и INT1.
//INT0 PD2. Mode: Falling Edge. INT1 PD2. Mode: Rising Edge.
EICRA = (1<<ISC11) | (1<<ISC10) | (1<<ISC01) | (0<<ISC00);
EIMSK = (1<<INT1) | (1<<INT0);
EIFR = (1<<INTF1) | (1<<INTF0);
PCICR = (0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
//======================================================================
if((digitalRead(10) == 0)&&(triger == 0)) //compare.
{
temp++;
if(temp == 0xff)
{
if(counter_lcd < calibre_lcd) //motor_cww.
{
compare = 0;
PORTD |= (1<<5); //on motor cw.
while(compare == 0)
{
}
PORTD &= ~(1<<5); //off motor.
PORTB |= (1<<4); //on braking.
braking = 0x3300; //13056 time braking.
triger = 1; //set triger.
goto compare_end;
}
if(counter_lcd > calibre_lcd) //motor_cww.
{
compare = 0;
PORTD |= (1<<4);//on motor cww.
while(compare == 0)
{
}
PORTD &= ~(1<<4); //off motor.
PORTB |= (1<<4); //on braking.
braking = 0x3300; //13056 time braking.
triger = 1; //set triger.
}
}
}
compare_end:
ISR(INT0_vect)//INT0 PD2. Mode: Falling Edge. обработка прерываний с деление и люфтом INT0 and INT1 - ON
{
cli();
if((inc_cw == 1)&&(digitalRead(3) == 0))// энкодер++.
{
if(backlash_CW == backlash)//выбор люфта вперед.
{
if(division_CW == division) //деление входных импульсов.
{
counter_lcd++;
if(compare == 0)
{
if(counter_lcd == calibre_lcd)
{
PORTD &= ~(1<<5);
compare = 1;
}
}
division_CW = 0;
goto out_int_A;
}
division_CW++;
goto out_int_A;
}
backlash_CW++;
backlash_CWW = 0;
division_CWW = 0;
goto out_int_A;
}
if((inc_cww == 1)&&(digitalRead(3) == 1))//энкодер--.
{
if(backlash_CWW == backlash)//выбор люфта назад.
{
if(division_CWW == division)//деление входных импульсов.
{
counter_lcd--;
if(compare == 0)
{
if(counter_lcd == calibre_lcd)
{
PORTD &= ~(1<<4);
compare = 1;
}
}
division_CWW = 0;
goto out_int_A;
}
division_CWW++;
goto out_int_A;
}
backlash_CWW++;
backlash_CW = 0;
division_CW = 0;
}
out_int_A:
inc_cw = 0;
inc_cww = 0;
sei();
}
//==================================================================
//ISR(INT1_vect)//INT1 PD2. Mode: Rising Edge.
{
cli();
if(digitalRead(2) == 0){inc_cw = 1; inc_cww = 0; goto out_int_B;}//энкодер++.
if(digitalRead(2) == 1){inc_cww = 1; inc_cw = 0; goto out_int_B;}//энкодер--.
out_int_B:
sei();
}
//====================================================================
Вот мой код обработке энкодера, смысл в том что есть переменная calibre_lcd к значению которой крутится двигатель. В первом прерывании задаются направление энкодера в нулевом отсчёт. В коде есть выборка люфта и деление входных импульсов от энкодера.
Проблема такова, не срабатывает вот этот код, двигатель крутится постоянно. Я убирал люфт и деление, проблема остаётся значит дело не в них?
if(compare == 0)
{
if(counter_lcd == calibre_lcd)
{ PORTD &= ~(1<<5); // или PORTD &= ~(1<<4);
compare = 1;
}
}
Когда я вынес код из прерывания все заработало нормально
while(compare == 0)
{
if(counter_lcd == calibre_lcd)
{PORTD &= ~(1<<5); // или PORTD &= ~(1<<4);
compare = 1;
}
}
boolean compare, triger, inc_cw, nc_cww;
byte division,division_CW,division_CWW, backlash_CW, backlash_CWW, backlash;
int counter_lcd , calibre_lcd;
// настройка вннешнего прерывания INT0 и INT1.
//INT0 PD2. Mode: Falling Edge. INT1 PD2. Mode: Rising Edge.
EICRA = (1<<ISC11) | (1<<ISC10) | (1<<ISC01) | (0<<ISC00);
EIMSK = (1<<INT1) | (1<<INT0);
EIFR = (1<<INTF1) | (1<<INTF0);
PCICR = (0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
//======================================================================
if((digitalRead(10) == 0)&&(triger == 0)) //compare.
{
temp++;
if(temp == 0xff)
{
if(counter_lcd < calibre_lcd) //motor_cww.
{
compare = 0;
PORTD |= (1<<5); //on motor cw.
while(compare == 0)
{
}
PORTD &= ~(1<<5); //off motor.
PORTB |= (1<<4); //on braking.
braking = 0x3300; //13056 time braking.
triger = 1; //set triger.
goto compare_end;
}
if(counter_lcd > calibre_lcd) //motor_cww.
{
compare = 0;
PORTD |= (1<<4);//on motor cww.
while(compare == 0)
{
}
PORTD &= ~(1<<4); //off motor.
PORTB |= (1<<4); //on braking.
braking = 0x3300; //13056 time braking.
triger = 1; //set triger.
}
}
}
compare_end:
ISR(INT0_vect)//INT0 PD2. Mode: Falling Edge. обработка прерываний с деление и люфтом INT0 and INT1 - ON
{
cli();
if((inc_cw == 1)&&(digitalRead(3) == 0))// энкодер++.
{
if(backlash_CW == backlash)//выбор люфта вперед.
{
if(division_CW == division) //деление входных импульсов.
{
counter_lcd++;
if(compare == 1)
{
if(counter_lcd == calibre_lcd)
{
PORTD &= ~(1<<5);
compare = 1;
}
}
division_CW = 0;
goto out_int_A;
}
division_CW++;
goto out_int_A;
}
backlash_CW++;
backlash_CWW = 0;
division_CWW = 0;
goto out_int_A;
}
if((inc_cww == 1)&&(digitalRead(3) == 1))//энкодер--.
{
if(backlash_CWW == backlash)//выбор люфта назад.
{
if(division_CWW == division)//деление входных импульсов.
{
counter_lcd--;
if(compare == 1)
{
if(counter_lcd == calibre_lcd)
{
PORTD &= ~(1<<4);
compare = 1;
}
}
division_CWW = 0;
goto out_int_A;
}
division_CWW++;
goto out_int_A;
}
backlash_CWW++;
backlash_CW = 0;
division_CW = 0;
}
out_int_A:
inc_cw = 0;
inc_cww = 0;
sei();
}
//==================================================================
//ISR(INT1_vect)//INT1 PD2. Mode: Rising Edge.
{
cli();
if(digitalRead(2) == 0){inc_cw = 1; inc_cww = 0; goto out_int_B;}//энкодер++.
if(digitalRead(2) == 1){inc_cww = 1; inc_cw = 0; goto out_int_B;}//энкодер--.
out_int_B:
sei();
}
//====================================================================
Вот мой код обработке энкодера, смысл в том что есть переменная calibre_lcd к значению которой крутится двигатель. В первом прерывании задаются направление энкодера в нулевом отсчёт. В коде есть выборка люфта и деление входных импульсов от энкодера.
Проблема такова, не срабатывает вот этот код, двигатель крутится постоянно. Я убирал люфт и деление, проблема остаётся значит дело не в них???
if(compare == 1)
{
if(counter_lcd == calibre_lcd)
{ PORTD &= ~(1<<5); // или PORTD &= ~(1<<4);
compare = 1;
}
}
https://discord.gg/6hbs98y Мой канал в Discord.
Если написать скетч на ардуино экспортировать бинарный файл, как я понял IDE создаёт файл с загрузчиком и без него. Если файл без загрузчика прошить через SPI или STK 500 это будет работать?
...eightanaloginputs.hex
...with_bootloader.eightanaloginputs.hex
При нормальном переходнике ничего жать не надо. DTR или RTS должны жать за Вас.
Что значит нормальный?
/*
********** Pin - D - **********
Arduino 00 – ATmega pin 02/0 –
Arduino 01 – ATmega pin 03/1 –
Arduino 02 – ATmega pin 04/2 – CLK - A энкодера
Arduino 03 – ATmega pin 05/3 – DT - B энкодера
Arduino 04 – ATmega pin 06/4 –
Arduino 05 – ATmega pin 11/5 –
Arduino 06 – ATmega pin 12/6 –
Arduino 07 – ATmega pin 13/7 –
********** Pin - B - **********
Arduino 08 – ATmega pin 14/0 –
Arduino 09 – ATmega pin 15/1 –
Arduino 10 – ATmega pin 16/2 –
Arduino 11 – ATmega pin 17/3 –
Arduino 12 – ATmega pin 18/4 –
Arduino 13 – ATmega pin 19/5 –
Arduino RC – ATmega pin 09/6 – (ZQ)
Arduino RC – ATmega pin 10/7 – (ZQ)
********** Pin - C - **********
Arduino 14_A0 – ATmega pin 23/0 –
Arduino 15_A1 – ATmega pin 24/1 –
Arduino 16_A2 – ATmega pin 25/2 –
Arduino 17_A3 – ATmega pin 26/3 –
Arduino 18_A4 – ATmega pin 27/4 –
Arduino 19_A5 – ATmega pin 28/5 –
****************************************************
****************************************************
Dx_Out; - установка пина Х как выход
Dx_In; - установка пина Х как вход
Dx_High; - установка высокого уровна на пине Х
Dx_Low; - установка низкого уровня на пине Х
Ax_Read; - чтение аналогового пина Х
****************************************************
****************************************************
if ((PIND&(1<<2)) == 0) {} // если на пин *2D* лог 0
if ((PIND&(1<<2)) != 0) {} // если на пин *2D* лог 1PORTD |= (1<<2); // установить на пин *2D* лог 1
PORTD &=~ (1<<2); // установить на пин *2D* лог 0
PORTD ^= (1<<2); // инвертировать состо¤ние пин *2D*
****************************************************
****************************************************
*/unsigned long currentTime;
unsigned long loopTime;
boolean e_B, e_A, spin;void setup() {
Serial.begin(57600);
Serial.println(" KY-040 Encoder Test Interrupt ");
DDRD = B00000000; // назначает выводы со 0 по 7 входными
PORTD = B11111111; // устанавливает на цифровых выводах с 0 по 7 HIGH
DDRB = B111111; // назначает вывод с 8 по 13 выходными
PORTB = B000000; // устанавливает на выводах с 8 по 13 LOW
DDRC = B000011; // назначает выводы с 14 по 15 выходными, с 16 по 19 входными
PORTC = B100000; // устанавливает на выводах с 14 по 18 LOW, с 19 HIGH
// определяем внешнее прерывание на выводе 2
attachInterrupt(0, KY040, FALLING);
}void loop() {
}
void KY040() {
if( millis() < (loopTime + 4) ) { return; }
loopTime = millis();
// считываем состояние выхода А и В энкодера
e_B = PIND&(1<<3); e_A = PIND&(1<<2);// выход В = 1, значит вращение против часовой стрелки
if((e_B && !e_A) && spin) { f01(); Serial.println(" counter-clockwise "); }
if(e_B && !e_A) { spin = true; }
// выход В = 0, значит вращение по часовой стрелке
if((!e_B && !e_A) && !spin) { f02(); Serial.println(" clockwise "); }
if(!e_B && !e_A) { spin = false; }}
void f01() { PORTB |= (1<<5); }
void f02() { PORTB &=~ (1<<5); }KY040 Encoder_203.txt
Открыть с помощью
KY040 Encoder_203.txt. Н
//=====================================================================
if( millis() < (loopTime + 4) ) { return; }
loopTime = millis(); Мне не понятно для чего это и что оно куда возвращает