Spence Konde
Published

Adjustable Color Temperature Desk Lamp

Espruino controlled adjustable color desk lamp

Full instructions provided1,203
Adjustable Color Temperature Desk Lamp

Story

Read more

Code

DeskLamp.js

JavaScript
Version 2 desklamp code
 

//Pins:

//keypad to A1-B12, jumper to B7

//Serial for nixies on B6

//Desk Lamp on C6-A8

//I2C2 used for the big long I2C chain

//B0 = backlight, C5 = DHT22

//B1 = DHT22 FET



//If C4 is held low during reset, the saved code will be loaded, but not run, permitting changes. 



//fram memory:

// 0-320: Presets. 

// 320-512: History for temp/rh/pressure graphs, including space for one extra graph.



/*

@@@@@@@@@@@@@@@@@@@@@

@@@@@@@        @@@@@@

@@@@@@@ OnInit @@@@@@

@@@@@@@        @@@@@@

@@@@@@@@@@@@@@@@@@@@@ */





function onInit() {

	pinMode(C4,'input_pullup');

	digitalWrite(B1,0);

	if (!digitalRead(C4)) {return;}

	rh=-1;

	t=-1;

	tlst=t;

	tsam=0;

	pr=0;

	temh=new Uint8Array(48);

	rhh=new Uint8Array(48);

	prh=new Uint8Array(48);

	usrmsg="";

	MnuS=0;

	MnuO=0;

	inval="";

	msg="";

	lastSen=0;

	setBusyIndicator(A13);

	fargosturl="http://192.168.2.12/fargostatus.php";

	dateurl="http://192.168.2.12/date.php";

	fargourl="http://192.168.2.14/api/relay/";

	fargo=new Uint8Array(8);

	colors="BLUECOOLWARMYELLRED ";

	gw=new Uint8Array([7,9,9,7,7]);

	gwx=new Uint8Array([3,14,27,40,51]);

	fargostrs="Colored,White,Wizard,Tentacle,Desk,Micro,Fan,Under";

	ledstate=new Float32Array([0.0,0.0,0.0,0.0,0.0]);

	nixs=0;

	nixr=0;

	//presets=[new Float32Array([0.0,0.0,0.0,0.0,0.0]),new Float32Array([0.9,1,0.6,0,0]),new Float32Array([0,0.6,1,0.8,0.4]),new Float32Array([0.5,0.5,0.5,0.5,0.5])];

	//prenames=["OFF","COLD\nWHIT","VERY\nWARM","HALF\nHALF"];

	Clock = require("clock").Clock;

	ledpins=[A8,C9,C8,C7,C6];

	upled();

  I2C2.setup({scl:B10,sda:B11,baud:200000});

	kp=require("KeyPad").connect([C2,C3,A0,A1],[C1,C0,B7,C12,B12], function(e) {onKey("AB#*123U456D789CL0RE"[e]);});

	//I2C1.setup({scl:B8,sda:B9});

	//bmp=require("BMP085").connect(I2C1,3);

	Serial1.setup(115200,{tx:B6});

	nixie=require("SmartNixie2").connect(Serial1,6);

	e=require("DHT22").connect(C5);

	//e.rst=function(){B1.set();setTimeout("B1.unset()",100);};

	require("Font8x12").add(Graphics);

	fram=require("AT24_new").connect(I2C2,0,4,4);

	//rom2=require("AT24").connect(I2C2,64,256,2);

	rom1=require("AT24_new").connect(I2C2,128,512,1);

	eth=require("WIZnet").connect();

	eth.setIP();

	setTimeout("var s=require('http').createServer(function (req, res) {var par=url.parse(req.url,true);var q=par.query; var nam=par.pathname; nam=nam.split('/');nam=nam[1];var rd=procreq(nam,q);res.writeHead(rd.code,{'Content-Type': 'text/plain'}); res.write(rd.body);res.end();}).listen(80);",15000);

	setInterval("upSensors();",15000);

	setTimeout('setInterval("upHist()",60000*30);',59000);

	setTimeout("setInterval(function(){uplcd();},30000);",15000);

	setTimeout("setInterval('getfargostatus();',30000);",20000);

	setTimeout("getDate();setInterval('getDate();',1800000);",2000);

	setInterval("delete onInit",500); 

	g = require("DigoleBuf").connect(I2C2,128,64); //setup graphics and define a few new functions on it. 

	g.clear();

	g.setFont8x12();

	g.drawString("LCD OK",0,0);

	g.flip();

	g.setContrast(0x26);

	g.bktm=0;

	g.HWs= function(c) {this.i2c.writeTo(0x27,c);}; //send hardware draw command

	g.HWdR = function(x1,y1,x2,y2,col) {this.HWs("SC"+(col?1:0));this.HWs("DR"+String.fromCharCode(x1,y1,x2,y2));}; //drawrect

	g.HWfR = function(x1,y1,x2,y2,col) {this.HWs("SC"+(col?1:0));this.HWs("FR"+String.fromCharCode(x1,y1,x2,y2));}; //fillrect

    g.backlighton = function(tim_) { //backlight control

		digitalWrite(B0,1);

		if (this.bktm) {

			try {

				clearTimeout(this.bktm);

			}

			catch (err) {

				this.bktm=0;

			}

			this.bktm=0;

		}

		this.bktm=setTimeout("digitalWrite(B0,0);g.bktm=0;",tim_?tim_:10000);

	};

	g.backlighton();

	presets=[new Float32Array([0.0,0.0,0.0,0.0,0.0])];

	prenames=["OFF"];

	var i=1;

	while (fram.read(24*(i-1),1) != 255) { //read presets from fram

		 prenames[i]=E.toString(fram.read(24*(i-1),12));

		 var temp=fram.read(24*(i-1)+16,5);

		 presets[i]=new Float32Array([temp[0]/100.0,temp[1]/100.0,temp[2]/100.0,temp[3]/100.0,temp[4]/100.0]);

		 i++;

	}

	if (fram.read(320,1)!=255) { //if we have stored history in the fram, read it in

		rhh=fram.read(320,48);

		temh=fram.read(368,48);

		prh=fram.read(416,48);

	}





	menu=[2,4,presets.length-1];

}









