I2C and UART not working together

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi all. i want using Arduino mega to receive data (using uart 110 byte ) from another board and save it to eeprom in real time. So i using  UART interrupt. but when i using i2c in the function UART interput. they are not working together. i setting 2 board 4800 baud rate , 8 bit data, 1 stop bit, no check bit.  this is my code : 

#define F_CPU 16000000UL
#define BAUD 9600
#include <MKSEEPROM.h> // this is my library save eeprom (i2c) .

void setup()
{
  Serial.begin(115200);
  Serial.println("begin");
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  setting();
  UBRR2H = 0;
  UBRR2L = 207;
  UCSR2A = 0x00;
  UCSR2C = (30 << UMSEL21) | (1 << UCSZ21) | (1 << UCSZ20) ;
  UCSR2B = (1 << RXEN2) | (1 << TXEN2) | ( 1 << RXCIE2); //enable Tx and Rx
  sei();

}
void loop()
{
    // working another
}
ISR(USART2_RX_vect)
{
  char c = UDR2 ;
  if (str.length() < 110)
    str += c ;
  if (str.length() == 110)
  {
    writeblock(0x50, 0, str); // this is my funciton using i2c save to eeprom.
    str = "";
  }
}

 

Divide

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does the i2c code use interrupts? If it does, it won't work as interrupts are disabled when you enter an ISR. Doing a long write in an ISR is not a real good idea anyway. The 'usual' technique is to set a flag when you want the write to happen and have your main() code poll the flag and write the data.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HI. I Using i2c library from arduino .I modified the arduino's wire library to no interrupt. but it not working together

 

Divide

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

you_mylove wrote:
I modified the arduino's wire library to no interrupt. but it not working together

So does the modified library work on its own?

 

You keep saying, "doesn't work" - but that tells us nothing.

 

So what, exactly, are the symptoms you are seeing?

 

As already noted, I2C transactions are relatively long & involved - so not the kind of thing you want to be doing in an interrupt at all.

 

Surely, the "normal" approach would be for the UART receive ISR to just put the data into a buffer (usually a ring buffer) - and the EEPROM code to take it from there to store it in the "main" code ?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When using each library, it works well. but i2c and uart are the same as my code. board 2 receives about 30 bytes from board 1 then board 2 stops working. I want my board 2 to always read the data in the eeprom and send them to the server, unless I get data from board 1 and save to eeprom. So i used i2c in UART interrupt function

 

Divide

Last Edited: Tue. Nov 7, 2017 - 10:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We have no idea of what your code does since you have not shown it to us. We already given you a suggestion based on our guess. How many guesses do you want us to make? Do we get three?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

this is function receiver data and save to eeprom 

 ISR(USART1_RX_vect)
  {
  char c = UDR1 ;
  if (str.length() < 110  )
    str += c ;
  if (str.length() == 110)
  {
    Serial.println(str);
    writebyte(0x50, 0, 1);
    str = "";
  }
  }

and this is my function save to eeprom using i2c.  

uint16_t writeblock(uint8_t deviceaddress,uint16_t StartAddress, String str)
{
	Wire.beginTransmission(deviceaddress);
	Wire.write((int)((StartAddress) >> 8)); // MSB
	Wire.write((int)((StartAddress) & 0xFF)); // LSB
	for ( i= 0 ; i < 30; i++)
		Wire.write(s[i]);
	Wire.endTransmission();
	delay(2);	

	Wire.beginTransmission(deviceaddress);
	Wire.write((int)((StartAddress) >> 8)); // MSB
	Wire.write((int)((StartAddress) & 0xFF)); // LSB
	for ( i= 0 ; i < 25; i++)
		Wire.write(s[i]);
	Wire.endTransmission();
	delay(2);
}

   this is setting for i2c

TWCR = _BV(TWEN) | (0<< TWIE) | _BV(TWEA);

 

Divide

Last Edited: Tue. Nov 7, 2017 - 10:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Originally I intended to use the flag when receiving the data. However, time to send to my server takes about 2-3s. While the data transmitted from board 1 can be up to 2 data / s. I did not think of a way to overcome this except to save data in the interrupt function. I use SPI in uart interrupt, it works.

Divide

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

you_mylove wrote:
 board 2 stops working.

Again, that tells us nothing.

 

It certainly does not just "stop working" completely - it must be doing something!

 

Your job, in debugging your code, is to find out what it is doing.

 

You still haven't shown the full code - the latest code (in #7) never calls writeblock()

 

Did you understand what I said about using a buffer ... ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where is str defined?