我需要为工作做一个仪表计数器,所以我决定只使用Arduino。我找到了一个旧的编码器,找到/编写了一个简单的代码,并将其全部砍掉,并遇到了意外的问题。
由于某种原因,我的计数器无法计数超过8米或31991个编码器脉冲。一旦达到8m的限制,该数字将变为负数,并开始向后倒计数,例如-7.9> -7.8(即继续向上计数到0)。
然后达到零,然后再次计数到8 ...
这对我来说很奇怪,我有限的编码知识无法解决。
有人知道如何解决此问题,或者我能做些什么使它起作用?
#include <LiquidCrystal.h>
#define inputA_in 6
#define inputB_in 7
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int inputA_V = 0;
int inputB_V = 0;
int inputA = 0;
int inputB = 0;
int counter = 0;
// smeni vrednost tuka pred run
int console_frequency_milliseconds = 200; /// edna sekunda
int aLastState = 0;
int bLastState = 0;
float meters = 0.0;
unsigned long lasttime = 0;
int move_positive = 0;
int move_negative = 0;
int maximum_input_digital_v = 300; //treba da citash od konzola i da gi setirash max i min
int minimum_input_digital_v = 0;
int logical_threshold_v = 150; //brojkive se random staveni
void setup() {
pinMode (inputA_in, INPUT);
pinMode (inputB_in, INPUT);
Serial.begin (9600);
lcd.begin(16, 2);
// Print a message to the LCD
lcd.print("Metraza [m]");
aLastState = inputA;
bLastState = inputB;
lasttime = 0;
}
void loop () {
inputA = digitalRead(inputA_in);
if (inputA != aLastState) {
if (digitalRead(inputB_in) != inputA) {
counter ++;
aLastState = inputA;
} else {
counter --;
aLastState = inputA;
}
}
if (millis() - console_frequency_milliseconds > lasttime)//Detect once every 150ms
{
meters = 0.50014 * counter / 2000;
Serial.print("Position: ");
Serial.println(meters);
lasttime = millis();
lcd.setCursor(0, 1);
//Print a message to second line of LCD
lcd.print(meters);
}
}
答案 0 :(得分:6)
您的计数器是一个简单的int
,
int counter = 0;
在您的系统上,它们似乎只有16位宽(最大值为32767),不足为奇。
使用
long int counter = 0;
获取更大的变量。
您可能还希望将计算从
更改为meters = 0.50014 * counter / 2000;
到
meters = 0.50014 * counter / 2000.0;
以避免丢失精度和范围。即使使用int函数,您的范围也将从31991编码器脉冲扩展到32757编码器脉冲;和模拟范围更广。
您可能还想尝试将counter
更改为unsigned int
或unsigned long int
。我没有分析您的整个代码,但我认为您没有任何依赖于负数表示的内容。因此,您可能可以再次将范围扩大一倍。但是没有保证,需要测试。