Перейти к публикации
iT4iT.CLUB
init.d

Нужна помощь ГУРУ: проблема инициализации состояния датчиков холла

Рекомендованные сообщения

Дано: модуль датчика холла A3144 подключенный через I2C расширитель PCF8575 к UNO R3

Необходимо контролировать наличие магнита и передавать информацию на сервер по mqtt-протоколу

При инициализации устройства магниты УЖЕ поднесены к датчику Холла. 

Проблема: при старте устройства с поднесенными магнитом, скетчу "сносит" башню и Ардуино не понимает состояние датчика и не может отслеживать их переключение.

Если изначально при старте магниты не поднесены, всё прекрасно работает.

Код (часть связанную с сетью и передачей по mqtt-протоколу на брокер исключил):

01  #include <SPI.h>
02	#include <Wire.h>
03	#include <PCF8575.h>
04	
05	#define PUB_DELAY 3000 // Частота передачи данных ото всех ключей
06	#define CHK_DELAY 500 // Частота проверки ключей
07	#define KEYS 3 // Кол-во ключей
08	#define ACT LOW // Состояние входа при активации
09	#define DIS !ACT
10	
11	PCF8575 ex1;
12	  
13	long previousMillis, checkMillis;
14	boolean kst[KEYS] = {0};
15	  
16	void setup () {
17	  // setup serial communication
18	  Serial.begin(9600);
19	  
20	  
21	  // Адрес i2c расширителя pcf8575
22	  ex1.begin(0x20);
23	   
24	  for (int i = 0; i < 3; i++) ex1.pinMode(i, INPUT);
25	  for (int i = 0; i < KEYS; i++) kst = DIS; // состояние датчика задается константой 
26   
27   delay(1500); // Allow hardware to stabilize
28   
29   previousMillis = millis();
30   checkMillis = millis();
31    
32 }
33   
34 void loop () {
35   if (millis() - checkMillis > CHK_DELAY) { // проверка ключей
36     for (int i = 0; i < 3; i++) kst = ex1.digitalRead(i);
37     for (int i = 0; i < 3; i++){
38       if (kst[i] == ACT) { // если хотя бы 1 ключ активен
39         String state = "Active";
40         Serial.println (state);
41       }
42     }
43     checkMillis = millis();
44   }
45   if (millis() - previousMillis > PUB_DELAY) { // передача данных о ключах
46     String request;
47     for (int i = 0; i < 3; i++) {
48        Serial.println (request);
49     }
50     previousMillis = millis();
51   }
52     // mqttClient.loop();
53 }

 

Изменено пользователем init.d
не корректная тема топика

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@init.d У Вас ряд явных проблем при работе с массивом.

for (int i = 0; i < KEYS; i++) kst = DIS; // состояние датчика задается константой

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

for (int i = 0; i < KEYS; i++) kst[i] = DIS;

Вообще два одинаковых цикла for можно и одним заменить, но если честно, то наполнение массива kst не имеет смысла т.к массив был заполнен при объявлении, просто заполните его нужными значениями.

boolean kst[KEYS] = {0};

Та же самая ситуация происходит и в цикле loop - двойные циклы и попытка перезаписать память, значениями которых там быть не должно.

for (int i = 0; i < 3; i++) kst = ex1.digitalRead(i);
  for (int i = 0; i < 3; i++){
  if (kst[i] == ACT) { // если хотя бы 1 ключ активен
    String state = "Active";
    Serial.println (state);
  }
}

А хотели, видимо, получить это

bool state = false; // Водим bool переменную чтобы не спамить Active в Serial если более одного порта активно
for (int i = 0; i < KEYS; i++) { // Все делаем в одном цикле с лимитом указанным к KEYS
  kst[i] = ex1.digitalRead(i); // Пишем состояние порта в соответствующий элемент массива
  if (kst[i] == ACT) state = true; // Меняем состояние если хотябы один порт в состоянии ACT
}
if (state) Serial.println("Active"); // Сообщаем о состоянии ACT

Ну и все в таком духе.

А если по нормальному, то надо использовать прерывания, PCF8575 их поддерживает. Но опять вопрос, зачем нужен этот расширитель портов, если не задействованы стандартные порты микроконтроллера (в данном случае UNO). Выкидываем PCF и используем прерывания на стандартных портах. Почитать о них можно тут https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

И в таком случае код будет выглядеть совсем иначе, а работать намного быстрее и стабильнее. Единственный минус, это всего два порта поддерживающих прерывания у UNO.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пожалуйста, войдите для комментирования

Вы сможете оставить комментарий после входа



Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.

×
×
  • Создать...