I2C Project

Hello, I recently entered the world of arduino with no experience in programming, so I don´t understand much, I’m making a project using the I2C Master/Writer - Slave/Reader, the master has TMP36, LDR, Led, Servo and 16x2 LCD, the slave has Led, Servo and 16x2 LCD. I found 3 problems that I ask for help, I would like the Led’s to blink when there’s communication between arduinos, all char is on master, when printing via wire.write(“something”) in slave arduino :
while (1 < Wire.available()) {
char c=Wire.read();
lcd.print(c);}
int x = Wire.read();
lcd.print(x);
int angle=Wire.read();
myservo.write(angle);
}
the last letter comes in ASCII,
in master theres a wire.write like this:
Wire.beginTransmission(8);
Wire.write("There are ");
Wire.write(x); // temperature value
Wire.endTransmission();
this cause to print the angles off the servos in Lcd
So I already use this types off syntax Wire.write(value), Wire.write(string)
I’ve been looking for a example that i don’t find off this
Wire.write(data, length) or other type off transmission
The Master works has expected.(without Led)
Being so I’m asking if someone can help me on this.
Thanks

Please post your code using code tags (Read the first post in this forum for details)

Second, just look at the documentation for Wire.write Arduino - WireWrite to see how to write an array of bytes

Finally, the Wire library uses interrupts in the background to do the actual transmissions (after the Wire.endTransmission() call) so you can't really blink an LED while this is happening. As far as your code is concerned, after you call Wire.endTransmission(), it moves on to the next instruction.

From the slave side, you could turn on an LED whenever there are data available and you are reading them.

I don´t understand much,
I'm making a project using the I2C Master/Writer - Slave/Reader, the master has TMP36, LDR, Led, Servo and 16x2 LCD, the slave has Led, Servo and 16x2 LCD.

If the above is true, you should be learning the basics before you climb 'Mount Everest'.

Why are you trying to send bulky overhead such as human readable strings to a computer? The normal approach is to send a byte telling the receiver what kind of data to expect, followed by one or more bytes with the actual data.

For blinking an LED as you receive/send data, that won't work too well as the data is sent so fast you probably don't see it. The transfer of something as simple as a temperature reading shouldn't take more than 1-2 ms, and that's too short of a flash to see with your eyes. If you want to do this, you have to extend the duration of the flash.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Have you tried some basic code to make an LED flash?

Thanks.. Tom... :slight_smile:

Master code

#include <LiquidCrystal.h>
#include <Wire.h>
#include <Servo.h>
LiquidCrystal lcd(12 , 11, 5, 4, 3, 2);
const long intervaloT=3000;
const long intervaloL=4000;
unsigned long tempoanteriorT=0;
unsigned long tempoanteriorL=0;
const int sensorPinT=A2;
const int sensorPinL=A3;
int sensorvalueT=0;
int sensorvalueL=0;
Servo myservo;
int angle;
byte y=0;
byte z[2];
int temperature;
byte x;
int led=2;

void setup() {
Wire.begin();
lcd.begin(16, 2);
byte x=temperature;
myservo.attach(9);
pinMode(2, OUTPUT);
}

