Christian Dupaty 10/2021 IS31FL3731 with CHARLEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview

Dependencies:   mbed

Christian Dupaty 10/2021

IS31FL3731 with CHARLIEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ

for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview

The program reads the data from an images file and places it alternately on pages 0 and 1 of IS31FL3731

Data structure in data.h :

first byte x1 PF and y1 pf, second byte x2 PF and y2 pf

loop from x1 to x2

loop from y1 to y2

copy from the third byte into the img buffer (144 bytes)

https://os.mbed.com/media/uploads/cdupaty/stm32_flame.jpg

data structure

const uint8_t anim[] = {
  0x00, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x0E, 0x19, 0x22, 0x22, 0x17, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x0D, 0x40, 0x99, 0xF2, 0xFF, 0xFF, 0xF4, 0x91, 0x38, 0x0B, 0x01,
  0x00, 0x00, 0x00, 0x16, 0x6B, 0xC6, 0xE5, 0xDB, 0xCF, 0xBC, 0x93, 0x4B,
  0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0xB4, 0xC8, 0xBC, 0xBA,
  0xB8, 0xAD, 0x8A, 0x42, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x0C, 0x40, 0x9D, 0xF4, 0xFF, 0xFF, 0xFF, 0xDB, 0x70, 0x24, 0x06, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x19, 0x26, 0x2C, 0x29,
  0x1D, 0x0F, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00

.............................
Committer:
cdupaty
Date:
Tue Oct 05 13:33:00 2021 +0000
Revision:
0:eb53bdf2b7eb
Child:
1:81948520c7ed
Christian Dupaty 10/2021; candle flame simulator; IS31FL3731 with CHARLEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ; for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cdupaty 0:eb53bdf2b7eb 1 #include "mbed.h"
cdupaty 0:eb53bdf2b7eb 2
cdupaty 0:eb53bdf2b7eb 3 //--------------------------------------------------------------------------
cdupaty 0:eb53bdf2b7eb 4 // Animated flame for Adafruit Pro Trinket. Uses the following parts:
cdupaty 0:eb53bdf2b7eb 5 // - Pro Trinket microcontroller (adafruit.com/product/2010 or 2000)
cdupaty 0:eb53bdf2b7eb 6 // (#2010 = 3V/12MHz for longest battery life, but 5V/16MHz works OK)
cdupaty 0:eb53bdf2b7eb 7 // - Charlieplex LED Matrix Driver (2946)
cdupaty 0:eb53bdf2b7eb 8 // - Charlieplex LED Matrix (2947, 2948, 2972, 2973 or 2974)
cdupaty 0:eb53bdf2b7eb 9 // - 350 mAh LiPoly battery (2750)
cdupaty 0:eb53bdf2b7eb 10 // - LiPoly backpack (2124)
cdupaty 0:eb53bdf2b7eb 11 // - SPDT Slide Switch (805)
cdupaty 0:eb53bdf2b7eb 12 //
cdupaty 0:eb53bdf2b7eb 13 // This is NOT good "learn from" code for the IS31FL3731; it is "squeeze
cdupaty 0:eb53bdf2b7eb 14 // every last byte from the Pro Trinket" code. If you're starting out,
cdupaty 0:eb53bdf2b7eb 15 // download the Adafruit_IS31FL3731 and Adafruit_GFX libraries, which
cdupaty 0:eb53bdf2b7eb 16 // provide functions for drawing pixels, lines, etc. This sketch also
cdupaty 0:eb53bdf2b7eb 17 // uses some ATmega-specific tricks and will not run as-is on other chips.
cdupaty 0:eb53bdf2b7eb 18 //--------------------------------------------------------------------------
cdupaty 0:eb53bdf2b7eb 19 /*
cdupaty 0:eb53bdf2b7eb 20 Christian Dupaty 10/2021
cdupaty 0:eb53bdf2b7eb 21 IS31FL3731 with CHARLEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ
cdupaty 0:eb53bdf2b7eb 22 for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview
cdupaty 0:eb53bdf2b7eb 23
cdupaty 0:eb53bdf2b7eb 24 The program reads the data from an image and places it alternately
cdupaty 0:eb53bdf2b7eb 25 on pages 0 and 1 of IS31FL3731
cdupaty 0:eb53bdf2b7eb 26
cdupaty 0:eb53bdf2b7eb 27 Data structure in data.h
cdupaty 0:eb53bdf2b7eb 28 first byte x1 PF and y1 pf
cdupaty 0:eb53bdf2b7eb 29 second byte x2 PF and y2 pf
cdupaty 0:eb53bdf2b7eb 30 loop from x1 to x2
cdupaty 0:eb53bdf2b7eb 31 loop from y1 to y2
cdupaty 0:eb53bdf2b7eb 32 copy from the third byte into the img buffer (144 bytes)
cdupaty 0:eb53bdf2b7eb 33
cdupaty 0:eb53bdf2b7eb 34 the I2C write method sends the write address then a series of data, the number of data is then specified
cdupaty 0:eb53bdf2b7eb 35 ex: Wire.write (I2C_ADDR, cmd, s); I2C_ADDR address on 8bits, cmd pointer to data to send, s number of data
cdupaty 0:eb53bdf2b7eb 36 */
cdupaty 0:eb53bdf2b7eb 37
cdupaty 0:eb53bdf2b7eb 38 #include "data.h" // Flame animation data
cdupaty 0:eb53bdf2b7eb 39 //#define debug
cdupaty 0:eb53bdf2b7eb 40 #define I2C_ADDR 0xE8 // I2C address of Charlieplex matrix 0x74
cdupaty 0:eb53bdf2b7eb 41 I2C Wire(I2C_SDA, I2C_SCL);
cdupaty 0:eb53bdf2b7eb 42 uint8_t page = 0; // Front/back buffer control
cdupaty 0:eb53bdf2b7eb 43 const uint8_t *ptr = anim; // Current pointer into animation data
cdupaty 0:eb53bdf2b7eb 44 uint8_t img[9 * 16]; // Buffer for rendering image
cdupaty 0:eb53bdf2b7eb 45
cdupaty 0:eb53bdf2b7eb 46 //Buffer for I2C write method
cdupaty 0:eb53bdf2b7eb 47 char cmd[200];
cdupaty 0:eb53bdf2b7eb 48
cdupaty 0:eb53bdf2b7eb 49 // to select register on IS31FL3731, see datasheet page 9
cdupaty 0:eb53bdf2b7eb 50 void pageSelect(uint8_t n)
cdupaty 0:eb53bdf2b7eb 51 {
cdupaty 0:eb53bdf2b7eb 52 cmd[0]=0xFD;
cdupaty 0:eb53bdf2b7eb 53 cmd[1]=n;
cdupaty 0:eb53bdf2b7eb 54 Wire.write(I2C_ADDR,cmd,2); // attention write method close communications (stop condition is issued)
cdupaty 0:eb53bdf2b7eb 55 }
cdupaty 0:eb53bdf2b7eb 56
cdupaty 0:eb53bdf2b7eb 57 // SETUP FUNCTION - RUNS ONCE AT STARTUP -----------------------------------
cdupaty 0:eb53bdf2b7eb 58
cdupaty 0:eb53bdf2b7eb 59 void setup()
cdupaty 0:eb53bdf2b7eb 60 {
cdupaty 0:eb53bdf2b7eb 61 uint8_t i, p, s;
cdupaty 0:eb53bdf2b7eb 62
cdupaty 0:eb53bdf2b7eb 63 s=0;
cdupaty 0:eb53bdf2b7eb 64 pageSelect(0x0B); // Access to the Function Registers (page Night)
cdupaty 0:eb53bdf2b7eb 65 cmd[0]=0;
cdupaty 0:eb53bdf2b7eb 66 s++; // adress first internal register
cdupaty 0:eb53bdf2b7eb 67 for(i=0; i<=0x0C; i++)
cdupaty 0:eb53bdf2b7eb 68 {
cdupaty 0:eb53bdf2b7eb 69 cmd[i+1]=0x00;
cdupaty 0:eb53bdf2b7eb 70 if (i==0) cmd[i+1]=0x00; // 0x08 for Auto Frame Play Mode 0x00 for picture mode
cdupaty 0:eb53bdf2b7eb 71 if (i==0x0A) cmd[i+1]=0xFF; // all to 0 except shutdown register
cdupaty 0:eb53bdf2b7eb 72 s++;
cdupaty 0:eb53bdf2b7eb 73 }
cdupaty 0:eb53bdf2b7eb 74 Wire.write(I2C_ADDR,cmd,s);
cdupaty 0:eb53bdf2b7eb 75
cdupaty 0:eb53bdf2b7eb 76 for(p=0; p<2; p++)
cdupaty 0:eb53bdf2b7eb 77 {
cdupaty 0:eb53bdf2b7eb 78 s=0;
cdupaty 0:eb53bdf2b7eb 79 // For each page used (0 & 1)...
cdupaty 0:eb53bdf2b7eb 80 pageSelect(p); // Access the Frame Registers
cdupaty 0:eb53bdf2b7eb 81 cmd[0]=0; // Start from 1st LED control reg
cdupaty 0:eb53bdf2b7eb 82 s++;
cdupaty 0:eb53bdf2b7eb 83 for(i=0; i<0xB4; i++)
cdupaty 0:eb53bdf2b7eb 84 {
cdupaty 0:eb53bdf2b7eb 85 if (i<18) cmd[i+1]=0xFF; // Enable all LEDs (18*8=144)
cdupaty 0:eb53bdf2b7eb 86 else cmd[i+1]=0x00; // desable blink and PWM
cdupaty 0:eb53bdf2b7eb 87 s++;
cdupaty 0:eb53bdf2b7eb 88 }
cdupaty 0:eb53bdf2b7eb 89 Wire.write(I2C_ADDR,cmd,s);
cdupaty 0:eb53bdf2b7eb 90 }
cdupaty 0:eb53bdf2b7eb 91 }
cdupaty 0:eb53bdf2b7eb 92
cdupaty 0:eb53bdf2b7eb 93 void loop()
cdupaty 0:eb53bdf2b7eb 94 {
cdupaty 0:eb53bdf2b7eb 95 uint8_t a, x1, y1, x2, y2, x, y,s;
cdupaty 0:eb53bdf2b7eb 96 #ifdef debug
cdupaty 0:eb53bdf2b7eb 97 printf("-------------------------------------------------------------\n");
cdupaty 0:eb53bdf2b7eb 98 printf("start loop\n");
cdupaty 0:eb53bdf2b7eb 99 printf("-------------------------------------------------------------\n");
cdupaty 0:eb53bdf2b7eb 100 #endif
cdupaty 0:eb53bdf2b7eb 101 pageSelect(0x0B); // Function registers
cdupaty 0:eb53bdf2b7eb 102 cmd[0]=0x01; // Picture Display reg
cdupaty 0:eb53bdf2b7eb 103 cmd[1]=page;
cdupaty 0:eb53bdf2b7eb 104 Wire.write(I2C_ADDR,cmd,2);
cdupaty 0:eb53bdf2b7eb 105
cdupaty 0:eb53bdf2b7eb 106 page ^= 1; // Flip front/back buffer index
cdupaty 0:eb53bdf2b7eb 107
cdupaty 0:eb53bdf2b7eb 108 // Then render NEXT frame. Start by getting bounding rect for new frame:
cdupaty 0:eb53bdf2b7eb 109 a = *ptr++; // New frame X1/Y1
cdupaty 0:eb53bdf2b7eb 110 if(a >= 144) // 0x90
cdupaty 0:eb53bdf2b7eb 111 {
cdupaty 0:eb53bdf2b7eb 112 // EOD marker? (valid X1 never exceeds 8)
cdupaty 0:eb53bdf2b7eb 113 ptr = anim; // Reset animation data pointer to start
cdupaty 0:eb53bdf2b7eb 114 a = *ptr++; // and take first value
cdupaty 0:eb53bdf2b7eb 115 }
cdupaty 0:eb53bdf2b7eb 116 x1 = a >> 4; // X1 = high 4 bits
cdupaty 0:eb53bdf2b7eb 117 y1 = a & 0x0F; // Y1 = low 4 bits
cdupaty 0:eb53bdf2b7eb 118 a = *ptr++; // New frame X2/Y2
cdupaty 0:eb53bdf2b7eb 119 x2 = a >> 4; // X2 = high 4 bits
cdupaty 0:eb53bdf2b7eb 120 y2 = a & 0x0F; // Y2 = low 4 bits
cdupaty 0:eb53bdf2b7eb 121
cdupaty 0:eb53bdf2b7eb 122 // Read rectangle of data from anim[] into portion of img[] buffer
cdupaty 0:eb53bdf2b7eb 123 #ifdef debug
cdupaty 0:eb53bdf2b7eb 124 printf("x1= %d y1= %d x2= %d y2 = %d \n",x1,y1,x2,y2);
cdupaty 0:eb53bdf2b7eb 125 #endif
cdupaty 0:eb53bdf2b7eb 126 for(x=x1; x<=x2; x++) {
cdupaty 0:eb53bdf2b7eb 127 // Column-major
cdupaty 0:eb53bdf2b7eb 128 for(y=y1; y<=y2; y++)
cdupaty 0:eb53bdf2b7eb 129 {
cdupaty 0:eb53bdf2b7eb 130 img[(x << 4) + y] = *ptr++;
cdupaty 0:eb53bdf2b7eb 131 #ifdef debug
cdupaty 0:eb53bdf2b7eb 132 printf("x= %d y= %d data= %d \n",x,y,img[(x << 4) + y]);
cdupaty 0:eb53bdf2b7eb 133 #endif
cdupaty 0:eb53bdf2b7eb 134 }
cdupaty 0:eb53bdf2b7eb 135 }
cdupaty 0:eb53bdf2b7eb 136
cdupaty 0:eb53bdf2b7eb 137 // Write img[] to matrix (not actually displayed until next pass)
cdupaty 0:eb53bdf2b7eb 138 pageSelect(page); // Select background buffer
cdupaty 0:eb53bdf2b7eb 139 s=0;
cdupaty 0:eb53bdf2b7eb 140 cmd[0]=0x24; // First byte of PWM data
cdupaty 0:eb53bdf2b7eb 141 s++;
cdupaty 0:eb53bdf2b7eb 142 // copy img buffer to IS31FL3731
cdupaty 0:eb53bdf2b7eb 143 for(uint8_t j=0; j<144; j++)
cdupaty 0:eb53bdf2b7eb 144 {
cdupaty 0:eb53bdf2b7eb 145 cmd[j+1]=img[j];
cdupaty 0:eb53bdf2b7eb 146 s++;
cdupaty 0:eb53bdf2b7eb 147 #ifdef debug
cdupaty 0:eb53bdf2b7eb 148 printf("j= %d img[j]= %d \n",j,img[j]);
cdupaty 0:eb53bdf2b7eb 149 #endif
cdupaty 0:eb53bdf2b7eb 150 }
cdupaty 0:eb53bdf2b7eb 151 Wire.write(I2C_ADDR,cmd,s);
cdupaty 0:eb53bdf2b7eb 152 wait_ms(30);
cdupaty 0:eb53bdf2b7eb 153 }
cdupaty 0:eb53bdf2b7eb 154
cdupaty 0:eb53bdf2b7eb 155 int main()
cdupaty 0:eb53bdf2b7eb 156 {
cdupaty 0:eb53bdf2b7eb 157 //printf("Simulation flame with IS31FL3731\n\n");
cdupaty 0:eb53bdf2b7eb 158 setup();
cdupaty 0:eb53bdf2b7eb 159
cdupaty 0:eb53bdf2b7eb 160 while(1) loop();;
cdupaty 0:eb53bdf2b7eb 161 }