Взаимодействие Arduino по интерфейсу I2C.
- Войдите на сайт для отправки комментариев
Ср, 23/02/2022 - 17:01
Добрый день. Есть небольшой проект, в котором участвуют две платы Arduino Uno. Есть необходимость настроить одностороннее управление ведомой платы (без передачи обратных данных). Для взаимодействия используется интерфейс I2C.
Arduino Master собирает информацию, поступающую от трёх сонаров HC-SR04 и отправляет данные.
Arduino Slave принимает переданные данные и на их основании управляет светодиодами - включает правый, левый или два одновременно на заданный промежуток времени.
Для настройки был собран мини-стенд:
В результате включается только LedR с хаотичными миганиями. Есть ли возможность подсказать в чём может быть причина? Скетчи ведущего и ведомого прикрепил.
Скетч Master:
ARDUINO MASTER #include <Wire.h> //Sonar_pin x3 // №1 int TRIG1 = 7; int ECHO1 = 6; // №2 int TRIG2 = 9; int ECHO2 = 8; // №3 int TRIG3 = 11; int ECHO3 = 10; //переменные для передачи данных int right = 1; int forward = 2; int left = 3; void setup() { Wire.begin(); pinMode (TRIG1, OUTPUT); pinMode (ECHO1, INPUT); pinMode (TRIG2, OUTPUT); pinMode (ECHO2, INPUT); pinMode (TRIG3, OUTPUT); pinMode (ECHO3, INPUT); } void loop() { // переменные обработки данных сонаров int duration1, distance1; int duration2, distance2; int duration3, distance3; //sonar1 digitalWrite (TRIG1, LOW); delayMicroseconds (2); digitalWrite (TRIG1, HIGH); delayMicroseconds (10); digitalWrite (TRIG1, LOW); duration1 = pulseIn (ECHO1, HIGH); distance1 = duration1 / 58; //sonar2 digitalWrite (TRIG2, LOW); delayMicroseconds (2); digitalWrite (TRIG2, HIGH); delayMicroseconds (10); digitalWrite (TRIG2, LOW); duration2 = pulseIn (ECHO2, HIGH); distance2 = duration2 / 58; //sonar3 digitalWrite (TRIG3, LOW); delayMicroseconds (2); digitalWrite (TRIG3, HIGH); delayMicroseconds (10); digitalWrite (TRIG3, LOW); duration3 = pulseIn (ECHO3, HIGH); distance3 = duration3 / 58; //если дистанция на сонаре №1 меньше 10см, то отправляем данные if(distance1 <= 10){ Wire.beginTransmission(8); Wire.write(right); Wire.endTransmission(); delay (2000); } //если дистанция на сонаре №2 меньше 10см, то отправляем данные else if (distance2 <= 10){ Wire.beginTransmission(8); Wire.write(forward); Wire.endTransmission(); delay (2000); } //если дистанция на сонаре №3 меньше 10см, то отправляем данные else if (distance3 <= 10){ Wire.beginTransmission(8); Wire.write(left); Wire.endTransmission(); delay (2000); } }
Скетч Slave:
ARDUINO SLAVE #include <Wire.h> // переменная для входящих данных int go; // светодиоды правый и левый int LedL = 9; int LedR = 8; void setup() { Wire.begin(8); Wire.onReceive(receiveEvent); pinMode (LedL, OUTPUT); pinMode (LedR, OUTPUT); } void loop() { delay(100); } void receiveEvent(int howMany) { while (Wire.available()) { go = Wire.read(); } // если поступило значение 1 (right) if (go = 1){ digitalWrite (LedR, HIGH); delay (2000); digitalWrite (LedR, LOW); } // если поступило значение 2 (forward) else if (go = 2) { digitalWrite (LedR, HIGH); digitalWrite (LedL, HIGH); delay (2000); digitalWrite (LedR, LOW); digitalWrite (LedL, LOW); } // если поступило значение 3 (left) else if (go = 3) { digitalWrite (LedL, HIGH); delay (2000); digitalWrite (LedL, LOW); } // во всех остальных случаях else { digitalWrite (LedR, LOW); digitalWrite (LedL, LOW); } }
Избавьтесь, для начала, от delay() в коде.
http://arduino.ru/tutorials/BlinkWithoutDelay
delay(2000) в обработчике прерывания - это что-то за пределами добра и зла.
Ну и когда избавитесь от этого ужаса, пересмотрите типы переменных. Навскидку все или почти все переменные int лучше заменить на byte.
1. Зачем используются присваивания в строках №№ 33, 40 и 49 в Slave? Что Вы этим хотели сказать?
2. Почему бы в строке №31 не поставить вывод в Serial значения переменной go, чтобы быть уверенным, что передалось нормально?
ЕвгенийП, в строках скетча Slave №№ 33, 40 и 49 должно быть равенство, а не оператор присваивания. Вы обнаружили ошибку, исправил, спасибо. Требуемая функция стала выполняться правильно.
BOOM, andriano, delay() в коде Master убрал полностью, в коде Slave оставил в строках №№ 35, 43, 51, так как светодиод не успевает набрать яркость.
Требуемый функционал выполняется как планировалось. Всем спасибо за помощь