/*

@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@         @@@@@@

@@@@@@@ Utility @@@@@@

@@@@@@@         @@@@@@

@@@@@@@@@@@@@@@@@@@@@@ */



function getTStr(sep){

  var hrs=clk.getDate().getHours();

  var mins=clk.getDate().getMinutes();

  return (hrs>9?hrs:" "+hrs)+sep+(mins>9?mins:"0"+mins);

}



function getDstr(){

  var mon=clk.getDate().getMonth()+1;

  var day=clk.getDate().getDate();

  var year=clk.getDate().getFullYear();

  return (mon+"/"+day+"/"+year);

}





function upled() {

	for (var i=0;i<5;i++) {

		analogWrite(ledpins[i],ledstate[i]);

	}

}





function upHist() {

	for (i=47;i>0;i--) {

		temh[i]=temh[i-1];

		rhh[i]=rhh[i-1];

		prh[i]=prh[i-1];

	}

	temh[0]=E.clip(Math.round(t-10)*2,0,50);

	//prh[0]=pr;

	rhh[0]=E.clip(Math.round(rh/2),0,50);

	fram.write(320,E.toString(temh,rhh,prh));

}

function getLedStr() {

	var rtst="";

	for (var it=0;it < 5; it++ ) {

		rtst+=String.fromCharCode(Math.round(ledstate[it]*100));

	}

	return rtst;

}





