Отправка 4 аналоговых значений от одного arduino к другому с помощью I2C

Я модифицировал дешевый контроллер дрона, чтобы вывести его значения джойстика на Arduino Nano.

Я сделал это, чтобы вывести его значения 4 pot с помощью I2C на другой Arduino, не спрашивайте почему. Итак, моя проблема в том, что мне нужно отправить 4 значения, но я могу отправить только 1. Помогите мне, пожалуйста.

У меня нет ограничения по времени или что-то в этом роде, так что мне не нужно это быстро или сейчас!

Я также использую ЖК-дисплей 16x2 без I2C, чтобы показать текущие значения, и иногда я хочу сделать там меню или что-то в этом роде.

Я бы хотел, чтобы вы написали код для меня, но это нормально, если вы не можете. Кроме того, я своего рода нуб в программировании arduino.

Мастер (он же нано в контроллере):

int pot1 = A0;
int pot2 = A1;
int pot3 = A2;
int pot4 = A3;

int potValue1 = 0;
int potValue2 = 0;
int potValue3 = 0;
int potValue4 = 0;

int led = 10;
int button = 8;

int lastButtonState;    // предыдущее состояние кнопки
int currentButtonState; // текущее состояние кнопки

int output1 = A4;
int output2 = A5;
int output3 = A6;
int output4 = A7;

#include <Wire.h>
#include <LiquidCrystal.h> // включает библиотеку LiquidCrystal

LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // Создает объект LC. Параметры: (rs, enable, d4, d5, d6, d7)

#define SLAVE_ADDR 9

void setup() {
  pinMode(led, OUTPUT);
  pinMode(button, INPUT_PULLUP);

  // Откройте последовательную связь и дождитесь открытия порта:
  Wire.begin();

  lcd.begin(16, 2);
  lcd.print("   ArduinoTX");
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
  delay(600);
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
  delay(600);
  digitalWrite(led, HIGH);
  delay(600);
  delay(3000);
  lcd.clear();
}

void loop() {
  currentButtonState = digitalRead(button);
  potValue1 = analogRead(pot1);
  potValue2 = analogRead(pot2);
  potValue3 = analogRead(pot3);
  potValue4 = analogRead(pot4);

  int sendValue = map(potValue4, 1, 1023, 1, 255);  // преобразование в значения 255 макс
  int sendValue2 = map(potValue3, 1, 1023, 1, 255);
  int sendValue3 = map(potValue2, 1, 1023, 1, 255);
  int sendValue4 = map(potValue1, 1, 1023, 1, 255);

  Wire.beginTransmission(SLAVE_ADDR); // отправка только одного значения pot
  Wire.write(sendValue);
  Wire.endTransmission();

  lastButtonState  = currentButtonState;      // сохранить последнее состояние
  currentButtonState = digitalRead(button); // прочитать новое состояние

  if (lastButtonState == LOW && currentButtonState == LOW) { //не беспокойтесь об этом
    lcd.print(potValue4);
    lcd.print("        ");
    lcd.print(potValue2);
    delay(delayTime);
    lcd.clear();
    lcd.setCursor(0, 2);
    lcd.print(potValue3);
    lcd.print("        ");
    lcd.print(potValue1);
    delay(delayTime);
    lcd.clear();
  }
}

Раб (или uno, который получает значения):

int rd;
int br;

#include <Wire.h>

#define SLAVE_ADDR 9

void setup() {
  // поместите свой установочный код здесь, чтобы запустить один раз:
  Wire.begin(SLAVE_ADDR);
   
  // Функция для запуска при получении данных от мастера
  Wire.onReceive(receiveEvent);
 
  // Настройка последовательного монитора
  Serial.begin(9600);
}

void receiveEvent() {
  // считывание одного символа из I2C
  rd = Wire.read();
  Serial.println(rd);  
}

void loop() {
  delay(50);
}

Спасибо!

, 👍0

Обсуждение

- Я бы хотел, чтобы ты написал код для меня, но ничего страшного, если ты не можешь. Это очень тактично с вашей стороны., @romkey

"Мне нужно отправить 4 значения, но я могу отправить только 1" почему вы можете отправить только 1?, @timemage


1 ответ


1

Почему вы ограничиваетесь отправкой одного значения? Вы можете иметь несколько вызовов Wire.write() в одной передаче.

Ведомая сторона просто должна знать, чтобы ожидать несколько значений для того, чтобы приспособиться. Лучший способ сделать это - читать значения до тех пор, пока мастер их отправляет (проверьте https://www.arduino.cc/en/Reference/WireRead).

Тогда ваш хозяин меняется с

Wire.beginTransmission(SLAVE_ADDR);
Wire.write(sendValue);
Wire.endTransmission();

Для

Wire.beginTransmission(SLAVE_ADDR);
Wire.write(sendValue);
Wire.write(sendValue2);
Wire.write(sendValue3);
Wire.write(sendValue4);
Wire.endTransmission();

И раб receiveEvent() становится

int receiveValue;
int receiveValue2;
int receiveValue3;
int receiveValue4;  
int index = 0;
while(Wire.available()){
    if(index == 0){ receiveValue = Wire.read(); }
    else if(index == 1) {receiveValue2 = Wire.read(); }
    else if(index == 2) {receiveValue3 = Wire.read(); }
    else if(index == 3) {receiveValue4 = Wire.read(); }
    index++;
}

Я бы также рассмотрел использование массивов как способ очистки некоторых ваших переменных, но внесение вышеуказанных изменений должно выполнить то, что вы хотите, если не так чисто.

,

С Наступающим Новым Годом! Но это все равно не работает:( А также как мне последовательно печатать эти значения, может быть, это моя проблема, потому что я поместил Serial.print (receiveValue); в цикл void, потому что я думал, что так и должно быть. Скажем, если мне нужно опубликовать обновленный код, @Imanoobdotcom

Если вы хотите напечатать receiveValue, то лучше всего сделать это в void receiveEvent(). Если вы не сделали "receiveValue" глобальной переменной, печать ее в вашем цикле не будет работать и в любом случае может привести к вводящим в заблуждение результатам. Я не знаю точно, какую проблему вы видите на данный момент. Не могли бы вы предоставить более подробную информацию? Если это просто не * printing * 4 значения, см. Мой предыдущий ответ и добавьте Serial.println() для всех receiveValues., @Andrew