Oskar Weigl
/
LED_for_hackspace
LED screen driver build for hackspace.
Diff: main.cpp
- Revision:
- 0:f16a1d69a386
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Feb 29 17:01:43 2012 +0000 @@ -0,0 +1,778 @@ +#include "mbed.h" +#include "ledScreen.h" + +LocalFileSystem local("local"); + +// screen instance +ledScreen screen; + +// sin lookup table and related functions +unsigned char sinlut[256]; + +void initSinLut() { + for (int i=0; i<256; i++) + sinlut[i] = cos((float)i / 256.0 * (3.14159265 * 2))*127 + 128; +} + +inline unsigned char lut_sin(int x) { + + return (x>0)?sinlut[x%256]:sinlut[(-x)%256]; +} + + +// Example frame makes: + + +//rainbow +void makeFrame1(unsigned char* data) { + + static int time=0; + time++; + + // override data with a intensity gradient test pattern + for (int x=0; x<3*16; x++) { + for (int y=0; y<16; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = lut_sin(x*255/48+(time/2)%256+y); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+1] = lut_sin(x*255/48+(time/2)%256 + 85+y); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+2] = lut_sin(x*255/48+(time/2)%256 +170+y); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + } + } + +} + +// static gradients +void makeFrame3(unsigned char* data) { + + static int time=0; + time++; + + // override data with a intensity gradient test pattern + for (int x=0; x<3*16; x++) { + for (int y=0; y<16; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+1] = 0; // green + data[i+2] = y*256/16; //(i/3)%256 ; // blue + } + } + +} + +// wavy animation +void makeFrame4(unsigned char* data) { + + static int time=0; + time++; + + // override data with a intensity gradient test pattern + for (int x=0; x<3*16; x++) { + for (int y=0; y<16; y++) { + + int i = (x%16 + y*16 + (x/16)*256) * 3; // figure out the memory location + + data[i] = lut_sin(time*15/16 - x*32 + y*32); + data[i+1] = 0; + data[i+2] = lut_sin((((x-24)*(x-24) + (y-8)*(y-8)) - time/1)); + } + } + +} + +// stars + smoothed (convolved) travelling comet +void makeFrame7(unsigned char* data) { + + static int time=0; + + //stars + data[rand()%(3*16*16*3)] = 255; + + //increment time + time++; + + //Do convolution + for (int x=1; x<47; x++) { // ignore first and last column + for (int y=1; y<15; y++) { + if (time%2) { + data[x*3+y*3*48] = ((data[x*3+y*3*48]*30)/32 + (data[(x+1)*3+y*3*48]*1)/32 + (data[(x-1)*3+y*3*48]*1)/32); + data[x*3+y*3*48 +1] = ((data[x*3+y*3*48 +1]*30)/32 + (data[(x+1)*3+y*3*48 +1]*1)/32 + (data[(x-1)*3+y*3*48 +1]*1)/32); + data[x*3+y*3*48 +2] = ((data[x*3+y*3*48 +2]*30)/32 + (data[(x+1)*3+y*3*48 +2]*1)/32 + (data[(x-1)*3+y*3*48 +2]*1)/32); + } else { + data[x*3+y*3*48] = ((data[x*3+y*3*48]*30)/32 + (data[(x)*3+(y+1)*3*48]*1)/32 + (data[(x)*3+(y-1)*3*48]*1)/32); + data[x*3+y*3*48 +1] = ((data[x*3+y*3*48 +1]*30)/32 + (data[(x)*3+(y+1)*3*48 +1]*1)/32 + (data[(x)*3+(y-1)*3*48 +1]*1)/32); + data[x*3+y*3*48 +2] = ((data[x*3+y*3*48 +2]*30)/32 + (data[(x)*3+(y+1)*3*48 +2]*1)/32 + (data[(x)*3+(y-1)*3*48 +2]*1)/32); + } + + } + } + + // handle the border + for (int y=0; y<16; y++) { + if (time%2) { + int x=0; + data[x*3+y*3*48] = (data[x*3+y*3*48]*30)/32 + (data[(x+1)*3+y*3*48]*1)/32 ; + data[x*3+y*3*48 +1] = (data[x*3+y*3*48 +1]*30)/32 + (data[(x+1)*3+y*3*48 +1]*1)/32 ; + data[x*3+y*3*48 +2] = (data[x*3+y*3*48 +2]*30)/32 + (data[(x+1)*3+y*3*48 +2]*1)/32 ; + + x=47; + data[x*3+y*3*48] = ((data[x*3+y*3*48]*30)/32 + (data[(x-1)*3+y*3*48]*1)/32); + data[x*3+y*3*48 +1] = ((data[x*3+y*3*48 +1]*30)/32 + (data[(x-1)*3+y*3*48 +1]*1)/32); + data[x*3+y*3*48 +2] = ((data[x*3+y*3*48 +2]*30)/32 + (data[(x-1)*3+y*3*48 +2]*1)/32); + } + } + + for (int x=0; x<48; x++) { + if (!(time%2)) { + int y=0; + data[x*3+y*3*48] = ((data[x*3+y*3*48]*30)/32 + (data[(x)*3+(y+1)*3*48]*1)/32); + data[x*3+y*3*48 +1] = ((data[x*3+y*3*48 +1]*30)/32 + (data[(x)*3+(y+1)*3*48 +1]*1)/32); + data[x*3+y*3*48 +2] = ((data[x*3+y*3*48 +2]*30)/32 + (data[(x)*3+(y+1)*3*48 +2]*1)/32); + + y=15; + data[x*3+y*3*48] = ((data[x*3+y*3*48]*30)/32 + (data[(x)*3+(y-1)*3*48]*1)/32); + data[x*3+y*3*48 +1] = ((data[x*3+y*3*48 +1]*30)/32 + (data[(x)*3+(y-1)*3*48 +1]*1)/32); + data[x*3+y*3*48 +2] = ((data[x*3+y*3*48 +2]*30)/32 + (data[(x)*3+(y-1)*3*48 +2]*1)/32); + + } + } + + // determine current comet location + int ballx = (8 + sin((float)time/25)*4+sin((float)time/17)*3+sin((float)time/13)*2)*3; + int bally = 8 + sin((float)time/12)*4+sin((float)time/15)*3+sin((float)time/14)*2; + + unsigned char r = lut_sin(time); + unsigned char g = lut_sin(time*15/16); + unsigned char b = lut_sin(time*17/16); + + // saturate brightness to a certain level + while ((int)r+g+b<255) { + r++; + g++; + b++; + }; + + // write the circle of the comet to the buffer + for (int x=-2; x<=2; x++) { + for (int y=-2; y<=2; y++) { + if (x*x + y*y<1.5 ) { + if (x+ballx<16*3 && x+ballx>=0 && y+bally<16 && y+bally>=0) { + int i = (x+ballx)*3 + (y+bally)*3*48; + + data[i] = r; + data[i+1] = g; + data[i+2] = b; + } + } + } + } +} + +struct charsz{ + unsigned char width; + unsigned int data; + + charsz() { + width=0; + } + + charsz(char c) { + width=0; + + } + bool get(int x, int y) + { + return data & (1 << (y * 5 + x)); + } +}; + + +#define _C(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y) \ + ((a) | (b << 1) | (c << 2) | (d << 3) | (e << 4) | \ + (f << 5) | (g << 6) | (h << 7) | (i << 8) | (j << 9) | \ + (k << 10) | (l << 11) | (m << 12) | (n << 13) | (o << 14) | \ + (p << 15) | (q << 16) | (r << 17) | (s << 18) | (t << 19) | \ + (u << 20) | (v << 21) | (w << 22) | (x << 23) | (y << 24)) + + + +static charsz numbers[128]; + + +int charToScreen(int xco,int yco, char d, unsigned char *data, unsigned int colour) +{ + + for(int x=0; x<numbers[d].width; x++) + for(int y=0; y<5; y++) + for(unsigned int col = 0; col < 3; ++col) + //data[3 * ((x+xco) + (y+yco) * 48) + col] = numbers[d].get(x,y) ? ((colour & (0xFF << ((2-col)*8))) >> ((2-col)*8) ) : 0; + if (numbers[d].get(x,y) && xco+x<48 && x+xco >= 0) + data[3 * ((x+xco) + (y+yco) * 48) + col] = ((colour & (0xFF << ((2-col)*8))) >> ((2-col)*8) ); + + return numbers[d].width; + + + +} + +void printString(const char *s, float xco, int yco, unsigned char *data, unsigned int col) +{ + unsigned int len = strlen(s); + for (int d=0; d < len; ++d) + { + if(xco >= -numbers[s[d]].width && xco < 48) + charToScreen(xco,yco,s[d],data,col); + + xco += numbers[s[d]].width + 1; + } +} + +void fadeFrame(unsigned char* data, float amount) + { + for (int x = 0; x < 48; x++) + for (int y = 0; y < 16; y++) + { + data[x*3+y*3*48]-=amount; + data[x*3+y*3*48+1]-=amount; + data[x*3+y*3*48+2]-=amount; + } + } + +// Scroll text +class scrollingText { +public: + const char *s; + int xco; + int yco; + unsigned char *data; + unsigned int col; + float scroller; + float scrollspeed; + + scrollingText(const char *sp, int xcop, int ycop, unsigned char *datap, unsigned int colp, float scrollspeedp) + : s(sp), xco(xcop), yco(ycop), data(datap), col(colp), scroller(0), scrollspeed(scrollspeedp) {} + + void update() + { + //printString(s, xco+(int)scroller, yco, data, col); + printString(s, xco+scroller, yco, data, col); + unsigned int len = strlen(s); + int actualStringLength = len+1; + for (int d=0; d < len; ++d) { actualStringLength += numbers[d].width; } + if ((int)scroller+xco < -actualStringLength) { scroller=48-xco; } + + scroller-=scrollspeed; + } +}; + +// Binary counter timer +Timer t; +// Read file counter +Timer s; + +char *txt = NULL; + +void makeFrame9(unsigned char* data) { + fadeFrame(data, 255); + + /* + //0 screen + for(unsigned int x = 0; x < 48; ++x) + for(unsigned int y = 0; y < 16; ++y) + for(unsigned int col = 0; col < 3; ++col) + data[3 * ((x) + y * 48) + col] = 0; + */ + + time_t seconds = time(NULL); + + //uptime! + static scrollingText uptimeText(txt, 4, 1, data, 0xFF0000, 0.1); + + uptimeText.update(); + + + + int yoff=6; + unsigned int startX = 7; + for(unsigned int x = 0; x < 32; ++x) + for(unsigned int y = 0; y < 4; ++y) + for(unsigned int col = 0; col < 3; ++col) + //data[3 * ((x+startX) + (y+yoff) * 48) + col] = (col == 0 ? ((seconds & (1 << (31-x))) ? 255 : 0) : 0); + if(((int)(t.read()*50) & (1 << (31-x))) && col == 0) + data[3 * ((x+startX) + (y+yoff) * 48) + col] = 255; + + int day = (seconds/(3600*24))%10; + int hour = (seconds/3600)%24; + int min = (seconds/60)%60; + int sec = (seconds)%60; + + + char digits[11] = {day+'0',':', (hour/10)+'0', hour%10+'0', ':', min/10+'0', min%10+'0', ':', sec/10+'0', sec%10+'0', 0}; + + + printString(digits, 4, 10, data, 0x0000FF); + +} + + +void readTextFromMBed() +{ + //txt = "test"; + + + //stringy + FILE *set = fopen("/local/scroller.txt", "r"); // Open "scroller.txt" on the local file system for read + if(set) + { + fseek(set, 0L, SEEK_END); + int sz = ftell(set); + fseek(set, 0L, SEEK_SET); + + if(txt) + free(txt); + + txt = (char *) malloc(sz); + + fread(txt, sz, sz, set); + + fclose(set); + } + else + { + txt = "File not found"; + } +} + + + +void initCharArray(); + + +int main() +{ + + initCharArray(); + readTextFromMBed(); + set_time(0); + + s.reset(); + t.start(); + + int time=0; // optional + int frametype=1; // optional + + // framebuffer on client side + unsigned char imageSource[256*3*3] = { 0 }; + + // prepare sin lookup table (optional) + initSinLut(); + + // start the screen output, which will keep outputting the frames that are in its internal buffer (updated via .transformFrame) + screen.start(); + + while (1) { + // Reload the file every 60 seconds + if(s.read()>60) + { + //readTextFromMBed(); + //s.reset(); + } + + time++; //optional + if(time%5000 == 0){ + frametype = (frametype+1)%5; + if (frametype == 0) + time = 4500; + } + + switch (frametype) + { + case 0: + makeFrame9(imageSource); + break; + case 1: + makeFrame4(imageSource); + break; + case 2: + makeFrame7(imageSource); + break; + case 3: + makeFrame7(imageSource); + break; + case 4: + makeFrame1(imageSource); + break; + } + + //makeFrame2(imageSource); // prepare framebuffer with current frame + screen.transformFrame(imageSource); // write framebuffer to output framebuffer + wait_ms(1); // slow down the framerate (optional) + } + +} + + + + + +//////////////////////////////// +///////STOPPP!!!!!!! +//////////GO BACK!!!!!!! +/////////////////////////////// + + + + + + + + + +void initCharArray() +{ + for(int i=0; i<128; i++){ + numbers[i].width=3; + numbers[i].data=_C(1,1,1,0,0, + 0,0,1,0,0, + 0,1,1,0,0, + 0,0,0,0,0, + 0,1,0,0,0); + } + + numbers['A'].width=3; + numbers['A'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0); + numbers['B'].width=3; + numbers['B'].data=_C(1,1,0,0,0, + 1,0,1,0,0, + 1,1,0,0,0, + 1,0,1,0,0, + 1,1,0,0,0); + numbers['C'].width=3; + numbers['C'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,1,1,0,0); + numbers['D'].width=3; + numbers['D'].data=_C(1,1,0,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,1,0,0,0); + numbers['E'].width=3; + numbers['E'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0); + numbers['F'].width=3; + numbers['F'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0, + 1,0,0,0,0, + 1,0,0,0,0); + numbers['G'].width=3; + numbers['G'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,1,0,0, + 1,1,1,0,0); + numbers['H'].width=3; + numbers['H'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0); + numbers['I'].width=3; + numbers['I'].data=_C(1,1,1,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 1,1,1,0,0); + numbers['J'].width=4; + numbers['J'].data=_C(0,1,1,1,0, + 0,0,1,0,0, + 0,0,1,0,0, + 1,0,1,0,0, + 0,1,0,0,0); + numbers['K'].width=4; + numbers['K'].data=_C(1,0,0,1,0, + 1,0,1,0,0, + 1,1,1,0,0, + 1,0,1,0,0, + 1,0,0,1,0); + numbers['L'].width=3; + numbers['L'].data=_C(1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,1,1,0,0); + numbers['M'].width=5; + numbers['M'].data=_C(1,1,0,1,1, + 1,1,1,1,1, + 1,0,1,0,1, + 1,0,0,0,1, + 1,0,0,0,1); + numbers['N'].width=4; + numbers['N'].data=_C(1,0,0,1,0, + 1,1,0,1,0, + 1,1,1,1,0, + 1,0,1,1,0, + 1,0,0,1,0); + numbers['O'].width=3; + numbers['O'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0); + numbers['P'].width=3; + numbers['P'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 1,0,0,0,0, + 1,0,0,0,0); + numbers['Q'].width=3; + numbers['Q'].data=_C(0,1,1,0,0, + 1,0,0,1,0, + 1,0,0,1,0, + 1,0,1,1,0, + 0,1,1,1,0); + numbers['R'].width=3; + numbers['R'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 1,1,0,0,0, + 1,0,1,0,0); + numbers['S'].width=3; + numbers['S'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0, + 0,0,1,0,0, + 1,1,1,0,0); + numbers['T'].width=3; + numbers['T'].data=_C(1,1,1,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 0,1,0,0,0); + numbers['U'].width=3; + numbers['U'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0); + numbers['V'].width=3; + numbers['V'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 0,1,0,0,0); + numbers['W'].width=5; + numbers['W'].data=_C(1,0,0,0,1, + 1,0,0,0,1, + 1,0,1,0,1, + 1,1,1,1,1, + 0,1,0,1,0); + numbers['X'].width=3; + numbers['X'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 0,1,0,0,0, + 1,1,1,0,0, + 1,0,1,0,0); + numbers['Y'].width=3; + numbers['Y'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 0,1,0,0,0); + numbers['Z'].width=3; + numbers['Z'].data=_C(1,1,1,0,0, + 0,0,1,0,0, + 0,1,0,0,0, + 1,0,0,0,0, + 1,1,1,0,0); + numbers['\''].width=1; + numbers['\''].data=_C(1,0,0,0,0, + 1,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0); + numbers['"'].width=3; + numbers['"'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0); + numbers[' '].width=1; + numbers[' '].data=_C(0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0); + numbers[':'].width=1; + numbers[':'].data=_C(0,0,0,0,0, + 1,0,0,0,0, + 0,0,0,0,0, + 1,0,0,0,0, + 0,0,0,0,0); + + numbers['0'].width=3; + numbers['0'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0); + numbers['1'].width=1; + numbers['1'].data=_C(1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0); + numbers['2'].width=3; + numbers['2'].data=_C(1,1,1,0,0, + 0,0,1,0,0, + 1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0); + numbers['3'].width=3; + numbers['3'].data=_C(1,1,1,0,0, + 0,0,1,0,0, + 1,1,1,0,0, + 0,0,1,0,0, + 1,1,1,0,0); + numbers['4'].width=3; + numbers['4'].data=_C(1,0,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 0,0,1,0,0, + 0,0,1,0,0); + numbers['5'].width=3; + numbers['5'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0, + 0,0,1,0,0, + 1,1,1,0,0); + numbers['6'].width=3; + numbers['6'].data=_C(1,1,1,0,0, + 1,0,0,0,0, + 1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0); + numbers['7'].width=3; + numbers['7'].data=_C(1,1,1,0,0, + 0,0,1,0,0, + 0,0,1,0,0, + 0,0,1,0,0, + 0,0,1,0,0); + numbers['8'].width=3; + numbers['8'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0); + numbers['9'].width=3; + numbers['9'].data=_C(1,1,1,0,0, + 1,0,1,0,0, + 1,1,1,0,0, + 0,0,1,0,0, + 0,0,1,0,0); + + numbers['.'].width=1; + numbers['.'].data=_C(0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 1,0,0,0,0); + + numbers['|'].width=1; + numbers['|'].data=_C(1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0); + + numbers[')'].width=2; + numbers[')'].data=_C(1,0,0,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 0,1,0,0,0, + 1,0,0,0,0); + + numbers['('].width=2; + numbers['('].data=_C(0,1,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 1,0,0,0,0, + 0,1,0,0,0); + + numbers['+'].width=3; + numbers['+'].data=_C(0,0,0,0,0, + 0,1,0,0,0, + 1,1,1,0,0, + 0,1,0,0,0, + 0,0,0,0,0); + + numbers['-'].width=3; + numbers['-'].data=_C(0,0,0,0,0, + 0,0,0,0,0, + 1,1,1,0,0, + 0,0,0,0,0, + 0,0,0,0,0); + + numbers[';'].width=2; + numbers[';'].data=_C(0,0,0,0,0, + 0,1,0,0,0, + 0,0,0,0,0, + 0,1,0,0,0, + 1,0,0,0,0); + + numbers['>'].width=3; + numbers['>'].data=_C(1,0,0,0,0, + 0,1,0,0,0, + 0,0,1,0,0, + 0,1,0,0,0, + 1,0,0,0,0); + + numbers[','].width=2; + numbers[','].data=_C(0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,1,0,0,0, + 1,0,0,0,0); + + numbers['_'] = numbers[' ']; + numbers['a'] = numbers['A']; + numbers['b'] = numbers['B']; + numbers['c'] = numbers['C']; + numbers['d'] = numbers['D']; + numbers['e'] = numbers['E']; + numbers['f'] = numbers['F']; + numbers['g'] = numbers['G']; + numbers['h'] = numbers['H']; + numbers['i'] = numbers['I']; + numbers['j'] = numbers['J']; + numbers['k'] = numbers['K']; + numbers['l'] = numbers['L']; + numbers['m'] = numbers['M']; + numbers['n'] = numbers['N']; + numbers['o'] = numbers['O']; + numbers['p'] = numbers['P']; + numbers['q'] = numbers['Q']; + numbers['r'] = numbers['R']; + numbers['s'] = numbers['S']; + numbers['t'] = numbers['T']; + numbers['u'] = numbers['U']; + numbers['v'] = numbers['V']; + numbers['w'] = numbers['W']; + numbers['x'] = numbers['X']; + numbers['y'] = numbers['Y']; + numbers['z'] = numbers['Z']; + +} \ No newline at end of file