Как добавить или вычесть заранее определенное значение, не возвращая его по умолчанию к исходному значению?

Типичные извинения заранее, прошло довольно много времени с тех пор, как я возился с ардуино. Используя клон Arduino Micro (Pro Micro), лидар TF02 и 1,2-дюймовый 7-сегментный дисплей Adafruit, я работал над дальномером, который можно регулировать вверх / вниз с шагом 1. Однако я уперся в стену. Я не могу настроить значение расстояния без того, чтобы оно не вернулось к исходному значению. Допустим, расстояние составляет 6'2". Когда я нажимаю кнопку "вверх", значение равно 6'3", но затем возвращается к 6'2". То же самое относится и к кнопке "вниз". Кроме того, когда расстояние составляет, например, 1'0", и я нажимаю кнопку вниз, вместо того, чтобы перейти к 0'11", отображается 0'99". Я нахожусь в тупике с точки зрения того, что я могу сделать, чтобы решить эту проблему. Любая помощь приветствуется!

*
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment(); // вывод d 2, вывод c 3
#include <SoftwareSerial.h>// программный последовательный порт
#include <Wire.h>


//содержимое кнопки
int Up_buttonState = 0;
int Dn_buttonState = 0;
int Up_lastButtonState = 0;
int Dn_lastButtonState = 0;
const int  UpPin = 7;    
const int  DnPin = 8;

// LiDAR stuff
int dist;// ЛиДАР фактически измерил значение расстояния
int strength;// Проверка уровня сигнала лидара
int check;// проверка хранения числовых значений
int i;
int uart[9];// хранение данных, измеренных лидаром
const int HEADER=0x59;// заголовок кадра пакета данных
long inches, INCH, feet, ftin;




SoftwareSerial mySerial(9,10); // rx tx, 


void setup()
{
pinMode(UpPin, INPUT);
pinMode(DnPin, INPUT);
 Serial.begin(9600);
  
 mySerial.begin(115200);//установка скорости передачи данных LiDAR и последовательного порта Arduino
  #ifndef __AVR_ATtiny85__
 
  #endif
  matrix.begin(0x70);
}
void loop()
{

 if (mySerial.available())//проверьте, есть ли в последовательном порту ввод данных
 {
    if(mySerial.read()==HEADER)// определить заголовок фрейма пакета данных 0x59
    {
   
      uart[0]=HEADER;
 
      if(mySerial.read()==HEADER)//определить заголовок фрейма пакета данных 0x59
      {
       uart[1]=HEADER;
       
      for(i=2;i<9;i++)// хранить данные в массиве
         {
          uart[i]=mySerial.read();
         }
           check=uart[0]+uart[1]+uart[2]+uart[3]+uart[4]+uart[5]+uart[6]+uart[7];
           if(uart[8]==(check&0xff))// проверьте полученные данные в соответствии с протоколами // если данные получены
 
             { //начальные уравнения
               dist=uart[2]+uart[3]*256;// вычислить значение расстояния
               
               //уравнения для преобразования мм в фут, в
               inches = (dist * .3937);
               INCH = inches% 12; 
               feet = (dist / 2.54) / 12;
               ftin = feet*100 + INCH; 

               Up_buttonState = digitalRead(UpPin); // добавить 1 к ftin
                if (Up_buttonState != Up_lastButtonState) 
                {
                  if (Up_buttonState == HIGH)
                  {
                    ftin++;
                  }
                  delay(500);
                }
                Up_lastButtonState = Up_buttonState;

               Dn_buttonState = digitalRead(DnPin); // вычесть 1 из ftin
                if (Dn_buttonState != Dn_lastButtonState) 
                {
                  if (Dn_buttonState == HIGH)
                  {
                    ftin--;
                  }
                  delay(500);
                }
                Dn_lastButtonState = Dn_buttonState;
           
               Serial.print(ftin); 
               matrix.print( ftin , DEC );
               matrix.writeDisplay();

             }
      }
    }
 }
   

 
}

, 👍1

Обсуждение

Использование «длинного» и деление на 2,54 может не дать желаемого результата, используйте число с плавающей запятой., @Michel Keijzers


1 ответ


Лучший ответ:

1

Вы написали:

ftin = feet*100 + INCH;

Что это за чудовище? Я не очень хорошо знаком с имперскими единицами измерения (и мне интересно, почему кто-то все еще хочет их использовать), но я считаю, что фут - это не 100 дюймов.

О, я понимаю. Монстр - это клудж для управления отображением в футах и дюймах. Но обратите внимание, что он вычисляется на каждой итерации цикла как функция измеренного расстояния. I не имеет смысла применять коррекцию к монстру, поскольку она будет пересчитана на следующей итерации. Вот почему значение “возвращается” к тому, каким оно должно быть. Что касается того, почему кнопка вниз меняет “100” на “99”, я думаю, это совершенно очевидно: 100 минус один равно 99. Это не очень хорошая идея заниматься арифметикой с монстром.

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

// В глобальном масштабе:
int correction = 0;

// В цикле ():
dist = ...;
inches = dist * 0.3937008 + correction;  // здесь добавлена коррекция
ftin = (inches/12) * 100 + (inches%12);  // используется только для отображения

if (Up_lastButtonState == LOW && Up_buttonState == HIGH) {
    correction++;
    delay(500);
}
if (Dn_lastButtonState == LOW && Dn_buttonState == HIGH) {
    correction--;
    delay(500);
}

Обратите внимание, что монстр используется только для отображения. Никакая арифметика на нем не выполняется, так как это не имело бы никакого смысла.

,

Монстр это точно ха-ха. Я делаю дальномер для фокусировки на кинообъективах. У нас объективы имперские, так что лучше раскошелиться на метрические объективы, а то придет монстр. Не могу отблагодарить вас за четкое объяснение, это сработало!, @Suspicious Soup