Как с помощью сигнала HIGH на pin прибавлять к переменной int?

ToxaRU
Offline
Зарегистрирован: 03.04.2015
Как с помощью сигнала HIGH на pin прибавлять или убавлять(сигнал на другой пин)  к переменной int скетча определенное число и ограничить это число 360, чтобы после 360 шло не 361, а 1?
 
ну понятно что декларируем пины, ставим их на прием.... а дальше?
kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Ждём нужного события и если оно произошло, то добавляем 1 к переменной, проверяем на переполнение и если оно больше 360 устанавливаемые переменную в 1

Arhat109
Offline
Зарегистрирован: 26.05.2015

Смотря какой пин и какая машинка. На старших моделях можно подавать на счетный вход счетчиков (на плате Ардуино Мега2560 выведены входы от Т0 и Т5 только) и тупо считать счетчиком. Счетчик ограничить ICRNx регистром или CRxA до заданного значения, разрешить и обрабатывать прерывание по переполнению TOVx ... Фсё :)

... или установить его в режим непрерывного счета внутр. импульсов, а как ногу счетного пина использовать сигнал "захвата счетчика" (ICRx).. Тогда ловить прерыванием по захвату каждый импульс  и корректировать чиселку в памяти ручками ... сложнее, но позволяет использовать таймер и для других целей одновременно. На плате Меги выведено всего 2 таких сигнала для счетчиков 4 и 5...

:)

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Можно засекать время прохода loop и если оно увеличивается на величину установленую в дополнительной функции, то добавлять элемент в массив, при достижении массивом длинны в 360 элементов выполнять софт резет.

 

А че Arhat109 можно а мне нет?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Вы тут тряпки жжете и смеетесь?

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Puhlyaviy пишет:
Вы тут тряпки жжете и смеетесь?

Не засоряй тему. Есть что сказать - предлагай свой вариант.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

JollyBiber пишет:

Puhlyaviy пишет:
Вы тут тряпки жжете и смеетесь?

Не засоряй тему. Есть что сказать - предлагай свой вариант.


Предлагаю сделать коробку и серва туда будет шарики складывать, как 360 наберется, коробка переворачивается.

std
Offline
Зарегистрирован: 05.01.2012
digitalRead(pin) && i++;
delay(10);
i=1 && i>360;

 

zhenious
Offline
Зарегистрирован: 03.07.2014

std пишет:

i=1 && i>360;

может так :

 

i>360 && i=1;
Datak
Offline
Зарегистрирован: 09.10.2014


digitalRead(pin) && ++i > 360 && i = 1;

Лучше так, чтобы уж совсем понятно было. :)

vov4ik
Offline
Зарегистрирован: 10.09.2013

Datak пишет:

digitalRead(pin) && ++i > 360 && i = 1;

Лучше так, чтобы уж совсем понятно было. :)

Извените, а какую магию вы использовали для для написания вычисления, ради интереса попробывал Ваши умозаключения преоброзовать в скече выдаёт ошибку, может быть я что-то недопонял или где ошибся.

int i;
void setup() {
  Serial.begin (9600);
  pinMode(9, INPUT); digitalWrite(9, HIGH);
}
void loop(){
  //digitalRead(9) && ++i > 360 && i = 1;
if (digitalRead(9)) i++;
if (i > 360) i = 1;

Serial.println(i);
delay(20);
}

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Че проще написано, тем проще потом разобраться. Чем "мудрее" написано, тем проще допустить ошибку.

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

vov4ik, +1, читабельно и сразу понятно.

То All:

Только всё равно это всё некорректно, потому что читать высокий уровень на пине, а не ловить фронт, i будет расти в зависимости от частоты опроса пина. Сомневающиеся могут попробовать менять в последнем скетче величину delay и подавать на 9 пин импульс определенной длины. Значения будут очень разные.

Ваш КЭП.

 

Datak
Offline
Зарегистрирован: 09.10.2014

vov4ik пишет:

Извените, а какую магию вы использовали для для написания вычисления, ради интереса попробывал Ваши умозаключения преоброзовать в скече выдаёт ошибку, может быть я что-то недопонял или где ошибся.

Ну, зачем же сразу извеняца - ошибиться может каждый! :)

Вот так ещё попробуйте, ради интереса:

digitalRead(pin) && ++i > 360 && ( i = 1 );

А если магия непонятна - это я не виноват, это они первые начали.

vov4ik
Offline
Зарегистрирован: 10.09.2013

kisoft пишет:

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

Может компилятору всеравно но разница есть.

int i;
void setup() {
  Serial.begin (9600);
  pinMode(9, INPUT); digitalWrite(9, HIGH);
}
void loop(){
//if (digitalRead(9)) ++i;
//if (i > 360) i = 1;
digitalRead(9) && ++i == 361 && ( i = 1 );
Serial.println(i);
delay(20);
}
//Sketch uses 2 950 bytes (9%) of program storage space. Maximum is 30 720 bytes.
int i;
void setup() {
  Serial.begin (9600);
  pinMode(9, INPUT); digitalWrite(9, HIGH);
}
void loop(){
if (digitalRead(9)) ++i;
if (i > 360) i = 1;
//digitalRead(9) && ++i == 361 && ( i = 1 );
Serial.println(i);
delay(20);
}
//Sketch uses 2 958 bytes (9%) of program storage space. Maximum is 30 720 bytes.

Если внимательно просмотрется разница в восемь бит.

По магии, я так понимаю когда значение пина истина && пропускает дальше, ++i самостоятельно увеличивается, далле читается как (i = i + 1) > 360, тоесть истина если i > 360 (при i = 361), пропускает дальше, далее присвоение которое должно быть самостоятельным поэтому без скобок не захотело работать.

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

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

08 строку можно выполнять только если меняется i, тогда точно не будет разницы с && вариантом.
UPD: про 8 бит не понял

vov4ik
Offline
Зарегистрирован: 10.09.2013

kisoft пишет:
UPD: про 8 бит не понял

Когда я пишу 

if (digitalRead(9)) ++i;
if (i > 360) i = 1;
памяти тяпается на восемь бит больше
Arhat109
Offline
Зарегистрирован: 26.05.2015

kisoft пишет:
То All:

Только всё равно это всё некорректно, потому что читать высокий уровень на пине, а не ловить фронт, i будет расти в зависимости от частоты опроса пина.

Ваш КЭП.

Верно. А ещё опрос внутри loop() приведет к строго последовательной работе и задержкам на обслуживание остальных задач. Поэтому и отписал про сигнал захвата таймера. Его прерывание как раз можно программировать как на фронт, так и на спад.

Спасибо, КЭП. :)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

vov4ik пишет:

kisoft пишет:
UPD: про 8 бит не понял

Когда я пишу 

if (digitalRead(9)) ++i;
if (i > 360) i = 1;
памяти тяпается на восемь бит больше


Ну так бы и сказал, на один байт. Странно, надо посмотреть листинг.

Datak
Offline
Зарегистрирован: 09.10.2014

kisoft пишет:
Ну так бы и сказал, на один байт. Странно, надо посмотреть листинг.

Там на 8 байт разница, судя по сообщениям компилятора.

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

Но я согласен - редко бывают случаи, когда стоит жертвовать понятностью кода ради такой экономии. Себе дороже выйдет.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Ну вот и дошли руки до этого дела. Два разных подхода дают абсолютно одинаковый код (осторожно, ассемблер):

0000013a <loop>:
 13a:	89 e0       	ldi	r24, 0x09	; 9
 13c:	0e 94 2c 02 	call	0x458	; 0x458 <digitalRead>
 140:	89 2b       	or	r24, r25
 142:	91 f0       	breq	.+36     	; 0x168 <loop+0x2e>
 144:	80 91 10 01 	lds	r24, 0x0110
 148:	90 91 11 01 	lds	r25, 0x0111
 14c:	01 96       	adiw	r24, 0x01	; 1
 14e:	90 93 11 01 	sts	0x0111, r25
 152:	80 93 10 01 	sts	0x0110, r24
 156:	89 36       	cpi	r24, 0x69	; 105
 158:	91 40       	sbci	r25, 0x01	; 1
 15a:	34 f0       	brlt	.+12     	; 0x168 <loop+0x2e>
 15c:	81 e0       	ldi	r24, 0x01	; 1
 15e:	90 e0       	ldi	r25, 0x00	; 0
 160:	90 93 11 01 	sts	0x0111, r25
 164:	80 93 10 01 	sts	0x0110, r24
 168:	60 91 10 01 	lds	r22, 0x0110
 16c:	70 91 11 01 	lds	r23, 0x0111
 170:	4a e0       	ldi	r20, 0x0A	; 10
 172:	50 e0       	ldi	r21, 0x00	; 0
 174:	8b e1       	ldi	r24, 0x1B	; 27
 176:	91 e0       	ldi	r25, 0x01	; 1
 178:	0e 94 4b 05 	call	0xa96	; 0xa96 <_ZN5Print7printlnEii>
 17c:	64 e1       	ldi	r22, 0x14	; 20
 17e:	70 e0       	ldi	r23, 0x00	; 0
 180:	80 e0       	ldi	r24, 0x00	; 0
 182:	90 e0       	ldi	r25, 0x00	; 0
 184:	0c 94 31 01 	jmp	0x262	; 0x262 <delay>

Скетч 1, вариант, который я предлагал (и не только я):

int i;
void setup() {
  Serial.begin (9600);
  pinMode(9, INPUT); digitalWrite(9, HIGH);
}
void loop() {
  if (digitalRead(9)) {
    i++;
    if (i > 360) i = 1;
  }

  Serial.println(i);
  delay(20);
}

Второй вариант, хитронаписанный:

int i;
void setup() {
  Serial.begin (9600);
  pinMode(9, INPUT); digitalWrite(9, HIGH);
}
void loop() {
  digitalRead(9) && ++i > 360 && ( i = 1 );

  Serial.println(i);
  delay(20);
}

Собственно, что и требовалось доказать.

PS Да, компилял на АрдуиноИДЕ 1.6.4 с опциями при компиляции по-умолчанию, не менял.