function upSensors() {

	if (lastSen==0) {

		//bmp.getPressure(function(b){if (pr==-1){pr=b.pressure;} else {pr=pr*0.8+b.pressure*0.2;}});

		lastSen=1;

	} else if (lastSen==1){

		e.read(function(a){if(a.rh != -1) {if (a.temp==tlst){tsam++;}else{tsam=0;}tlst=a.temp;if (rh==-1){rh=a.rh;t=a.temp;} else {rh=rh*0.8+a.rh*0.2;t=t*0.8+a.temp*0.2;}}});

		lastSen=0;

		if (tsam>10) { //krutz, the DHT22 died!

			e.rst();

		}

	}

}



/*

@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@         @@@@@@

@@@@@@@ Network @@@@@@

@@@@@@@         @@@@@@

@@@@@@@@@@@@@@@@@@@@@@ */



function getfargostatus() {

	var fargost="";

	require("http").get(fargosturl, function(res) {

		res.on('data',function (data) {fargost+=data;});

		res.on('close',function() {var tfs=JSON.parse(fargost); vtfs=tfs; for (var i=0;i<8;i++) { fargo[i]=tfs.relaystate[i].state;} if(MnuS==3){uplcd(1);}});

	});

}

function setFargo(relay,state) {

	var postfix = (state) ? "/on":"/off";

	require("http").get(fargourl+(relay+1).toString()+postfix, function(res) {

		res.on('close',function () {

			if(this.code!=200) {

				fargo[relay]=state;

			}

		});

	});

}



function getDate() {

	var date="";

	require("http").get(dateurl, function(res) {

		res.on('data',function (data) {date+=data;});

		res.on('close',function() {clk=new Clock(date);});

	});

	//delete getDate;

}



function procreq(path,query) {

	var rd={};

	rd.code=404;

	rd.body="";

	if (path=="status.json") {

		rd.code=200;

		var r='{"lamp":{';

		for (var i=0;i<5;i++) {

			r+='"'+colors.substr(i*4,4)+'":'+ledstate[i].toFixed(2);

			if (i<4) {r+=",";}

		}

		r+='},\n"sensors":{"rh":'+rh.toFixed(1)+',"temp":'+t.toFixed(1)+',"pressure":'+pr.toFixed(2)+'}}';

		rd.body=r;

	} else if (path=="lamp.cmd") {

		rd.code=200;

		rd.body="Command applied";

		ledstate[0]=query.BLUE==undefined ? 0:E.clip(query.BLUE,0,1);

		ledstate[1]=query.COOL==undefined ? 0:E.clip(query.COOL,0,1);

		ledstate[2]=query.WARM==undefined ? 0:E.clip(query.WARM,0,1);

		ledstate[3]=query.YELL==undefined ? 0:E.clip(query.YELL,0,1);

		ledstate[4]=query.RED==undefined ? 0:E.clip(query.RED,0,1);

		setTimeout("uplcd(); upled();",100);

	} else if (path=="code.run") {

		if (query.code) {

			rd.code=200;

			rd.body=eval(query.code);

		} else {

			rd.code=400;

			rd.body="400 Bad Request: No code supplied!";

		}

	} else if (path=="usrmsg.cmd") {

		if (query.msg && query.msg.length > 1) {

			rd.code=200;

			usrmsg=query.msg;

			rd.body="Message set: "+query.msg;

			MnuS=10;

			setTimeout("uplcd();",100);

		} else {rd.code=400; rd.body="400 Bad Request: No message supplied";}

	} else {rd.code=403; rd.body="403 Forbidden";}

	return rd;

}









/*

@@@@@@@@@@@@@@@@@@@@@

@@@@@@@        @@@@@@

@@@@@@@ KEYPAD @@@@@@

@@@@@@@        @@@@@@

@@@@@@@@@@@@@@@@@@@@@ 



MnuS:

0 - Bars, blank space, fargo status

1 - Bars, per-color adjust, fargo status

2 - Bars, preset select, fargo status

3 - Fargo control

4 - Blank (???)

5 - Save dialog - not normally accessible. 

6 - 



KeyW=Text entry timeout

KeyN=Text entry number pressed

KeyC=Text entry keypress count

KeyS=Text entry string



*/





