Traffic Light Project


I am part of dynamic daves IoT club and we were working on a traffic light patten, the guy next to was trying to do it the simplest way. He says it does not work can anyone help



Please he is desperate.



Hi @IoT_Student

it is hard to help from just a screenshot and no description of what the problem is. Have you got any more details you can share? What isn't working? What is it supposed to do?



Well I carn’t get hold of the flow right at the minute but I can tell you it evolved from a 4 node flow (which worked) and then he duplicated all the nodes again to make them go in a pattern, in my opinion it has something to to with the wiring. When I next get hold of the RPI then I will take more screenshots



Just to put everyone's mind at rest... this student either hadn't listened to the instructions on how to build a Traffic Light Controller using a Finite State Machine (FSM) or had entered a (self-set) personal challenge to throw as many nodes onto the workspace as he could.

This is what the final result SHOULD HAVE LOOKED LIKE.

Please do not waste your time and effort trying to debug/decipher the original screenshot.

[{"id":"54c45d46.5c3234","type":"function","z":"bcd0e410.06d5f","name":"Index the State Counter","func":"// In this particular situation the state_counter increments by unity on each clock pulse\n// so you could code it as below\n\n\nvar fsm_state = flow.get(\"state_counter\") || 0;\n\nif (fsm_state > 2)\n   {fsm_state = 0;}\nelse\n   {fsm_state = fsm_state + 1;}\n\nflow.set(\"state_counter\", fsm_state);\nmsg.payload = fsm_state;\nnode.status({text:\"State counter = \" + fsm_state});\n\nreturn msg;","outputs":"1","noerr":0,"x":490,"y":340,"wires":[[]]},{"id":"760b4fc6.26e1","type":"function","z":"bcd0e410.06d5f","name":"Decode RED light","func":"var fsm_state = flow.get(\"state_counter\");\n\nif (fsm_state === 0 || fsm_state == 1)\n   {msg.payload = 1;\n    node.status({fill:\"red\",shape:\"dot\",text:\"Red ON\"});\n   }\n   \nelse\n   {msg.payload = 0;\n    node.status({});\n   }\n\nreturn msg;","outputs":1,"noerr":0,"x":770,"y":120,"wires":[["c94d8288.2c5768"]]},{"id":"c24343bf.b80df8","type":"function","z":"bcd0e410.06d5f","name":"Decode YELLOW light","func":"var fsm_state = flow.get(\"state_counter\");\n\nif (fsm_state == 1 || fsm_state == 3)\n   {msg.payload = 1;\n   node.status({fill:\"yellow\",shape:\"dot\",text:\"Yellow ON\"});\n   }\nelse\n   {msg.payload = 0;\n   node.status({});}\n\nreturn msg;","outputs":1,"noerr":0,"x":780,"y":180,"wires":[["63d8f972.47a4a8"]]},{"id":"6b986e0f.b813b8","type":"function","z":"bcd0e410.06d5f","name":"Decode GREEN light","func":"var fsm_state = flow.get(\"state_counter\");\n\nif (fsm_state == 2)\n   {msg.payload = 1;\n   node.status({fill:\"green\",shape:\"dot\",text:\"Green ON\"});\n   }\nelse\n   {msg.payload = 0;\n   node.status({});\n   }\n\nreturn msg;","outputs":1,"noerr":0,"x":780,"y":240,"wires":[["5e6efa8f.a722fc"]]},{"id":"c94d8288.2c5768","type":"mqtt out","z":"bcd0e410.06d5f","name":"","topic":"/node45/gpio/14","qos":"","retain":"","broker":"2a59a09b.7857c","x":1050,"y":120,"wires":[]},{"id":"63d8f972.47a4a8","type":"mqtt out","z":"bcd0e410.06d5f","name":"","topic":"/node45/gpio/12","qos":"","retain":"","broker":"2a59a09b.7857c","x":1050,"y":180,"wires":[]},{"id":"5e6efa8f.a722fc","type":"mqtt out","z":"bcd0e410.06d5f","name":"","topic":"/node45/gpio/13","qos":"","retain":"","broker":"2a59a09b.7857c","x":1050,"y":240,"wires":[]},{"id":"801d6dfd.1244","type":"inject","z":"bcd0e410.06d5f","name":"Trigger every 3 seconds","topic":"","payload":"1","payloadType":"num","repeat":"3","crontab":"","once":true,"x":230,"y":180,"wires":[["d748e7bb.cdeb78"]]},{"id":"d748e7bb.cdeb78","type":"function","z":"bcd0e410.06d5f","name":"Index the State Counter","func":"// Here is the classical way of coding a state machine.\n// It uses a 'case construct' to check the current state and then set the next state.\n\nvar fsm_state = flow.get(\"state_counter\") || 0;\n\nswitch (fsm_state)\n    {\n        case 0:\n            fsm_state = 1;\n            break;\n            \n        case 1:\n            fsm_state = 2;\n            break;\n        \n        case 2:\n            fsm_state = 3;\n            break;\n            \n        case 3:\n            fsm_state = 0;\n            break;\n    }\n    \nflow.set(\"state_counter\", fsm_state);\nmsg.payload = fsm_state;\nnode.status({text:\"State counter = \" + fsm_state});\n\nreturn msg;","outputs":"1","noerr":0,"x":490,"y":180,"wires":[["760b4fc6.26e1","c24343bf.b80df8","6b986e0f.b813b8"]]},{"id":"593de78a.0972a8","type":"comment","z":"bcd0e410.06d5f","name":"Simple way to code the state machine","info":"","x":490,"y":300,"wires":[]},{"id":"2a59a09b.7857c","type":"mqtt-broker","z":"","name":"BeeBotte","broker":"","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]


That looks nice but, just for the recorded, I think, you should avoid using function nodes for simple things like changing operations (for example the “Decode XXXX light” functions).
You can easily do that by using”change” together with “switch” nodes. I learnt from my past experience that, by using those nodes the flow became much more easy to read, understand and develop.



Hi - I agree the "change" node does simplify the flow, but in this situation the students are outputting "node.status" (within the function node) to indicate what each LED is doing (just in case the MQTT link wasn't working). I don't think the "change" node can handle 'node.status' ???