Подсчёт оборотов лебедки.

EduardHyco
Offline
Зарегистрирован: 09.03.2014
Всем доброго времени суток. Пишу диплом. Специальность мехатроника. 
 
Есть лебёдка. два магнитных датчика считают обороты (два, чтобы была возможность считать и направление вращения). Информация об оборотах выводится на lcd экран. Также нужно кнопка для reset. 
 
Составил схему и написал код. 
 


#include <LiquidCrystal.h>



LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
const int buttonPin=1;
const int sensor1=7;
const int sensor2=8;


int FWD=0, REV=0;
boolean z1=0, z1_old=0, z2=0, z2_old=0;

int buttonState = 0; 

void setup() {

lcd.begin(16, 2);
pinMode (sensor1, INPUT);
pinMode (sensor2, INPUT);
pinMode (buttonPin, INPUT);
Serial.begin(9600);

}

void loop() {

	
	lcd.clear();
	buttonState = digitalRead(buttonPin);
	z1=digitalRead(sensor1);
	z2=digitalRead(sensor2);


	while (buttonState != HIGH)
	{


		if ((z1 != z1_old) || (z2 != z2_old))
		{   
      			if (((z1_old==0) && (z2==0) && (z1 == 1)) || ((z1_old==1) && (z2==1) && (z1 == 0)) || ((z2_old==0) && (z2==1) && (z1 == 1)) || ((z2_old==1) && (z2==0) && (z1 == 0)))
     			 FWD++;
      			else if (((z1==0) && (z2_old==0) && (z2 == 1)) || ((z1==1) && (z2_old==1) && (z2 == 0)) || ((z1==1) && (z1_old==0) && (z2 == 1)) || ((z1==0) && (z1_old==1) && (z2 == 0)))
     			 REV++;
    
   		}
    		z1_old=z1;
    		z2_old=z2;
		lcd.setCursor(0, 0);
		lcd.print(FWD);
		lcd.setCursor(0, 1);
		lcd.print(REV);


	}

	if (buttonState == HIGH)
	{
		lcd.clear();
		FWD =0;
		REV =0;
		lcd.print("Stand alone mode");
		delay(2000);
		lcd.clear();
	}
}

 
Весь колхоз был написан использую следующие источники 
 
Волнуют вопросы о том правильно ли я выбрал распиновку и, чисто теоретически, мог бы работать этот код. 
 
Огромное спасибо заранее!
Diemon
Offline
Зарегистрирован: 18.11.2011

Так а вы диплом уже сдали, или еще предстоит сдать? Или вам нужно его в железе сотворить...

Конкретно в коде не копался, но принцип определения направления вращения по 2м датчикам, сдвинутым на 90 градусов верен. Единственно - цикл while (buttonState != HIGH) конечно ужасен. уверен, его можно упростить и переделать...

EduardHyco
Offline
Зарегистрирован: 09.03.2014

Диплом предстоит сдать. И да, в будущем это будет в железе. Буду очень признателен, если углубитесь в проблему

Diemon
Offline
Зарегистрирован: 18.11.2011

Собрал на макетке ваш пример, залил скетч в ардуину

Первое: в строке LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); число 10 лишнее.  Без него ардуина запускается, на дисплей выводит "Stand alone mode"

Второе: на кнопки не реагирует. Надпись на дисплее не меняется.

EduardHyco
Offline
Зарегистрирован: 09.03.2014

Допустим уберём 10. но почему на кнопки не реагирует?

EduardHyco
Offline
Зарегистрирован: 09.03.2014

может у вас кнопка изначально нажата так, что подаёт напряжение? или ошибка всё-таки у меня?

Diemon
Offline
Зарегистрирован: 18.11.2011

Апдейт. забыл про кнопку сброса. Подключил - работает. Только переназначьте её лучше на 10 пин. 1й зарезервирован за ком портом, может потом аукнуться.

Программа считает нажатие/отжатие кнопок. 

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

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

EduardHyco
Offline
Зарегистрирован: 09.03.2014

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

EduardHyco
Offline
Зарегистрирован: 09.03.2014

по идеи кнопки должни имитировать следующую последовательность: первый шаг Z1(1), Z2(0) , второй шаг Z1(1), Z2(1), третий шаг Z1(0), Z2(1) четвертый шаг Z1(0) Z2(0). Этим, если я не ошибся, должен эмитироваться оборот в сторону "вперёд". тоесть в любом случае, один магнит попадает под два сенсора.

у вас сейчас срабатовало условие ((z1_old==0) && (z2==0) && (z1 == 1)) для верхней части экрана, как я понял

Diemon
Offline
Зарегистрирован: 18.11.2011

Теперь понял. Я просто не знал, как нужно нажимать на кнопки =) 

Итого мои действия (кнопка1,кнопка2):  (0,0)->(1,0)->(1,1)->(0,1)->(0,0). Верхняя строчка дисплея досчитывает до числа 4

Тоже самое с комбинацией (кнопка2,кнопка1). нижняя строчка 4

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

EduardHyco
Offline
Зарегистрирован: 09.03.2014

замечательно! только теперь не могу понять. за один оборот в реальной жизни он покажет мне число 4 или 1?

или мне достаточно для вращения вперёд оставить только ((z1_old==0) && (z2==0) && (z1 == 1)), кпримеру?

Diemon
Offline
Зарегистрирован: 18.11.2011

Логика работы программы зависит от того, как вы поставите датчики относительно барабана. Если сможете обеспечить диаграмму как в предыдущем посте то проще некуда: По прерыванию с 7 пина проверяем значение 8 пина. Если 8 пин=1 то едем вперед, Если =0 то назад.

EduardHyco
Offline
Зарегистрирован: 09.03.2014

Большое вам спасибо, дай Бог вам здоровья. Разобрались)

dim4zZz
Offline
Зарегистрирован: 07.08.2019

Добрый день! Подскажите как переделать скетч для подключения lcd 1602 по шине I2C?