function onKey(k){

	msg="";

	var ulcd=1;

	if (MnuS==5) { // Save dialog

		if (k=="L" && KeyS.length > 0) {

			KeyS=KeyS.substr(0,KeyS.length-1);

			KeyC=0;

			KeyN=-1;

			if (KeyW!=-1) {

				clearTimeout(KeyW);

				KeyW=-1;

			}

		} else if ( k=="C" ) {

			MnuS=0;

			inval="";

			MnuO=0;

			t9rst();

			if (KeyW!=-1) {

				clearTimeout(KeyW);

				KeyW=-1;

			}

		} else if ( k =="E" && KeyS != "") {

			prenames[prenames.length]=KeyS;

			presets[presets.length]=new Float32Array(ledstate);

			var outstr=KeyS;

			while (outstr.length <= 15) {

				outstr+=" ";

			}

			outstr+=getLedStr();

			while (outstr.length <= 24) {

				outstr+=" ";

			}

			fram.write((presets.length-2)*24,outstr);

			menu[2]=presets.length-1;

			msg="Saved";

			MnuS=0;

			MnuO=0;

			t9rst();

			if (KeyW!=-1) {

				clearTimeout(KeyW);

				KeyW=-1;

			}

		} else  if (KeyS.length < 12) {

			var a=parseInt(k);

			if (a != NaN) {

				if (KeyW!=-1) {

					clearTimeout(KeyW);

					KeyW=-1;

				}

				if (KeyC==0) {

					KeyN=a;

					KeyC=1;

				} else if (KeyN==1) {

					KeyS+="1";

					KeyN=-1;

					KeyC=0;

				} else if (KeyN==a) {

				if (((KeyN==9 || KeyN==7) && KeyC==5) || (KeyN==0 && KeyC==2) || (KeyN!=9 && KeyN!=7 && KeyN!=0 && KeyC==4) ) {

					KeyC=1;

				} else {

					KeyC++;

				}

			} else {

				KeyS+=getT9();

				KeyN=a;

				KeyC=1;

			}

				KeyW=setTimeout("KeyS+=getT9();KeyN=-1;KeyC=0;KeyW=-1;;uplcd();",2000);

			}

		}

	} else if ( k=="B" ) { //nixie toggle

    	nixs=!nixs;

    	ulcd=3; //don't redraw LCD

	} else if (k=="A") { //all off

		ledstate=new Float32Array([0,0,0,0,0]);

		upled();

    	ulcd=3;//Don't redraw LCD

	} else if ( k=="C" ) {

		MnuS=0;

		inval="";

		MnuO=0;

	} else if (k=="*"){ //advance to next top level menu

		if (MnuS>=3){

			MnuS=0;

		} else {

			MnuS++;

			if (MnuS==1){

				nixr=MnuO;

			}

		}

		MnuO=0;

		inval="";

	} else if ((MnuS==2 || MnuS == 1) && k=="#"){ //save command

		if (MnuO==0 || MnuS ==1) { //new

			MnuS=5;

			t9rst();

		} else { //modift

			presets[MnuO]=new Float32Array(ledstate);

			fram.write((MnuO-1)*24+16,getLedStr());

			msg="Saved";

			MnuO=0;

			MnuS=0;

		}



	} else if (k=="E" && MnuS) { //enter

		if (MnuS==1 && inval) { //apply single led changes

			var v=E.clip(parseInt(inval),0,100);

			v=v/100;

			ledstate[MnuO]=v;

			inval="";

			upled();

		} else if (MnuS==2) { //apply preset led changes

			ledstate=new Float32Array(presets[MnuO]);

			MnuO=0;

			MnuS=0;

			upled();

		} else if (MnuS==3) { //fargo

			var ex=fargo[MnuO];

			setFargo(MnuO,!ex);

			ulcd=7+(ex?0:16);

		}

	} else if ((k=="L"||k=="R") && (MnuS==1||MnuS==2||MnuS==0)) { //left/right arrows

		if (k=="R") {

			if (MnuO>=menu[MnuS]) {

				MnuO=0;

			} else {

				MnuO++;

			}

		} else {

			if (MnuO==0) {

				MnuO=menu[MnuS];

			} else {

				MnuO--;

			}

		}

		inval="";

	} else if ((k=="U"||k=="D") && MnuS==1) { //up/down arrows for individual LED adjust

		ledstate[MnuO]=E.clip(100*ledstate[MnuO]+(k=="U"?4:-4),0,100)/100;

		inval="";

		ulcd=8;

		upled();

	} else if (MnuS==3) { //2-way navigation for fargo screen. 

		ulcd=5+(MnuO<<4); //hardware update

		if (k=="D") {

			MnuO=(MnuO&4)|((MnuO+1)&3);

		} else if (k=="U") {

			MnuO=(MnuO&4)|((MnuO-1)&3);

		} else if (k=="R"||k=="L") {

			MnuO=MnuO^4;

		} else { ulcd=3; } //Don't update lcd

	} else if (MnuS==1) {

		if (inval.length < 3) {

			inval=inval+k;

		} else {

			inval="";

		}

	}

	uplcd(ulcd);

	g.backlighton();

}



