Introduction: How to Make the EchoLight

The EchoLight is a relatively simple device designed to make the road safer by making people aware when they are speeding. The EchoLight is a Raspberry Pi based device coded in node-red which shines a multi-color LED and sounds an alarm to warn people if they reach dangerous speed. The EchoLight also has SMS capabilities, allowing it to send text message warnings and send summaries of your driving excursions.

Supplies

  1. One (1) Raspberry Pi 3
  2. One (1) Multicolor LED
  3. One (1) Active Alarm Sound Module (for Arduino)
  4. Six (6) Female to Female Wire
  5. One (1) Ethernet Cable
  6. (Optional) Raspberry Pi Protective Case (comes with two (2) Heatsinks)

Step 1: Installation

This project used a variety of different libraries, most of which created new nodes for Node-Red. Some of these installations will need to be done on your computer, while others should be done on your Raspberry Pi.

Computer Installations and Operations:

(Windows) Install PuTTY

(Mac) No Download Necessary

Next, we SSH into the Raspberry Pi. Doing this is different Mac and Windows users, so follow the corresponding links.

First, connect your Raspberry Pi to your WiFi with an Ethernet Cable

(Windows) Connect to Raspberry Pi with PuTTY, then Connect the Raspberry Pi to your WiFi

(Mac) SSH from Terminal Directly, then Connect the Raspberry Pi to your WiFi

Optional for Mac and Windows:

Expand the Root Partition of Raspberry Pi SD card

Installations on Raspberry Pi:

Node-Red

SMS Node - Twilio

Counter Node

Step 2: Wiring

Now that you have all of the necessary downloads completed, its time to connect the LED and alarm to your Raspberry Pi. You can use the image above or the following list to help you connect the correct wires to the correct pins.

Note: These wirings must be exact for the program on the next step to work, though if you want to program it yourself feel free to wire the system differently.

Multicolor LED:

We will only be wiring the red and green parts of the LED, as red will indicate speeding and green will indicate a safe speed, so blue is unnecessary.

Red - Pin 16

Ground - Pin 9

Green - Pin 15

Active Alarm Sound Module:

Though it may be unnecessary, I recommend putting tape or another material over the alarm, as it can be extraordinarily loud and annoying.

VCC - Pin 1

I/O - Pin 11

Ground - Pin 6

Step 3: Adding the Program

Now its time to add the code. SSH into your Raspberry Pi, go into the .node-red file, and start the node-red program. Then, go the the top right button (looks like three stacked lines), click it, click on import > clipboard. Then, paste the following code into the box. This code will activate the alarm, make the light change from green to red as the simulated driver's speed increases (as shown in the images above), and sends text messages when the driver is going too fast and information about the ride when the array is emptied.

