Jump to content
43oh

TI_Trey

Members
  • Content Count

    225
  • Joined

  • Last visited

  • Days Won

    7

Reputation Activity

  1. Like
    TI_Trey got a reaction from tripwire in WiFi Sous Vide Sources   
    Hi 43oh,
     
    Last month I posted the sources for the solid state relay board, and I promised I'd post the source code for the sous vide application.  Well here it is!
    sous_vide.zip
    libraries.zip
     
    You'll also need the standard PID and PID autotune libraries available on your favorite Arduino site.
     
    I just celebrated my birthday and cooked a surf and turf with it.  As you can see, it works pretty well:

     
    Happy Holidays!
  2. Like
    TI_Trey got a reaction from pine in WiFi Sous Vide Sources   
    Hi 43oh,
     
    Last month I posted the sources for the solid state relay board, and I promised I'd post the source code for the sous vide application.  Well here it is!
    sous_vide.zip
    libraries.zip
     
    You'll also need the standard PID and PID autotune libraries available on your favorite Arduino site.
     
    I just celebrated my birthday and cooked a surf and turf with it.  As you can see, it works pretty well:

     
    Happy Holidays!
  3. Like
    TI_Trey got a reaction from Fmilburn in WiFi Sous Vide Sources   
    Hi 43oh,
     
    Last month I posted the sources for the solid state relay board, and I promised I'd post the source code for the sous vide application.  Well here it is!
    sous_vide.zip
    libraries.zip
     
    You'll also need the standard PID and PID autotune libraries available on your favorite Arduino site.
     
    I just celebrated my birthday and cooked a surf and turf with it.  As you can see, it works pretty well:

     
    Happy Holidays!
  4. Like
    TI_Trey got a reaction from abecedarian in Quadcopter BoosterPack   
    Hi 43oh!
     
    Some of you may have seen me over at c2kcentral, but I'm mostly a lurker here.  For a while now, I've been working on developing a low cost quadcopter.  Well that quadcopter is nearly done!  Boards are being manufactured as I type this, and I plan to have it flying at the Bay Area MakerFaire in May.
     
    Here's a picture of the top of the motor driver board:

     
    Personally, I would like to see this manufactured and sold, but before I invest the effort to do that I need to ensure there is a demand for such a board.  The finished quad will be about 1 square foot in size, will cost ~$200, and will be able to carry a small payload (I've got my fingers crossed we'll have enough thrust for a Go Pro).  If you would please take a second to answer the poll as to whether or not you would be interested in purchasing one.
     
    This is all very preliminary, but I appreciate any feedback you may have.
     
    Thanks!
     
    Edit:
    Moving some of the information regarding the setup up here:
     
    4x TMS320F28027F + DRV8312 make up the ESC.  That is the bulk of what is on the board which you can see on the first post.
    1x C2000 LP acts as the brain.  This board decodes the control signals and sends torque commands to each of the ESCs via a PWM signal.  This LaunchPad runs the open source AeroQuad firmware on top of Energia...which also means other LaunchPads could be used as the brain.
    Control Inputs come via a standard RC 2.4GHz radio and receiver.  Because the LaunchPad doesn't have 1 million capture inputs I am using a receiver which supports S.Bus.
    3 axis accelerometer, gyro, magnetometer, barometer and GPS
     
    Update 4/16:
    Got the IMU board in today.  Here's a picture:

     
    Yellow - TC6000GN - CC4000 based GPS
    Red - MPU6000 - 6 axis IMU
    Blue - HMC5983 - 3 axis Mag
    Purple - MS5611 Barometer
     
    Update 4/21:
    Got in a car accident and have been dealing with insurance, so instead of working on this I've been dealing with BS.  Good news is that all that is finally taken care of and the motor boards are here!  These are by far the most complex and visually appealing boards I've even designed.  Take a look:

     
    I'm still waiting on a few structural pieces to arrive which are being water cut.  I expect I'll have them later this week.  I'll post some more pictures once I get the boards assembled.
     
    Update 4/22:
    Motor boards are assembled and basic functionality checks out.  Next checks will include JTAG connectivity, and then motor drive capability.  The design is based off an earlier prototype that was proven out, so I expect everything to work splendidly on this board.

     
     
    If you're not already, follow me on twitter for up to the minute project updates! @yertnamreg1218
     
    Update 4/24:
    The 4 InstaSpin Piccolos are all in a JTAG chain.  Initially I had a little trouble getting CCS to connect, but after a little re-soldering of the ICs JTAG started working.  I now have all 4 device programmed with the motor control software.  I was also able to verify operating on a battery and the serial data link between the receiver and main microcontroller.

     
    Yes, I'm aware my desk is a mess right now. :-P
     
    Update 5/6:
    Lots of work has been going into the AeroQuad firmware I'll be running on the LaunchPad.  The two main contenders for firmware were Arducopter and Aeroquad.  The reason Aeroquad was chosen over Arducopter was their use of the standard Arduino IDE to build their firmware.  Arducopter uses a hacked together one off build system.  Since Energia is based off Arduino, getting the AeroQuad project to build was much easier than Arducopter would have been.  
     
    With that said, I'm happy to announce that today I was able to compile AeroQuad successfully for the C2k LaunchPad in Energia.  This is a huge milestone!

     
    As you can see it didn't link, but that's an easy problem to fix.  With MakerFaire less than 2 week away, the pressure is on!  Will Trey get the quadcopter flying in time or will Murphy raise his evil head and sabotage the project?  Stay tuned to find out!
     
    Update 5/23:
    After my last update I had to really focus on getting the thing done in time for MakerFaire, so I slacked off on project updates.  Sadly, Murphy paid me a visit and threw a few wrenches into my plan.
     
    Problem #1: Everything on the motor drive boards appears to be working as planned with the exception of the current feedback circuitry for the motors.  The old board can spin the motors just fine, but on the new board the current feedback isn't behaving nicely which is causing us problems with the motor control software.  The boards are based on the same schematic, but the original developer changed some of the components in the feedback circuitry.  I have a list of the changes and the new board has incorporated those changes, but still has problems.  I'm unsure if the issue is layout or component related and will be doing some experiments in the coming weeks to determine and fix the cause.
     
    Problem #2: I pulled a special favor to get the structural materials (i.e. frame) for the quadcopter cut on a waterjet.  I kicked this off in early April, but because it was a favor and there were other users of this machine my parts didn't end up getting cut in time.  I'm currently looking for a place in town that can do CNC routing and drilling to get these parts cut.
     
    MakerFaire was still a big success and I was able to talk to a ton of people about LaunchPad, Energia, and the quadcopter.  I even met a few 43oh members while I was there!  I also talked to the creators of the Aeroquad firmware and they are very excited about this project.  Once the C2000 port is more stable I will be merging my changes upstream to the main Aeroquad repository.  
     
    I also talked to them about structural materials for the frame.  The Aeroquad guys use a material called DiBond.  Its a composite aluminum/polyethylene laminate which is less dense than FR4 with comparable material properties.  It is commonly used in signage applications, but also makes for an excellent quadcopter frame.  At MakerFaire the AeroQuad team participated in an event called the "Game of Drones".  This event pitted two quadcopters against eachother in air to air combat.  Take a look at this video showing off some of the fights: 
     

    http://youtu.be/91OCQ-1KP08
     
    After seeing how well they performed in the competition I am considering switching to use DiBond as the structural material in my quadcopter as well.
     
    Update 8/19
    It took me a while to find someone to cut the frame at a reasonable price, but I finally did.  I just received the frame back from the fabricator and it looks great.  I'll still need to tweak the design a bit due to machining tolerances, but that's something that's easily accomplished.  Without further ado, here are the pics:

     

     
    There are some spars that connect the two pieces together that should also be here, but the fabricator was confused and thought they were scrap.  I should be able to fully assembled the quad after I get back the tweaked version of the frame.
     
    I also was lucky enough to be a guest on "The Amp Hour" this week.  Be sure to tune in!  I talk about my experience in college at Rose-Hulman, my first job after college with Simma Software, and I reveal a new job I've accepted at TI!!!!
  5. Like
    TI_Trey got a reaction from bluehash in c2000 issues   
    Sorry to hear y'all are having trouble.  I don't check these forums as much as I should.  My apologies.
     
    A couple things to note:
    Compiler version should be completely independent of whether the upload works or not.  Nearly any C2k compiler version should be ok.  Also there is a new version of the compiler out that I should be able to integrate into Energia, so that user's will not have to do this step manually.  Hopefully I can get this into the next release, but no promises. Energia currently uses the device's serial boot mode to program the device.  This is why you have to set all those d@mn switches.  First the PC loads a small program into the device's RAM.  This is the short LED blink you see in the beginning.  Then this program recieves the actual application and programs it into flash.  This is the part where you see the LEDs alternately blink.  Because of how everything shakes out, the baud rate needs to be 38400 or less. I will be updating Energia for C2k to use a new progamming mechanism called DSLite.  DSLite is a lightweight version of the debug server CCS uses. This new programming scheme will use JTAG instead of serial, will be faster, and will not require any switch configuration prior to programming CCS programming is probably failing due to the 3rd boot switch.  For CCS to connect this needs to be in the up position.  I believe this is documented in the user's guide for the LaunchPad. I've seen programming failures with the 27F (instaSPIN) version of the LaunchPad in Energia.  I've recreated the issue here, but haven't been able to isolate the cause.  This will automatically be fixed when we switch over to DSLite.  
    Hopefully that answers some questions and helps people get up and running!
  6. Like
    TI_Trey got a reaction from spirilis in c2000 issues   
    Sorry to hear y'all are having trouble.  I don't check these forums as much as I should.  My apologies.
     
    A couple things to note:
    Compiler version should be completely independent of whether the upload works or not.  Nearly any C2k compiler version should be ok.  Also there is a new version of the compiler out that I should be able to integrate into Energia, so that user's will not have to do this step manually.  Hopefully I can get this into the next release, but no promises. Energia currently uses the device's serial boot mode to program the device.  This is why you have to set all those d@mn switches.  First the PC loads a small program into the device's RAM.  This is the short LED blink you see in the beginning.  Then this program recieves the actual application and programs it into flash.  This is the part where you see the LEDs alternately blink.  Because of how everything shakes out, the baud rate needs to be 38400 or less. I will be updating Energia for C2k to use a new progamming mechanism called DSLite.  DSLite is a lightweight version of the debug server CCS uses. This new programming scheme will use JTAG instead of serial, will be faster, and will not require any switch configuration prior to programming CCS programming is probably failing due to the 3rd boot switch.  For CCS to connect this needs to be in the up position.  I believe this is documented in the user's guide for the LaunchPad. I've seen programming failures with the 27F (instaSPIN) version of the LaunchPad in Energia.  I've recreated the issue here, but haven't been able to isolate the cause.  This will automatically be fixed when we switch over to DSLite.  
    Hopefully that answers some questions and helps people get up and running!
  7. Like
    TI_Trey reacted to bluehash in Facebook's Parse.com Support For the CC3200 Development Board.   
    First Temboo, now parse. Alot of cloud tools for the CC3200.
    Saw this on @@TI_Trey's twitter post.
     
    https://parse.com/apps/quickstart#embedded/ticc3200
     

  8. Like
    TI_Trey got a reaction from bluehash in IoT Smoker   
    @bluehash: 5529 LP + ADS1118 BP + CC3100 BP + Solid State Relay board
    @geometrikal: I hosted the Node-RED code on IBM Bluemix.
  9. Like
    TI_Trey got a reaction from JonnyBoats in IoT Smoker   
    Hey folks!
     
    I took the electronics I used for my Sous Vide controller and repurposed them for a smoker.  I also completely redid the software to come up with a much better user interface.  You can read the story about it on the TI site here:
    http://e2e.ti.com/group/launchyourdesign/b/blog/archive/2015/03/09/yeee-hawww-launchpad-ropes-rodeo-bbq
     
    The Energia source code is here:
    wifi_smoker.ino
     
    I tried to upload the Node-RED flow as a JSON, but the forums won't let me.  Hence you get plain text you can copy and paste:
    [{"id":"e4924113.e3d978","type":"mqtt-broker","broker":"198.41.30.241","port":"1883","clientid":""},{"id":"c66445d5.585f48","type":"websocket-listener","path":"/ws/mobiui","wholemsg":"false"},{"id":"c8ba3187.3745d","type":"http in","name":"http request: control","url":"/control","method":"get","x":178,"y":90,"z":"6fb59101.904a7","wires":[["413cc48.fbec33c"]]},{"id":"413cc48.fbec33c","type":"template","name":"chart","field":"payload","template":"<!DOCTYPE HTML>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <meta HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /> \n <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n <title>Node-RED mobi ui</title>\n <link rel=\"stylesheet\" href=\"//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.css\" />\n <script src=\"//code.jquery.com/jquery-1.11.1.min.js\"></script>\n <script src=\"//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.js\"></script>\n <script src=\"//cdnjs.cloudflare.com/ajax/libs/highcharts/4.0.3/highcharts.js\"></script>\n <script>//Node-Red mobi ui - LHG industrialinternet.co.uk\n//\tconsole.log(\"NR mobi UI 1.0: Controls, Chart\");\n\tvar schedule = null;\n\tvar itemLookup = null;\n\tvar statusMsg = false;\n\tvar daiableWidgets = false; \n\tvar connected = false;\n\tvar wsUri=\"wss://\"+window.location.hostname+\"/ws/mobiui\";\n\tvar ws=null;\n\tvar smokerTempAct=69;\n\tvar meatTempAct=69;\n\t\n\t var options = {\n chart: {\n type: 'spline',\n animation: Highcharts.svg, // don't animate in old IE\n events: {\n load: function () {\n\n // set up the updating of the chart each second\n var series0 = this.series[0];\n setInterval(function () {\n var x = (new Date()).getTime(), // current time\n y = smokerTempAct;\n series0.addPoint([x, y], true, true);\n }, 15000);\n var series1 = this.series[1];\n setInterval(function () {\n var x = (new Date()).getTime(), // current time\n y = meatTempAct;\n series1.addPoint([x, y], true, true);\n }, 15000);\n }\n }\n\n },\n title: {\n text: 'Current Smoker Temperature'\n },\n xAxis: {\n type: 'datetime',\n tickPixelInterval: 1500\n },\n yAxis: {\n title: {\n text: 'Temperature (F)'\n },\n plotLines: [{\n value: 0,\n width: 1,\n color: '#808080'\n }]\n },\n tooltip: {\n formatter: function () {\n return '<b>' + this.series.name + '</b><br/>' +\n Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +\n Highcharts.numberFormat(this.y, 2);\n }\n },\n legend: {\n enabled: true\n },\n exporting: {\n enabled: false\n },\n series: [{\n name: 'Smoker Temperature',\n data: (function () {\n // generate an array of random data\n var data = [],\n time = (new Date()).getTime(),\n i;\n\n for (i = -19; i <= 0; i += 1) {\n data.push({\n x: time + i * 1000,\n y: Math.random()\n });\n }\n return data;\n }())\n },{\n name: 'Meat Temperature',\n data: (function () {\n // generate an array of random data\n var data = [],\n time = (new Date()).getTime(),\n i;\n\n for (i = -19; i <= 0; i += 1) {\n data.push({\n x: time + i * 1000,\n y: Math.random()\n });\n }\n return data;\n }())\n }]\n };\n\n\n\t\n\tfunction wsConn() {\n\t\tws = new WebSocket(wsUri);\n\t\tws.onmessage = function(m) {\n//\t\t\tconsole.log('< from-node-red:',m.data);\n\t\t\tif (typeof(m.data) === \"string\" && m. data !== null){\n\t\t\t\tvar msg =JSON.parse(m.data);\n\t\t\t\tvar ftc = msg.id.substring(0, 3);\n\t\t\t\t//console.log(\"id:\"+msg.id+\" fct:\"+ftc);\n\t\t\t\tif(ftc== \"init\") {init( msg.v);}\n\t\t\t\tif(ftc==\"tsw\"){setFlip(msg.id,msg.v);}\n\t\t\t\tif(ftc==\"sld\"){setSlider(msg.id,msg.v);}\n\t\t\t\tif(ftc==\"val\"){setValue(msg.id,msg.v);}\n\t\t\t\t//if(ftc==\"cha\"){showCharts( msg.v.values,msg.v.colors,msg.v.engs,msg.v.tags,msg.v.names,msg.v.nos,msg.v.title,.msg.v.yTitle)};\n\t\t\t\tif(ftc==\"cha\"){showCharts(msg.id,msg.v)};\n\t\t\t\tif(ftc==\"shd\"){setSchedule(msg.v);}\n\t\t\t\tif(ftc==\"sta\"){setStatus(msg.v.stMsg,msg.v.dur,msg.v.pri);}\n\t\t\t\tif(ftc==\"ack\"){clearReq();}\n\t\t\t}\n\t\t}\n\t\tws.onopen = function() { \n\t\t\tstatusMsg=false;\n\t\t\tif(daiableWidgets==true){enablePage();}\n\t\t\tsetStatus(\"Connected\",5,0); \n\t\t\tconnected = true;\n\t\t\tvar obj = {\"id\":\"init\",\"v\":1};\n\t\t\tgetRequest = JSON.stringify(obj); \t\n\t\t\tws.send(getRequest);\t\t\t// Request ui status from NR\n//\t\t\tconsole.log(\"sent init requeset\");\n\t\t\t\n\t\t$('#container').highcharts(options);\n\t\t\t\n\t\t\t\n\t\t}\n\t\tws.onclose = function() {\n//\t\t\tconsole.log('Node-RED connection closed: '+new Date().toUTCString()); \n\t\t\tconnected = false; \n\t\t\tws = null;\n\t\t\tsetStatus(\"No connection to server!\",0,1);\n\t\t\tif(daiableWidgets==false){disablePage();}\n\t\t\tsetTimeout(wsConn, 10000);\n\t\t}\t\n\t\tws.onerror = function(){\n\t\t\t//console.log(\"connection error\");\n\t\t}\n\t}\n\t$( window ).load(function(){wsConn()});\n//\t wsConn(); \t\t\t\t\t// connect to Node-RED server\n\tfunction init(values){ \t\t// initialise UI controls\n\t\tui = JSON.parse(values);\n\t\t for (var item in ui) {\n\t\t\t//console.log(\"item: \"+item);\n\t\t\tvar m = ui[item];\n\t\t\tinitSetters(m);\n\t\t}\n\t}\n\tfunction initSetters(msg){ \t// update UI widgets on connect \n//\t\tconsole.log(\"init item id:\"+msg.id+\" value:\"+ msg.v);\n\t\tif(ftc==\"tsw\"){setFlip(msg.id,msg.v);}\n\t\tif(ftc==\"sld\"){setSlider(msg.id,msg.v);}\n\t\tif(ftc==\"val\"){setValue(msg.id,msg.v);}\n\t\tif(ftc==\"cha\"){showCharts(msg.id,msg.v)};\n\t\tif(ftc==\"shd\"){setSchedule(msg.v);}\n\t\tif(ftc==\"sta\"){setStatus(msg.v);}\n\t}\n\tfunction setFlip(_id,_v){ \t// update flip \n\t\tmyselect = $(\"#\"+_id);\n\t\t//console.log(\"flip id:\"+_id+\" value:\"+_v+\" tyepof:\"+ typeof _v +\" state:\"+.data('state')+\" req:\"+myselect.data('req'));\n\t\t//if(myselect.data('req')==1) return; // request on progress stops flip UI chatter \n\t\tif(myselect.data('state')!=_v){\n\t\t\tif(_v== true || _v=='true'){\n\t\t\t\tmyselect[0].selectedIndex=1; \n\t\t\t\tmyselect.data('state',1)\n\t\t\t} \n\t\t\telse { \n\t\t\t\tmyselect[0].selectedIndex=0;\n\t\t\t\tmyselect.data('state',0);\n\t\t\t}\n\t\t\tmyselect.flipswitch(\"refresh\");\n\t\t\t//myselect.stopImmediatePropagation();\n\t\t\t//console.log(\"jq:\"+myselect[0].selectedIndex+\" flip id:\"+_id+\" v:\"+value+\" data-state:\"+myselect.data('state'));\n\t\t}\n\t}\n\tfunction setSlider(_id,_v){\t// update slider\n\t\tmyselect = $(\"#\"+_id);\n\t\t myselect.val(_v);\n\t\t myselect.slider('refresh');\n\t}\n\tfunction setValue(_id,_v){\t// update value display\n\t\tmyselect = $(\"#\"+_id);\n\t\tmyselect.val(_v);\n\t}\n\tfunction showCharts(_id,_v){ // render chart\n\t\tif(_id == \"chart-1\"){\n\t\t\tsmokerTempAct = _v;\n\t\t}else if(_id == \"chart-2\"){\n\t\t\tmeatTempAct = _v;\n\t\t}\n\t\t\t\n \n\t}\n\tfunction setSchedule(_v){\t// update schedule \n\t\t//console.log(\"shed:\"+_v);\n\t\tschedule = JSON.parse(_v);\n//\t\tconsole.log(\"shed:\"+schedule.items[0].id);\n\t}\n\tfunction setStatus(msg,dur,pri){\t // show msg on status bar\n\t\tif(statusMsg == true){return};\n\t\tstatusMsg= true;\n\t\tif(pri>0){\n\t\t\t//msg = \"<span class='alert'>\"+msg+\"</span>\";\n\t\t\t$(\"#statusView\").toggleClass(\"statusViewAlert\");\n\t\t} else {\n\t\t\t$(\"#statusView\").toggleClass(\"statusView\");\n\t\t}\n\t\t$(\"#statusView\").show();\n\t\t$(\"#statusView\").html(msg);\n\t\tdur = dur*1000;\n\t\tif(dur >0){\n\t\t\tsetTimeout(function(){$(\"#statusView\").hide(200);$(\"#statusView\").html(\"\"); statusMsg= false},dur)\n\t\t}\n\t}\t\n\tfunction disablePage(){\t\t\n\t\t$(\"[data-role=flipswitch]\").flipswitch( \"disable\" );\n\t\t//$(\"[data-role=range]\").disabled = true;\n\t\t$(\"[data-role=range]\").slider( \"option\", \"disabled\", true );\n\t\t$(\"[data-rel=popup]\").toggleClass(\"ui-disabled\");\n\t\tdaiableWidgets = true;\n\t}\n\tfunction enablePage(){\n\t\t$(\"[data-role=flipswitch]\").flipswitch( \"enable\" );\n\t\t$(\"[data-role=range]\").slider( \"option\", \"enabled\", true );\n\t\t$(\"[data-role=range]\").slider( \"enable\" );\n\t\t$(\"[data-rel=popup]\").toggleClass(\"ui-disabled\");\n\t\tdaiableWidgets = false;\n\t}\n\t$(function() { \t\t\t\t// UI event handlers \n\t\t// Flip-switch change\n\t\t$(\"[data-role=flipswitch]\").bind( \"change\", function(event, ui) {\n\t\t\t//console.log(\"id:\"+this.id+\" val:\"+$(this).flipswitch().val()+\" state:\"+$(this).data('state')+\" req:\"+$(this).data('reqstate'));\n\t\t\tvar _value = $(this).flipswitch().val();\n\t\t\tif($(this).data('state') != _value){\n\t\t\t\t$(this).data('state',_value); \n\t\t\t\tvar obj = {\"id\":\"\"+this.id+\"\",\"v\":_value};\n\t\t\t\tsetActions = JSON.stringify(obj); \t\n\t\t\t\tws.send(setActions);\n\t\t\t}\n\t\t});\n\t\t// Slider end\n\t\t$(\".ui-slider\").bind( \"slidestop\", function(event, ui) {\n\t\t\tvar obj = {\"id\":\"\"+event.target.id+\"\",\"v\":event.target.value};\n\t\t\tsetActions = JSON.stringify(obj); \t\n\t\t\tws.send(setActions);\n\t\t});\n\t\t// Popup send\n\t\t$(\"[data-ui-type=pop-save]\").bind( \"click\", function(event, ui) {\n\t\t\tbid = this.id.split(\"_\");\n\t\t\twid =\"#\"+bid[0]+\"-pop\";\n\t\t\t$(wid ).popup( \"close\" );\n\t\t\ttid=\"#\"+bid[0];\n\t\t\tvar obj = {\"id\":\"\"+bid[0]+\"\",\"v\":$(tid ).val()};\n\t\t\tsetActions = JSON.stringify(obj); \t\n\t\t\tws.send(setActions);\n\t\t});\n\t\t// Grouped Radio buttons click\n\t\t$(\"[data-ui-type=shd-sel]\").bind( \"click\", function(event, ui) {\n\t\t\t$(\"[data-ui-type=shd-sel]\").prop( \"checked\", false ).checkboxradio( \"refresh\" );\n\t\t\t$(this ).prop( \"checked\", true ).checkboxradio( \"refresh\" );\n\t\t\tvar item = this.id.split(\"-\");\n\t\t\tif( itemLookup == null){\n\t\t\t\t itemLookup = item[1]-1;\n\t\t\t } else { // Copy item edits back obj\n\t\t\t\tschedule.items[itemLookup].tag\t\t = $('#shd-tag').val();\n\t\t\t\tschedule.items[itemLookup].startTime = $('#shd-st').val();\n\t\t\t\tschedule.items[itemLookup].startValue = $('#shd-st-v').val();\n\t\t\t\tschedule.items[itemLookup].endTime\t = $('#shd-et').val();\n\t\t\t\tschedule.items[itemLookup].endValue\t = $('#shd-et-v').val();\n\t\t\t\tfor (dow = 0; dow< 7; dow++) {\n\t\t\t\t\tvar dowUI = '#shd-dow-'+dow;\n\t\t\t\t\tif( $(dowUI).prop( \"checked\")){\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 1 ;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 0 ;\n\t\t\t\t\t}\n\t\t\t\t} \n\t\t\t\titemLookup = item[1]-1;\n\t\t\t }\n//\t\t\tconsole.log(\"shed item\"+item[1]+\" lookup tag:\"+schedule.items[itemLookup].tag);\n\t\t\t$('#shd-tag').val(schedule.items[itemLookup].tag);\n\t\t\t$('#shd-st').val(schedule.items[itemLookup].startTime);\n\t\t\t$('#shd-st-v').val(schedule.items[itemLookup].startValue);\n\t\t\t$('#shd-et').val(schedule.items[itemLookup].endTime);\n\t\t\t$('#shd-et-v').val(schedule.items[itemLookup].endValue);\n\t\t\t//console.log(\"group radio - id:\"+ this.id+\" val:\"+$(this).val());\n\t\t\tfor (dow = 0; dow< 7; dow++) {\n\t\t\t\tvar dowUI = '#shd-dow-'+dow;\n\t\t\t\tif (schedule.items[itemLookup].dofWeek[dow]==1){\n\t\t\t\t\t$(dowUI).prop( \"checked\", true ).checkboxradio( \"refresh\" )\n\t\t\t\t} else {\n\t\t\t\t\t$(dowUI).prop( \"checked\", false ).checkboxradio( \"refresh\" )\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t// Schedule save\n\t\t$( \"#shd-save\" ).bind( \"click\", function(event, ui) {\n//\t\t\tconsole.log(\"shd-save\");\n\t\t\tif( itemLookup != null){\n\t\t\t\tschedule.items[itemLookup].tag\t\t = $('#shd-tag').val();\n\t\t\t\tschedule.items[itemLookup].startTime = $('#shd-st').val();\n\t\t\t\tschedule.items[itemLookup].startValue = $('#shd-st-v').val();\n\t\t\t\tschedule.items[itemLookup].endTime\t = $('#shd-et').val();\n\t\t\t\tschedule.items[itemLookup].endValue\t = $('#shd-et-v').val();\n\t\t\t\tfor (dow = 0; dow< 7; dow++) {\n\t\t\t\t\tvar dowUI = '#shd-dow-'+dow;\n\t\t\t\t\tif( $(dowUI).prop( \"checked\")){\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 1 ;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 0 ;\n\t\t\t\t\t}\n\t\t\t\t} \n\t\t\t\tvar obj = {\"id\":\"shd-save\",\"v\":schedule};\n\t\t\t\tgetRequest = JSON.stringify(obj); \t\n\t\t\t\tws.send(getRequest);\n\t\t\t}\n\t\t});\n\t\t// Utills\n\t\tvar showHide=0;\n\t\t$(window).keydown(function(event) {\n\t\t\tif(event.shiftKey && event.keyCode == 68 ) { \n\t\t\t\t//console.log(event.keyCode);\n\t\t\t\tif(showHide==0){$(\"#foo\").show('slow');showHide=1;}else{$(\"#foo\").hide();showHide=0;}\n\t\t\t\tevent.preventDefault(); \n\t\t\t}\n\t\t}); \n\t\t$( document ).on( \"vclick\", \"#b1\", function() {\n\t\t\tlocation.reload();\n//\t\t\tconsole.log(\"reload button\");\n\t\t});\t\n\t});\n </script>\n <style>\n\t\t@media only screen and (min-width: 521px){\n\t\t\t#header1 {width: 507px !important; margin:auto auto !important; position: relative !important; border:1px solid #cccccc;}\n\t\t\t#c1 {width: 475px !important; min-height:500px !important; margin:auto auto !important; position: relative !important; border:1px solid #cccccc;}\n\t\t}\t\n\t\t.alert {font-weight: bold; color: #FF6C01;}\n\t\t.smallin .ui-input-text {width: 200px !important; color:red;}\n\t\tlegend.h1lb {padding:10px 0 5px 0;}\n\t\t.statusView {width: 100% !important; margin:0px; position: relative !important; height:28px; padding:10px 0 0 0; background-color:#FAFAFA; font-weight:bold; -webkit-border-radius: 0.7em !important; border-radius: 0.7em; display:none; text-align:center; }\n\t\t.statusViewAlert {width: 100% !important; margin:0px; position: relative !important; height:28px; padding:10px 0 0 0; background-color:#F8B584 !important; font-weight:bold; -webkit-border-radius: 0.7em !important; border-radius: 0.7em; display:none; text-align:center; }\n\t\t.ui-flipswitch {\"border-radius: 2em !important; -webkit-border-radius: 2em !important; -moz-border-radius: 2em !important;}\n\t\t/* Active button */\n\t\t.ui-page-theme-a .ui-btn.ui-btn-active,html .ui-bar-a .ui-btn.ui-btn-active,html .ui-body-a .ui-btn.ui-btn-active,html body .ui-group-theme-a .ui-btn.ui-btn-active,html head + body .ui-btn.ui-btn-a.ui-btn-active,\n\t\t/* Active checkbox icon */\n\t\t.ui-page-theme-a .ui-checkbox-on:after,html .ui-bar-a .ui-checkbox-on:after,html .ui-body-a .ui-checkbox-on:after,html body .ui-group-theme-a .ui-checkbox-on:after,.ui-btn.ui-checkbox-on.ui-btn-a:after,\n\t\t/* Active flipswitch background */.ui-page-theme-a .ui-flipswitch-active,html .ui-bar-a .ui-flipswitch-active,html .ui-body-a .ui-flipswitch-active,html body .ui-group-theme-a .ui-flipswitch-active,\n\t\thtml body .ui-flipswitch.ui-bar-a.ui-flipswitch-active,\n\t\t/* Active slider track */\n\t\t.ui-page-theme-a .ui-slider-track .ui-btn-active,html .ui-bar-a .ui-slider-track .ui-btn-active,html .ui-body-a .ui-slider-track .ui-btn-active,html body .ui-group-theme-a .ui-slider-track .ui-btn-active,html body div.ui-slider-track.ui-body-a .ui-btn-active {\n\t\t\tbackground-color: \t\t#2A2A2A !important;\n\t\t\tborder-color:\t \t\t#FF6C01 !important;\n\t\t\tcolor: \t\t\t\t\t#fff /*{a-active-color}*/;\n\t\t\ttext-shadow: 0 /*{a-active-shadow-x}*/ 1px /*{a-active-shadow-y}*/ 0 /*{a-active-shadow-radius}*/ #005599 /*{a-active-shadow-color}*/;\n\t\t}\n </style>\n</head>\n<body bgcolor=\"#2A2A2A\">\n <!-- Home -->\n <div data-role=\"page\" id=\"controls-charts\">\n\t<div id=\"c1\" class=\"ui-content\">\n\t<div id=\"statusView\" style=\"\"></div>\t\n\t\t<div class=\"ui-field-contain\">\n\t\t\t<label for=\"tsw-1\">Smoker State:</label>\n\t\t\t<select id=\"tsw-1\" data-role=\"flipswitch\" data-state=\"0\" data-req=\"\">\n\t\t\t <option value=\"0\">Off</option>\n\t\t\t <option value=\"1\">On</option>\n\t\t\t</select>\n\t\t\t</div>\n\t\t\t<div class=\"ui-field-contain\">\n\t\t\t<form>\n \t\t\t<label for=\"sld-1\">Smoker Setpoint (F):</label>\n \t\t\t<input type=\"range\" name=\"sld-1\" id=\"sld-1\" min=\"100\" max=\"350\" value=\"225\">\n \t\t</form>\n\t\t\t</div>\n\t\t\t<div class=\"ui-field-contain\">\n\t\t\t<form>\n \t\t\t \t<label for=\"sld-2\">Meat Done Temperature (F):</label>\n \t\t\t \t<input type=\"range\" name=\"sld-2\" id=\"sld-2\" min=\"100\" max=\"350\" value=\"190\">\n \t\t\t</form>\n\t\t</div>\n\t\t<div id=\"container\" style=\"width: 100%; ;\"></div>\n\t\t</div>\n\t\t\t\t\n\t</div><!-- eof content -->\n </body>\n</html>","x":451,"y":81,"z":"6fb59101.904a7","wires":[["5cc132d3.a33ecc"]]},{"id":"5cc132d3.a33ecc","type":"http response","name":"http response: Control Interface","x":737,"y":106,"z":"6fb59101.904a7","wires":[]},{"id":"b1b3bc12.4e4c4","type":"function","name":"ui dispatcher","func":"/* \tUI dispatcher v0.1a 23/06/2014\n\tRecives changes from UI and actions them */\nvar obj = JSON.parse(msg.payload);\ndelete msg.payload;\ndelete msg._session;\n\n// toggle switch tsw-1\t- output 1 \nif(obj.id==\"tsw-1\"){\n\tmsg.id = obj.id; \t\n\tmsg.state = obj.v;\t\n\treturn [msg, null, null, null];\n\n// toggle switch tsw-2\t- output 2 \n} else if(obj.id==\"tsw-2\"){\n\tmsg.id = obj.id; \t\t\n\tmsg.state = obj.v;\t\n\treturn [null, msg, null];\n\t\n// slider sld-1 \t\t- output 3 \t\n} else if(obj.id==\"sld-1\"){\n\tmsg.id = obj.id; \n\tmsg.value = obj.v;\t\n\treturn [null, null, msg, null];\n\n// txt popup txt-1 \t\t- output 4 \t\n} else if(obj.id==\"sld-2\"){\n\tmsg.id = obj.id; \n\tmsg.value = obj.v;\t\n\treturn [null, null, null, msg];\n\n// do nothing\n} else {\n\treturn [null, null, null, null];\n}","outputs":"4","x":398,"y":384,"z":"6fb59101.904a7","wires":[["e6cf752c.193088","531e2139.ace1e"],[],["5ae130f6.a51ed","531e2139.ace1e"],["7229fba2.8dd604","531e2139.ace1e"]]},{"id":"13af600d.ec50a","type":"comment","name":"Dispatch mobi UI commands - web sockets","info":"","x":244.9999942779541,"y":328.9999899864197,"z":"6fb59101.904a7","wires":[]},{"id":"2fdb1f6c.d024e","type":"websocket in","name":"web socket mobiUI - in","server":"c66445d5.585f48","x":185.9999942779541,"y":383.99998235702515,"z":"6fb59101.904a7","wires":[["b1b3bc12.4e4c4","4474dc21.bb8b24"]]},{"id":"e6cf752c.193088","type":"function","name":"Format state slider","func":"if(msg.id == \"tsw-1\"){\n\tmsg.payload = msg.state.toString();\n\treturn msg;\n}\nreturn null;\n","outputs":1,"x":598.888916015625,"y":326.4444274902344,"z":"6fb59101.904a7","wires":[["bfdce141.40232","fdb92c8e.0246d"]]},{"id":"5ae130f6.a51ed","type":"function","name":"Format Smoker Slider","func":"msg.payload = msg.value.toString();\nreturn msg;","outputs":1,"x":606.4444580078125,"y":389.22222900390625,"z":"6fb59101.904a7","wires":[["d630819b.29cf8","fdb92c8e.0246d"]]},{"id":"de0cac56.21f35","type":"websocket out","name":"web socket mobiUI - in","server":"c66445d5.585f48","x":625,"y":530,"z":"6fb59101.904a7","wires":[]},{"id":"da42a1b8.25bd6","type":"inject","name":"","topic":"","payload":"0","payloadType":"string","repeat":"","crontab":"","once":false,"x":189,"y":511,"z":"6fb59101.904a7","wires":[["5e418315.a1be7c"]]},{"id":"5e418315.a1be7c","type":"function","name":"","func":"msg.payload = {id:\"tsw-1\",v:parseInt(msg.payload)};\nreturn msg;","outputs":1,"x":360,"y":516,"z":"6fb59101.904a7","wires":[["de0cac56.21f35"]]},{"id":"832107a6.7cdef8","type":"inject","name":"","topic":"","payload":"1","payloadType":"string","repeat":"","crontab":"","once":false,"x":190,"y":545,"z":"6fb59101.904a7","wires":[["5e418315.a1be7c"]]},{"id":"e939184.f16c6e8","type":"function","name":"","func":"msg.payload = {id:\"sld-1\",v:msg.payload}\nreturn msg;","outputs":1,"x":356,"y":595,"z":"6fb59101.904a7","wires":[[]]},{"id":"6f43f374.90bc0c","type":"inject","name":"","topic":"","payload":"120","payloadType":"string","repeat":"","crontab":"","once":false,"x":187,"y":619,"z":"6fb59101.904a7","wires":[["e939184.f16c6e8"]]},{"id":"e7881b62.1877e8","type":"mqtt in","name":"","topic":"LpSmokerTempAct","broker":"e4924113.e3d978","x":192,"y":747,"z":"6fb59101.904a7","wires":[["47016916.b8fe98"]]},{"id":"47016916.b8fe98","type":"function","name":"","func":"msg.payload = {id:\"chart-1\",v:parseInt(msg.payload)}\nreturn msg;","outputs":1,"x":363,"y":748,"z":"6fb59101.904a7","wires":[["de0cac56.21f35"]]},{"id":"644d8c90.9bb274","type":"function","name":"","func":"msg.payload = {id:\"chart-2\",v:parseInt(msg.payload)}\nreturn msg;","outputs":1,"x":364,"y":790,"z":"6fb59101.904a7","wires":[["de0cac56.21f35"]]},{"id":"7059f7d9.8fa608","type":"mqtt in","name":"","topic":"LpMeatTempAct","broker":"e4924113.e3d978","x":184,"y":784,"z":"6fb59101.904a7","wires":[["644d8c90.9bb274"]]},{"id":"7229fba2.8dd604","type":"function","name":"Format Meat Slider","func":"msg.payload = msg.value.toString();\nreturn msg;","outputs":1,"x":600,"y":439,"z":"6fb59101.904a7","wires":[["adaed7a4.525128","fdb92c8e.0246d"]]},{"id":"bfdce141.40232","type":"mqtt out","name":"","topic":"LpSmokerStateOut","qos":"","retain":"","broker":"e4924113.e3d978","x":856,"y":326,"z":"6fb59101.904a7","wires":[]},{"id":"d630819b.29cf8","type":"mqtt out","name":"","topic":"LpSmokerSetOut","qos":"","retain":"","broker":"e4924113.e3d978","x":850,"y":389,"z":"6fb59101.904a7","wires":[]},{"id":"adaed7a4.525128","type":"mqtt out","name":"","topic":"LpMeatSetOut","qos":"","retain":"","broker":"e4924113.e3d978","x":842,"y":439,"z":"6fb59101.904a7","wires":[]},{"id":"4ca6fb60.b35904","type":"mqtt in","name":"","topic":"LpSmokerStateIn","broker":"e4924113.e3d978","x":180,"y":471,"z":"6fb59101.904a7","wires":[["597cc969.a68338","5e418315.a1be7c"]]},{"id":"45539404.baac6c","type":"mqtt in","name":"","topic":"LpSmokerSetIn","broker":"e4924113.e3d978","x":173,"y":580,"z":"6fb59101.904a7","wires":[["e939184.f16c6e8"]]},{"id":"5ed28371.a12d7c","type":"mqtt in","name":"","topic":"LpMeatSetIn","broker":"e4924113.e3d978","x":173,"y":655,"z":"6fb59101.904a7","wires":[["b996cebd.46693"]]},{"id":"3ee6ccd8.c11934","type":"inject","name":"","topic":"","payload":"150","payloadType":"string","repeat":"","crontab":"","once":false,"x":182,"y":691,"z":"6fb59101.904a7","wires":[["b996cebd.46693"]]},{"id":"b996cebd.46693","type":"function","name":"","func":"msg.payload = {id:\"sld-2\",v:msg.payload}\nreturn msg;","outputs":1,"x":360,"y":668,"z":"6fb59101.904a7","wires":[[]]},{"id":"b2b8212.f4d47e","type":"inject","name":"","topic":"","payload":"120","payloadType":"string","repeat":"","crontab":"","once":false,"x":177,"y":844,"z":"6fb59101.904a7","wires":[["47016916.b8fe98"]]},{"id":"9f5aea11.60a518","type":"inject","name":"","topic":"","payload":"130","payloadType":"string","repeat":"","crontab":"","once":false,"x":193,"y":891,"z":"6fb59101.904a7","wires":[["644d8c90.9bb274"]]},{"id":"4474dc21.bb8b24","type":"debug","name":"","active":false,"console":"false","complete":"false","x":389,"y":277,"z":"6fb59101.904a7","wires":[]},{"id":"531e2139.ace1e","type":"debug","name":"","active":false,"console":"false","complete":"false","x":580,"y":268,"z":"6fb59101.904a7","wires":[]},{"id":"fdb92c8e.0246d","type":"debug","name":"","active":false,"console":"false","complete":"false","x":903,"y":220,"z":"6fb59101.904a7","wires":[]},{"id":"b25b38fc.4da4c8","type":"inject","name":"","topic":"","payload":"1","payloadType":"string","repeat":"","crontab":"","once":false,"x":660,"y":202,"z":"6fb59101.904a7","wires":[["bfdce141.40232","fdb92c8e.0246d"]]},{"id":"597cc969.a68338","type":"debug","name":"","active":true,"console":"false","complete":"false","x":382,"y":471,"z":"6fb59101.904a7","wires":[]}]
  10. Like
    TI_Trey got a reaction from bluehash in IoT Smoker   
    Hey folks!
     
    I took the electronics I used for my Sous Vide controller and repurposed them for a smoker.  I also completely redid the software to come up with a much better user interface.  You can read the story about it on the TI site here:
    http://e2e.ti.com/group/launchyourdesign/b/blog/archive/2015/03/09/yeee-hawww-launchpad-ropes-rodeo-bbq
     
    The Energia source code is here:
    wifi_smoker.ino
     
    I tried to upload the Node-RED flow as a JSON, but the forums won't let me.  Hence you get plain text you can copy and paste:
    [{"id":"e4924113.e3d978","type":"mqtt-broker","broker":"198.41.30.241","port":"1883","clientid":""},{"id":"c66445d5.585f48","type":"websocket-listener","path":"/ws/mobiui","wholemsg":"false"},{"id":"c8ba3187.3745d","type":"http in","name":"http request: control","url":"/control","method":"get","x":178,"y":90,"z":"6fb59101.904a7","wires":[["413cc48.fbec33c"]]},{"id":"413cc48.fbec33c","type":"template","name":"chart","field":"payload","template":"<!DOCTYPE HTML>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <meta HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /> \n <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n <title>Node-RED mobi ui</title>\n <link rel=\"stylesheet\" href=\"//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.css\" />\n <script src=\"//code.jquery.com/jquery-1.11.1.min.js\"></script>\n <script src=\"//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.js\"></script>\n <script src=\"//cdnjs.cloudflare.com/ajax/libs/highcharts/4.0.3/highcharts.js\"></script>\n <script>//Node-Red mobi ui - LHG industrialinternet.co.uk\n//\tconsole.log(\"NR mobi UI 1.0: Controls, Chart\");\n\tvar schedule = null;\n\tvar itemLookup = null;\n\tvar statusMsg = false;\n\tvar daiableWidgets = false; \n\tvar connected = false;\n\tvar wsUri=\"wss://\"+window.location.hostname+\"/ws/mobiui\";\n\tvar ws=null;\n\tvar smokerTempAct=69;\n\tvar meatTempAct=69;\n\t\n\t var options = {\n chart: {\n type: 'spline',\n animation: Highcharts.svg, // don't animate in old IE\n events: {\n load: function () {\n\n // set up the updating of the chart each second\n var series0 = this.series[0];\n setInterval(function () {\n var x = (new Date()).getTime(), // current time\n y = smokerTempAct;\n series0.addPoint([x, y], true, true);\n }, 15000);\n var series1 = this.series[1];\n setInterval(function () {\n var x = (new Date()).getTime(), // current time\n y = meatTempAct;\n series1.addPoint([x, y], true, true);\n }, 15000);\n }\n }\n\n },\n title: {\n text: 'Current Smoker Temperature'\n },\n xAxis: {\n type: 'datetime',\n tickPixelInterval: 1500\n },\n yAxis: {\n title: {\n text: 'Temperature (F)'\n },\n plotLines: [{\n value: 0,\n width: 1,\n color: '#808080'\n }]\n },\n tooltip: {\n formatter: function () {\n return '<b>' + this.series.name + '</b><br/>' +\n Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +\n Highcharts.numberFormat(this.y, 2);\n }\n },\n legend: {\n enabled: true\n },\n exporting: {\n enabled: false\n },\n series: [{\n name: 'Smoker Temperature',\n data: (function () {\n // generate an array of random data\n var data = [],\n time = (new Date()).getTime(),\n i;\n\n for (i = -19; i <= 0; i += 1) {\n data.push({\n x: time + i * 1000,\n y: Math.random()\n });\n }\n return data;\n }())\n },{\n name: 'Meat Temperature',\n data: (function () {\n // generate an array of random data\n var data = [],\n time = (new Date()).getTime(),\n i;\n\n for (i = -19; i <= 0; i += 1) {\n data.push({\n x: time + i * 1000,\n y: Math.random()\n });\n }\n return data;\n }())\n }]\n };\n\n\n\t\n\tfunction wsConn() {\n\t\tws = new WebSocket(wsUri);\n\t\tws.onmessage = function(m) {\n//\t\t\tconsole.log('< from-node-red:',m.data);\n\t\t\tif (typeof(m.data) === \"string\" && m. data !== null){\n\t\t\t\tvar msg =JSON.parse(m.data);\n\t\t\t\tvar ftc = msg.id.substring(0, 3);\n\t\t\t\t//console.log(\"id:\"+msg.id+\" fct:\"+ftc);\n\t\t\t\tif(ftc== \"init\") {init( msg.v);}\n\t\t\t\tif(ftc==\"tsw\"){setFlip(msg.id,msg.v);}\n\t\t\t\tif(ftc==\"sld\"){setSlider(msg.id,msg.v);}\n\t\t\t\tif(ftc==\"val\"){setValue(msg.id,msg.v);}\n\t\t\t\t//if(ftc==\"cha\"){showCharts( msg.v.values,msg.v.colors,msg.v.engs,msg.v.tags,msg.v.names,msg.v.nos,msg.v.title,.msg.v.yTitle)};\n\t\t\t\tif(ftc==\"cha\"){showCharts(msg.id,msg.v)};\n\t\t\t\tif(ftc==\"shd\"){setSchedule(msg.v);}\n\t\t\t\tif(ftc==\"sta\"){setStatus(msg.v.stMsg,msg.v.dur,msg.v.pri);}\n\t\t\t\tif(ftc==\"ack\"){clearReq();}\n\t\t\t}\n\t\t}\n\t\tws.onopen = function() { \n\t\t\tstatusMsg=false;\n\t\t\tif(daiableWidgets==true){enablePage();}\n\t\t\tsetStatus(\"Connected\",5,0); \n\t\t\tconnected = true;\n\t\t\tvar obj = {\"id\":\"init\",\"v\":1};\n\t\t\tgetRequest = JSON.stringify(obj); \t\n\t\t\tws.send(getRequest);\t\t\t// Request ui status from NR\n//\t\t\tconsole.log(\"sent init requeset\");\n\t\t\t\n\t\t$('#container').highcharts(options);\n\t\t\t\n\t\t\t\n\t\t}\n\t\tws.onclose = function() {\n//\t\t\tconsole.log('Node-RED connection closed: '+new Date().toUTCString()); \n\t\t\tconnected = false; \n\t\t\tws = null;\n\t\t\tsetStatus(\"No connection to server!\",0,1);\n\t\t\tif(daiableWidgets==false){disablePage();}\n\t\t\tsetTimeout(wsConn, 10000);\n\t\t}\t\n\t\tws.onerror = function(){\n\t\t\t//console.log(\"connection error\");\n\t\t}\n\t}\n\t$( window ).load(function(){wsConn()});\n//\t wsConn(); \t\t\t\t\t// connect to Node-RED server\n\tfunction init(values){ \t\t// initialise UI controls\n\t\tui = JSON.parse(values);\n\t\t for (var item in ui) {\n\t\t\t//console.log(\"item: \"+item);\n\t\t\tvar m = ui[item];\n\t\t\tinitSetters(m);\n\t\t}\n\t}\n\tfunction initSetters(msg){ \t// update UI widgets on connect \n//\t\tconsole.log(\"init item id:\"+msg.id+\" value:\"+ msg.v);\n\t\tif(ftc==\"tsw\"){setFlip(msg.id,msg.v);}\n\t\tif(ftc==\"sld\"){setSlider(msg.id,msg.v);}\n\t\tif(ftc==\"val\"){setValue(msg.id,msg.v);}\n\t\tif(ftc==\"cha\"){showCharts(msg.id,msg.v)};\n\t\tif(ftc==\"shd\"){setSchedule(msg.v);}\n\t\tif(ftc==\"sta\"){setStatus(msg.v);}\n\t}\n\tfunction setFlip(_id,_v){ \t// update flip \n\t\tmyselect = $(\"#\"+_id);\n\t\t//console.log(\"flip id:\"+_id+\" value:\"+_v+\" tyepof:\"+ typeof _v +\" state:\"+.data('state')+\" req:\"+myselect.data('req'));\n\t\t//if(myselect.data('req')==1) return; // request on progress stops flip UI chatter \n\t\tif(myselect.data('state')!=_v){\n\t\t\tif(_v== true || _v=='true'){\n\t\t\t\tmyselect[0].selectedIndex=1; \n\t\t\t\tmyselect.data('state',1)\n\t\t\t} \n\t\t\telse { \n\t\t\t\tmyselect[0].selectedIndex=0;\n\t\t\t\tmyselect.data('state',0);\n\t\t\t}\n\t\t\tmyselect.flipswitch(\"refresh\");\n\t\t\t//myselect.stopImmediatePropagation();\n\t\t\t//console.log(\"jq:\"+myselect[0].selectedIndex+\" flip id:\"+_id+\" v:\"+value+\" data-state:\"+myselect.data('state'));\n\t\t}\n\t}\n\tfunction setSlider(_id,_v){\t// update slider\n\t\tmyselect = $(\"#\"+_id);\n\t\t myselect.val(_v);\n\t\t myselect.slider('refresh');\n\t}\n\tfunction setValue(_id,_v){\t// update value display\n\t\tmyselect = $(\"#\"+_id);\n\t\tmyselect.val(_v);\n\t}\n\tfunction showCharts(_id,_v){ // render chart\n\t\tif(_id == \"chart-1\"){\n\t\t\tsmokerTempAct = _v;\n\t\t}else if(_id == \"chart-2\"){\n\t\t\tmeatTempAct = _v;\n\t\t}\n\t\t\t\n \n\t}\n\tfunction setSchedule(_v){\t// update schedule \n\t\t//console.log(\"shed:\"+_v);\n\t\tschedule = JSON.parse(_v);\n//\t\tconsole.log(\"shed:\"+schedule.items[0].id);\n\t}\n\tfunction setStatus(msg,dur,pri){\t // show msg on status bar\n\t\tif(statusMsg == true){return};\n\t\tstatusMsg= true;\n\t\tif(pri>0){\n\t\t\t//msg = \"<span class='alert'>\"+msg+\"</span>\";\n\t\t\t$(\"#statusView\").toggleClass(\"statusViewAlert\");\n\t\t} else {\n\t\t\t$(\"#statusView\").toggleClass(\"statusView\");\n\t\t}\n\t\t$(\"#statusView\").show();\n\t\t$(\"#statusView\").html(msg);\n\t\tdur = dur*1000;\n\t\tif(dur >0){\n\t\t\tsetTimeout(function(){$(\"#statusView\").hide(200);$(\"#statusView\").html(\"\"); statusMsg= false},dur)\n\t\t}\n\t}\t\n\tfunction disablePage(){\t\t\n\t\t$(\"[data-role=flipswitch]\").flipswitch( \"disable\" );\n\t\t//$(\"[data-role=range]\").disabled = true;\n\t\t$(\"[data-role=range]\").slider( \"option\", \"disabled\", true );\n\t\t$(\"[data-rel=popup]\").toggleClass(\"ui-disabled\");\n\t\tdaiableWidgets = true;\n\t}\n\tfunction enablePage(){\n\t\t$(\"[data-role=flipswitch]\").flipswitch( \"enable\" );\n\t\t$(\"[data-role=range]\").slider( \"option\", \"enabled\", true );\n\t\t$(\"[data-role=range]\").slider( \"enable\" );\n\t\t$(\"[data-rel=popup]\").toggleClass(\"ui-disabled\");\n\t\tdaiableWidgets = false;\n\t}\n\t$(function() { \t\t\t\t// UI event handlers \n\t\t// Flip-switch change\n\t\t$(\"[data-role=flipswitch]\").bind( \"change\", function(event, ui) {\n\t\t\t//console.log(\"id:\"+this.id+\" val:\"+$(this).flipswitch().val()+\" state:\"+$(this).data('state')+\" req:\"+$(this).data('reqstate'));\n\t\t\tvar _value = $(this).flipswitch().val();\n\t\t\tif($(this).data('state') != _value){\n\t\t\t\t$(this).data('state',_value); \n\t\t\t\tvar obj = {\"id\":\"\"+this.id+\"\",\"v\":_value};\n\t\t\t\tsetActions = JSON.stringify(obj); \t\n\t\t\t\tws.send(setActions);\n\t\t\t}\n\t\t});\n\t\t// Slider end\n\t\t$(\".ui-slider\").bind( \"slidestop\", function(event, ui) {\n\t\t\tvar obj = {\"id\":\"\"+event.target.id+\"\",\"v\":event.target.value};\n\t\t\tsetActions = JSON.stringify(obj); \t\n\t\t\tws.send(setActions);\n\t\t});\n\t\t// Popup send\n\t\t$(\"[data-ui-type=pop-save]\").bind( \"click\", function(event, ui) {\n\t\t\tbid = this.id.split(\"_\");\n\t\t\twid =\"#\"+bid[0]+\"-pop\";\n\t\t\t$(wid ).popup( \"close\" );\n\t\t\ttid=\"#\"+bid[0];\n\t\t\tvar obj = {\"id\":\"\"+bid[0]+\"\",\"v\":$(tid ).val()};\n\t\t\tsetActions = JSON.stringify(obj); \t\n\t\t\tws.send(setActions);\n\t\t});\n\t\t// Grouped Radio buttons click\n\t\t$(\"[data-ui-type=shd-sel]\").bind( \"click\", function(event, ui) {\n\t\t\t$(\"[data-ui-type=shd-sel]\").prop( \"checked\", false ).checkboxradio( \"refresh\" );\n\t\t\t$(this ).prop( \"checked\", true ).checkboxradio( \"refresh\" );\n\t\t\tvar item = this.id.split(\"-\");\n\t\t\tif( itemLookup == null){\n\t\t\t\t itemLookup = item[1]-1;\n\t\t\t } else { // Copy item edits back obj\n\t\t\t\tschedule.items[itemLookup].tag\t\t = $('#shd-tag').val();\n\t\t\t\tschedule.items[itemLookup].startTime = $('#shd-st').val();\n\t\t\t\tschedule.items[itemLookup].startValue = $('#shd-st-v').val();\n\t\t\t\tschedule.items[itemLookup].endTime\t = $('#shd-et').val();\n\t\t\t\tschedule.items[itemLookup].endValue\t = $('#shd-et-v').val();\n\t\t\t\tfor (dow = 0; dow< 7; dow++) {\n\t\t\t\t\tvar dowUI = '#shd-dow-'+dow;\n\t\t\t\t\tif( $(dowUI).prop( \"checked\")){\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 1 ;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 0 ;\n\t\t\t\t\t}\n\t\t\t\t} \n\t\t\t\titemLookup = item[1]-1;\n\t\t\t }\n//\t\t\tconsole.log(\"shed item\"+item[1]+\" lookup tag:\"+schedule.items[itemLookup].tag);\n\t\t\t$('#shd-tag').val(schedule.items[itemLookup].tag);\n\t\t\t$('#shd-st').val(schedule.items[itemLookup].startTime);\n\t\t\t$('#shd-st-v').val(schedule.items[itemLookup].startValue);\n\t\t\t$('#shd-et').val(schedule.items[itemLookup].endTime);\n\t\t\t$('#shd-et-v').val(schedule.items[itemLookup].endValue);\n\t\t\t//console.log(\"group radio - id:\"+ this.id+\" val:\"+$(this).val());\n\t\t\tfor (dow = 0; dow< 7; dow++) {\n\t\t\t\tvar dowUI = '#shd-dow-'+dow;\n\t\t\t\tif (schedule.items[itemLookup].dofWeek[dow]==1){\n\t\t\t\t\t$(dowUI).prop( \"checked\", true ).checkboxradio( \"refresh\" )\n\t\t\t\t} else {\n\t\t\t\t\t$(dowUI).prop( \"checked\", false ).checkboxradio( \"refresh\" )\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t// Schedule save\n\t\t$( \"#shd-save\" ).bind( \"click\", function(event, ui) {\n//\t\t\tconsole.log(\"shd-save\");\n\t\t\tif( itemLookup != null){\n\t\t\t\tschedule.items[itemLookup].tag\t\t = $('#shd-tag').val();\n\t\t\t\tschedule.items[itemLookup].startTime = $('#shd-st').val();\n\t\t\t\tschedule.items[itemLookup].startValue = $('#shd-st-v').val();\n\t\t\t\tschedule.items[itemLookup].endTime\t = $('#shd-et').val();\n\t\t\t\tschedule.items[itemLookup].endValue\t = $('#shd-et-v').val();\n\t\t\t\tfor (dow = 0; dow< 7; dow++) {\n\t\t\t\t\tvar dowUI = '#shd-dow-'+dow;\n\t\t\t\t\tif( $(dowUI).prop( \"checked\")){\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 1 ;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tschedule.items[itemLookup].dofWeek[dow] = 0 ;\n\t\t\t\t\t}\n\t\t\t\t} \n\t\t\t\tvar obj = {\"id\":\"shd-save\",\"v\":schedule};\n\t\t\t\tgetRequest = JSON.stringify(obj); \t\n\t\t\t\tws.send(getRequest);\n\t\t\t}\n\t\t});\n\t\t// Utills\n\t\tvar showHide=0;\n\t\t$(window).keydown(function(event) {\n\t\t\tif(event.shiftKey && event.keyCode == 68 ) { \n\t\t\t\t//console.log(event.keyCode);\n\t\t\t\tif(showHide==0){$(\"#foo\").show('slow');showHide=1;}else{$(\"#foo\").hide();showHide=0;}\n\t\t\t\tevent.preventDefault(); \n\t\t\t}\n\t\t}); \n\t\t$( document ).on( \"vclick\", \"#b1\", function() {\n\t\t\tlocation.reload();\n//\t\t\tconsole.log(\"reload button\");\n\t\t});\t\n\t});\n </script>\n <style>\n\t\t@media only screen and (min-width: 521px){\n\t\t\t#header1 {width: 507px !important; margin:auto auto !important; position: relative !important; border:1px solid #cccccc;}\n\t\t\t#c1 {width: 475px !important; min-height:500px !important; margin:auto auto !important; position: relative !important; border:1px solid #cccccc;}\n\t\t}\t\n\t\t.alert {font-weight: bold; color: #FF6C01;}\n\t\t.smallin .ui-input-text {width: 200px !important; color:red;}\n\t\tlegend.h1lb {padding:10px 0 5px 0;}\n\t\t.statusView {width: 100% !important; margin:0px; position: relative !important; height:28px; padding:10px 0 0 0; background-color:#FAFAFA; font-weight:bold; -webkit-border-radius: 0.7em !important; border-radius: 0.7em; display:none; text-align:center; }\n\t\t.statusViewAlert {width: 100% !important; margin:0px; position: relative !important; height:28px; padding:10px 0 0 0; background-color:#F8B584 !important; font-weight:bold; -webkit-border-radius: 0.7em !important; border-radius: 0.7em; display:none; text-align:center; }\n\t\t.ui-flipswitch {\"border-radius: 2em !important; -webkit-border-radius: 2em !important; -moz-border-radius: 2em !important;}\n\t\t/* Active button */\n\t\t.ui-page-theme-a .ui-btn.ui-btn-active,html .ui-bar-a .ui-btn.ui-btn-active,html .ui-body-a .ui-btn.ui-btn-active,html body .ui-group-theme-a .ui-btn.ui-btn-active,html head + body .ui-btn.ui-btn-a.ui-btn-active,\n\t\t/* Active checkbox icon */\n\t\t.ui-page-theme-a .ui-checkbox-on:after,html .ui-bar-a .ui-checkbox-on:after,html .ui-body-a .ui-checkbox-on:after,html body .ui-group-theme-a .ui-checkbox-on:after,.ui-btn.ui-checkbox-on.ui-btn-a:after,\n\t\t/* Active flipswitch background */.ui-page-theme-a .ui-flipswitch-active,html .ui-bar-a .ui-flipswitch-active,html .ui-body-a .ui-flipswitch-active,html body .ui-group-theme-a .ui-flipswitch-active,\n\t\thtml body .ui-flipswitch.ui-bar-a.ui-flipswitch-active,\n\t\t/* Active slider track */\n\t\t.ui-page-theme-a .ui-slider-track .ui-btn-active,html .ui-bar-a .ui-slider-track .ui-btn-active,html .ui-body-a .ui-slider-track .ui-btn-active,html body .ui-group-theme-a .ui-slider-track .ui-btn-active,html body div.ui-slider-track.ui-body-a .ui-btn-active {\n\t\t\tbackground-color: \t\t#2A2A2A !important;\n\t\t\tborder-color:\t \t\t#FF6C01 !important;\n\t\t\tcolor: \t\t\t\t\t#fff /*{a-active-color}*/;\n\t\t\ttext-shadow: 0 /*{a-active-shadow-x}*/ 1px /*{a-active-shadow-y}*/ 0 /*{a-active-shadow-radius}*/ #005599 /*{a-active-shadow-color}*/;\n\t\t}\n </style>\n</head>\n<body bgcolor=\"#2A2A2A\">\n <!-- Home -->\n <div data-role=\"page\" id=\"controls-charts\">\n\t<div id=\"c1\" class=\"ui-content\">\n\t<div id=\"statusView\" style=\"\"></div>\t\n\t\t<div class=\"ui-field-contain\">\n\t\t\t<label for=\"tsw-1\">Smoker State:</label>\n\t\t\t<select id=\"tsw-1\" data-role=\"flipswitch\" data-state=\"0\" data-req=\"\">\n\t\t\t <option value=\"0\">Off</option>\n\t\t\t <option value=\"1\">On</option>\n\t\t\t</select>\n\t\t\t</div>\n\t\t\t<div class=\"ui-field-contain\">\n\t\t\t<form>\n \t\t\t<label for=\"sld-1\">Smoker Setpoint (F):</label>\n \t\t\t<input type=\"range\" name=\"sld-1\" id=\"sld-1\" min=\"100\" max=\"350\" value=\"225\">\n \t\t</form>\n\t\t\t</div>\n\t\t\t<div class=\"ui-field-contain\">\n\t\t\t<form>\n \t\t\t \t<label for=\"sld-2\">Meat Done Temperature (F):</label>\n \t\t\t \t<input type=\"range\" name=\"sld-2\" id=\"sld-2\" min=\"100\" max=\"350\" value=\"190\">\n \t\t\t</form>\n\t\t</div>\n\t\t<div id=\"container\" style=\"width: 100%; ;\"></div>\n\t\t</div>\n\t\t\t\t\n\t</div><!-- eof content -->\n </body>\n</html>","x":451,"y":81,"z":"6fb59101.904a7","wires":[["5cc132d3.a33ecc"]]},{"id":"5cc132d3.a33ecc","type":"http response","name":"http response: Control Interface","x":737,"y":106,"z":"6fb59101.904a7","wires":[]},{"id":"b1b3bc12.4e4c4","type":"function","name":"ui dispatcher","func":"/* \tUI dispatcher v0.1a 23/06/2014\n\tRecives changes from UI and actions them */\nvar obj = JSON.parse(msg.payload);\ndelete msg.payload;\ndelete msg._session;\n\n// toggle switch tsw-1\t- output 1 \nif(obj.id==\"tsw-1\"){\n\tmsg.id = obj.id; \t\n\tmsg.state = obj.v;\t\n\treturn [msg, null, null, null];\n\n// toggle switch tsw-2\t- output 2 \n} else if(obj.id==\"tsw-2\"){\n\tmsg.id = obj.id; \t\t\n\tmsg.state = obj.v;\t\n\treturn [null, msg, null];\n\t\n// slider sld-1 \t\t- output 3 \t\n} else if(obj.id==\"sld-1\"){\n\tmsg.id = obj.id; \n\tmsg.value = obj.v;\t\n\treturn [null, null, msg, null];\n\n// txt popup txt-1 \t\t- output 4 \t\n} else if(obj.id==\"sld-2\"){\n\tmsg.id = obj.id; \n\tmsg.value = obj.v;\t\n\treturn [null, null, null, msg];\n\n// do nothing\n} else {\n\treturn [null, null, null, null];\n}","outputs":"4","x":398,"y":384,"z":"6fb59101.904a7","wires":[["e6cf752c.193088","531e2139.ace1e"],[],["5ae130f6.a51ed","531e2139.ace1e"],["7229fba2.8dd604","531e2139.ace1e"]]},{"id":"13af600d.ec50a","type":"comment","name":"Dispatch mobi UI commands - web sockets","info":"","x":244.9999942779541,"y":328.9999899864197,"z":"6fb59101.904a7","wires":[]},{"id":"2fdb1f6c.d024e","type":"websocket in","name":"web socket mobiUI - in","server":"c66445d5.585f48","x":185.9999942779541,"y":383.99998235702515,"z":"6fb59101.904a7","wires":[["b1b3bc12.4e4c4","4474dc21.bb8b24"]]},{"id":"e6cf752c.193088","type":"function","name":"Format state slider","func":"if(msg.id == \"tsw-1\"){\n\tmsg.payload = msg.state.toString();\n\treturn msg;\n}\nreturn null;\n","outputs":1,"x":598.888916015625,"y":326.4444274902344,"z":"6fb59101.904a7","wires":[["bfdce141.40232","fdb92c8e.0246d"]]},{"id":"5ae130f6.a51ed","type":"function","name":"Format Smoker Slider","func":"msg.payload = msg.value.toString();\nreturn msg;","outputs":1,"x":606.4444580078125,"y":389.22222900390625,"z":"6fb59101.904a7","wires":[["d630819b.29cf8","fdb92c8e.0246d"]]},{"id":"de0cac56.21f35","type":"websocket out","name":"web socket mobiUI - in","server":"c66445d5.585f48","x":625,"y":530,"z":"6fb59101.904a7","wires":[]},{"id":"da42a1b8.25bd6","type":"inject","name":"","topic":"","payload":"0","payloadType":"string","repeat":"","crontab":"","once":false,"x":189,"y":511,"z":"6fb59101.904a7","wires":[["5e418315.a1be7c"]]},{"id":"5e418315.a1be7c","type":"function","name":"","func":"msg.payload = {id:\"tsw-1\",v:parseInt(msg.payload)};\nreturn msg;","outputs":1,"x":360,"y":516,"z":"6fb59101.904a7","wires":[["de0cac56.21f35"]]},{"id":"832107a6.7cdef8","type":"inject","name":"","topic":"","payload":"1","payloadType":"string","repeat":"","crontab":"","once":false,"x":190,"y":545,"z":"6fb59101.904a7","wires":[["5e418315.a1be7c"]]},{"id":"e939184.f16c6e8","type":"function","name":"","func":"msg.payload = {id:\"sld-1\",v:msg.payload}\nreturn msg;","outputs":1,"x":356,"y":595,"z":"6fb59101.904a7","wires":[[]]},{"id":"6f43f374.90bc0c","type":"inject","name":"","topic":"","payload":"120","payloadType":"string","repeat":"","crontab":"","once":false,"x":187,"y":619,"z":"6fb59101.904a7","wires":[["e939184.f16c6e8"]]},{"id":"e7881b62.1877e8","type":"mqtt in","name":"","topic":"LpSmokerTempAct","broker":"e4924113.e3d978","x":192,"y":747,"z":"6fb59101.904a7","wires":[["47016916.b8fe98"]]},{"id":"47016916.b8fe98","type":"function","name":"","func":"msg.payload = {id:\"chart-1\",v:parseInt(msg.payload)}\nreturn msg;","outputs":1,"x":363,"y":748,"z":"6fb59101.904a7","wires":[["de0cac56.21f35"]]},{"id":"644d8c90.9bb274","type":"function","name":"","func":"msg.payload = {id:\"chart-2\",v:parseInt(msg.payload)}\nreturn msg;","outputs":1,"x":364,"y":790,"z":"6fb59101.904a7","wires":[["de0cac56.21f35"]]},{"id":"7059f7d9.8fa608","type":"mqtt in","name":"","topic":"LpMeatTempAct","broker":"e4924113.e3d978","x":184,"y":784,"z":"6fb59101.904a7","wires":[["644d8c90.9bb274"]]},{"id":"7229fba2.8dd604","type":"function","name":"Format Meat Slider","func":"msg.payload = msg.value.toString();\nreturn msg;","outputs":1,"x":600,"y":439,"z":"6fb59101.904a7","wires":[["adaed7a4.525128","fdb92c8e.0246d"]]},{"id":"bfdce141.40232","type":"mqtt out","name":"","topic":"LpSmokerStateOut","qos":"","retain":"","broker":"e4924113.e3d978","x":856,"y":326,"z":"6fb59101.904a7","wires":[]},{"id":"d630819b.29cf8","type":"mqtt out","name":"","topic":"LpSmokerSetOut","qos":"","retain":"","broker":"e4924113.e3d978","x":850,"y":389,"z":"6fb59101.904a7","wires":[]},{"id":"adaed7a4.525128","type":"mqtt out","name":"","topic":"LpMeatSetOut","qos":"","retain":"","broker":"e4924113.e3d978","x":842,"y":439,"z":"6fb59101.904a7","wires":[]},{"id":"4ca6fb60.b35904","type":"mqtt in","name":"","topic":"LpSmokerStateIn","broker":"e4924113.e3d978","x":180,"y":471,"z":"6fb59101.904a7","wires":[["597cc969.a68338","5e418315.a1be7c"]]},{"id":"45539404.baac6c","type":"mqtt in","name":"","topic":"LpSmokerSetIn","broker":"e4924113.e3d978","x":173,"y":580,"z":"6fb59101.904a7","wires":[["e939184.f16c6e8"]]},{"id":"5ed28371.a12d7c","type":"mqtt in","name":"","topic":"LpMeatSetIn","broker":"e4924113.e3d978","x":173,"y":655,"z":"6fb59101.904a7","wires":[["b996cebd.46693"]]},{"id":"3ee6ccd8.c11934","type":"inject","name":"","topic":"","payload":"150","payloadType":"string","repeat":"","crontab":"","once":false,"x":182,"y":691,"z":"6fb59101.904a7","wires":[["b996cebd.46693"]]},{"id":"b996cebd.46693","type":"function","name":"","func":"msg.payload = {id:\"sld-2\",v:msg.payload}\nreturn msg;","outputs":1,"x":360,"y":668,"z":"6fb59101.904a7","wires":[[]]},{"id":"b2b8212.f4d47e","type":"inject","name":"","topic":"","payload":"120","payloadType":"string","repeat":"","crontab":"","once":false,"x":177,"y":844,"z":"6fb59101.904a7","wires":[["47016916.b8fe98"]]},{"id":"9f5aea11.60a518","type":"inject","name":"","topic":"","payload":"130","payloadType":"string","repeat":"","crontab":"","once":false,"x":193,"y":891,"z":"6fb59101.904a7","wires":[["644d8c90.9bb274"]]},{"id":"4474dc21.bb8b24","type":"debug","name":"","active":false,"console":"false","complete":"false","x":389,"y":277,"z":"6fb59101.904a7","wires":[]},{"id":"531e2139.ace1e","type":"debug","name":"","active":false,"console":"false","complete":"false","x":580,"y":268,"z":"6fb59101.904a7","wires":[]},{"id":"fdb92c8e.0246d","type":"debug","name":"","active":false,"console":"false","complete":"false","x":903,"y":220,"z":"6fb59101.904a7","wires":[]},{"id":"b25b38fc.4da4c8","type":"inject","name":"","topic":"","payload":"1","payloadType":"string","repeat":"","crontab":"","once":false,"x":660,"y":202,"z":"6fb59101.904a7","wires":[["bfdce141.40232","fdb92c8e.0246d"]]},{"id":"597cc969.a68338","type":"debug","name":"","active":true,"console":"false","complete":"false","x":382,"y":471,"z":"6fb59101.904a7","wires":[]}]
  11. Like
    TI_Trey got a reaction from ShamsheerVerma in C2000:Problem with flash memory   
    Shamsheer,
     
    This is due to the boot modes of the device.  When we flash with Energia, we use the serial boot mode to load the program into the device.  When the load completes it automatically starts running the application.  
     
    Pressing the reset button without changing the boot switches will put the board back at the start of the serial boot mode.
     
    Instead, change the switches to UP-UP-DOWN, reset the board and your application should run.  This selects the boot to flash mode (which is where your application is stored).
     
    BR,
    Trey
  12. Like
    TI_Trey got a reaction from spirilis in WiFi Sous Vide Sources   
    Hi 43oh,
     
    Last month I posted the sources for the solid state relay board, and I promised I'd post the source code for the sous vide application.  Well here it is!
    sous_vide.zip
    libraries.zip
     
    You'll also need the standard PID and PID autotune libraries available on your favorite Arduino site.
     
    I just celebrated my birthday and cooked a surf and turf with it.  As you can see, it works pretty well:

     
    Happy Holidays!
  13. Like
    TI_Trey got a reaction from bluehash in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  14. Like
    TI_Trey got a reaction from JonnyBoats in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  15. Like
    TI_Trey got a reaction from roadrunner84 in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  16. Like
    TI_Trey got a reaction from Automate in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  17. Like
    TI_Trey got a reaction from abecedarian in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  18. Like
    TI_Trey got a reaction from greeeg in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  19. Like
    TI_Trey got a reaction from RobG in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  20. Like
    TI_Trey got a reaction from xxx1 in Discrete Solid State Relay BP   
    Hi 43oh!
     
    It seemed like there was some interest in my solid state relay board, so I figured I'd post up the design files.  Because of liability reasons (being high voltage and what not) I can't produce this, but your welcome to get some boards made and solder them yourself.  Be warned, soldering the heat-sinks to the board is VERY DIFFICULT!  You'll need a board pre-heater, hot air, and some good flux.
     

     
    Schematic:
    triac_board.pdf
     
    Design package (in EAGLE 6.5):
    triac_board.zip
     
    Cheers!
     
     
  21. Like
    TI_Trey got a reaction from RobG in How are you using TI tech to create a connected holiday?   
    Hi 43oh!
     
    Its the holiday season and that means its time for holiday hacks!  I recently completed my WiFi connected sous vide (using a MSP430 and CC3100) which I used to cook my Thanksgiving turkey.
     
    I'm curious if anyone else out there has come up with some cool connected holiday projects?  If so, post them (or a link) in this thread.  We're trying to collect the best hacks and write up an article about them!
     
    Here's another view of my LaunchPad Sous Vide Controller for inspiration :-D

     
    Thanks everyone!
  22. Like
    TI_Trey got a reaction from khwatch in Quadcopter BoosterPack   
    Hi 43oh!
     
    Some of you may have seen me over at c2kcentral, but I'm mostly a lurker here.  For a while now, I've been working on developing a low cost quadcopter.  Well that quadcopter is nearly done!  Boards are being manufactured as I type this, and I plan to have it flying at the Bay Area MakerFaire in May.
     
    Here's a picture of the top of the motor driver board:

     
    Personally, I would like to see this manufactured and sold, but before I invest the effort to do that I need to ensure there is a demand for such a board.  The finished quad will be about 1 square foot in size, will cost ~$200, and will be able to carry a small payload (I've got my fingers crossed we'll have enough thrust for a Go Pro).  If you would please take a second to answer the poll as to whether or not you would be interested in purchasing one.
     
    This is all very preliminary, but I appreciate any feedback you may have.
     
    Thanks!
     
    Edit:
    Moving some of the information regarding the setup up here:
     
    4x TMS320F28027F + DRV8312 make up the ESC.  That is the bulk of what is on the board which you can see on the first post.
    1x C2000 LP acts as the brain.  This board decodes the control signals and sends torque commands to each of the ESCs via a PWM signal.  This LaunchPad runs the open source AeroQuad firmware on top of Energia...which also means other LaunchPads could be used as the brain.
    Control Inputs come via a standard RC 2.4GHz radio and receiver.  Because the LaunchPad doesn't have 1 million capture inputs I am using a receiver which supports S.Bus.
    3 axis accelerometer, gyro, magnetometer, barometer and GPS
     
    Update 4/16:
    Got the IMU board in today.  Here's a picture:

     
    Yellow - TC6000GN - CC4000 based GPS
    Red - MPU6000 - 6 axis IMU
    Blue - HMC5983 - 3 axis Mag
    Purple - MS5611 Barometer
     
    Update 4/21:
    Got in a car accident and have been dealing with insurance, so instead of working on this I've been dealing with BS.  Good news is that all that is finally taken care of and the motor boards are here!  These are by far the most complex and visually appealing boards I've even designed.  Take a look:

     
    I'm still waiting on a few structural pieces to arrive which are being water cut.  I expect I'll have them later this week.  I'll post some more pictures once I get the boards assembled.
     
    Update 4/22:
    Motor boards are assembled and basic functionality checks out.  Next checks will include JTAG connectivity, and then motor drive capability.  The design is based off an earlier prototype that was proven out, so I expect everything to work splendidly on this board.

     
     
    If you're not already, follow me on twitter for up to the minute project updates! @yertnamreg1218
     
    Update 4/24:
    The 4 InstaSpin Piccolos are all in a JTAG chain.  Initially I had a little trouble getting CCS to connect, but after a little re-soldering of the ICs JTAG started working.  I now have all 4 device programmed with the motor control software.  I was also able to verify operating on a battery and the serial data link between the receiver and main microcontroller.

     
    Yes, I'm aware my desk is a mess right now. :-P
     
    Update 5/6:
    Lots of work has been going into the AeroQuad firmware I'll be running on the LaunchPad.  The two main contenders for firmware were Arducopter and Aeroquad.  The reason Aeroquad was chosen over Arducopter was their use of the standard Arduino IDE to build their firmware.  Arducopter uses a hacked together one off build system.  Since Energia is based off Arduino, getting the AeroQuad project to build was much easier than Arducopter would have been.  
     
    With that said, I'm happy to announce that today I was able to compile AeroQuad successfully for the C2k LaunchPad in Energia.  This is a huge milestone!

     
    As you can see it didn't link, but that's an easy problem to fix.  With MakerFaire less than 2 week away, the pressure is on!  Will Trey get the quadcopter flying in time or will Murphy raise his evil head and sabotage the project?  Stay tuned to find out!
     
    Update 5/23:
    After my last update I had to really focus on getting the thing done in time for MakerFaire, so I slacked off on project updates.  Sadly, Murphy paid me a visit and threw a few wrenches into my plan.
     
    Problem #1: Everything on the motor drive boards appears to be working as planned with the exception of the current feedback circuitry for the motors.  The old board can spin the motors just fine, but on the new board the current feedback isn't behaving nicely which is causing us problems with the motor control software.  The boards are based on the same schematic, but the original developer changed some of the components in the feedback circuitry.  I have a list of the changes and the new board has incorporated those changes, but still has problems.  I'm unsure if the issue is layout or component related and will be doing some experiments in the coming weeks to determine and fix the cause.
     
    Problem #2: I pulled a special favor to get the structural materials (i.e. frame) for the quadcopter cut on a waterjet.  I kicked this off in early April, but because it was a favor and there were other users of this machine my parts didn't end up getting cut in time.  I'm currently looking for a place in town that can do CNC routing and drilling to get these parts cut.
     
    MakerFaire was still a big success and I was able to talk to a ton of people about LaunchPad, Energia, and the quadcopter.  I even met a few 43oh members while I was there!  I also talked to the creators of the Aeroquad firmware and they are very excited about this project.  Once the C2000 port is more stable I will be merging my changes upstream to the main Aeroquad repository.  
     
    I also talked to them about structural materials for the frame.  The Aeroquad guys use a material called DiBond.  Its a composite aluminum/polyethylene laminate which is less dense than FR4 with comparable material properties.  It is commonly used in signage applications, but also makes for an excellent quadcopter frame.  At MakerFaire the AeroQuad team participated in an event called the "Game of Drones".  This event pitted two quadcopters against eachother in air to air combat.  Take a look at this video showing off some of the fights: 
     

    http://youtu.be/91OCQ-1KP08
     
    After seeing how well they performed in the competition I am considering switching to use DiBond as the structural material in my quadcopter as well.
     
    Update 8/19
    It took me a while to find someone to cut the frame at a reasonable price, but I finally did.  I just received the frame back from the fabricator and it looks great.  I'll still need to tweak the design a bit due to machining tolerances, but that's something that's easily accomplished.  Without further ado, here are the pics:

     

     
    There are some spars that connect the two pieces together that should also be here, but the fabricator was confused and thought they were scrap.  I should be able to fully assembled the quad after I get back the tweaked version of the frame.
     
    I also was lucky enough to be a guest on "The Amp Hour" this week.  Be sure to tune in!  I talk about my experience in college at Rose-Hulman, my first job after college with Simma Software, and I reveal a new job I've accepted at TI!!!!
  23. Like
    TI_Trey reacted to Antscran in C2000 Launchpad Solar MPPT Project and Tutorial   
    Hi All,
     
    Just finished off writing up a tutorial about a project I did earlier this year.  It's a solar maximum power point tracker (MPPT), based on the C2000 Launchpad.  There are some links to the project and tutorial below as well as a few videos on YouTube, all the code is also downloadable.
     

     
    I intend to work on a second iteration at some point with some larger panels, and a battery charging state machine.
     
    http://coder-tronics.com/c2000-solar-mppt-tutorial-pt1/
    http://coder-tronics.com/c2000-solar-mppt-tutorial-pt2/
    http://coder-tronics.com/c2000-solar-mppt-tutorial-pt3/
    http://coder-tronics.com/c2000-solar-mppt-tutorial-pt4/
     
    https://www.youtube.com/watch?v=XJc2RtL-iBk&list=UUUIN5H4aVjwwqXUS39_CEBQ
    https://www.youtube.com/watch?v=AV4J9uGyiKo&list=UUUIN5H4aVjwwqXUS39_CEBQ
     
    Comments welcome on improvements etc.
     
    Cheers,
    Ant
  24. Like
    TI_Trey got a reaction from legailutin in Quadcopter BoosterPack   
    I've been just editing the first post and adding updates there.  I just got back from MakerFaire, and I'm getting caught up.  I'll post a new update later today.
  25. Like
    TI_Trey got a reaction from oPossum in Quadcopter BoosterPack   
    Hi 43oh!
     
    Some of you may have seen me over at c2kcentral, but I'm mostly a lurker here.  For a while now, I've been working on developing a low cost quadcopter.  Well that quadcopter is nearly done!  Boards are being manufactured as I type this, and I plan to have it flying at the Bay Area MakerFaire in May.
     
    Here's a picture of the top of the motor driver board:

     
    Personally, I would like to see this manufactured and sold, but before I invest the effort to do that I need to ensure there is a demand for such a board.  The finished quad will be about 1 square foot in size, will cost ~$200, and will be able to carry a small payload (I've got my fingers crossed we'll have enough thrust for a Go Pro).  If you would please take a second to answer the poll as to whether or not you would be interested in purchasing one.
     
    This is all very preliminary, but I appreciate any feedback you may have.
     
    Thanks!
     
    Edit:
    Moving some of the information regarding the setup up here:
     
    4x TMS320F28027F + DRV8312 make up the ESC.  That is the bulk of what is on the board which you can see on the first post.
    1x C2000 LP acts as the brain.  This board decodes the control signals and sends torque commands to each of the ESCs via a PWM signal.  This LaunchPad runs the open source AeroQuad firmware on top of Energia...which also means other LaunchPads could be used as the brain.
    Control Inputs come via a standard RC 2.4GHz radio and receiver.  Because the LaunchPad doesn't have 1 million capture inputs I am using a receiver which supports S.Bus.
    3 axis accelerometer, gyro, magnetometer, barometer and GPS
     
    Update 4/16:
    Got the IMU board in today.  Here's a picture:

     
    Yellow - TC6000GN - CC4000 based GPS
    Red - MPU6000 - 6 axis IMU
    Blue - HMC5983 - 3 axis Mag
    Purple - MS5611 Barometer
     
    Update 4/21:
    Got in a car accident and have been dealing with insurance, so instead of working on this I've been dealing with BS.  Good news is that all that is finally taken care of and the motor boards are here!  These are by far the most complex and visually appealing boards I've even designed.  Take a look:

     
    I'm still waiting on a few structural pieces to arrive which are being water cut.  I expect I'll have them later this week.  I'll post some more pictures once I get the boards assembled.
     
    Update 4/22:
    Motor boards are assembled and basic functionality checks out.  Next checks will include JTAG connectivity, and then motor drive capability.  The design is based off an earlier prototype that was proven out, so I expect everything to work splendidly on this board.

     
     
    If you're not already, follow me on twitter for up to the minute project updates! @yertnamreg1218
     
    Update 4/24:
    The 4 InstaSpin Piccolos are all in a JTAG chain.  Initially I had a little trouble getting CCS to connect, but after a little re-soldering of the ICs JTAG started working.  I now have all 4 device programmed with the motor control software.  I was also able to verify operating on a battery and the serial data link between the receiver and main microcontroller.

     
    Yes, I'm aware my desk is a mess right now. :-P
     
    Update 5/6:
    Lots of work has been going into the AeroQuad firmware I'll be running on the LaunchPad.  The two main contenders for firmware were Arducopter and Aeroquad.  The reason Aeroquad was chosen over Arducopter was their use of the standard Arduino IDE to build their firmware.  Arducopter uses a hacked together one off build system.  Since Energia is based off Arduino, getting the AeroQuad project to build was much easier than Arducopter would have been.  
     
    With that said, I'm happy to announce that today I was able to compile AeroQuad successfully for the C2k LaunchPad in Energia.  This is a huge milestone!

     
    As you can see it didn't link, but that's an easy problem to fix.  With MakerFaire less than 2 week away, the pressure is on!  Will Trey get the quadcopter flying in time or will Murphy raise his evil head and sabotage the project?  Stay tuned to find out!
     
    Update 5/23:
    After my last update I had to really focus on getting the thing done in time for MakerFaire, so I slacked off on project updates.  Sadly, Murphy paid me a visit and threw a few wrenches into my plan.
     
    Problem #1: Everything on the motor drive boards appears to be working as planned with the exception of the current feedback circuitry for the motors.  The old board can spin the motors just fine, but on the new board the current feedback isn't behaving nicely which is causing us problems with the motor control software.  The boards are based on the same schematic, but the original developer changed some of the components in the feedback circuitry.  I have a list of the changes and the new board has incorporated those changes, but still has problems.  I'm unsure if the issue is layout or component related and will be doing some experiments in the coming weeks to determine and fix the cause.
     
    Problem #2: I pulled a special favor to get the structural materials (i.e. frame) for the quadcopter cut on a waterjet.  I kicked this off in early April, but because it was a favor and there were other users of this machine my parts didn't end up getting cut in time.  I'm currently looking for a place in town that can do CNC routing and drilling to get these parts cut.
     
    MakerFaire was still a big success and I was able to talk to a ton of people about LaunchPad, Energia, and the quadcopter.  I even met a few 43oh members while I was there!  I also talked to the creators of the Aeroquad firmware and they are very excited about this project.  Once the C2000 port is more stable I will be merging my changes upstream to the main Aeroquad repository.  
     
    I also talked to them about structural materials for the frame.  The Aeroquad guys use a material called DiBond.  Its a composite aluminum/polyethylene laminate which is less dense than FR4 with comparable material properties.  It is commonly used in signage applications, but also makes for an excellent quadcopter frame.  At MakerFaire the AeroQuad team participated in an event called the "Game of Drones".  This event pitted two quadcopters against eachother in air to air combat.  Take a look at this video showing off some of the fights: 
     

    http://youtu.be/91OCQ-1KP08
     
    After seeing how well they performed in the competition I am considering switching to use DiBond as the structural material in my quadcopter as well.
     
    Update 8/19
    It took me a while to find someone to cut the frame at a reasonable price, but I finally did.  I just received the frame back from the fabricator and it looks great.  I'll still need to tweak the design a bit due to machining tolerances, but that's something that's easily accomplished.  Without further ado, here are the pics:

     

     
    There are some spars that connect the two pieces together that should also be here, but the fabricator was confused and thought they were scrap.  I should be able to fully assembled the quad after I get back the tweaked version of the frame.
     
    I also was lucky enough to be a guest on "The Amp Hour" this week.  Be sure to tune in!  I talk about my experience in college at Rose-Hulman, my first job after college with Simma Software, and I reveal a new job I've accepted at TI!!!!
×
×
  • Create New...