我需要为工作制作米计数器,所以我决定只为Arduino.我找到了一个旧的编码器,发现/编写了一个简单的代码并将它们全部一起攻击并遇到了意想不到的问题. 出于某种原因,我的计数器不会
出于某种原因,我的计数器不会超过8米或31991编码器脉冲.一旦达到这个8米的限制,该数字变为负数并开始向后计数,如-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); } }你的计数器是一个简单的int,
int counter = 0;
看起来在你的系统上它们只有16位宽(最大值为32767),这并不奇怪.
使用
long int counter = 0;
获得更广泛的变数.
您可能还想更改计算
meters = 0.50014 * counter / 2000;
至
meters = 0.50014 * counter / 2000.0;
避免失去精度和范围.即使使用int也可以将范围从31991编码器脉冲扩展到32757编码器脉冲;和模拟更广泛的范围.
您可能还想尝试将计数器更改为unsigned int或unsigned long int.我没有分析你的整个代码,但我认为你没有任何依赖于负数表示的东西.所以你可能会再次将范围加倍.但不保证,需经测试.