Sending 4 pot values with I2C from one arduino to another

Hello

I have modded a cheap drone controller to output its joystick values to an Arduino nano. I made it to output its 4 pot values using i2c to another Arduino don’t ask why. So my problem is that I need to send 4 values but I can send only 1. help me please I don’t have a time limit or something so I don’t need this quick or now! I am also using a 16x2 LCD without i2c to show the live values and sometime I want to make a menu there or stuff like that

Master(a.k.a the nano in the controller):

/*
   Set delay time on delayTime
   its like the refresh rate for the lcd
*/

int delayTime = 50;


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;    // the previous state of button
int currentButtonState; // the current state of button


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

#include<Wire.h>
#include <LiquidCrystal.h> // includes the LiquidCrystal Library 
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
#define SLAVE_ADDR 9



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

  // Open serial communications and wait for port to open:
  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);  //converting to values 255 max 
  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); //sending only one pot value
  Wire.write(sendValue);
  Wire.endTransmission();
 

  lastButtonState  = currentButtonState;      // save the last state
  currentButtonState = digitalRead(button); // read new state




  if (lastButtonState == LOW && currentButtonState == LOW) { //dont worry about this

    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();


  }

}

Slave(or an uno who receives the values):

int rd;
int br;
#include <Wire.h>

#define SLAVE_ADDR 9



void setup() {
  // put your setup code here, to run once:
  Wire.begin(SLAVE_ADDR);
   
  // Function to run when data received from master
  Wire.onReceive(receiveEvent);
  
  // Setup Serial Monitor 
  Serial.begin(9600);
}
void receiveEvent() {
  // read one character from the I2C
  rd = Wire.read();
  Serial.println(rd);
    
}

void loop() {
  delay(50);

}

Thanks!

This Arduino to Arduino I2C Tutorial may help.

...R

Thank you i will look into it

This is very close to my setup but I need to have the pots connected to the master and I don't understand that complicated of code so maybe you can modify it for me? I understand if you cant

Why does the pot measuring nano need be master? It can still run display as slave.

adrianskalni:
How to send 4 Pot values via i2c from Arduino to Arduino? How to differentiate these values while receiving them? - Stack Overflow

This is very close to my setup but I need to have the pots connected to the master and I don't understand that complicated of code so maybe you can modify it for me? I understand if you cant

Sorry, but I don't like that code. At first glance I see more than ten issues with it. Don't be tempted to use it as example. Please ignore that sketch in the answer at stackoverflow.

Your sketch is going in the right direction. If you look at the Robin2 tutorial, you will notice that it is more complex with the struct, but the base principle is the same as what your sketch was heading to. If you don't understand something, just ask.

adrianskalni:
I made it to output its 4 pot values using i2c to another Arduino don't ask why.

Why ?

Well, I would be happy if someone could rewrite the code for me but in my opinion, it feels like I'm wasting someone's time? But if you can I will be thankful.

Koepel:
Why ?

Well I'm making it as an all in one controller for everything so that's why I'm outputting it to another Arduino

adrianskalni:
Well, I would be happy if someone could rewrite the code for me

Have you tried using the code from my Tutorial?

...R

I don't understand that complicated of code

adrianskalni:
I don't understand that complicated of code

If you explain what exactly you don't understand I will try to help.

...R

I dont understand like the byte stuff like all i do is simple code so this is a challenge for me i just really wanted to make myself face a challenge not like write in the serial monitor on blink leds and other a little bit complicated stuff

I have not used tge string byte and other stuff like that when i learned to code they teached like the basic basic stuff

adrianskalni:
I dont understand like the byte stuff

That is not specific enough for me to help you. You can't really do any Arduino programming without understanding about bytes - they are the fundamental building block for everything.

Can you identify the lines of code in my Tutorial that you don't understand?

...R

Wire.write((byte*) &sendData, sizeof(sendData))
I dont understand senddata and the byte sizeof
Thats what i dont understand

adrianskalni:
Wire.write((byte*) &sendData, sizeof(sendData))
I dont understand senddata and the byte sizeof
Thats what i dont understand

In the example Master program the equivalent line is

Wire.write((byte*) &txData, sizeof(txData));

Perhaps I should have used the same name in both cases - you can consider sendData and txData to be different names for the same thing.

txData is the name of the struct that is to be sent
sizeof(txData) figures out how many bytes there are in txData

Wire.write() sends a block of bytes and the code (byte*) tells the compiler to treat the contents of txData as block of bytes. The &txData tells the compiler to use the data that starts at the address in memory where txData is stored.

…R

The sizeof() is not a real function, it is solved by the compiler and gives the size of that thing in bytes.
Below I show a few different ways to return data in the onRequest handler. You can use it without fully understanding it :wink:

The Wire.write() can be used in two ways: with a single byte or with a pointer. The name of an array is already a pointer and the name of a struct is not a pointer. To get the address of a struct the '&' is used. The address of a struct is a pointer.

// send a single byte
byte myByte;
Wire.write( myByte);

// send an array of bytes
byte myArray[10]
Wire.write( myArray, 10);

// send an array of integers
int myIntegers[10];
Wire.write( (char *) myIntegers, 20);  // assuming an int is 2 byte

// send an array of integers in a smart way
int myIntegers[10];
Wire.write( (char *) myIntegers, sizeof( myIntegers));

// send a struct
Wire.write((byte*) &sendData, sizeof(sendData));

All of this can be greatly simplified by using SerialTransfer.h. It comes with several I2C examples (master and slave). To install

// send an array of integers
int myIntegers[10];
Wire.write( (char *) myIntegers, 20);  // assuming an int is 2 byte

So i need to use this one?
Because i have those 4 pot values i make them integers and send them in an array.
If yes then how do i put this in my code?
But isnt arduino sending 4byte integers?

Power_Broker:
All of this can be greatly simplified by using SerialTransfer.h. It comes with several I2C examples (master and slave). To install

And i cant find any good video tutorials maybe you can find a article or a video

If you prefer to use integers, then yes, you can use an array.
With an Arduino Nano, an integer is two bytes, so if you want to send 10 integers, you have to send 20 bytes.
Using the "sizeof()" is nicer, but not needed.

Instead of using the struct, you can use an array of 4 integers and send 8 bytes.

Master:

int myData[4];

...

Wire.beginTransmission( otherAddress);
Wire.write( (byte*) myData, 8);
Wire.endTransmission();    // this is what actually sends the data

Slave:

volatile int myData[4];

...

Wire.readBytes( (byte*) myData, 8);
newRxData = true;

Now I understand but how do I put the 4 pot values in the

int myData[4];

Like this?

int myData[pot1, pot2, pot3, pot4];