### Project 9: 8*16 Facial Expression LED Dot Matrix ![](./media/image-20250709110751263.png) #### **(1)Description:** Won’t it be fun if a expression board is added to the robot? And the Keyestudio 8*16 LED dot matrix can do the trick. With the help of it, you could design facial expressions, images, patterns and other displays by yourselves. The 8*16 LED board comes with 128 LEDs. The data of the microprocessor (Arduino) communicates with the AiP1640 through a two-wire bus interface. Therefore, it can control the on and off of 128 LEDs on the module, so as to make the dot matrix on the module to display the pattern you need. A HX-2.54 4Pin cable is provided for your convenience of wiring. #### **(2)Parameters:** - Working voltage: DC 3.3-5V - Power loss: 400mW - Oscillation frequency: 450KHz - Drive current: 200mA - Working temperature: -40\~80℃ - Communication mode: two-wire bus #### **(3)Knowledge:** **Principle of the 8\*16 LED dot matrix** How to control each LED of the 8\*16 dot matrix? It is known that each byte has 8 bits and each bit is 0 or 1. when it is 0, LED is off while when it is 1 LED is on. One byte can control one column of the LED,and naturally 16 bytes can control 16 columns of LEDs, that’s the 8\*16 dot matrix. ![](media/image-20230427082712905.png) **Pins description and communication protocol** The data of the microprocessor (Arduino) communicates with the AiP1640 through a two-wire bus cable. The communication protocol diagram is as follows (SCLK) is SCL, (DIN) is SDA ![](media/ea2bab37f23c09453c680590b84653d6.png) ①The starting condition for data input: SCL is high level and SDA changes from high to low. ②For data command setting, there are methods as shown in the figure below In our sample program, select the way to **add 1 to the address automatically**, the binary value is 0100 0000 and the corresponding hexadecimal value is 0x40 ![](media/image-20230427083500152.png) ③For address command setting, the address can be selected as shown below. The first 00H is selected in our sample program, and the binary number 1100 0000 corresponds to the hexadecimal 0xc0 ![](media/image-20230427083716284.png) ④The requirement for data input is that when SCL is at high level when inputting data, the signal on SDA must remain unchanged. Only when the clock signal on SCL is at low level, can the signal on SDA be changed. The input of data is the low bit first, and the high bit later. ⑤The condition for the end of data transmission is that when SCL is at low level, SDA at low level and SCL at high level, the level of SDA becomes high. ⑥Display control, set different pulse width, pulse width can be selected as shown in the figure below.In the example, the pulse width is 4/16, and the hexadecimal corresponding to 1000 1010 is 0x8A ![](media/image-20230427084941994.png) **Instructions for the use of modulus tool** The dot matrix tool uses the online version, and the link is: [http://dotmatrixtool.com/#]( http://dotmatrixtool.com/#) ①Enter the link and the page appears as shown below ![](media/354693b5679a2615c62e99b7025d6355.png) ②The dot matrix is 8\*16, so adjust the height to 8 and width to 16, as shown in the figure below ![](media/5f0278d66ade370e871b447d360d6e7b.png) ③Generate hexadecimal data from the pattern As shown in the figure below, press the left mouse button to select, right click to cancel; draw the pattern you want, click Generate, and the hexadecimal data we need will be generated. ![](media/586e88bf13c61b0918046437ed7f6796.png) #### **(4)Connection Diagram:** ![](media/cec50fec4a335b6922e4c6694a133bc1.png) The GND, VCC, SDA, and SCL of the 8x16 LED light board are respectively connected to the keyestudio sensor expansion board-(GND), + (VCC), A4, A5 for two-wire serial communication. (Note: though it is connected with the IIC pin of Arduino, this module is not for IIC communication. And the IO port here is to simulate I2C communication and can be connected with any two pins ) #### **(5)Test Code:** The code to show the smile face (**Note:** Do not connect the Bluetooth module before uploading the code, because uploading the code also uses serial communication, and there may be conflicts with the Bluetooth serial communication, which can cause the upload to fail.) ```C /* Keyestudio Mini Tank Robot V3 (Popular Edition) lesson 9.1 Matrix face http://www.keyestudio.com */ //get the data of smile image from a modulus tool unsigned char smile[] = {0x00, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x5c, 0x40, 0x40, 0x5c, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00}; #define SCL_Pin A5 //set a pin of clock to A5 #define SDA_Pin A4 //set a data pin to A4 void setup() { //set the pin to OUTPUT pinMode(SCL_Pin, OUTPUT); pinMode(SDA_Pin, OUTPUT); //clear screen //matrix_display(clear); } void loop() { matrix_display(smile); //display the smile image } //this function is used for the display of dot matrix void matrix_display(unsigned char matrix_value[]) { IIC_start(); //use the function to start transmitting data IIC_send(0xc0); //select an address for (int i = 0; i < 16; i++) //image data have 16 characters { IIC_send(matrix_value[i]); //data to transmit pictures } IIC_end(); //end the data transmission of pictures IIC_start(); IIC_send(0x8A); //show control and select pulse width 4/16 IIC_end(); } //the condition that data starts transmitting void IIC_start() { digitalWrite(SDA_Pin, HIGH); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); } //the sign that transmission of data ends void IIC_end() { digitalWrite(SCL_Pin, LOW); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, HIGH); delayMicroseconds(3); } //transmit data void IIC_send(unsigned char send_data) { for (byte mask = 0x01; mask != 0; mask <<= 1) //each character has 8 digits, which is detected one by one { if (send_data & mask) { //set high or low levels in light of each bit(0 or 1) digitalWrite(SDA_Pin, HIGH); } else { digitalWrite(SDA_Pin, LOW); } delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); //pull up the clock pin SCL_Pin to end the transmission of data delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); //pull down the clock pin SCL_Pin to change signals of SDA } } ``` #### **(6)Test Results:** After uploading the test code successfully, connecting according to the wiring diagram, dialing the DIP switch to the right end and powering it on, a smile-shaped pattern shows on the dot matrix. ![](media/0fd4831db288e04e75828346ea66a3f5.png) #### **(7)Expansion Project:** We use the modulus tool we just learned, [http://dotmatrixtool.com/#](http://dotmatrixtool.com/#), to make the dot matrix display the pattern start , going forward, and stop and then clear the pattern. The time interval is 2000 ms. ![](media/9866c73416df7466b5fe8be3712e6eb3.png) ![](media/1c7ab4b08636c2fe61deaf6c784da7d8.png) ![](media/b0a961f27eb5f0b66603abe23d6bb56a.png) **Code obtained from the module tool:** **Code for the pattern start:** 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 **Code for the pattern going forward:** 0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00 **Code for the pattern stepping back:** 0x00,0x00,0x00,0x00,0x00,0x24,0x48,0x90,0x48,0x24,0x00,0x00,0x00,0x00,0x00,0x00 **Code for the pattern turning left:** 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00 **Code for the pattern turning right:** 0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00 **Code for the pattern stop:** 0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00 **Code to clear screen:** 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 **Test Code** (**Note:** Do not connect the Bluetooth module before uploading the code, because uploading the code also uses serial communication, and there may be conflicts with the Bluetooth serial communication, which can cause the upload to fail.) ```C /* keyestudio Mini Tank Robot V3 (Popular Edition) lesson 9.2 Matrix face http://www.keyestudio.com */ //Array, used to save data of images, can be calculated by yourself or gotten from modulus tool unsigned char start01[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; unsigned char front[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x12, 0x09, 0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char back[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x48, 0x90, 0x48, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char left[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x00}; unsigned char right[] = {0x00, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char STOP01[] = {0x2E, 0x2A, 0x3A, 0x00, 0x02, 0x3E, 0x02, 0x00, 0x3E, 0x22, 0x3E, 0x00, 0x3E, 0x0A, 0x0E, 0x00}; unsigned char clear[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #define SCL_Pin A5 //set a pin of clock to A5 #define SDA_Pin A4 //set a data pin to A4 void setup() { //set the pin to OUTPUT pinMode(SCL_Pin, OUTPUT); pinMode(SDA_Pin, OUTPUT); //clear screen matrix_display(clear); } void loop() { matrix_display(start01); //show "Start" image delay(2000); matrix_display(front); //show "front" image delay(2000); matrix_display(STOP01); //show "STOP01" image delay(2000); matrix_display(clear); //show "clear" image delay(2000); } //this function is used for the display of dot matrix void matrix_display(unsigned char matrix_value[]) { IIC_start(); //use the function to start transmitting data IIC_send(0xc0); //select an address for (int i = 0; i < 16; i++) //image data have 16 characters { IIC_send(matrix_value[i]); //data to transmit pictures } IIC_end(); //end the data transmission of pictures IIC_start(); IIC_send(0x8A); //show control and select pulse width 4/16 IIC_end(); } //the condition that data starts transmitting void IIC_start() { digitalWrite(SDA_Pin, HIGH); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); } //the sign that transmission of data ends void IIC_end() { digitalWrite(SCL_Pin, LOW); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, HIGH); delayMicroseconds(3); } //transmit data void IIC_send(unsigned char send_data) { for (byte mask = 0x01; mask != 0; mask <<= 1) //each character has 8 digits, which is detected one by one { if (send_data & mask) { //set high or low levels in light of each bit(0 or 1) digitalWrite(SDA_Pin, HIGH); } else { digitalWrite(SDA_Pin, LOW); } delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); //pull up the clock pin SCL_Pin to end the transmission of data delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); //pull down the clock pin SCL_Pin to change signals of SDA } } ``` After uploading test code, the facial expression board shows these patterns orderly and repeats this sequence. ![](media/e7ba47508826acc25d348182a0530c05.png) ![](media/831b7e0e07250cbc7bdc4fa509c5a0a3.png) ![](media/dce75583e8bf4bc4377364bf8ed3aa99.png)