Communication between two MCU is called embedded communication.To perform the communication one of the MCU act as a Sender and other to be as a receiver.MCU communications may in one direction or both, depends on the users choice.
There are enough number of communication protocol available to transmit/receive the data between to MCUs, in general, they are two parallel or serial.This week my plan is to use two types of netweork communication techniques using the boards that i developed during Input week and Output week For programming this week i used FABISP i made during Electronic production week
Parallel Communication
Parallel interfaces transfer multiple bits at the same time. They usually require buses of data - transmitting across eight, sixteen, or more wires. Data is transferred in huge, crashing waves of 1’s and 0’s.It transmit multiple bits of data at same time.they require buses of data to transmitting across eight, sixteen, or more wires.
Paralle communication is fast and straightforward. If we go with this, we need to more I/O pins to establish this communication.. Details are taken from Link
Series Communication
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. But this way of communication is slow, but its more reliable compare to Parallel. I refer Sparkfun website for knowing more about serial communication:
There are various serial protocols for MCU to esstablish communication between other MCU.Serial Communication are sorted into two forms they are
synchronous serial interface means this both sender and receiver shares the same clock. This makes for a more straightforward, often faster serial transfer, but it also requires at least one extra wire between communicating devices. E.g. SPI, and I2C.
Asynchronous means that data is transferred without support from an external clock signal. This way of transmission method is perfect for minimising the required wires and I/O pins. This method established trough Rx and TX pins in MCUs.Device like GSM, GPS, Xbee etc. are connected using this mode.
Fist I plan to go with Asynchronous means of communication.I choose RX and TX pins for this mode
To to communication using RX and TX pins we need to keep in mind about some relevant terms. The first is Baud rate, the speed at which data sent over the serial line. Its usually expressed in bits-per-second. Standard baud rates available is 9600, but we also use some other baud rates 1200, 2400, 4800, 19200, 38400, 57600, and 115200. The higher a baud rate goes, the faster data is sent/received but we need to check whether our MCU cacapable of communicating in this speed otherwise data loss would occur.
To establish this communication I took the MCU boards made in Input and Output week .Input week I made an Attiny 44 board and Output week I made a 328p board with an LCD module. I plan to send the word “hello “ from Attiny, and that would send over RX/TX and display on the LCD module fitted on Atmega 328p.
First I upload the serial data sender code in Attiny 44 and then upload the display code on My atmega 328 ( For uploading code i used USBtiny ISP made in electronic production week ) then connect TX pin of attiny44 with RX pin of 328p. Here Attiny 44 does not have hardware serial, so we need to assign software serial communication. I used PA0 and PA1 as Rx and Tx pins.
// Code is created by Amith: April 29 , 2018 #include <SoftwareSerial.h > // serial library intialization SoftwareSerial serial(0, 1); char mystr[5] = "Hello"; //String data void setup() { serial.begin(4800); // open the serial communication } // the loop function runs over and over again forever void loop() { serial.write(mystr, 5); //Write the serial data delay(1000); }
//Code is created by Amith: April 29 ,2018 #include <LiquidCrystal.h> const int rs = 5, en = 6, d4 = 7, d5 = 8, d6 = 9, d7 = 10; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); char string[5]; //intialized variable to stroe recieved data void setup() { Serial.begin(4800); lcd.begin(16,2); } void loop() { if (Serial.available()) // Check is serial data available or Not { Serial.readBytes(string,5); // Read the datatbye by byte and store in location lcd.clear(); lcd.setCursor(0, 0); // set the cursor lcd.print(string); // print on the LCD } }// join i2c bus
For 328p it already have hardware serial on Do and D1 pins:Explanation of code
Serial.readBytes() reads characters from the serial port into a buffer. The function terminates if the determined length has been read, or it times out
Serial.available() Get the number of bytes (characters) available for reading from the serial port.
Serial.write Writes binary data to the serial port. This data is sent as a byte or series of bytes;
After made connection and upload the program using USBtiny ISP made in electronic production week, display shows the values but some other symbols ar shown along with that, i dont know why that, i try with all other buad rates but the value remain same.
After doing Asychronous serial communication using RX and TX , i go with i2c communication.here i am suing the same boards i used for Rx,TX communication.Atmega328p MCU board is used as master and Attiny44 board as slave .
I2C communication
I2C is a communication protocol which help to communicate between multiple slaves to single master chip.Like Asynchronous Serial communication it only requires two wires for communication.i refered Sparkfun website for knowing more about i2C :Link
In Asynchronous Serial communication, clock data is not transmitted so devices must also have clocks that are close to the same rate, and will remain so any excessive differences between clock rates on eany of the devices will cause garbled data.
While I2C requires two wires similar to Asynchronous Serial communicationand those wires an support large unber of slaves.Each I2c contain two singnals SCL and SDA in which SCL stands forclock signal, and SDA is the data signal. The SCL line is the clock signal which synchronize the data transfer between the devices on the I2C bus and it’s generated by the master device and SDA line which carries the data.
My work
I decide to make I2C communication between Atmega328p board and Attiny44 board. Attiny44 is act as slave.
In Attiny44 PA4 ans PA6 are SCL and SDA repectively , basically I2C buses should be open drive means that they can pull the corresponding signal line low, but cannot drive it high. So inoder to make SDA and SCL pins of Attiny44 should made as High . We can do that by hardware manner or software manner. In hardware manner connect a 4.7k resistor series and connect to 5v and software manner we can also make it high.
Here For Atmega328p by default SDA and SCL pins are in high state so we dont need to make it high . Arduino code is simple , here in which wire.h library is used for to establish i2c connection.
// created by : Amith Gopakumar Nair : Apr 30,2018 #include <Wire.h> #include <LiquidCrystal.h> const int rs = 5, en = 6, d4 = 7, d5 = 8, d6 = 9, d7 = 10; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); int address= 2; void setup() { Wire.begin(); // join i2c bus Serial.begin(9600); lcd.begin(16,2); } void loop() { Wire.requestFrom(address,1); // transmit to device 1 while(Wire.available()) { int i = Wire.read(); String x= String(address); String p = ""; p += x; p += " value is "; p += i; lcd.clear(); lcd.setCursor(0, 1); lcd.print(p); } delay(500); }
Wire.begin() intiate the i2C bus and join the I2C bus as a master or slave.Wire.requestFrom() Used by the master to request bytes from a slave device.The bytes may then be retrieved with the available() and read() functions. Her is used is Wire.requestFrom(address, quantity) in which address means the 7-bit address of the device to request bytes from and quantity means the number of bytes to request .
In Attiny44 arduino code , we need to add a aditional library named tinywires.h , wire .h library doesnot work for attiny44.There are two version of tinywire library mainly they are tinywires.h for Slave and tinywireM.h for master.
We can add the libray from this link :tinywireS.h : tinywireM.h . In arduino code for the slave . Slave address should be defines , here i choose address as 0x2 as my slave address.TinyWireS.begin(address) initialize I2C library ,TinyWireS.send(data) sends a requested byte to master.
// created by : Amith Gopakumar Nair : Apr 30,2018 #include <TinyWireS.h> //the ATTiny Wire library int LEDPin = A0; //indicator LED int i = 0; #define address 0x2 //this slave address void setup() { TinyWireS.begin(address); //TinyWireS.onRequest(requestEvent); pinMode(LEDPin, OUTPUT); digitalWrite(LEDPin, HIGH); digitalWrite(4,HIGH); // software pullup digitalWrite(6,HIGH); // software pull up } void loop() { TinyWireS.send(i); i++; }
After writing the codes and upload it to each boards and make I2C connection between the two boards connect SDa and SCL of mater to SCL and SDA of Attiny44. My master board Atemega 328p read the value send by the Attiny44 slave board and sshows the display on the LCD display connected to Master board.
After that I plan to combine both rx- tx communication with i2c , what i plan is send commands to master from pc through serial monitor and master send data to Slave and slave perform the action and send reply message.
Using serial monitor i send R, G,B as the commands and Master acepts these values and send values to slave , RGB led is connected in slave and for R red colur shows and for G green and for B blue colur glows.
Master : Atmega328p board- Using USB to ttl converter to communicate with Serial monitor
Slave : Attiny44 – RGB led is connected to A3,A7,PB2 pins, I2C connection is explain in above project
Master Code
// created by : Amith Gopakumar Nair : Apr 30,2018 #include <Wire.h > #define ADDR 1 // i2c slave address void setup() { Wire.begin(); // join i2c bus Serial.begin(9600); Serial.println("Hello mater enter R or B or G to light up "); } void loop() { int led_number; if ( Serial.available()) { char chr = Serial.read(); if (chr == 'R') { Serial.println("RED"); Wire.beginTransmission(ADDR); // transmit to device address is specified Wire.write(1); // // sendsvalue byte Wire.endTransmission(); // stop transmitting Wire.requestFrom(ADDR, 1); // Request 1 byte from slave led_number = Wire.read(); Serial.println(led_number); } else if (chr == 'B') { Serial.println("BLUE"); Wire.beginTransmission(ADDR); // transmit to device address is specified Wire.write(2); //// sends value byte Wire.endTransmission(); // stop transmitting Wire.requestFrom(ADDR, 1); // Request 1 byte from slave led_number = Wire.read(); Serial.println(led_number); } else if (chr == 'G') { Serial.println("Green"); Wire.beginTransmission(ADDR); // transmit to device address is specified Wire.write(3); // sends value byte Wire.endTransmission(); // stop transmitting Wire.requestFrom(ADDR, 1); // Request 1 byte from slave led_number = Wire.read(); Serial.println(led_number); } } }
Slave Code
// created by : Amith Gopakumar Nair : Apr 30,2018 #include <TinyWireS.h > #define ADDR 1 // i2c slave address #define LED1_PIN1 A3 // ATtiny Pin PA3 #define LED1_PIN2 8 // ATtiny PB2 #define LED1_PIN3 A7 // ATtiny PA7 void red() //turn On Red led only { TinyWireS.send(5); // sends value byte digitalWrite(LED1_PIN1, HIGH); digitalWrite(LED1_PIN2, LOW); digitalWrite(LED1_PIN3, LOW); } void blue() //turn On Blue only { TinyWireS.send(6); // sends value byte digitalWrite(LED1_PIN1, LOW); digitalWrite(LED1_PIN2, HIGH); digitalWrite(LED1_PIN3, LOW); } void green() //turn On green led only { TinyWireS.send(7); // sends value byte digitalWrite(LED1_PIN1, LOW); digitalWrite(LED1_PIN2, LOW); digitalWrite(LED1_PIN3, HIGH); } void none () // for turn off all leds { digitalWrite(LED1_PIN1, LOW); digitalWrite(LED1_PIN2, LOW); digitalWrite(LED1_PIN3, LOW); } void setup() { pinMode(LED1_PIN1, OUTPUT); pinMode(LED1_PIN2, OUTPUT); pinMode(LED1_PIN3, OUTPUT); TinyWireS.begin(ADDR); // join i2c bus digitalWrite(4, HIGH); // software pull up for SDA digitalWrite(6, HIGH); // software pull up for SCL } void loop() { byte byteRc = 0; if (TinyWireS.available()) // executes when connection is avilable { byteRc = TinyWireS.receive(); // Recive a byte values if (byteRc == 1) { red(); } else if (byteRc == 2) { blue(); } else if (byteRc == 3) { green(); } else { none(); } } }