Global variable arduino

2019-07-28 06:02发布

问题:

I'm using I2C to communicate a Master Arduino to 4 Slaves Arduinos, and an Shield (OULIMEX Shield LCD 16x2) on every Arduino slave. I send Data from the master to slaves using I2C. So I use this code in the master :

#include <Wire.h>
#include <math.h>
#include <floatToString.h>

double incomingData;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  incomingData = Serial.parseFloat();    //read incoming data
}

void loop()
{
  delay (1000);

  if (Serial.available())
  {

    incomingData = Serial.parseFloat(); //read incoming data
    Wire.beginTransmission(8);    // transmit to device #8 



    if ((M==0) || (M==1) || (M==2))
      Wire.beginTransmission(8);    // transmit to device #8 *****************************************************************

    else
      Wire.beginTransmission(7);    // transmit to device #7 *****************************************************************     
    M++;
    if (M==5)
      M=0;

    String a = ""; 
    a = floatToString(test,incomingData,3,5,true);
    for(i=0; a[i]!='\0'; ++i);    // length of the string

    Wire.write(i);
    Wire.write(floatToString(test,incomingData,3,5,true));      //  sends one byte
    Wire.endTransmission();    //    stop transmitting
    }

}

I wanted the Data to be printed on the Shield, but I'm connecting all slaves with the same way with the master. For that I have two problems :

1- The global data I'm using to print value is always printed as 0, and not giving the real value;

2- All Shields print the same thing : For exemple, I print "hello" in the first Shield, and I print "hi" in the second Shield, but bouth are printing the same thing (hello or hi).

The code using for the first slave is :

#include <LCD16x2.h>
#include <Wire.h>

LCD16x2 lcd;

int buttons;

int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor

float numOut;
int comp=1 ;
String wordd = "";
int M =0;

void setup()
{

  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output  

}

void loop()
{
 delay(500);
}   
 // function that executes whenever data is received from master
 // this function is registered as an event, see setup()
  void receiveEvent(int howMany) {
  wordd = "";
  int x = Wire.read();
  for (int i=0; i<=x; i++)
  {
    char c = Wire.read();
    wordd += c;
  }
  numOut = wordd.toFloat();
  Serial.println(numOut,3);         // print the integer
}

Thank you in advance !!

回答1:

I think it's due to a poor program structure in master shield.

This block selects the slave but on the first line you already select #8 I think this is confusing for the slaves.

Wire.beginTransmission(8);    // transmit to device #8 

    if ((M==0) || (M==1) || (M==2))
      Wire.beginTransmission(8);    // transmit to device #8 
    else
      Wire.beginTransmission(7);    // transmit to device #7 

This block should be at the end of the function

M++;
if (M==5)
  M=0;

Then you parse the value in a string. But leave out the first char because you write ++i instead of i++

Moreover you close the loop with ; so it does nothing

String a = ""; 
a = floatToString(test,incomingData,3,5,true);
for(i=0; a[i]!='\0'; ++i);    // length of the string

Finally you write the ordinal number of the byte And then again the Whole string

So you should get "0" (or "1" because of ++i) followed by your number if Wire.write() supports it

Wire.write(i);
Wire.write(floatToString(test,incomingData,3,5,true));      //  sends one byte
Wire.endTransmission();    //    stop transmitting
}

Your sketch should be:

if (Serial.available())
    {
    incomingData = Serial.parseFloat(); //read incoming data

    String a = ""; 
    a = floatToString(test,incomingData,3,5,true);

    if ((M==0) || (M==1) || (M==2))
        Wire.beginTransmission(8);    // transmit to device #8 
    else
        Wire.beginTransmission(7);    // transmit to device #7 

    for(i=0; a[i]!='\0'; ++i)    // length of the string
        Wire.write(a[i]);        // write one byte


    Wire.endTransmission();    //    stop transmitting

    M++;
    if (M==5) M=0;
    }

Let me know if this works.



回答2:

I already ask this question but I think I have the answer of it. A global variable have to be diclared befor the void setup, and the void loop too, like that :

type YourGlobalVariable;

void setup()
{
}
void loop()
{
}

So, it is exactly how I did already. The reason it didn't work for me, it was cause of I used this function :

  void receiveEvent(int howMany) {}

I don't really know what are the properties of it that let it not work for a global variables, but It works like I sayd already.

Thank you all