void loop() {
 
lcd.clear();
lcd.setCursor(0, 0);
lcd.print ("Ola ");
Wire.beginTransmission(8);
Wire.write("Ola ");
Wire.endTransmission();
  led();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Esta calor?");
  if (millis() < intervaloT){
    int sensorvalueT=analogRead(sensorPinT);
float voltage=(sensorvalueT/1024.0)*5.0;
float temperature=(voltage-0.5)*100;
    x=temperature;}
  if(millis()-tempoanteriorT>=intervaloT){
  tempoanteriorT=millis();
int sensorvalueT=analogRead(sensorPinT);
float voltage=(sensorvalueT/1024.0)*5.0;
float temperature=(voltage-0.5)*100;
  x=temperature;}
Wire.beginTransmission(8);
Wire.write("Estao  ");
Wire.write(x);
  Wire.endTransmission();
  led();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Esta Sol?");
if(millis()< intervaloL){
  int sensorvalueL=analogRead(sensorPinL);}
  if(millis()-tempoanteriorL>=intervaloL){
  tempoanteriorL=millis();
  int sensorvalueL=analogRead(sensorPinL);}
 if( sensorvalueL<341){
  Wire.beginTransmission(8);
  Wire.write("A anoitecer ");
  Wire.endTransmission();
 led();}
else if((sensorvalueL>=341) && (sensorvalueL<=681)){
  Wire.beginTransmission(8);
    Wire.write("Esta nublado ");
    Wire.endTransmission();
led();}
    else{
      Wire.beginTransmission(8);
      Wire.write("Esta Sol ");
      Wire.endTransmission();
    led();}
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Vamos apoiar");
lcd.setCursor(0,1);
lcd.print("Portugal.");
Wire.beginTransmission(8);
Wire.write("Vamos ");
Wire.endTransmission();
  led();
delay(1000);
flag();
flag();
flag();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Tchau");
Wire.beginTransmission(8);
Wire.write("Tchau ");
Wire.endTransmission();
  led();
delay(1000);
}
void flag(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("PORTUGAL");
  Wire.beginTransmission(8);
  Wire.write("PORTUGAL");
  Wire.endTransmission();
  led();
  angle=110;
  myservo.write(angle);
  //z[0]=110;
  //z[1]=45;  
  Wire.beginTransmission(8);
  Wire.write(angle);
  Wire.endTransmission();
  led();
  delay (400);
  angle=45;
  myservo.write(angle);
  //z[0]=45;
  //z[1]=110;
  Wire.beginTransmission(8);
  Wire.write(angle);
  Wire.endTransmission();
  led();
  delay (400);
}
void led(){
digitalWrite(2, HIGH);
delay(200);
digitalWrite(2, LOW);}

Slave code:

#include <Wire.h>

#include <LiquidCrystal.h>

#include <Servo.h>
LiquidCrystal lcd(12 , 11, 5, 4, 3, 2);
Servo myservo;
int x;
char c;


void setup() {
Wire.begin(8);
lcd.begin(16, 2);
myservo.attach(9);
Wire.onReceive(receiveEvent);
pinMode(1,OUTPUT);
}

void loop() {
  
}
void receiveEvent(int x) {
lcd.clear();
lcd.setCursor(0, 0);
  while (1<Wire.available()){
  char c=Wire.read();
    lcd.print(c);}
	int x = Wire.read();
  switch (x){
    case 1:
    if(x==45){
      myservo.write(x);}
    break;
    case 2:
    if(x==110){
      myservo.write(x);}
    break;
    default:
    lcd.print(x);
  }
}

Hi,
OPs image…
781a17c30751a5427eb9b1a08c6baa5951006b89.jpg
Fritzy does not convey the information needed.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Showing power supply ,pin names and transistor lead names please.

Where is your I2C connection, your code inferred its pin8?
Also powering servos off the 5V of the UNO is not advisable as they can draw more than the UNO is rated for?

Tom… :slight_smile:

This is off the Tinkercad Simulator.
Reuploading.
Fritzing file not possible

Don’t worry, Fritzings are quite useless. This schematic is quite readable, that Fritzing of yours not at all. A higher resolution would be good, though, most letterings are unreadable.

FCT:
c65e72afa7b01db04a6da41a0a947d27e6584525.jpg

I would like to present to you the finished project:

Master/Writer code:

#include <LiquidCrystal.h>
#include <Wire.h>
#include <Servo.h>
LiquidCrystal lcd(12 , 11, 5, 4, 3, 2);
const long intervaloT=3000;
unsigned long tempoanteriorT=0;
const int sensorPinT=A2;
const int sensorPinL=A3;
int sensorvalueT=0;
int sensorvalueL=0;
Servo myservo;
int temperature;
byte x;
int led=1;

void setup() {
Wire.begin();
lcd.begin(16, 2);
byte x=temperature;
myservo.attach(9);
pinMode(1, OUTPUT);
}

void loop() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print ("Ola ");
Wire.beginTransmission(8);
Wire.write("Ola ");
Wire.endTransmission();
  light();
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Esta calor?");
  if (millis() < intervaloT){
    int sensorvalueT=analogRead(sensorPinT);
float voltage=(sensorvalueT/1024.0)*5.0;
float temperature=(voltage-0.5)*100;
    x=temperature;}
  if(millis()-tempoanteriorT>=intervaloT){
  tempoanteriorT=millis();
int sensorvalueT=analogRead(sensorPinT);
float voltage=(sensorvalueT/1024.0)*5.0;
float temperature=(voltage-0.5)*100;
  x=temperature;}
