Проект не работает после 2 - 3 раз, требует частого выключения и включения

Я новичок в Arduino и работаю над проектом. Этот проект вдохновил меня, и я попытался это сделать.

В описании был указан следующий код:

int maxPeople = 5; // максимальное количество людей, разрешенное до срабатывания будильника
int sensitivity = 5; //более низкие значения сделают его более чувствительным, а более высокие-менее чувствительным
//---------------------------------------------------


#include <TM1637.h>

int currentPeople = 0;

int buzzer = 8;

TM1637 tm(2,3);

int sensor1[] = {4,5};
int sensor2[] = {6,7};
int sensor1Initial;
int sensor2Initial;

String sequence = "";

int timeoutCounter = 0;

void setup() {
  //Setup code
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  tm.init();
  tm.set(2);

  delay(500);
  sensor1Initial = measureDistance(sensor1);
  sensor2Initial = measureDistance(sensor2);
}

void loop() {
  //Read ultrasonic sensors
  int sensor1Val = measureDistance(sensor1);
  int sensor2Val = measureDistance(sensor2);

  //Process the data
  if(sensor1Val < sensor1Initial - 30 && sequence.charAt(0) != '1'){
    sequence += "1";
  }else if(sensor2Val < sensor2Initial - 30 && sequence.charAt(0) != '2'){
    sequence += "2";
  }

  if(sequence.equals("12")){
    currentPeople++;  
    sequence="";
    delay(550);
  }else if(sequence.equals("21") && currentPeople > 0){
    currentPeople--;  
    sequence="";
    delay(550);
  }

  //Сбрасывает последовательность, если она недопустима или таймауты
  if(sequence.length() > 2 || sequence.equals("11") || sequence.equals("22") || timeoutCounter > 200) 
 {
    sequence="";  
  }

  if(sequence.length() == 1){ //
    timeoutCounter++;
  }else{
    timeoutCounter=0;
  }

  //Вывод значений в последовательный порт
  Serial.print("Seq: ");
  Serial.print(sequence);
  Serial.print(" S1: ");
  Serial.print(sensor1Val);
  Serial.print(" S2: ");
  Serial.println(sensor2Val);

  //Display current people count on 4-digit display
  tm.display(3, currentPeople % 10);
  int pos2 = currentPeople / 10;
  tm.display(2, pos2 % 10);
  int pos1 = pos2 / 10;
  tm.display(1, pos1 % 10);
  int pos0 = pos1 / 10;
  tm.display(0, pos0 % 10);

  //Если количество людей слишком велико, вызовите зуммер
  if(currentPeople > maxPeople){
    tone(buzzer, 1700);  
  }else{
    noTone(buzzer);  
  }
}

//Возвращает пройденное расстояние ультразвукового датчика
//a[0] = echo, a[1] = trig
int measureDistance(int a[]) {
  pinMode(a[1], OUTPUT);
  digitalWrite(a[1], LOW);
  delayMicroseconds(2);
  digitalWrite(a[1], HIGH);
  delayMicroseconds(10);
  digitalWrite(a[1], LOW);
  pinMode(a[0], INPUT);
  long duration = pulseIn(a[0], HIGH, 100000);
  return duration / 29 / 2;
}

Необходимые библиотеки установлены. Я загрузил это на Arduino nano, и он работал нормально. Я менял maxPeople и проверял, потом тоже все работало правильно. В третьем я заставлял предметы входить и выходить из комнаты, пересекая ультразвуковые датчики. Он, казалось, работал правильно, максимальный счет (maxPeople) был достигнут, и зуммер продолжал работать. Затем я заставил объект покинуть комнату. Вместо уменьшения числа на дисплее (TM1637 4-значный дисплей) продолжал увеличиваться.

Затем я выключил USB - источник и попробовал еще раз. Опять же, он работал правильно один или два раза, и та же проблема сохраняется.

Иногда даже до того, как максимальное количество будет достигнуто, когда объект уходит, количество увеличивается. А иногда счетчик на дисплее остается неподвижным на отметке 0000 или колеблется между "0000" и "0001".

(Я думал, что это может быть неисправность в Arduino, ультразвуковом датчике или дисплее, но я проверил их с помощью других программ с открытым исходным кодом, они работали нормально.)

Я также попытался распределить различные контакты между зуммером, датчиками и дисплеем, но проблема все еще сохраняется.

Заявленная целочисленная чувствительность никогда не используется в коде. Кто - то прокомментировал. Я тоже пробовал это делать, но даже тогда это не работает должным образом.

Есть ли какая-то ошибка в коде, которая вызывает эту проблему, или что-то еще? Я застрял на этом с прошлой недели.

Любая помощь будет оценена по достоинству.


Правка:
Согласно комментарию @Michel's, я попытался изменить строки в массивы символов.

int maxPeople = 5; // максимальное количество людей, разрешенное до срабатывания будильника
int sensitivity = 5; //более низкие значения сделают его более чувствительным, а более высокие значения сделают его менее чувствительным
//---------------------------------------------------


#include <TM1637.h>

int currentPeople = 0;

int buzzer = 8;

TM1637 tm(2, 3);

