Проект не работает после 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" и больше не работает.
@Ak., 👍1
Обсуждение0
- Проблемы с добавлением обратного отсчета к фрагменту кода
- Пытаюсь добавить обратный отсчет в код Arduino, но он делает 0 дней, 04:09:36 вместо того, чтобы начинать с 7 дней
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- как быстро loop() работает в Arduino
- Использовать Arduino Nano V3 для программирования другого Arduino (Pro Mini)?
- Как прочитать значение PIN PWM-выхода?
- Как я могу прервать задержку() при нажатии кнопки?
- Как мигать светодиодом и одновременно запускать другой код?
Возможно, стоит избавиться от типа "Строка" и использовать массив фиксированных символов. Из-за динамического выделения памяти в "Строку" могут возникнуть пробелы в памяти, и в конечном итоге закончится память., @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