/*

@@@@@@@@@@@@@@@@@@@@@

@@@@@@@        @@@@@@

@@@@@@@ SCREEN @@@@@@

@@@@@@@        @@@@@@

@@@@@@@@@@@@@@@@@@@@@ */





function uplcd(isky) {

	g.clear();

    var tpr=0.000295333727*pr;

	g.drawString(t.toFixed(1)+" C "+rh.toFixed(1)+"% "+tpr.toFixed(1)+" "+getTStr(":"),0,0);

	if ((isky&14)==2) { //do nothing

	} else if ((isky&14)==4) {

		var oldO=isky>>4;

		g.HWdR(2+(oldO>>2)*64,15+(oldO&3)*12,61+(oldO>>2)*64,24+(oldO&3)*12,0);

		g.HWdR(2+(MnuO>>2)*64,15+(MnuO&3)*12,61+(MnuO>>2)*64,24+(MnuO&3)*12,1);

	} else if ((isky&14)==6) {

    	g.HWfR(5+(MnuO>>2)*64,18+(MnuO&3)*12,10+(MnuO>>2)*64,21+(MnuO&3)*12,isky>>4);

    	if (!(isky>>4)) {g.HWs("SC1");}

	} else if ((isky&14)==8) {

		g.HWfR(gwx[MnuO]+1,16,gwx[MnuO]+gw[MnuO]-1,46,0);

    	g.HWfR(gwx[MnuO],(47-ledstate[MnuO]*32),gwx[MnuO]+gw[MnuO],47,1);

	} else {

		slcd(); //full LCD update

	}

	nixie.setAllLED(0,0,0);

	if (nixs){

      var tp=(MnuS===0?MnuO:nixr);

		if (tp===0) {

			nixie.setString(getTStr(" ")+" ");

          //nixie.setLED(2,128,32,0);

          if((isky&1)==0){nixr++;}

		} else if (tp==1) {

			nixie.setString("  "+t.toFixed(1)+"5");nixie.setAllLED(96,0,0);nixie.setLED(1,0,0,0);nixie.setLED(0,0,0,0);if((isky&1)==0){nixr++;}

		} else if (tp==2) {

			nixie.setString("  "+rh.toFixed(1)+"6");nixie.setAllLED(16,24,64);nixie.setLED(1,0,0,0);nixie.setLED(0,0,0,0);if((isky&1)==0){nixr=0;};

		}

	} else {

		nixie.setString("      ");

	}

	nixie.send();

}





function slcd() {

	if (MnuS == 3) {

		var fst=fargostrs.split(',');

		g.setFontBitmap();

		for (var j=0;j<8;j++) {

...

This file has been truncated, please download it to see its full contents.

Credits

Spence Konde

Spence Konde

1 project • 0 followers

Comments