[{"id":"412bd4f2.ad4b3c","type":"tab","label":"Main","disabled":false,"info":""},{"id":"e490141d.ad9358","type":"function","z":"412bd4f2.ad4b3c","name":"Speedometer Sim","func":"msg.payload = msg.payload[msg.count];\nreturn msg;","outputs":1,"noerr":0,"x":110,"y":300,"wires":[["b05eed30.7329f","b5ff75ab.1d5718"]]},{"id":"51482e72.24321","type":"inject","z":"412bd4f2.ad4b3c","name":"Speedometer Time","topic":"Time","payload":"","payloadType":"date","repeat":"0.1","crontab":"","once":false,"onceDelay":"5","x":140,"y":140,"wires":[["850493c5.19df7"]]},{"id":"c74f2ce5.6749b","type":"inject","z":"412bd4f2.ad4b3c","name":"speedArray","topic":"","payload":"[0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,9,10,10,10,10,10,11,11,11,11,11,12,12,12,12,12,13,13,13,13,13,14,14,14,14,14,15,15,15,15,15,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,19,19,19,19,19,20,20,20,20,20,21,21,21,21,21,22,22,22,22,22,23,23,23,23,23,24,24,24,24,24,25,25,25,25,25,26,26,26,26,26,27,27,27,27,27,28,28,28,28,28,29,29,29,29,29,30,30,30,30,30,31,31,31,31,31,32,32,32,32,32,33,33,33,33,33,34,34,34,34,34,35,35,35,35,35,36,36,36,36,36,37,37,37,37,37,38,38,38,38,38,39,39,39,39,39,40,40,40,40,40,41,41,41,41,41,42,42,42,42,42,43,43,43,43,43,44,44,44,44,44,45,45,45,45,45,46,46,46,46,46,47,47,47,47,47,48,48,48,48,48,49,49,49,49,49,50,50,50,50,50,51,51,51,51,51,52,52,52,52,52,53,53,53,53,53,54,54,54,54,54,55,55,55,55,55,56,56,56,56,56,57,57,57,57,57,58,58,58,58,58,59,59,59,59,59,60,60,60,60,60,61,61,61,61,61,62,62,62,62,62,63,63,63,63,63,64,64,64,64,64,65,65,65,65,65,66,66,66,66,66,67,67,67,67,67,68,68,68,68,68,69,69,69,69,69,70,70,70,70,70,71,71,71,71,71,72,72,72,72,72,73,73,73,73,73,74,74,74,74,74,75,75,75,75,75,76,76,76,76,76,77,77,77,77,77,78,78,78,78,78,79,79,79,79,79,80,80,80,80,80,80,80,80,81,81,81,81,81,81,81,81,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,83,84,84,84,84,84,84,84,84,85,85,85,85,85,85,85,85,86,86,86,86,86,86,86,86,87,87,87,87,87,87,87,87,88,88,88,88,88,88,88,88,89,89,89,89,89,89,89,89,90,90,90,90,90,90,90,90,91,91,91,91,91,91,91,91,92,92,92,92,92,92,92,92,93,93,93,93,93,93,93,93,94,94,94,94,94,94,94,94,95,95,95,95,95,95,95,95,96,96,96,96,96,96,96,96,97,97,97,97,97,97,97,97,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99,99,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,102,103,103,103,103,103,103,103,103,104,104,104,104,104,104,104,104,80,80,80,80,80,79,79,79,79,79,78,78,78,78,78,77,77,77,77,77,76,76,76,76,76,75,75,75,75,75,74,74,74,74,74,73,73,73,73,73,72,72,72,72,72,71,71,71,71,71,70,70,70,70,70,69,69,69,69,69,68,68,68,68,68,67,67,67,67,67,66,66,66,66,66,65,65,65,65,65,64,64,64,64,64,63,63,63,63,63,62,62,62,62,62,61,61,61,61,61,60,60,60,60,60,59,59,59,59,59,58,58,58,58,58,57,57,57,57,57,56,56,56,56,56,55,55,55,55,55,54,54,54,54,54,53,53,53,53,53,52,52,52,52,52,51,51,51,51,51,50,50,50,50,50,49,49,49,49,49,48,48,48,48,48,47,47,47,47,47,46,46,46,46,46,45,45,45,45,45,44,44,44,44,44,43,43,43,43,43,42,42,42,42,42,41,41,41,41,41,40,40,40,40,40,39,39,39,39,39,38,38,38,38,38,37,37,37,37,37,36,36,36,36,36,35,35,35,35,35,34,34,34,34,34,33,33,33,33,33,32,32,32,32,32,31,31,31,31,31,30,30,30,30,30,29,29,29,29,29,28,28,28,28,28,27,27,27,27,27,26,26,26,26,26,25,25,25,25,25,24,24,24,24,24,23,23,23,23,23,22,22,22,22,22,21,21,21,21,21,20,20,20,20,20,19,19,19,19,19,18,18,18,18,18,17,17,17,17,17,16,16,16,16,16,15,15,15,15,15,14,14,14,14,14,13,13,13,13,13,12,12,12,12,12,11,11,11,11,11,10,10,10,10,10,9,9,9,9,9,8,8,8,8,8,7,7,7,7,7,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1]","payloadType":"json","repeat":"0.1","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":220,"wires":[["e73874e2.974208"]]},{"id":"e73874e2.974208","type":"counter","z":"412bd4f2.ad4b3c","name":"Array Index Counter sped","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":"1","x":130,"y":260,"wires":[["e490141d.ad9358"]]},{"id":"516ef6e2.e20ec8","type":"debug","z":"412bd4f2.ad4b3c","name":"Speed check","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1370,"y":240,"wires":[]},{"id":"7921cb9f.750374","type":"function","z":"412bd4f2.ad4b3c","name":"Average Speed Calculator","func":"var speedArray = flow.get(\"speedArray\");\ntotalAddedSpeed=0\nif (msg.count<1000){\n speedArray.push(msg.payload);\n}\n\nfor (i = 0; i < speedArray.length; i++) {\n totalAddedSpeed += speedArray[i];\n}\n\ncurrentAvgSpeed = Math.round(totalAddedSpeed/i);\n\nflow.set(\"currentAvgSpeed\", currentAvgSpeed);\n\nreturn msg;","outputs":1,"noerr":0,"x":930,"y":320,"wires":[["c1fac611.490d88"]]},{"id":"b05eed30.7329f","type":"function","z":"412bd4f2.ad4b3c","name":"create speed array","func":"if (msg.count === 1) {\n flow.set(\"speedArray\",[]);\n \n}\n\nflow.set(\"currentSpeedCheck\", msg.payload)\n\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":320,"wires":[["c2b03efc.23c42"]]},{"id":"c1fac611.490d88","type":"function","z":"412bd4f2.ad4b3c","name":"Final Formatting","func":"var currentAvgSpeed = flow.get(\"currentAvgSpeed\");\nvar instantaneousAvgSpeed = flow.get(\"instantaneousAvgSpeed\");\n\nvar totalStartTime = flow.get(\"totalStartTime\"); \nvar totalEndTime = flow.get(\"totalEndTime\"); \nvar totalPassedTime = flow.get(\"totalPassedTime\");\n\nvar currentSpeed = msg.payload;\n\nflow.set(\"currentSpeed\", currentSpeed)\n\nmsg.payload = {\n \"\\nTotal Average Speed\" : \" \" + currentAvgSpeed,\n \"\\nShort Term Average Speed\" : \" \" + instantaneousAvgSpeed,\n \"\\nCurrent Speed\" : \" \" + currentSpeed,\n \"\\nStart Time\" : \" \" + totalStartTime,\n \"\\nEnd Time\" : \" \" + totalEndTime,\n \"\\nTime Spent Driving\" : \" \" + totalPassedTime\n};\n\nreturn msg;","outputs":1,"noerr":0,"x":1140,"y":320,"wires":[["516ef6e2.e20ec8","3a47c8a5.8bbe18","c3184744.71c928","df9ddb16.7e6518","b50fd153.5f771"]]},{"id":"b6487b90.228818","type":"function","z":"412bd4f2.ad4b3c","name":"Time Convert/Store","func":"if ( !msg.timestamp ) msg.timestamp = Math.round(+new Date());\n\nvar dt = new Date(msg.timestamp)\nvar month=dt.getMonth() + 1;\nvar day=dt.getDate();\nvar year=dt.getFullYear();\nvar hours=dt.getHours();\nvar mins=dt.getMinutes();\nvar secs=dt.getSeconds();\n\nvar speedArray = flow.get(\"speedArray\")\nif (msg.count+1 === 1000){\n flow.set(\"EndYears\", year)\n flow.set(\"EndMonths\", month)\n flow.set(\"EndDays\", day);\n flow.set(\"EndHours\", hours);\n flow.set(\"EndMinutes\", mins);\n flow.set(\"EndSeconds\", secs);\n \n} else if (msg.count===1) {\n flow.set(\"StartYears\", year)\n flow.set(\"StartMonths\", month)\n flow.set(\"StartDays\", day);\n flow.set(\"StartHours\", hours);\n flow.set(\"StartMinutes\", mins);\n flow.set(\"StartSeconds\", secs);\n \n flow.set(\"EndYears\", 0)\n flow.set(\"EndMonths\", 0)\n flow.set(\"EndDays\", 0);\n flow.set(\"EndHours\", 0);\n flow.set(\"EndMinutes\", 0);\n flow.set(\"EndSeconds\", 0);\n} \n\nflow.set(\"CurrentYears\", year)\nflow.set(\"CurrentMonths\", month)\nflow.set(\"CurrentDays\", day);\nflow.set(\"CurrentHours\", hours);\nflow.set(\"CurrentMinutes\", mins);\nflow.set(\"CurrentSeconds\", secs);\n\n\nreturn msg;","outputs":1,"noerr":0,"x":590,"y":140,"wires":[["8a6bbffc.28076"]]},{"id":"8a6bbffc.28076","type":"function","z":"412bd4f2.ad4b3c","name":"Passed Time Calculate and Store","func":"var startYears = flow.get(\"StartYears\");\nvar startMonths = flow.get(\"StartMonths\");\nvar startDays = flow.get(\"StartDays\");\nvar startHours = flow.get(\"StartHours\");\nvar startMins = flow.get(\"StartMinutes\");\nvar startSecs = flow.get(\"StartSeconds\");\n\nvar currentYears = flow.get(\"CurrentYears\");\nvar currentMonths = flow.get(\"CurrentMonths\");\nvar currentDays = flow.get(\"CurrentDays\");\nvar currentHours = flow.get(\"CurrentHours\");\nvar currentMins = flow.get(\"CurrentMinutes\");\nvar currentSecs = flow.get(\"CurrentSeconds\");\n \nvar passedYears = currentYears-startYears \nvar passedMonths = currentMonths-startMonths \nvar passedDays = currentDays-startDays \nvar passedHours = currentHours-startHours \nvar passedMins = currentMins-startMins \nvar passedSecs = currentSecs-startSecs \n\nif (passedYears < 0){\n alert(\"Year error!\");\n}\nif (passedMonths<0){\n passedMonths += 12\n passedYears-=1\n}\nif (passedDays<0){\n passedDays += 30\n passedMonths -= 1\n}\nif (passedHours<0){\n passedHours += 24\n passedDays-=1\n}\nif(passedMins<0){\n passedMins+=60\n passedHours-=1\n}\nif (passedSecs<0){\n passedSecs+=60\n passedMins-=1\n} \n\nflow.set(\"passedYears\", passedYears)\nflow.set(\"passedMonths\", passedMonths)\nflow.set(\"passedDays\", passedDays);\nflow.set(\"passedHours\", passedHours);\nflow.set(\"passedMins\", passedMins);\nflow.set(\"passedSecs\", passedSecs);\n \n \nreturn msg;","outputs":1,"noerr":0,"x":860,"y":140,"wires":[["ed206da2.1a4f5"]]},{"id":"ed206da2.1a4f5","type":"function","z":"412bd4f2.ad4b3c","name":"Formatting Time","func":"var startYears = flow.get(\"StartYears\");\nvar startMonths = flow.get(\"StartMonths\");\nvar startDays = flow.get(\"StartDays\");\nvar startHours = flow.get(\"StartHours\");\nvar startMins = flow.get(\"StartMinutes\");\nvar startSecs = flow.get(\"StartSeconds\");\n\nvar endYears = flow.get(\"EndYears\");\nvar endMonths = flow.get(\"EndMonths\");\nvar endDays = flow.get(\"EndDays\");\nvar endHours = flow.get(\"EndHours\");\nvar endMins = flow.get(\"EndMinutes\");\nvar endSecs = flow.get(\"EndSeconds\");\n\nvar passedYears = flow.get(\"passedYears\");\nvar passedMonths = flow.get(\"passedMonths\");\nvar passedDays = flow.get(\"passedDays\");\nvar passedHours = flow.get(\"passedHours\");\nvar passedMins = flow.get(\"passedMins\");\nvar passedSecs = flow.get(\"passedSecs\");\n\ntotalStartTime = startHours + \":\" + startMins + \":\" + startSecs + \" | \" + startMonths + \"/\" + startDays + \"/\" + startYears\ntotalEndTime = endHours + \":\" + endMins + \":\" + endSecs + \" | \" + endMonths + \"/\" + endDays + \"/\" + endYears\n\nflow.set(\"totalStartTime\", totalStartTime); \nflow.set(\"totalEndTime\", totalEndTime); \n\npassedMonths+=passedYears*12;\npassedDays+=passedMonths*30;\npassedHours += passedDays*24;\n\ntotalPassedTime = passedHours + \":\" + passedMins + \":\" + passedSecs \nflow.set(\"totalPassedTime\", totalPassedTime);\n\n\n","outputs":1,"noerr":0,"x":1100,"y":140,"wires":[["97aab747.cc9c68"]]},{"id":"850493c5.19df7","type":"counter","z":"412bd4f2.ad4b3c","name":"Array Index Counter time","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":"1","x":370,"y":140,"wires":[["b6487b90.228818"]]},{"id":"3a47c8a5.8bbe18","type":"function","z":"412bd4f2.ad4b3c","name":"start time message","func":"var totalStartTime = flow.get(\"totalStartTime\");\nvar speedArray = flow.get(\"speedArray\")\nif (msg.count+1 === 1000){\n msg.payload = \"Start Time\" + \": \" + totalStartTime\n return msg;\n}","outputs":1,"noerr":0,"x":1350,"y":380,"wires":[["c98ecf46.7051f"]]},{"id":"c2b03efc.23c42","type":"function","z":"412bd4f2.ad4b3c","name":"Instantaneous Avg Speed Calculator","func":" var speedArray = flow.get(\"speedArray\");\ninstantaneousAvgSpeed = 0;\n\n\nfor (i=speedArray.length-5; i 50)\n{\n power = 50;\n \n}\nelse if (power < 0)\n{\n power = 0;\n \n}\nmsg.payload = power\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":680,"wires":[["f9850197.e2855"]]},{"id":"304be476.b029cc","type":"function","z":"412bd4f2.ad4b3c","name":"Store pwm Red","func":"// var power = Math.round(msg.delay/10)\n\nvar currentSpeedLimit = flow.get(\"currentSpeedLimit\")\nvar power = ((msg.payload-currentSpeedLimit)*10);\n\nif (power > 100)\n{\n power = 100;\n \n}\nelse if (power < 50)\n{\n power = 50;\n \n}\nmsg.payload = power\nreturn msg;","outputs":1,"noerr":0,"x":460,"y":720,"wires":[["15be26ea.f0fbf9"]]},{"id":"cd49701c.ab159","type":"function","z":"412bd4f2.ad4b3c","name":"Get Delay","func":"var currentSpeedLimit = flow.get(\"currentSpeedLimit\")\n//msg.payload = currentSpeed\n\n//500->1 as currentSpeed-currentSpeedLimit 10 -> 20\n\ndelayModifier = (msg.payload-currentSpeedLimit - 10)*50;\n\nmsg.delay = (1000-delayModifier);\nif (msg.delay<0){\n msg.delay=0\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":900,"wires":[["449e7783.1fa5e8","d0ddefd4.b4a16"]]},{"id":"48e5676c.8635f8","type":"rpi-gpio out","z":"412bd4f2.ad4b3c","name":"Buzzlightyear","pin":"11","set":true,"level":"1","freq":"","out":"out","x":900,"y":860,"wires":[]},{"id":"449e7783.1fa5e8","type":"delay","z":"412bd4f2.ad4b3c","name":"","pauseType":"delayv","timeout":"1","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":500,"y":900,"wires":[["76f2c6f5.9cad98"]]},{"id":"76f2c6f5.9cad98","type":"function","z":"412bd4f2.ad4b3c","name":"Repeat","func":"if(flow.get('counter') == 1)\n{\n counter = 0;\n msg.payload = 0;\n \n}\nelse if (flow.get('counter') === 0)\n{\n counter = 1;\n msg.payload = 1;\n}\nflow.set('counter', counter);\nreturn msg;","outputs":1,"noerr":0,"x":680,"y":880,"wires":[["27d53b6a.b0cc34","48e5676c.8635f8"]]},{"id":"e07715a4.5704d8","type":"function","z":"412bd4f2.ad4b3c","name":"initiate vars","func":"var currentSpeedLimit = msg.payload\nflow.set(\"currentSpeedLimit\", currentSpeedLimit)\nvar currentSpeed = flow.get('currentSpeedCheck');\nmsg.payload = currentSpeed;\nif (msg.count === 1) {\n flow.set(\"counter\", 1)\n}\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":90,"y":560,"wires":[["868704a2.58f4d8"]]},{"id":"43c31dab.4947e4","type":"function","z":"412bd4f2.ad4b3c","name":"full green","func":"msg.payload = 100;\nreturn msg;","outputs":1,"noerr":0,"x":460,"y":500,"wires":[["f9850197.e2855"]]},{"id":"2b0d3312.47c86c","type":"delay","z":"412bd4f2.ad4b3c","name":"textOverSpeeding?","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"30","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":370,"y":1000,"wires":[["e3d44f2c.3fecf"]]},{"id":"5ec8a66c.aeb0c8","type":"sms","z":"412bd4f2.ad4b3c","name":"sms","message":"","numbers":"","throttle":1000,"twilio":"","x":710,"y":1000,"wires":[["6b961fad.a9ba9"]]},{"id":"e3d44f2c.3fecf","type":"function","z":"412bd4f2.ad4b3c","name":"what to text","func":"var currentSpeedLimit = flow.get(\"currentSpeedLimit\")\nvar currentSpeed = msg.payload;\n\nvar textToText = \" !!WARNING!! - The driver is going \" + currentSpeed + \"mph on a road with a speed limit of \" + currentSpeedLimit + \", \" + (currentSpeed-currentSpeedLimit) + \"mph over the speed limit!\"\n\nmsg.payload = textToText\nif (currentSpeed>currentSpeedLimit){\n return msg;\n}","outputs":1,"noerr":0,"x":550,"y":1000,"wires":[["5ec8a66c.aeb0c8"]]},{"id":"6b961fad.a9ba9","type":"debug","z":"412bd4f2.ad4b3c","name":"Texted","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":830,"y":1000,"wires":[]},{"id":"b00f107.7aca7f","type":"function","z":"412bd4f2.ad4b3c","name":"no red","func":"msg.payload = 0;\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":560,"wires":[["15be26ea.f0fbf9"]]},{"id":"b5ff75ab.1d5718","type":"debug","z":"412bd4f2.ad4b3c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":380,"y":240,"wires":[]},{"id":"b9ff440e.474098","type":"debug","z":"412bd4f2.ad4b3c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":380,"y":400,"wires":[]},{"id":"8360091f.3d1d18","type":"function","z":"412bd4f2.ad4b3c","name":"turn off alarm buzzer","func":"var currentSpeedLimit = flow.get(\"currentSpeedLimit\")\n\nif (msg.payload-10<=currentSpeedLimit){\n msg.payload = 1\n return msg;\n}","outputs":1,"noerr":0,"x":620,"y":780,"wires":[["48e5676c.8635f8"]]},{"id":"d0ddefd4.b4a16","type":"debug","z":"412bd4f2.ad4b3c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"delay","targetType":"msg","x":500,"y":860,"wires":[]},{"id":"b3a37bc0.89c648","type":"function","z":"412bd4f2.ad4b3c","name":"count speed limit overs","func":"var speedLimitOverCounter = flow.get(\"speedLimitOverCounter\") || 0;\nspeedLimitOverCounter += 1\nflow.set(\"speedLimitOverCounter\", speedLimitOverCounter)","outputs":1,"noerr":0,"x":140,"y":860,"wires":[["48c40144.e01b1"]]},{"id":"59736074.c2188","type":"delay","z":"412bd4f2.ad4b3c","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":120,"y":780,"wires":[["b3a37bc0.89c648"]]},{"id":"48c40144.e01b1","type":"debug","z":"412bd4f2.ad4b3c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":110,"y":920,"wires":[]}]

Since we do not have a speedometer or GPS, although it could be somewhat easily added to the system, there are 6 nodes that together emulate speed limits and a car slowly speeding up you can modify the systems which output these values in the inject nodes' arrays.

Now, all you need to do is sign up for a Twilio account and input your phone number and account information into the two blue SMS nodes. You then can enter your phone number to receive the texts.

Your done! Just press the red "Deploy" button in the top right and you should be good to go! Feel free to add GPS capabilities, a speedometer, or other modules to improve on our design.