int sensor1[] = {4, 5};
int sensor2[] = {6, 7};
int sensor1Initial;
int sensor2Initial;

char sequence[2];

int timeoutCounter = 0;

void setup() {
  //Setup code
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  tm.init();
  tm.set(2);

  delay(500);
  sensor1Initial = measureDistance(sensor1);
  sensor2Initial = measureDistance(sensor2);
}

void loop() {
  //Читать ультразвуковые датчики
  int sensor1Val = measureDistance(sensor1);
  int sensor2Val = measureDistance(sensor2);

  //Process the data
  if (sensor1Val < sensor1Initial - 30 && sequence[0] != '1') {
    strcat(sequence, "1");
  } else if (sensor2Val < sensor2Initial - 30 && sequence[0] != '2') {
    strcat(sequence, "2");
  }

  if (strcmp(sequence, "12") == 0) {
    currentPeople++;
    sequence[0] = '\0';
    sequence[1] = '\0';
    delay(550);
  } else if (strcmp(sequence, "21") == 0 && currentPeople > 0) {
    currentPeople--;
    sequence[0] = '\0';
    sequence[1] = '\0';
    delay(550);
  }

  //Сбрасывает последовательность, если она недопустима или таймауты
  if (strlen(sequence) > 2 || strcmp(sequence, "11") == 0 || strcmp(sequence, "22") == 0 || timeoutCounter > 200) {
    sequence[0] = '\0';
    sequence[1] = '\0';

  }

  if (strlen(sequence) == 1) { //
    timeoutCounter++;
  } else {
    timeoutCounter = 0;
  }

  //Вывод значений в последовательный порт
  Serial.print("Seq: ");
  Serial.print(sequence);
  Serial.print(" S1: ");
  Serial.print(sensor1Val);
  Serial.print(" S2: ");
  Serial.println(sensor2Val);

  //Display current people count on 4-digit display
  tm.display(3, currentPeople % 10);
  int pos2 = currentPeople / 10;
  tm.display(2, pos2 % 10);
  int pos1 = pos2 / 10;
  tm.display(1, pos1 % 10);
  int pos0 = pos1 / 10;
  tm.display(0, pos0 % 10);

  //Если количество людей слишком велико, вызвать зуммер
  if (currentPeople > maxPeople) {
    tone(buzzer, 1700);
  } else {
    noTone(buzzer);
  }
}

//Возвращает пройденное расстояние ультразвукового датчика
//a[0] = echo, a[1] = trig
int measureDistance(int a[]) {
  pinMode(a[1], OUTPUT);
  digitalWrite(a[1], LOW);
  delayMicroseconds(2);
  digitalWrite(a[1], HIGH);
  delayMicroseconds(10);
  digitalWrite(a[1], LOW);
  pinMode(a[0], INPUT);
  long duration = pulseIn(a[0], HIGH, 100000);
  return duration / 29 / 2;
}

Есть ли в этом какая-то ошибка? При загрузке этого кода дисплей останавливается на "0001" и больше не работает.

, 👍1

Обсуждение

Возможно, стоит избавиться от типа "Строка" и использовать массив фиксированных символов. Из-за динамического выделения памяти в "Строку" могут возникнуть пробелы в памяти, и в конечном итоге закончится память., @Michel Keijzers

@MichelKeijzers Спасибо тебе! Я только что узнал о массивах символов. Я попробую это сделать и обновлю., @Ak.

Вам нужно будет изменить некоторые вещи, например, определить константу для МАКСИМАЛЬНОГО размера массива, и использовать функции "strcat", "strln" и " strcmp` вместо добавления, проверки размера и сравнения., @Michel Keijzers

При использовании строк C вам также нужно сохранить один \0 для конечного символа, поэтому для хранения "01" вам нужно 3 байта., иначе strlen/strcmp не будет работать., @Michel Keijzers

Также я думаю, что с - 30 вы хотите преобразовать '0' в 0, но затем вам нужно использовать 0x30 (шестнадцатеричный код), что означает "0", или лучше: используйте '0' напрямую (с приведением, если необходимо), @Michel Keijzers

Попробуйте использовать 0x30 вместо 30 (при условии, что вы хотите преобразовать " 0 " в 0 (символ ноль в число 0), @Michel Keijzers

@MichelKeijzers Огромное вам спасибо за всю вашу помощь. Сейчас это работает довольно хорошо. Однако, если кто-то перемещается (это невозможно в реальности, так как минимальное количество = 0), когда текущие люди = 0, он застревает на " 0000 и больше ничего не чувствует. Могу я добавить что-нибудь вроде, если (нынешние люди < 0 ) продолжить; ` в коде? Невозможно использовать continue в циклах, есть ли что-нибудь подобное, что можно использовать? Пожалуйста, опубликуйте все свои комментарии в качестве ответа, чтобы я мог это принять., @Ak.

Вы можете использовать оператор, я не уверен, будет ли он делать то, что вы хотите, но это правильное синтаксическое утверждение. Кроме того, вы, вероятно, можете пропустить всю последовательность[1] = '\0';` заявления. Когда первый элемент равен 0, считается, что строка заканчивается там, и, например, "strcmp" не проверяет дальше., @Michel Keijzers