You are reading a single comment by @DrAzzy and its replies. Click here to read the full conversation.
  • 
    
    
    
    SPI1.setup({sck:14,mosi:13,mode:1,order:­"msb",baud:4000000});
    I2C1.setup({scl:5,sda:4});
    
    var http = require("http");
    var eeprom=require("AT24").connect(I2C1, 32, 32);
    
    setBusyIndicator(2);
    require("ESP8266").logDebug(0);
    require("ESP8266").setLog(0);
    
    
    // Parameters:
    numleds=10;
    
    //global functions
    function animate() {
      setTimeout("animate()",20);
      var x;
      if (leds.animode) {x=getTime();}
      leds.flip();
      leds.dotwinkle();
      if (leds.animode) {console.log(getTime()-x);}
    }
    
    
    // Network
    
    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      if (a.pathname.split(".")[1]=="cmd"){
      	if (handleCmd(a.pathname,a.query,res)) {
      		res.writeHead(200,{'Access-Control-Allow­-Origin':'*'});
      	} 
      	res.end();
      } else {
    	res.writeHead(404);
    	res.end("NOT FOUND");	
      }
    }
    require("http").createServer(onPageReque­st).listen(80);
    
    function handleCmd(pn,q,r) {
    	try {
      if (pn=="/save.cmd") {
        //lreq=a.query;
        if (q.index==undefined || q.index>memmap.statMax || q.index < 0) {
        	r.write("MAX INDEX:");
        	r.write(memmap.statMax);
        	return 0;
        }
        leds.save(q.index);
        return 1;
      } if (pn=="/load.cmd") {
        if (q.index==undefined || q.index>memmap.statMax || q.index < 0) {
        	r.write("MAX INDEX:");
        	r.write(memmap.statMax);
        	return 0;
        }
        if (!leds.load(q.index)){
        	r.writeHead(404);
        	r.write("No such pattern");
        	return 0;
        }
        r.write("OK");
        return 1;
      }if (pn=="/showState.cmd") {
        //lreq=a.query;
        r.write(JSON.stringify({"base":leds.tbuf­,"twinkle":[leds.tm,leds.ti,leds.ta]}));­
        return 1;
      }if (pn=="/setAll.cmd") {
        //lreq=a.query;
        leds.setAll(eval(q.color),eval(q.mode),e­val(q.max),eval(q.min));
        r.write("OK");
        return 1;
      }else if (pn=="/setPixel.cmd") {
        leds.setPixel2(q.led,0,eval(q.color),eva­l(q.mode),eval(q.max),eval(q.min));
        r.write("OK");
        return 1;
      } else {
      	r.writeHead(404);
    	r.write("NO CMD");
      	return 0;
      }
    	} 
    	catch (err) {
    		r.writeHead(500);
    		r.write("ERROR");
    		return 0;
    	}
    }
    
    
    var memmap={
    	slen:32,
    	rlen:40,
    	statOff:0x100,
    	statMax:14,
    	sEep:eeprom,
    	oEep:eeprom,
    	oOff:0x800,
    	oMax:64,
    	oIEE:eeprom,
    	oIOF:0
    };
    
    
    // LEDS
    gtab=new Uint16Array(256);
    gtab=new Uint16Array([0,1,2,3,4,5,6,7,8,9,11,13,1­5,17,19,21,23,25,27,30,33,36,39,42,45,48­,51,54,58,62,66,70,74,78,82,86,91,96,101­,106,111,116,121,126,132,138,144,150,156­,162,168,174,181,188,195,202,209,216,223­,230,238,246,254,262,270,278,286,294,303­,312,321,330,339,348,357,366,376,386,396­,406,416,426,436,446,457,468,479,490,501­,512,523,534,546,558,570,582,594,606,618­,630,643,656,669,682,695,708,721,734,748­,762,776,790,804,818,832,846,861,876,891­,906,921,936,951,966,982,998,1014,1030,1­046,1062,1078,1094,1111,1128,1145,1162,1­179,1196,1213,1230,1248,1266,1284,1302,1­320,1338,1356,1374,1393,1412,1431,1450,1­469,1488,1507,1526,1546,1566,1586,1606,1­626,1646,1666,1686,1707,1728,1749,1770,1­791,1812,1833,1854,1876,1898,1920,1942,1­964,1986,2008,2030,2053,2076,2099,2122,2­145,2168,2191,2214,2238,2262,2286,2310,2­334,2358,2382,2406,2431,2456,2481,2506,2­531,2556,2581,2606,2631,2657,2683,2709,2­735,2761,2787,2813,2839,2866,2893,2920,2­947,2974,3001,3028,3055,3083,3111,3139,3­167,3195,3223,3251,3279,3308,3337,3366,3­395,3424,3453,3482,3511,3541,3571,3601,3­631,3661,3691,3721,3751,3782,3813,3844,3­875,3906,3937,3968,3999,4031,4063,4095])­;
    var leds = {};
    leds.map=memmap;
    leds.spi=SPI1;
    leds.num=numleds;
    leds.afr=0;
    leds.fbuf=new Uint8Array(numleds*4);
    leds.buff=new Uint8Array(numleds*3);
    leds.tbuf=new Uint8ClampedArray(numleds*3);
    leds.t=new Int8Array(numleds*3);
    leds.tm=new Uint8Array(numleds*3);
    leds.ti=new Int8Array(numleds*3);
    leds.ta=new Int8Array(numleds*3);
    leds.overlay=new Uint8Array(numleds*3);
    leds.tclb=new Uint8ClampedArray(numleds*3);
    for (var tem=0;tem<numleds;tem++){
    	for (var j=0;j<3;j++){
    		leds.ti[tem*3+j]=-10;
    		leds.ta[tem*3+j]=10;
    	}
    }
    leds.ison=1;
    leds.animode=0;
    leds.aniframe=0;
    leds.anilast=0;
    leds.aniaddr=0;
    leds.zz="\x00\x00";
    
    leds.dotwinkle = function () {
    	var t=this.t;
    	var tm= this.tm;
    	var ta=this.ta;
    	var ti=this.ti;
    	var b=this.buff;
    	var z=this.tbuf;
    	var o=this.overlay;
    	if (this.animode) {
    		if (this.aniframe > this.anilast) {
    			this.animode=0;
    			this.anilast=0;
    			this.aniframe=0;
    			leds.aniaddr=0;
    			this.overlay.fill(0);
    		} else {
    			this.overlay=this.map.oEep.read(this.ani­addr+this.map.slen*this.aniframe++,this.­num*3);
    		}
    	}
    	if (this.animode & 4 ){
    		leds.tclb.set(o);
        } else if (this.animode & 2){
            for (var i=0;i<30;i++){
              leds.tclb[i]=b[i]+t[i]+o[i];
            }
    	} else {
    		for (var i=0;i<30;i++){
    			var mode=tm[i];
    			var mo=mode&0x0F;
    			var pr=mode>>4;
    			if (!(this.animode&2)) {
    				if (mo==1) { //0x01 - high nybble is chance to change, from 0 (1/16) to 15 (16/16 chance to change)
    					var n=Math.random(); //3ms
    					var th=(pr+1)/32;
    	      				if (n<0.5+th){ //8ms
    	      					if(n<=(0.5-th) && t[i]>ti[i]){t[i]--;}
    		      			} else {
    	      					if (t[i]<ta[i]){t[i]++;}
    	      				}
    				} else if (mo==2) { //fade/pulse. 
    	          			if (this.afr%((1+pr)&7)==0){
    	            				t[i]+=(pr&8?1:-1);
    						if (t[i] == ti[i] || t[i] == ta[i]) {
    							tm[i]=mode^128;
    						}
    	        			}
    				} else {
    					if (t[i]!==0){if(t[i]>0){t[i]--;} else {t[i]++;}}
    				}
    			}
    			var c=b[i];
    			if (mo || this.afr%((1+pr)&7)==0) {
    				b[i]+=E.clip(z[i]-c,-1,1);
    			}
    			leds.tclb[i]=c+(c?t[i]:0)+o[i]; //10ms
    		}
    	}
    	this.afr=this.afr==255?0:this.afr+1;
    };
    
    leds.setAll= function (color,tmode,tmax,tmin,instant) {
    	for (var i=0;i<this.num;i++) {
    		for (j=0;j<3;j++){
    			//this.t[3*i+j]=0;
    			this.tbuf[3*i+j]=color[j];
                if (instant) {this.buff[3*i+j]=color[j];}
    			if (tmode) {
    				this.tm[3*i+j]=tmode[j];
    				this.ti[3*i+j]=tmin[j];
    				this.ta[3*i+j]=tmax[j];
    			}
    		}
    	}
    };
    
    leds.load = function (index) {
    	var s=this.map.slen;
    	var addr=this.map.statOff+(4*index*s);
    	if (this.map.sEep.read(addr+s-1,1)[0]==255)­ {
    		return 0;
    	}
    	this.tbuf=this.map.sEep.read(addr,this.n­um*3);
    	this.tm=this.map.sEep.read((addr+s),this­.num*3);
    	this.ti=new Int8Array(this.map.sEep.read((addr+s*2),­this.num*3));
    	this.ta=new Int8Array(this.map.sEep.read((addr+s*3),­this.num*3));
    	return 1;
    };
    
    leds.del = function (index) {
    	var t=new Uint8Array(this.map.slen*4);
    	t.fill("\xFF");
    	this.map.sEep.write(this.map.statOff+(4*­index*this.map.slen),t);
    };
    leds.setAnimate = function (mode,address,frames){
      leds.anilast=frames;
      leds.aniaddr=address;
      leds.animode=mode;
    };
    
    leds.save = function (index) {
    	var s=this.map.slen;
    	var addr=this.map.statOff+(4*index*s);
    	this.map.sEep.write(addr,E.toString(this­.tbuf)+leds.zz+E.toString(this.tm)+leds.­zz+E.toString(this.ti)+leds.zz+E.toStrin­g(this.ta)+leds.zz);
    };
    
    
    leds.setPixel = function (x, y, color) {
    	this.tbuf[x*3]=color[0];
    	this.tbuf[x*3+1]=color[1];
    	this.tbuf[x*3+2]=color[2];
    };
    
    leds.adjPixel=function (led,color) {
    	this.tbuf[led*3]+=color[0];
    	this.tbuf[led*3+1]+=color[1];
    	this.tbuf[led*3+2]+=color[2];
    };
    
    leds.adjAll=function (color) {
    	for (var i=0;i<this.num;i++){
    		this.adjPixel(i,color);
    	}
    };
    
    leds.setPixel2 = function (x, y, color,mode,mintwi,maxtwi,instant) {
    	x*=3;
    	for (var i=0;i<3;i++){
    		this.tbuf[x+i]=color[i];
          if (instant) {this.buff[x+i]=color[i];}
    		this.tbuf[x+i]=color[i];
    		this.tm[x+i]=mode[i];
    		this.ta[x+i]=maxtwi[i];
    		this.ti[x+i]=mintwi[i];
    	}
    };
    
    leds.flip = function () {
    	var j=0;
    	var i=0;
    	var z=leds.num*3;
    	while (i<z) {
          var rch=gtab[leds.tclb[i++]];
    		var gch=gtab[leds.tclb[i++]];
    		var bch=gtab[leds.tclb[i++]];
    		
    		var ma = Math.max(rch,gch,bch);
    		var mult=1;
            var gdim=31;
    		
    			if (ma <390) {
    				gdim=3;
    				mult=10.33;
    			} else if (ma <700) {
    				gdim=7;
    				mult=4.4;
    			} else if (ma <1700) {
    				gdim=15;
    				mult=2.06;
    			} 
    		
    		this.fbuf[j++]=(this.ison?(gdim|224):224­);
    		this.fbuf[j++]=(bch?Math.max((bch*mult)>­>4,1):0);
    		this.fbuf[j++]=(gch?Math.max((gch*mult)>­>4,1):0);
    		this.fbuf[j++]=(rch?Math.max((rch*mult)>­>4,1):0);
    
    	}
    
    	this.spi.write(0,0,0,0,this.fbuf,0xFF,0x­FF,0xFF,0xFF);
    };
    
    leds.zflip = function () {
    	var ca=startAddr+(frameLength*curFrame++);
    	this.fbuf=eep.read(ca,frameLength);
    	this.spi.write(0,0,0,0,this.fbuf,0xFF,0x­FF,0xFF,0xFF);
    };
    
    
    setBusyIndicator(2);
    
    

    Alternate modes for animations - this lets me get ~30 fps with animode =5 (where the background is totally replaced) or 18fps with animode=3 (where the background and current twinkle state is used, but all other calculations are stopped. I just wish I could do the twinkle calculations faster.

About

Avatar for DrAzzy @DrAzzy started