Wire.beginTransmission(8);
Wire.write("Estao  ");
Wire.write(x);
  Wire.endTransmission();
  light();
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Esta Sol?");
 int sensorvalueL=analogRead(sensorPinL);
 if( sensorvalueL<341){
  Wire.beginTransmission(8);
  Wire.write("A anoitecer ");
  Wire.endTransmission();
 light();}
else if((sensorvalueL>=341) && (sensorvalueL<=681)){
  Wire.beginTransmission(8);
    Wire.write("Esta nublado ");
    Wire.endTransmission();
light();}
    else{
      Wire.beginTransmission(8);
      Wire.write("Esta Sol ");
      Wire.endTransmission();
    light();}
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Vamos apoiar");
lcd.setCursor(0,1);
lcd.print("Portugal.");
Wire.beginTransmission(8);
Wire.write("Vamos ");
Wire.endTransmission();
  light();
delay(5000);
flag();
flag();
flag();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Tchau");
Wire.beginTransmission(8);
Wire.write("Tchau ");
Wire.endTransmission();
  light();
delay(5000);
}
void flag(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("PORTUGAL");
  Wire.beginTransmission(8);
  Wire.write("PORTUGAL ");
  Wire.endTransmission();
  light();
  x=110;
  myservo.write(x);
  Wire.beginTransmission(8);
  Wire.write(x);
  Wire.endTransmission();
  light();
  delay (400);
  x=45;
  myservo.write(x);
  Wire.beginTransmission(8);
  Wire.write(x);
  Wire.endTransmission();
  light();
  delay (400);
}
void light(){
digitalWrite(1, HIGH);
delay(200);
digitalWrite(1, LOW);}

Slave/Reader code:

#include <Wire.h>
#include <LiquidCrystal.h>
#include <Servo.h>

LiquidCrystal lcd(12 , 11, 5, 4, 3, 2);
Servo myservo;
int x;
char c;
int led=0;


void setup() { 
Wire.begin(8);
lcd.begin(16, 2);
myservo.attach(9);
Wire.onReceive(receiveEvent);
pinMode(0,OUTPUT);
}

void loop() {
}
  
void receiveEvent(int howMany) {
lcd.clear();
lcd.setCursor(0, 0);
  while (1<Wire.available()){
  char c=Wire.read();
    lcd.print(c);}
  int x = Wire.read();
  switch (x){
    case 45:
    myservo.write(x);
    break;
    case 110:
     myservo.write(x);
   break;
    default:
    lcd.print(x);
    break;
  }
  light();
}
void light(){
digitalWrite(0, HIGH);
delay(200);
digitalWrite(0, LOW);}

In attachment, Breadboard mounting and electrical circuit.

Code is working, but can get more improvement.

A special note to larryd, thanks for the incentive, has you can see after 50 hours of lessons, a newbie can climb ‘Mount Everest’.

Thanks
Filipe

Well done!

One quick and major improvement you can make is formatting your code better - ctrl-T in the IDE autoformats it so it becomes a lot more readable. Especially it corrects indentation so you can quickly see what belongs together.

The “while (1<Wire.available()){” in the receiveEvent() is not needed. That is in the example, but it is confusing.

I don’t understand what kind of data that you transfer. Is it one byte for the Servo and more than one byte a text for the LCD ? You should describe the data that is transferred from the Master to the Slave.

The receiveEvent() calls light() which contains a delay(). Since the receiveEvent() is an interrupt routine, that delay() is going to cause problems sooner or later. I prefer to move all the LCD and Servo functions into the loop(), but I show you how to move that delay() into the loop().

// global variable
volatile byte blinkLight;    // a variable that is used for a command from interrupt to loop()

void loop()
{
  if( blinkLight)    // read command, is it true ?
  {
    blinkLight = false;     // reset command

    digitalWrite( 0, HIGH);
    delay( 200);
    digitalWrite( 0, LOW);}
  }
}

void receiveEvent( int howMany) 
{
  if( howMany == 1)      // a single byte is a value for the Servo
  {
    int x = Wire.read();
    switch( x)
    {
      case 45:
        myservo.write(x);
        break;
      case 110:
        myservo.write(x);
        break;
    }
    blinkLight = true;     // set command
  }
  else if( howMany > 1)    // text for the display ?
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    for( int i=0; i<howMany; i++)
    {
      char c = Wire.read();
      lcd.print( c);
    }
    blinkLight = true;   // set command
  }
}