init.d 0 Report post Posted April 10, 2019 (edited) Дано: модуль датчика холла 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 } Edited April 11, 2019 by init.d не корректная тема топика Share this post Link to post Share on other sites
svchekalin 26 Report post Posted April 14, 2019 Может сопротивление добавить ? Share this post Link to post Share on other sites
Kitsum 238 Report post Posted April 15, 2019 @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. Share this post Link to post Share on other sites