init.d 0 Жалоба Опубликовано: 10 апреля 2019 (изменено) Дано: модуль датчика холла 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 } Изменено 11 апреля 2019 пользователем init.d не корректная тема топика Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
svchekalin 26 Жалоба Опубликовано: 14 апреля 2019 Может сопротивление добавить ? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Kitsum 238 Жалоба Опубликовано: 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. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах